Advanced Order Export For WooCommerce - Version 2.0.0

Version Description

  • 2018-10-24 =
  • It's a major update. Backup settings (tab "Tools") before upgrading
  • New section "Set up fields to export" - simplify UI, format fields, allow duplicates
  • Compatible with Woocommerce 3.5
Download this release

Release Info

Developer algol.plus
Plugin Icon 128x128 Advanced Order Export For WooCommerce
Version 2.0.0
Comparing to
See all releases

Code changes from version 1.5.6 to 2.0.0

Files changed (35) hide show
  1. assets/css/export.css +223 -14
  2. assets/css/select2/select2.min.css +1 -0
  3. assets/js/export.js +291 -141
  4. assets/js/select2/i18n/de.js +3 -0
  5. assets/js/select2/i18n/es.js +3 -0
  6. assets/js/select2/i18n/fr.js +3 -0
  7. assets/js/select2/i18n/pt-BR.js +3 -0
  8. assets/js/select2/i18n/pt.js +3 -0
  9. assets/js/select2/i18n/ru.js +3 -0
  10. assets/js/select2/i18n/zh-CN.js +3 -0
  11. assets/js/select2/select2.full.js +6436 -0
  12. assets/js/settings-form.js +815 -166
  13. classes/admin/class-wc-order-export-ajax.php +1 -1
  14. classes/admin/class-wc-order-export-labels.php +165 -0
  15. classes/admin/class-wc-order-export-manage.php +402 -57
  16. classes/class-wc-order-export-admin.php +54 -12
  17. classes/core/class-wc-order-export-data-extractor-ui.php +115 -20
  18. classes/core/class-wc-order-export-data-extractor.php +119 -261
  19. classes/core/class-wc-order-export-engine.php +183 -293
  20. classes/formats/abstract-class-woe-formatter-plain-format.php +273 -0
  21. classes/formats/abstract-class-woe-formatter-sv.php +33 -26
  22. classes/formats/abstract-class-woe-formatter.php +91 -14
  23. classes/formats/class-woe-formatter-json.php +28 -12
  24. classes/formats/class-woe-formatter-tsv.php +2 -2
  25. classes/formats/class-woe-formatter-xls.php +70 -34
  26. classes/formats/class-woe-formatter-xml.php +27 -19
  27. classes/formats/trait-woe-plain-format.php +242 -0
  28. i18n/languages/woo-order-export-lite.pot +450 -352
  29. readme.txt +8 -3
  30. view/modal-controls.php +0 -55
  31. view/settings-form.php +261 -88
  32. view/tab/order-actions.php +1 -1
  33. view/tab/profiles.php +1 -1
  34. view/tab/schedules.php +1 -1
  35. woo-order-export-lite.php +6 -18
assets/css/export.css CHANGED
@@ -1,9 +1,6 @@
1
- #fields {
2
-
3
-
4
  height: 800px;
5
- overflow: scroll;
6
- width: 530px;
7
  padding: 20px;
8
  border-color: rgb(187, 180, 180);
9
  border-style: solid;
@@ -33,7 +30,6 @@
33
 
34
  .fields_control_style {
35
  padding: 10px;
36
- // width: 530px;
37
  border-color: rgb(187, 180, 180);
38
  border-style: solid;
39
  border-width: 1px;
@@ -66,7 +62,7 @@
66
 
67
  #fields_control {
68
  padding: 10px;
69
- width: 530px;
70
  border-color: rgb(187, 180, 180);
71
  border-style: solid;
72
  border-width: 1px;
@@ -98,7 +94,15 @@
98
  padding: 0px;
99
  min-width: 100px;
100
  }
101
- #order_fields { list-style-type: none; margin: 0; padding: 0; width: 490px; }
 
 
 
 
 
 
 
 
102
  #output_preview {border-color:green; border-style: dashed; border-width: 1px; display:none; width:90% }
103
  .spit-settings-cols {width:20px}
104
 
@@ -121,7 +125,7 @@
121
  }
122
  .mapping_col_2{
123
  display:table-cell;
124
- width:150px;
125
  }
126
  .mapping_col_3{
127
  display:table-cell;
@@ -404,11 +408,7 @@ input.date{
404
  .email_body_textarea
405
  {
406
  height: 451px;
407
- width: 736px;
408
- }
409
- #modal-email-body
410
- {
411
- display: none;
412
  }
413
  .select_compare
414
  {
@@ -694,4 +694,213 @@ input.date{
694
 
695
  #my-shedule-days .input-mins-custom-interval {
696
  max-width: 100px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
697
  }
1
+ #fields, #unselected_fields {
 
 
2
  height: 800px;
3
+ /*overflow: scroll;*/
 
4
  padding: 20px;
5
  border-color: rgb(187, 180, 180);
6
  border-style: solid;
30
 
31
  .fields_control_style {
32
  padding: 10px;
 
33
  border-color: rgb(187, 180, 180);
34
  border-style: solid;
35
  border-width: 1px;
62
 
63
  #fields_control {
64
  padding: 10px;
65
+ /*width: 530px;*/
66
  border-color: rgb(187, 180, 180);
67
  border-style: solid;
68
  border-width: 1px;
94
  padding: 0px;
95
  min-width: 100px;
96
  }
97
+ #order_fields {
98
+ list-style-type: none;
99
+ margin: 0;
100
+ padding: 0;
101
+ min-height: 50vh;
102
+ overflow-y: scroll;
103
+ overflow-x: hidden;
104
+ height: 630px;
105
+ }
106
  #output_preview {border-color:green; border-style: dashed; border-width: 1px; display:none; width:90% }
107
  .spit-settings-cols {width:20px}
108
 
125
  }
126
  .mapping_col_2{
127
  display:table-cell;
128
+ min-width:150px;
129
  }
130
  .mapping_col_3{
131
  display:table-cell;
408
  .email_body_textarea
409
  {
410
  height: 451px;
411
+ width: 100%;
 
 
 
 
412
  }
413
  .select_compare
414
  {
694
 
695
  #my-shedule-days .input-mins-custom-interval {
696
  max-width: 100px;
697
+ }
698
+
699
+ .flat_format_controls div {
700
+ margin: 10px;
701
+ }
702
+
703
+ .mapping_row.segment_products {
704
+ background-color: #c5ffbb;
705
+ }
706
+
707
+ .mapping_row.segment_coupons {
708
+ background-color: #c2bdff;
709
+ }
710
+
711
+
712
+
713
+ .segment_choice {
714
+ cursor: pointer;
715
+ }
716
+
717
+ .segment_choice.active {
718
+ font-weight: bold;
719
+ color: #000;
720
+ }
721
+
722
+ .settings-segment:not(.active) {
723
+ display: none;
724
+ }
725
+
726
+ .segment_fields li {
727
+ /*padding: 3px;*/
728
+ }
729
+
730
+ .segment_field {
731
+ padding: 3px;
732
+ margin: 3px;
733
+ cursor: pointer;
734
+ /*display: inline-block;*/
735
+ vertical-align: top;
736
+ overflow: hidden;
737
+ /*flex-basis: 45%;*/
738
+ }
739
+
740
+ .segment_field.blink {
741
+ animation: blinker 3s linear infinite;
742
+ }
743
+
744
+ @keyframes blinker {
745
+ 50% { opacity: 0; }
746
+ }
747
+
748
+ .section {
749
+ display: flex;
750
+ flex-wrap: wrap;
751
+ }
752
+
753
+ .ui-draggable.segment_field .mapping_col_1,
754
+ .ui-draggable.segment_field .mapping_col_3:not(.custom-field-value),
755
+ .mapping_row.segment_field .mapping_row-delete_field,
756
+ .mapping_row.ui-draggabled .mapping_row-delete_custom_field {
757
+ display: none;
758
+ }
759
+
760
+ .ui-draggable.segment_field .mapping_col_3.custom-field-value {
761
+ padding: 0;
762
+ }
763
+
764
+ .ui-draggable.segment_field .mapping_col_3.custom-field-value .mapping_fieldname {
765
+ margin: 0 1px;
766
+ font-size: 12px;
767
+ padding: 0 3px;
768
+ }
769
+
770
+ .ui-draggable.segment_field .mapping_col_3.custom-field-value {
771
+ max-width: 50px;
772
+ }
773
+
774
+
775
+ #order_fields #sortable_products,
776
+ #order_fields #sortable_coupons {
777
+ min-height: 40px;
778
+ margin-left: 30px;
779
+ }
780
+
781
+ #order_fields.non_flat_height {
782
+ height: 750px;
783
+ }
784
+
785
+ .tab-actions-buttons {
786
+ margin-top: 10px;
787
+ line-height: 30px;
788
+ vertical-align: middle;
789
+ }
790
+
791
+ .tab-actions-buttons__title {
792
+ margin-right: 7px;
793
+ }
794
+
795
+ .tab-actions-forms .segment-form {
796
+ border-color: rgb(187, 180, 180);
797
+ border-style: solid;
798
+ border-width: 1px;
799
+ /*display: inline-block;*/
800
+ padding: 10px;
801
+ margin-top: 10px;
802
+ }
803
+
804
+ .tab-actions-forms label {
805
+ display: inline-block;
806
+ padding: 5px;
807
+ min-width: 100px;
808
+
809
+ }
810
+
811
+ .tab-actions-forms span {
812
+ display:block;
813
+ width:100px;
814
+ height: 100%;
815
+ margin: 0 auto;
816
+ padding: 5px;
817
+ }
818
+
819
+ .tab-actions-forms .div_meta label {
820
+ display: inline-block;
821
+ padding: 0px;
822
+ min-width: 120px;
823
+ }
824
+
825
+ .tab-actions-forms .segment-form:not(.active) {
826
+ display: none;
827
+ }
828
+
829
+ .tab-actions-forms .segment-form select {
830
+ margin-left: 1px;
831
+ }
832
+
833
+ #fields .fields-control-block .display_as {
834
+ display: none;
835
+ }
836
+
837
+ #fields .fields-control-block .display_as input[type="text"] {
838
+ max-width: 50px;
839
+ }
840
+
841
+ #fields .fields-control-block .display_as.active {
842
+ display: inline-block;
843
+ }
844
+
845
+ #fields .fields-control-block .display_as div {
846
+ display: inline-block;
847
+ }
848
+
849
+ #fields .fields-control-block .display_as.duplicate_columns_options > div {
850
+ margin: 0 5px 0 5px;
851
+ }
852
+
853
+ #fields .fields-control-block .display_as.duplicate_rows_options > div label,
854
+ #fields .fields-control-block .display_as.duplicate_inside_one_cell_options > div label{
855
+ margin: 0 5px 0 5px;
856
+ }
857
+
858
+ .fields-control-block {
859
+ margin-top: 10px;
860
+ }
861
+
862
+ .fields-control-block .segment-header {
863
+ margin-bottom: 5px;
864
+ display: inline-block;
865
+ }
866
+
867
+ .fields-control-block .segment-header select {
868
+ width: auto;
869
+ }
870
+
871
+ .fields-control-block .display_as .input-delimiter {
872
+ max-width: 40px;
873
+ }
874
+
875
+ #manage_fields.summary-products-report .fields-control-block,
876
+ #manage_fields.summary-products-report #order_fields .mapping_row:not(.segment_products),
877
+ #manage_fields.summary-products-report .field-prefix,
878
+ #manage_fields.summary-products-report #unselected_fields .subsubsub,
879
+ #manage_fields.summary-products-report #unselected_fields label[for="select_custom_meta_order_items"],
880
+ #manage_fields.summary-products-report #unselected_fields #select_custom_meta_order_items {
881
+ display: none;
882
+ }
883
+
884
+ #manage_fields.summary-products-report #unselected_fields .tab-actions-buttons {
885
+ margin-top: 0;
886
+ }
887
+
888
+ .mapping_row-delete_field_block .mapping_row-delete_field {
889
+ color: #000;
890
+ text-decoration: none;
891
+ }
892
+
893
+ .mapping_row-delete_field_block .mapping_row-delete_field .dashicons {
894
+ margin-top: 0;
895
+ }
896
+
897
+ #order_fields .mapping_row:not(.flat-products-group):not(.flat-coupons-group) {
898
+ position: relative;
899
+ padding-right: 35px;
900
+ }
901
+
902
+ #order_fields .mapping_row .mapping_row-delete_field_block {
903
+ position: absolute;
904
+ top: 5px;
905
+ right: 5px;
906
  }
assets/css/select2/select2.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;height:1px !important;margin:-1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__placeholder{color:#999;margin-top:5px;float:left}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb}
assets/js/export.js CHANGED
@@ -35,10 +35,10 @@ window.onload = function () {
35
  return undefined;
36
  }
37
  } );
38
-
39
  //force style for popup!
40
- var style = jQuery('<style>#TB_ajaxContent { overflow: auto !important; }</style>');
41
- jQuery('html > head').append(style);
42
  };
43
 
44
  function bind_events() {
@@ -63,15 +63,16 @@ function bind_events() {
63
  jQuery.each( response, function( index, value ) {
64
  options += '<option>' + value + '</option>';
65
  } );
66
- var $select = jQuery( '<div id="select_custom_fields--select2" style="margin-top: 0px;margin-right: 6px; vertical-align: top;'
67
  + 'display: ' + (('LIKE' === val_op || 'NOT SET' === val_op|| 'IS SET' === val_op) ? 'none' : 'inline-block') + ';">'
68
  + '<select id="select_custom_fields">' + options + '</select></div>' );
69
  $select.insertBefore( jQuery( '#add_custom_fields' ) )
70
- $select.find('select').select2({ tags: true });
71
  }
72
  else {
73
  jQuery( '<input type="text" id="select_custom_fields" style="margin-right: 8px;">' ).insertBefore( jQuery( '#add_custom_fields' ) );
74
  }
 
75
  }, 'json' );
76
  } );
77
  jQuery( '#add_custom_fields' ).click( function() {
@@ -97,7 +98,7 @@ function bind_events() {
97
  jQuery( '#custom_fields_check' ).append( '<option selected="selected" value="' + result + '">' + result + '</option>' );
98
  }
99
 
100
- jQuery( '#custom_fields_check' ).select2();
101
 
102
  jQuery( '#custom_fields_check option' ).each( function() {
103
  jQuery( '#custom_fields_check option[value=\"' + jQuery( this ).val() + '\"]:not(:last)' ).remove();
@@ -142,7 +143,7 @@ function bind_events() {
142
  method: "get_products_attributes_values",
143
  action: "order_exporter"
144
  };
145
-
146
  var val_op = jQuery( '#attributes_compare' ).val();
147
  jQuery( '#text_attributes' ).val( '' );
148
 
@@ -155,11 +156,11 @@ function bind_events() {
155
  jQuery.each( response, function( index, value ) {
156
  options += '<option>' + value + '</option>';
157
  } );
158
- var $select = jQuery( '<div id="select_attributes--select2" style="margin-top: 0px;margin-right: 6px; vertical-align: top;'
159
  + 'display: ' + (('LIKE' === val_op) ? 'none' : 'inline-block') + ';">'
160
  + '<select id="select_attributes">' + options + '</select></div>' );
161
  $select.insertBefore( jQuery( '#add_attributes' ) )
162
- $select.find('select').select2({ tags: true });
163
  }
164
  else {
165
  jQuery( '<input type="text" id="select_attributes" style="margin-right: 8px;">' ).insertBefore( jQuery( '#add_attributes' ) );
@@ -185,7 +186,7 @@ function bind_events() {
185
  if ( f ) {
186
 
187
  jQuery( '#attributes_check' ).append( '<option selected="selected" value="' + val + '">' + val + '</option>' );
188
- jQuery( '#attributes_check' ).select2(select2WODropdownOpts);
189
 
190
  jQuery( '#attributes_check option' ).each( function() {
191
  jQuery( '#attributes_check option[value=\"' + jQuery( this ).val() + '\"]:not(:last)' ).remove();
@@ -222,7 +223,7 @@ function bind_events() {
222
  method: "get_products_itemmeta_values",
223
  action: "order_exporter"
224
  };
225
-
226
  var val_op = jQuery( '#itemmeta_compare' ).val();
227
  jQuery( '#text_itemmeta' ).val( '' );
228
 
@@ -234,11 +235,11 @@ function bind_events() {
234
  jQuery.each( response, function( index, value ) {
235
  options += '<option>' + value + '</option>';
236
  } );
237
- var $select = jQuery( '<div id="select_itemmeta--select2" style="margin-top: 0px;margin-right: 6px; vertical-align: top;'
238
  + 'display: ' + (('LIKE' === val_op) ? 'none' : 'inline-block') + ';">'
239
  + '<select id="select_itemmeta">' + options + '</select></div>' );
240
  $select.insertBefore( jQuery( '#add_itemmeta' ) )
241
- $select.find('select').select2({ tags: true });
242
  }
243
  else {
244
  jQuery( '<input type="text" id="select_itemmeta" style="margin-right: 8px;">' ).insertBefore( jQuery( '#add_itemmeta' ) );
@@ -265,7 +266,7 @@ function bind_events() {
265
  if ( f ) {
266
 
267
  jQuery( '#itemmeta_check' ).append( '<option selected="selected" value="' + val + '">' + val + '</option>' );
268
- jQuery( '#itemmeta_check' ).select2(select2WODropdownOpts);
269
 
270
  jQuery( '#itemmeta_check option' ).each( function() {
271
  jQuery( '#itemmeta_check option[value=\"' + jQuery( this ).val() + '\"]:not(:last)' ).remove(); // jQuerySelectorEscape ?
@@ -313,7 +314,7 @@ function bind_events() {
313
  var $select = jQuery( '<div id="select_taxonomies--select2" style="margin-top: 0px;margin-right: 6px; vertical-align: top; display: inline-block;">'
314
  + '<select id="select_taxonomies">' + options + '</select></div>' );
315
  $select.insertBefore( jQuery( '#add_taxonomies' ) )
316
- $select.find('select').select2({ tags: true });
317
  }
318
  else {
319
  jQuery( '<input type="text" id="select_taxonomies" style="margin-right: 8px;">' ).insertBefore( jQuery( '#add_taxonomies' ) );
@@ -339,7 +340,7 @@ function bind_events() {
339
  if ( f ) {
340
 
341
  jQuery( '#taxonomies_check' ).append( '<option selected="selected" value="' + val + '">' + val + '</option>' );
342
- jQuery( '#taxonomies_check' ).select2(select2WODropdownOpts);
343
 
344
  jQuery( '#taxonomies_check option' ).each( function() {
345
  jQuery( '#taxonomies_check option[value=\"' + jQuery( this ).val() + '\"]:not(:last)' ).remove();
@@ -386,11 +387,11 @@ function bind_events() {
386
  jQuery.each( response, function( index, value ) {
387
  options += '<option>' + value + '</option>';
388
  } );
389
- var $select = jQuery( '<div id="select_product_custom_fields--select2" style="margin-top: 0px;margin-right: 6px; vertical-align: top;'
390
  + 'display: ' + (('LIKE' === val_op) ? 'none' : 'inline-block') + ';">'
391
  + '<select id="select_product_custom_fields">' + options + '</select></div>' );
392
  $select.insertBefore( jQuery( '#add_product_custom_fields' ) )
393
- $select.find('select').select2({ tags: true });
394
  }
395
  else {
396
  jQuery( '<input type="text" id="select_product_custom_fields" style="margin-right: 8px;">' ).insertBefore( jQuery( '#add_product_custom_fields' ) );
@@ -415,7 +416,7 @@ function bind_events() {
415
  if ( f ) {
416
 
417
  jQuery( '#product_custom_fields_check' ).append( '<option selected="selected" value="' + val + '">' + val + '</option>' );
418
- jQuery( '#product_custom_fields_check' ).select2(select2WODropdownOpts);
419
 
420
  jQuery( '#product_custom_fields_check option' ).each( function() {
421
  jQuery( '#product_custom_fields_check option[value=\"' + jQuery( this ).val() + '\"]:not(:last)' ).remove();
@@ -470,20 +471,22 @@ function bind_events() {
470
  jQuery( '#button_custom_field' ).click( function() {
471
  var colname = jQuery( '#colname_custom_field' ).val();
472
  var value = jQuery( '#value_custom_field' ).val();
 
473
  if ( !colname )
474
  {
475
  alert( export_messages.empty_column_name );
476
  jQuery( '#colname_custom_field' ).focus();
477
  return false
478
  }
479
- /*if ( !value )
480
- {
481
- alert( 'empty Value' );
482
- jQuery( '#value_custom_field' ).focus();
483
- return false
484
- }*/
485
- add_custom_field( jQuery( "#order_fields" ), 'orders', output_format, colname, value );
486
  reset_field_contorls();
 
 
 
487
  return false;
488
  } );
489
 
@@ -496,8 +499,8 @@ function bind_events() {
496
  jQuery( '#select_custom_meta_order' ).html( options );
497
  }
498
  else {
499
- var data = jQuery( '#export_job_settings' ).serialize()
500
- data = data + "&action=order_exporter&method=get_used_custom_order_meta";
501
 
502
  jQuery.post( ajaxurl, data, function( response ) {
503
  if ( response ) {
@@ -530,7 +533,7 @@ function bind_events() {
530
  jQuery( '#select_custom_meta_order_items' ).prop( "disabled", false );
531
  }
532
  else {
533
- jQuery('#modal-manage-products').html(jQuery('#TB_ajaxContent').html());
534
  var data = jQuery( '#export_job_settings' ).serialize(),
535
  data_products = data + "&action=order_exporter&method=get_used_custom_products_meta&mode=" + mode + "&id=" + job_id,
536
  data_order_items = data + "&action=order_exporter&method=get_used_custom_order_items_meta&mode=" + mode + "&id=" + job_id;
@@ -557,7 +560,7 @@ function bind_events() {
557
  }
558
  }, 'json' );
559
 
560
- jQuery('#modal-manage-products').html('');
561
  }
562
  });
563
  jQuery('input[name=custom_meta_products_mode]').trigger('change');
@@ -589,6 +592,7 @@ function bind_events() {
589
  jQuery( '#button_custom_meta' ).click( function() {
590
  var label = jQuery( '#select_custom_meta_order' ).val();
591
  var colname = jQuery( '#colname_custom_meta' ).val();
 
592
  if (! label) //try custom text
593
  label = jQuery( '#text_custom_meta_order' ).val();;
594
  if ( !label )
@@ -603,8 +607,15 @@ function bind_events() {
603
  jQuery( '#colname_custom_meta' ).focus();
604
  return false
605
  }
606
- add_custom_meta( jQuery( "#order_fields" ), 'orders', output_format, label, colname );
 
 
 
 
607
  reset_field_contorls();
 
 
 
608
  return false;
609
  } );
610
 
@@ -631,7 +642,7 @@ function bind_events() {
631
 
632
  var $select = jQuery( '<div id="text_shipping_locations--select2" style="margin-top: 0px;margin-right: 6px; vertical-align: top; display: inline-block;"><select id="text_shipping_locations">' + options + '</select></div>' );
633
  $select.insertBefore( jQuery( '#add_shipping_locations' ) )
634
- $select.find('select').select2({ tags: true });
635
  }
636
  else {
637
  jQuery( '<input type="text" id="text_shipping_locations" style="margin-right: 8px;">' ).insertBefore( jQuery( '#add_shipping_locations' ) );
@@ -657,7 +668,7 @@ function bind_events() {
657
  if ( f ) {
658
 
659
  jQuery( '#shipping_locations_check' ).append( '<option selected="selected" value="' + val + '">' + val + '</option>' );
660
- jQuery( '#shipping_locations_check' ).select2(select2WODropdownOpts);
661
 
662
  jQuery( '#shipping_locations_check option' ).each( function() {
663
  jQuery( '#shipping_locations_check option[value=\"' + jQuery( this ).val() + '\"]:not(:last)' ).remove();
@@ -690,7 +701,7 @@ function bind_events() {
690
  var $select = jQuery( '<div id="text_billing_locations--select2" style="margin-top: 0px;margin-right: 6px; vertical-align: top; display: inline-block;">'
691
  + '<select id="text_billing_locations">' + options + '</select></div>' );
692
  $select.insertBefore( jQuery( '#add_billing_locations' ) )
693
- $select.find('select').select2({ tags: true });
694
  }
695
  else {
696
  jQuery( '<input type="text" id="text_billing_locations" style="margin-right: 8px;">' ).insertBefore( jQuery( '#add_billing_locations' ) );
@@ -716,7 +727,7 @@ function bind_events() {
716
  if ( f ) {
717
 
718
  jQuery( '#billing_locations_check' ).append( '<option selected="selected" value="' + val + '">' + val + '</option>' );
719
- jQuery( '#billing_locations_check' ).select2(select2WODropdownOpts);
720
 
721
  jQuery( '#billing_locations_check option' ).each( function() {
722
  jQuery( '#billing_locations_check option[value=\"' + jQuery( this ).val() + '\"]:not(:last)' ).remove();
@@ -727,8 +738,8 @@ function bind_events() {
727
  }
728
  return false;
729
  } )
730
-
731
-
732
  // ITEM NAMES
733
  jQuery( '#item_names' ).change( function() {
734
 
@@ -750,7 +761,7 @@ function bind_events() {
750
 
751
  var $select = jQuery( '<div id="text_item_names--select2" style="margin-top: 0px;margin-right: 6px; vertical-align: top; display: inline-block;"><select id="text_item_names">' + options + '</select></div>' );
752
  $select.insertBefore( jQuery( '#add_item_names' ) )
753
- $select.find('select').select2({ tags: true });
754
  }
755
  else {
756
  jQuery( '<input type="text" id="text_item_names" style="margin-right: 8px;">' ).insertBefore( jQuery( '#add_item_names' ) );
@@ -776,7 +787,7 @@ function bind_events() {
776
  if ( f ) {
777
 
778
  jQuery( '#item_names_check' ).append( '<option selected="selected" value="' + val + '">' + val + '</option>' );
779
- jQuery( '#item_names_check' ).select2(select2WODropdownOpts);
780
 
781
  jQuery( '#item_names_check option' ).each( function() {
782
  jQuery( '#item_names_check option[value=\"' + jQuery( this ).val() + '\"]:not(:last)' ).remove();
@@ -787,7 +798,7 @@ function bind_events() {
787
  }
788
  return false;
789
  } );
790
-
791
  // ITEM METADATA
792
  jQuery( '#item_metadata' ).change( function() {
793
 
@@ -809,7 +820,7 @@ function bind_events() {
809
 
810
  var $select = jQuery( '<div id="text_item_metadata--select2" style="margin-top: 0px;margin-right: 6px; vertical-align: top; display: inline-block;"><select id="text_item_metadata">' + options + '</select></div>' );
811
  $select.insertBefore( jQuery( '#add_item_metadata' ) )
812
- $select.find('select').select2({ tags: true });
813
  }
814
  else {
815
  jQuery( '<input type="text" id="text_item_metadata" style="margin-right: 8px;">' ).insertBefore( jQuery( '#add_item_metadata' ) );
@@ -835,7 +846,7 @@ function bind_events() {
835
  if ( f ) {
836
 
837
  jQuery( '#item_metadata_check' ).append( '<option selected="selected" value="' + val + '">' + val + '</option>' );
838
- jQuery( '#item_metadata_check' ).select2(select2WODropdownOpts);
839
 
840
  jQuery( '#item_metadata_check option' ).each( function() {
841
  jQuery( '#item_metadata_check option[value=\"' + jQuery( this ).val() + '\"]:not(:last)' ).remove();
@@ -846,16 +857,7 @@ function bind_events() {
846
  }
847
  return false;
848
  } );
849
-
850
 
851
-
852
-
853
- jQuery( '#summary_report_by_products_checkbox' ).on('change', function() {
854
- jQuery('#manage_fields').parent().toggle(jQuery('#summary_report_by_products_checkbox').val());
855
- } );
856
- if( jQuery('#summary_report_by_products_checkbox').prop('checked') ) {
857
- jQuery('#manage_fields').parent().hide();
858
- }
859
  }
860
 
861
  function bind_events_users() {
@@ -887,7 +889,7 @@ function bind_events_users() {
887
  ) + ';">'
888
  + '<select id="select_user_custom_fields">' + options + '</select></div>' );
889
  $select.insertBefore( jQuery( '#add_user_custom_fields' ) )
890
- $select.find( 'select' ).select2( {tags: true} );
891
  }
892
  else {
893
  jQuery( '<input type="text" id="select_user_custom_fields" style="margin-right: 8px;">' ).insertBefore(
@@ -921,7 +923,7 @@ function bind_events_users() {
921
  '#user_custom_fields_check' ).append( '<option selected="selected" value="' + result + '">' + result + '</option>' );
922
  }
923
 
924
- jQuery( '#user_custom_fields_check' ).select2();
925
 
926
  jQuery( '#user_custom_fields_check option' ).each( function () {
927
  jQuery( '#user_custom_fields_check option[value=\"' + jQuery( this ).val() + '\"]:not(:last)' ).remove();
@@ -958,6 +960,7 @@ function add_bind_for_custom_fields( prefix, output_format, $to ) {
958
  jQuery( '#button_custom_field_' + prefix + '' ).click( function() {
959
  var colname = jQuery( '#colname_custom_field_' + prefix + '' ).val();
960
  var value = jQuery( '#value_custom_field_' + prefix + '' ).val();
 
961
  if ( !colname )
962
  {
963
  alert( export_messages.empty_column_name );
@@ -970,9 +973,18 @@ function add_bind_for_custom_fields( prefix, output_format, $to ) {
970
  jQuery( '#value_custom_field_' + prefix + '' ).focus();
971
  return false
972
  }
 
973
  jQuery( '#colname_custom_field_' + prefix + '' ).val( "" );
 
974
  jQuery( '#value_custom_field_' + prefix + '' ).val( "" );
975
- add_custom_field( $to, prefix, output_format, colname, value );
 
 
 
 
 
 
 
976
  return false;
977
  } );
978
 
@@ -981,17 +993,30 @@ function add_bind_for_custom_fields( prefix, output_format, $to ) {
981
  var prefix_items = 'order_items',
982
  original_prefix = prefix,
983
  prefix_items_select = jQuery( '#select_custom_meta_' + prefix_items + '' ),
984
- prefix_product_select = jQuery( '#select_custom_meta_' + prefix + '' );
 
 
 
 
 
 
 
 
 
985
 
986
- var type = ( prefix_items_select.val() || prefix_product_select.val() ) ? 'meta' : 'taxonomies';
987
  if ( 'meta' === type ) {
988
- original_prefix = prefix_product_select.val() ? prefix : prefix_items;
989
  } else {
990
  original_prefix = prefix;
991
  }
992
  type = type + '_' + original_prefix;
993
  var label = jQuery( '#select_custom_' + type + '' ).val();
994
  var colname = jQuery( '#colname_custom_meta_' + prefix + '' ).val();
 
 
 
 
 
995
  if ( !label )
996
  {
997
  alert( export_messages.empty_meta_key_and_taxonomy );
@@ -1005,19 +1030,37 @@ function add_bind_for_custom_fields( prefix, output_format, $to ) {
1005
  alert( export_messages.empty_column_name );
1006
  return false
1007
  }
1008
- add_custom_meta( $to, prefix, output_format, label, colname );
 
 
 
 
 
 
1009
  jQuery( '#select_custom_' + type + '' ).val( "" );
1010
  jQuery( '#colname_custom_meta_' + prefix + '' ).val( "" );
 
1011
  return false;
1012
  } );
1013
 
1014
  }
1015
 
1016
  function reset_field_contorls() {
1017
- jQuery( '#fields_control' ).find( 'input' ).val( '' );
 
 
 
 
 
 
 
 
 
 
1018
  jQuery( "#fields_control > div" ).hide();
1019
  jQuery( "#fields_control .div1" ).show();
1020
  jQuery( "#fields_control .div2" ).show();
 
1021
  }
1022
 
1023
  function formatItem( item ) {
@@ -1032,58 +1075,154 @@ function formatItem( item ) {
1032
  return markup;
1033
  }
1034
 
1035
- function add_custom_field( to, index_p, format, colname, value ) {
1036
 
1037
  value = escapeStr(value);
1038
  colname = escapeStr(colname);
1039
- var arr = jQuery( 'input[name*=' + index_p + '\\[label\\]\\[custom_field]' );
1040
- var count = arr.length;
1041
-
1042
- var max = 0;
1043
- for(var i=0; i<count; i++) {
1044
- var n = parseInt(arr[i].name.replace(index_p+'[label][custom_field_', '').replace(']','')); // fixed for popups
1045
- if(n > max) {
1046
- max = n;
 
 
 
 
 
 
 
 
 
 
 
1047
  }
1048
  }
1049
- count = max+1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1050
 
1051
  // console.log( to, index_p, format, colname, value );
1052
- var row = '<li class="mapping_row segment_modal_' + index_p + '">\
1053
- <div class="mapping_col_1">\
1054
- <input type=hidden name="' + index_p + '[exported][custom_field_' + count + ']" value="0">\
1055
- <input type=checkbox name="' + index_p + '[exported][custom_field_' + count + ']" value="1" checked>\
1056
- <input class="mapping_fieldname" type=hidden name="' + index_p + '[segment][custom_field_' + count + ']" value="misc">\
1057
- <input class="mapping_fieldname" type=hidden name="' + index_p + '[label][custom_field_' + count + ']" value="' + colname + '">\
1058
- </div>\
1059
- <div class="mapping_col_2">' + colname + '<a href="#" onclick="return remove_custom_field(this);" style="float: right;"><span class="ui-icon ui-icon-trash"></span></a></div>\
1060
- <div class="mapping_col_3"><input class="mapping_fieldname" type=input name="' + index_p + '[colname][custom_field_' + count + ']" value="' + colname + '"></div>\
1061
- <div class="mapping_col_3"><input class="mapping_fieldname" type=input name="' + index_p + '[value][custom_field_' + count + ']" value="' + value + '"></div>\
1062
- </li>\
1063
- ';
1064
- to.append( row );
1065
-
1066
- scroll_to_added_field( to );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1067
  }
1068
 
1069
- function add_custom_meta( to, index_p, format, label, colname ) {
1070
 
1071
  label = escapeStr(label);
1072
  colname = escapeStr(colname);
1073
 
1074
- // console.log();
1075
- var row = '<li class="mapping_row segment_modal_' + index_p + '">\
1076
- <div class="mapping_col_1">\
1077
- <input type=hidden name="' + index_p + '[exported][' + label + ']" value="0">\
1078
- <input type=checkbox name="' + index_p + '[exported][' + label + ']" value="1" checked>\
1079
- <input class="mapping_fieldname" type=hidden name="' + index_p + '[label][' + label + ']" value="' + label + '">\
1080
- </div>\
1081
- <div class="mapping_col_2">' + label + '<a href="#" onclick="return remove_custom_field(this);" style="float: right;"><span class="ui-icon ui-icon-trash"></span></a></div>\
1082
- <div class="mapping_col_3"><input class="mapping_fieldname" type=input name="' + index_p + '[colname][' + label + ']" value="' + colname + '"></div>\
1083
- </li>\
1084
- ';
1085
- to.append( row );
1086
- scroll_to_added_field( to );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1087
  }
1088
 
1089
  function scroll_to_added_field( to ) {
@@ -1100,65 +1239,74 @@ function formatItemSelection( item ) {
1100
  return item.text;
1101
  }
1102
 
 
 
 
 
 
 
 
 
 
 
 
1103
  function select2_inits()
1104
  {
1105
- jQuery( "#from_status, #to_status" ).select2({
1106
- multiple: true
1107
- });
1108
- jQuery( "#statuses" ).select2();
1109
- jQuery( "#shipping_methods" ).select2();
1110
- jQuery( "#user_roles" ).select2();
1111
- jQuery( "#payment_methods" ).select2();
1112
- jQuery( "#attributes" ).select2( {
1113
  width: 150
1114
  } );
1115
- jQuery( "#attributes_check" ).select2(select2WODropdownOpts);
1116
- jQuery( "#itemmeta" ).select2( {
1117
  width: 220
1118
  } );
1119
- jQuery( "#itemmeta_check" ).select2(select2WODropdownOpts);
1120
 
1121
- jQuery( "#custom_fields" ).select2( {
1122
  width: 150
1123
  } );
1124
- jQuery( "#custom_fields_check" ).select2();
1125
 
1126
- jQuery( "#product_custom_fields" ).select2( {
1127
  width: 150
1128
  } );
1129
- jQuery( "#product_custom_fields_check" ).select2(select2WODropdownOpts);
1130
 
1131
- jQuery( "#user_custom_fields" ).select2( {
1132
  width: 150
1133
  } );
1134
- jQuery( "#user_custom_fields_check" ).select2();
1135
 
1136
- jQuery( "#taxonomies" ).select2( {
1137
  width: 150
1138
  } );
1139
- jQuery( "#taxonomies_check" ).select2(select2WODropdownOpts);
1140
 
1141
- jQuery( "#shipping_locations" ).select2( {
1142
  width: 150
1143
  } );
1144
- jQuery( "#shipping_locations_check" ).select2(select2WODropdownOpts);
1145
 
1146
- jQuery( "#billing_locations" ).select2( {
1147
  width: 150
1148
  } );
1149
- jQuery( "#billing_locations_check" ).select2(select2WODropdownOpts);
1150
 
1151
- jQuery( "#item_names" ).select2( {
1152
  width: 150
1153
  } );
1154
- jQuery( "#item_names_check" ).select2(select2WODropdownOpts);
1155
 
1156
- jQuery( "#item_metadata" ).select2( {
1157
  width: 150
1158
  } );
1159
- jQuery( "#item_metadata_check" ).select2(select2WODropdownOpts);
1160
 
1161
- jQuery( "#product_categories" ).select2( {
1162
  ajax: {
1163
  url: ajaxurl,
1164
  dataType: 'json',
@@ -1189,7 +1337,7 @@ function select2_inits()
1189
  templateSelection: formatItemSelection // omitted for brevity, see the source of this page
1190
  } );
1191
 
1192
- jQuery( "#product_vendors" ).select2( {
1193
  ajax: {
1194
  url: ajaxurl,
1195
  dataType: 'json',
@@ -1220,7 +1368,7 @@ function select2_inits()
1220
  templateSelection: formatItemSelection // omitted for brevity, see the source of this page
1221
  } );
1222
 
1223
- jQuery( "#products" ).select2( {
1224
  ajax: {
1225
  url: ajaxurl,
1226
  dataType: 'json',
@@ -1251,7 +1399,7 @@ function select2_inits()
1251
  templateSelection: formatItemSelection // omitted for brevity, see the source of this page
1252
  } );
1253
 
1254
- jQuery( "#user_names" ).select2( {
1255
  ajax: {
1256
  url: ajaxurl,
1257
  dataType: 'json',
@@ -1282,7 +1430,7 @@ function select2_inits()
1282
  templateSelection: formatItemSelection // omitted for brevity, see the source of this page
1283
  } );
1284
 
1285
- jQuery( "#coupons" ).select2( {
1286
  ajax: {
1287
  url: ajaxurl,
1288
  dataType: 'json',
@@ -1339,7 +1487,7 @@ function jQuerySelectorEscape(expression) {
1339
  return expression.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~]/g, '\\$&');
1340
  }
1341
 
1342
- //for warning
1343
  function setup_alert_date_filter() {
1344
  default_date_filter_color = jQuery( "#my-date-filter" ).css('color');
1345
  try_color_date_filter();
@@ -1347,9 +1495,9 @@ function setup_alert_date_filter() {
1347
  jQuery( '#to_date' ).change( function() { try_color_date_filter(); });
1348
  }
1349
  function try_color_date_filter() {
1350
- var color = default_date_filter_color;
1351
- if( jQuery( "#from_date" ).val() || jQuery( "#to_date" ).val() )
1352
- color = 'red';
1353
  jQuery( "#my-date-filter" ).css('color', color);
1354
  }
1355
 
@@ -1357,7 +1505,7 @@ jQuery( document ).ready( function ($) {
1357
 
1358
  $( "#the-list" ).sortable( { handle: '.woe-row-sort-handle' } );
1359
 
1360
- $( '.wp-wrap .column-order' ).hide();
1361
 
1362
  $start_reorder_button = $( '#start_reorder' );
1363
  $apply_reorder_button = $( '#apply_reorder' );
@@ -1369,8 +1517,10 @@ jQuery( document ).ready( function ($) {
1369
  $apply_reorder_button.show();
1370
  $cancel_reorder_button.show();
1371
 
1372
- $( '.wp-wrap .check-column' ).hide();
1373
- $( '.wp-wrap .column-order' ).show();
 
 
1374
  } );
1375
 
1376
  $apply_reorder_button.click( function ( e ) {
@@ -1378,8 +1528,8 @@ jQuery( document ).ready( function ($) {
1378
  $apply_reorder_button.hide();
1379
  $cancel_reorder_button.hide();
1380
 
1381
- $( '.wp-wrap .check-column' ).show();
1382
- $( '.wp-wrap .column-order' ).hide();
1383
 
1384
  jQuery.ajax({
1385
  url: ajaxurl,
@@ -1404,8 +1554,8 @@ jQuery( document ).ready( function ($) {
1404
  $apply_reorder_button.hide();
1405
  $cancel_reorder_button.hide();
1406
 
1407
- $( '.wp-wrap .check-column' ).show();
1408
- $( '.wp-wrap .column-order' ).hide();
1409
 
1410
  $( $order_ids ).each( function ( $key, $job_id ) {
1411
  $element = $( '[data-job_id="' + $job_id + '"' ).detach();
35
  return undefined;
36
  }
37
  } );
38
+
39
  //force style for popup!
40
+ // var style = jQuery('<style>#TB_ajaxContent { overflow: auto !important; }</style>');
41
+ // jQuery('html > head').append(style);
42
  };
43
 
44
  function bind_events() {
63
  jQuery.each( response, function( index, value ) {
64
  options += '<option>' + value + '</option>';
65
  } );
66
+ var $select = jQuery( '<div id="select_custom_fields--select2" style="margin-top: 0px;margin-right: 6px; vertical-align: top;'
67
  + 'display: ' + (('LIKE' === val_op || 'NOT SET' === val_op|| 'IS SET' === val_op) ? 'none' : 'inline-block') + ';">'
68
  + '<select id="select_custom_fields">' + options + '</select></div>' );
69
  $select.insertBefore( jQuery( '#add_custom_fields' ) )
70
+ $select.find('select').select2_i18n({ tags: true });
71
  }
72
  else {
73
  jQuery( '<input type="text" id="select_custom_fields" style="margin-right: 8px;">' ).insertBefore( jQuery( '#add_custom_fields' ) );
74
  }
75
+ jQuery( '#custom_fields_compare').trigger('change');
76
  }, 'json' );
77
  } );
78
  jQuery( '#add_custom_fields' ).click( function() {
98
  jQuery( '#custom_fields_check' ).append( '<option selected="selected" value="' + result + '">' + result + '</option>' );
99
  }
100
 
101
+ jQuery( '#custom_fields_check' ).select2_i18n();
102
 
103
  jQuery( '#custom_fields_check option' ).each( function() {
104
  jQuery( '#custom_fields_check option[value=\"' + jQuery( this ).val() + '\"]:not(:last)' ).remove();
143
  method: "get_products_attributes_values",
144
  action: "order_exporter"
145
  };
146
+
147
  var val_op = jQuery( '#attributes_compare' ).val();
148
  jQuery( '#text_attributes' ).val( '' );
149
 
156
  jQuery.each( response, function( index, value ) {
157
  options += '<option>' + value + '</option>';
158
  } );
159
+ var $select = jQuery( '<div id="select_attributes--select2" style="margin-top: 0px;margin-right: 6px; vertical-align: top;'
160
  + 'display: ' + (('LIKE' === val_op) ? 'none' : 'inline-block') + ';">'
161
  + '<select id="select_attributes">' + options + '</select></div>' );
162
  $select.insertBefore( jQuery( '#add_attributes' ) )
163
+ $select.find('select').select2_i18n({ tags: true });
164
  }
165
  else {
166
  jQuery( '<input type="text" id="select_attributes" style="margin-right: 8px;">' ).insertBefore( jQuery( '#add_attributes' ) );
186
  if ( f ) {
187
 
188
  jQuery( '#attributes_check' ).append( '<option selected="selected" value="' + val + '">' + val + '</option>' );
189
+ jQuery( '#attributes_check' ).select2_i18n(select2WODropdownOpts);
190
 
191
  jQuery( '#attributes_check option' ).each( function() {
192
  jQuery( '#attributes_check option[value=\"' + jQuery( this ).val() + '\"]:not(:last)' ).remove();
223
  method: "get_products_itemmeta_values",
224
  action: "order_exporter"
225
  };
226
+
227
  var val_op = jQuery( '#itemmeta_compare' ).val();
228
  jQuery( '#text_itemmeta' ).val( '' );
229
 
235
  jQuery.each( response, function( index, value ) {
236
  options += '<option>' + value + '</option>';
237
  } );
238
+ var $select = jQuery( '<div id="select_itemmeta--select2" style="margin-top: 0px;margin-right: 6px; vertical-align: top;'
239
  + 'display: ' + (('LIKE' === val_op) ? 'none' : 'inline-block') + ';">'
240
  + '<select id="select_itemmeta">' + options + '</select></div>' );
241
  $select.insertBefore( jQuery( '#add_itemmeta' ) )
242
+ $select.find('select').select2_i18n({ tags: true });
243
  }
244
  else {
245
  jQuery( '<input type="text" id="select_itemmeta" style="margin-right: 8px;">' ).insertBefore( jQuery( '#add_itemmeta' ) );
266
  if ( f ) {
267
 
268
  jQuery( '#itemmeta_check' ).append( '<option selected="selected" value="' + val + '">' + val + '</option>' );
269
+ jQuery( '#itemmeta_check' ).select2_i18n(select2WODropdownOpts);
270
 
271
  jQuery( '#itemmeta_check option' ).each( function() {
272
  jQuery( '#itemmeta_check option[value=\"' + jQuery( this ).val() + '\"]:not(:last)' ).remove(); // jQuerySelectorEscape ?
314
  var $select = jQuery( '<div id="select_taxonomies--select2" style="margin-top: 0px;margin-right: 6px; vertical-align: top; display: inline-block;">'
315
  + '<select id="select_taxonomies">' + options + '</select></div>' );
316
  $select.insertBefore( jQuery( '#add_taxonomies' ) )
317
+ $select.find('select').select2_i18n({ tags: true });
318
  }
319
  else {
320
  jQuery( '<input type="text" id="select_taxonomies" style="margin-right: 8px;">' ).insertBefore( jQuery( '#add_taxonomies' ) );
340
  if ( f ) {
341
 
342
  jQuery( '#taxonomies_check' ).append( '<option selected="selected" value="' + val + '">' + val + '</option>' );
343
+ jQuery( '#taxonomies_check' ).select2_i18n(select2WODropdownOpts);
344
 
345
  jQuery( '#taxonomies_check option' ).each( function() {
346
  jQuery( '#taxonomies_check option[value=\"' + jQuery( this ).val() + '\"]:not(:last)' ).remove();
387
  jQuery.each( response, function( index, value ) {
388
  options += '<option>' + value + '</option>';
389
  } );
390
+ var $select = jQuery( '<div id="select_product_custom_fields--select2" style="margin-top: 0px;margin-right: 6px; vertical-align: top;'
391
  + 'display: ' + (('LIKE' === val_op) ? 'none' : 'inline-block') + ';">'
392
  + '<select id="select_product_custom_fields">' + options + '</select></div>' );
393
  $select.insertBefore( jQuery( '#add_product_custom_fields' ) )
394
+ $select.find('select').select2_i18n({ tags: true });
395
  }
396
  else {
397
  jQuery( '<input type="text" id="select_product_custom_fields" style="margin-right: 8px;">' ).insertBefore( jQuery( '#add_product_custom_fields' ) );
416
  if ( f ) {
417
 
418
  jQuery( '#product_custom_fields_check' ).append( '<option selected="selected" value="' + val + '">' + val + '</option>' );
419
+ jQuery( '#product_custom_fields_check' ).select2_i18n(select2WODropdownOpts);
420
 
421
  jQuery( '#product_custom_fields_check option' ).each( function() {
422
  jQuery( '#product_custom_fields_check option[value=\"' + jQuery( this ).val() + '\"]:not(:last)' ).remove();
471
  jQuery( '#button_custom_field' ).click( function() {
472
  var colname = jQuery( '#colname_custom_field' ).val();
473
  var value = jQuery( '#value_custom_field' ).val();
474
+ var format_field = jQuery( '#format_custom_field' ).val();
475
  if ( !colname )
476
  {
477
  alert( export_messages.empty_column_name );
478
  jQuery( '#colname_custom_field' ).focus();
479
  return false
480
  }
481
+
482
+ var segment = jQuery('.segment_choice.active').attr('data-segment');
483
+
484
+ add_custom_field( jQuery( "#" + segment + '_unselected_segment' ), 'orders', output_format, colname, value, segment, format_field );
485
+
 
 
486
  reset_field_contorls();
487
+
488
+ jQuery(this).siblings('.button-cancel').trigger('click');
489
+
490
  return false;
491
  } );
492
 
499
  jQuery( '#select_custom_meta_order' ).html( options );
500
  }
501
  else {
502
+ var json = makeJsonVar(jQuery( '#export_job_settings' ));
503
+ var data = "json="+ json +"&action=order_exporter&method=get_used_custom_order_meta";
504
 
505
  jQuery.post( ajaxurl, data, function( response ) {
506
  if ( response ) {
533
  jQuery( '#select_custom_meta_order_items' ).prop( "disabled", false );
534
  }
535
  else {
536
+ // jQuery('#modal-manage-products').html(jQuery('#TB_ajaxContent').html());
537
  var data = jQuery( '#export_job_settings' ).serialize(),
538
  data_products = data + "&action=order_exporter&method=get_used_custom_products_meta&mode=" + mode + "&id=" + job_id,
539
  data_order_items = data + "&action=order_exporter&method=get_used_custom_order_items_meta&mode=" + mode + "&id=" + job_id;
560
  }
561
  }, 'json' );
562
 
563
+ // jQuery('#modal-manage-products').html('');
564
  }
565
  });
566
  jQuery('input[name=custom_meta_products_mode]').trigger('change');
592
  jQuery( '#button_custom_meta' ).click( function() {
593
  var label = jQuery( '#select_custom_meta_order' ).val();
594
  var colname = jQuery( '#colname_custom_meta' ).val();
595
+ var format_field = jQuery( '#format_custom_meta' ).val();
596
  if (! label) //try custom text
597
  label = jQuery( '#text_custom_meta_order' ).val();;
598
  if ( !label )
607
  jQuery( '#colname_custom_meta' ).focus();
608
  return false
609
  }
610
+
611
+ var segment = jQuery('.segment_choice.active').attr('data-segment');
612
+
613
+ add_custom_meta( jQuery( "#" + segment + '_unselected_segment' ), 'orders', output_format, label, colname, segment, format_field );
614
+
615
  reset_field_contorls();
616
+
617
+ jQuery(this).siblings('.button-cancel').trigger('click');
618
+
619
  return false;
620
  } );
621
 
642
 
643
  var $select = jQuery( '<div id="text_shipping_locations--select2" style="margin-top: 0px;margin-right: 6px; vertical-align: top; display: inline-block;"><select id="text_shipping_locations">' + options + '</select></div>' );
644
  $select.insertBefore( jQuery( '#add_shipping_locations' ) )
645
+ $select.find('select').select2_i18n({ tags: true });
646
  }
647
  else {
648
  jQuery( '<input type="text" id="text_shipping_locations" style="margin-right: 8px;">' ).insertBefore( jQuery( '#add_shipping_locations' ) );
668
  if ( f ) {
669
 
670
  jQuery( '#shipping_locations_check' ).append( '<option selected="selected" value="' + val + '">' + val + '</option>' );
671
+ jQuery( '#shipping_locations_check' ).select2_i18n(select2WODropdownOpts);
672
 
673
  jQuery( '#shipping_locations_check option' ).each( function() {
674
  jQuery( '#shipping_locations_check option[value=\"' + jQuery( this ).val() + '\"]:not(:last)' ).remove();
701
  var $select = jQuery( '<div id="text_billing_locations--select2" style="margin-top: 0px;margin-right: 6px; vertical-align: top; display: inline-block;">'
702
  + '<select id="text_billing_locations">' + options + '</select></div>' );
703
  $select.insertBefore( jQuery( '#add_billing_locations' ) )
704
+ $select.find('select').select2_i18n({ tags: true });
705
  }
706
  else {
707
  jQuery( '<input type="text" id="text_billing_locations" style="margin-right: 8px;">' ).insertBefore( jQuery( '#add_billing_locations' ) );
727
  if ( f ) {
728
 
729
  jQuery( '#billing_locations_check' ).append( '<option selected="selected" value="' + val + '">' + val + '</option>' );
730
+ jQuery( '#billing_locations_check' ).select2_i18n(select2WODropdownOpts);
731
 
732
  jQuery( '#billing_locations_check option' ).each( function() {
733
  jQuery( '#billing_locations_check option[value=\"' + jQuery( this ).val() + '\"]:not(:last)' ).remove();
738
  }
739
  return false;
740
  } )
741
+
742
+
743
  // ITEM NAMES
744
  jQuery( '#item_names' ).change( function() {
745
 
761
 
762
  var $select = jQuery( '<div id="text_item_names--select2" style="margin-top: 0px;margin-right: 6px; vertical-align: top; display: inline-block;"><select id="text_item_names">' + options + '</select></div>' );
763
  $select.insertBefore( jQuery( '#add_item_names' ) )
764
+ $select.find('select').select2_i18n({ tags: true });
765
  }
766
  else {
767
  jQuery( '<input type="text" id="text_item_names" style="margin-right: 8px;">' ).insertBefore( jQuery( '#add_item_names' ) );
787
  if ( f ) {
788
 
789
  jQuery( '#item_names_check' ).append( '<option selected="selected" value="' + val + '">' + val + '</option>' );
790
+ jQuery( '#item_names_check' ).select2_i18n(select2WODropdownOpts);
791
 
792
  jQuery( '#item_names_check option' ).each( function() {
793
  jQuery( '#item_names_check option[value=\"' + jQuery( this ).val() + '\"]:not(:last)' ).remove();
798
  }
799
  return false;
800
  } );
801
+
802
  // ITEM METADATA
803
  jQuery( '#item_metadata' ).change( function() {
804
 
820
 
821
  var $select = jQuery( '<div id="text_item_metadata--select2" style="margin-top: 0px;margin-right: 6px; vertical-align: top; display: inline-block;"><select id="text_item_metadata">' + options + '</select></div>' );
822
  $select.insertBefore( jQuery( '#add_item_metadata' ) )
823
+ $select.find('select').select2_i18n({ tags: true });
824
  }
825
  else {
826
  jQuery( '<input type="text" id="text_item_metadata" style="margin-right: 8px;">' ).insertBefore( jQuery( '#add_item_metadata' ) );
846
  if ( f ) {
847
 
848
  jQuery( '#item_metadata_check' ).append( '<option selected="selected" value="' + val + '">' + val + '</option>' );
849
+ jQuery( '#item_metadata_check' ).select2_i18n(select2WODropdownOpts);
850
 
851
  jQuery( '#item_metadata_check option' ).each( function() {
852
  jQuery( '#item_metadata_check option[value=\"' + jQuery( this ).val() + '\"]:not(:last)' ).remove();
857
  }
858
  return false;
859
  } );
 
860
 
 
 
 
 
 
 
 
 
861
  }
862
 
863
  function bind_events_users() {
889
  ) + ';">'
890
  + '<select id="select_user_custom_fields">' + options + '</select></div>' );
891
  $select.insertBefore( jQuery( '#add_user_custom_fields' ) )
892
+ $select.find( 'select' ).select2_i18n( {tags: true} );
893
  }
894
  else {
895
  jQuery( '<input type="text" id="select_user_custom_fields" style="margin-right: 8px;">' ).insertBefore(
923
  '#user_custom_fields_check' ).append( '<option selected="selected" value="' + result + '">' + result + '</option>' );
924
  }
925
 
926
+ jQuery( '#user_custom_fields_check' ).select2_i18n();
927
 
928
  jQuery( '#user_custom_fields_check option' ).each( function () {
929
  jQuery( '#user_custom_fields_check option[value=\"' + jQuery( this ).val() + '\"]:not(:last)' ).remove();
960
  jQuery( '#button_custom_field_' + prefix + '' ).click( function() {
961
  var colname = jQuery( '#colname_custom_field_' + prefix + '' ).val();
962
  var value = jQuery( '#value_custom_field_' + prefix + '' ).val();
963
+ var format_field = jQuery( '#format_custom_field_' + prefix + '' ).val();
964
  if ( !colname )
965
  {
966
  alert( export_messages.empty_column_name );
973
  jQuery( '#value_custom_field_' + prefix + '' ).focus();
974
  return false
975
  }
976
+
977
  jQuery( '#colname_custom_field_' + prefix + '' ).val( "" );
978
+
979
  jQuery( '#value_custom_field_' + prefix + '' ).val( "" );
980
+ jQuery( '#format_custom_field_' + prefix + '' ).val( "" );
981
+
982
+ var segment = jQuery('.segment_choice.active').attr('data-segment');
983
+
984
+ add_custom_field( jQuery( "#" + segment + '_unselected_segment' ), prefix, output_format, colname, value, segment, format_field );
985
+
986
+ jQuery(this).siblings('.button-cancel').trigger('click');
987
+
988
  return false;
989
  } );
990
 
993
  var prefix_items = 'order_items',
994
  original_prefix = prefix,
995
  prefix_items_select = jQuery( '#select_custom_meta_' + prefix_items + '' ),
996
+ prefix_product_select = jQuery( '#select_custom_meta_' + prefix + '' ),
997
+ prefix_product_text = jQuery( '#text_custom_meta_' + prefix + '' ),
998
+ prefix_items_text = jQuery( '#text_custom_meta_' + prefix_items + '' );
999
+
1000
+ var type = (
1001
+ prefix_items_select.val() ||
1002
+ prefix_product_select.val() ||
1003
+ prefix_product_text.val() ||
1004
+ prefix_items_text.val()
1005
+ ) ? 'meta' : 'taxonomies';
1006
 
 
1007
  if ( 'meta' === type ) {
1008
+ original_prefix = prefix_product_select.val() || prefix_product_text.val() ? prefix : prefix_items;
1009
  } else {
1010
  original_prefix = prefix;
1011
  }
1012
  type = type + '_' + original_prefix;
1013
  var label = jQuery( '#select_custom_' + type + '' ).val();
1014
  var colname = jQuery( '#colname_custom_meta_' + prefix + '' ).val();
1015
+ var field_format = jQuery( '#format_custom_meta_' + prefix + '' ).val();
1016
+
1017
+ if (! label ) //try custom text
1018
+ label = jQuery( '#text_custom_' + type ).val();
1019
+
1020
  if ( !label )
1021
  {
1022
  alert( export_messages.empty_meta_key_and_taxonomy );
1030
  alert( export_messages.empty_column_name );
1031
  return false
1032
  }
1033
+
1034
+ var segment = jQuery('.segment_choice.active').attr('data-segment');
1035
+
1036
+ add_custom_meta( jQuery( "#" + segment + '_unselected_segment' ), prefix, output_format, label, colname, segment, field_format );
1037
+
1038
+ jQuery(this).siblings('.button-cancel').trigger('click');
1039
+
1040
  jQuery( '#select_custom_' + type + '' ).val( "" );
1041
  jQuery( '#colname_custom_meta_' + prefix + '' ).val( "" );
1042
+ jQuery( '#format_custom_meta_' + prefix + '' ).val( "" );
1043
  return false;
1044
  } );
1045
 
1046
  }
1047
 
1048
  function reset_field_contorls() {
1049
+ jQuery( '.tab-actions-forms' )
1050
+ .find( 'input,select' )
1051
+ .val( '' );
1052
+ }
1053
+
1054
+ function reset_field_contorls_() {
1055
+ jQuery( '#fields_control' )
1056
+ .find( 'input' )
1057
+ .not('.segment_products input')
1058
+ .not('.segment_coupons input')
1059
+ .val( '' );
1060
  jQuery( "#fields_control > div" ).hide();
1061
  jQuery( "#fields_control .div1" ).show();
1062
  jQuery( "#fields_control .div2" ).show();
1063
+ jQuery( "#fields_control .flat_format_controls" ).show();
1064
  }
1065
 
1066
  function formatItem( item ) {
1075
  return markup;
1076
  }
1077
 
1078
+ function add_custom_field( to, index_p, format, colname, value, segment, format_field ) {
1079
 
1080
  value = escapeStr(value);
1081
  colname = escapeStr(colname);
1082
+
1083
+ if ( is_flat_format(format) ) {
1084
+ _index = 'plain_' + index_p + '_';
1085
+ _index_p = 'orders[]';
1086
+ } else {
1087
+ _index = '';
1088
+ _index_p = index_p + '[]';
1089
+ }
1090
+
1091
+ var label_prefix = '';
1092
+
1093
+ if (is_flat_format(format)) {
1094
+
1095
+ if (segment === 'products' ) {
1096
+ label_prefix = '[P] '
1097
+ }
1098
+
1099
+ if (segment === 'coupons' ) {
1100
+ label_prefix = '[C] '
1101
  }
1102
  }
1103
+
1104
+ var suffix = 0;
1105
+
1106
+ jQuery('#unselected_fields input[value*="static_field_"]').each(function () {
1107
+
1108
+ var match = jQuery(this).attr('value').match(/static_field_(\d+)/);
1109
+
1110
+ if (!match) {
1111
+ return true;
1112
+ }
1113
+
1114
+ var n = parseInt(match[1]);
1115
+
1116
+ if(n > suffix) {
1117
+ suffix = n;
1118
+ }
1119
+ });
1120
+
1121
+ var field_key = 'static_field_' + (suffix + 1);
1122
+
1123
+ var delete_btn = '<div class="mapping_col_3 mapping_row-delete_field_block"><a href="#" class="mapping_row-delete_field"><span class="dashicons dashicons-trash"></span></a></div>';
1124
 
1125
  // console.log( to, index_p, format, colname, value );
1126
+ var row = jQuery('<li class="mapping_row segment_field segment_'+ segment +'">\
1127
+ <div class="mapping_col_1" style="width: 10px">\
1128
+ <input class="mapping_fieldname" type=hidden name="' + _index_p + '[segment]" value="'+ (segment ? segment : 'misc') +'">\
1129
+ <input class="mapping_fieldname" type=hidden name="' + _index_p + '[key]" value="'+ _index + field_key +'">\
1130
+ <input class="mapping_fieldname" type=hidden name="' + _index_p + '[label]" value="' + colname + '">\
1131
+ <input class="mapping_fieldname" type=hidden name="' + _index_p + '[format]" value="' + format_field + '">\
1132
+ </div>\
1133
+ <div class="mapping_col_2" title="'+field_key+'">' + '<span class="field-prefix">' + label_prefix + '</span>' + colname + '<a href="#" onclick="return remove_custom_field(this);" class="mapping_row-delete_custom_field" style="float: right;"><span class="ui-icon ui-icon-trash"></span></a></div>\
1134
+ <div class="mapping_col_3"><input class="mapping_fieldname" type=input name="' + _index_p + '[colname]" value="' + colname + '"></div>\
1135
+ <div class="mapping_col_3 custom-field-value"><input class="mapping_fieldname" type=input name="' + _index_p + '[value]" value="' + value + '"></div>'+ delete_btn +'\
1136
+ </li>\
1137
+ ');
1138
+
1139
+ row.find('input').prop('disabled', 'disabled');
1140
+
1141
+ to.prepend( row );
1142
+
1143
+ activate_draggable_field(
1144
+ to.find('.segment_field').first(),
1145
+ segment,
1146
+ format
1147
+ );
1148
+
1149
+ to.find('.segment_field').first().addClass('blink');
1150
+
1151
+ var field = {
1152
+ key: field_key,
1153
+ colname: colname,
1154
+ 'default': 0,
1155
+ label: colname,
1156
+ format: 'string',
1157
+ value: value,
1158
+ };
1159
+
1160
+ window.all_fields[segment].unshift(field);
1161
  }
1162
 
1163
+ function add_custom_meta( to, index_p, format, label, colname, segment, format_field ) {
1164
 
1165
  label = escapeStr(label);
1166
  colname = escapeStr(colname);
1167
 
1168
+ if ( is_flat_format(format) ) {
1169
+ _index = 'plain_' + index_p + '_' + label;
1170
+ _index_p = 'orders[]';
1171
+ } else {
1172
+ _index = label;
1173
+ _index_p = index_p + '[]';
1174
+ }
1175
+
1176
+ var label_prefix = '';
1177
+
1178
+ if (is_flat_format(format)) {
1179
+
1180
+ if (segment === 'products' ) {
1181
+ label_prefix = '[P] '
1182
+ }
1183
+
1184
+ if (segment === 'coupons' ) {
1185
+ label_prefix = '[C] '
1186
+ }
1187
+ }
1188
+
1189
+ var delete_btn = '<div class="mapping_col_3 mapping_row-delete_field_block"><a href="#" class="mapping_row-delete_field"><span class="dashicons dashicons-trash"></span></a></div>';
1190
+
1191
+ var row = jQuery('<li class="mapping_row segment_field segment_'+ segment +'">\
1192
+ <div class="mapping_col_1" style="width: 10px">\
1193
+ <input class="mapping_fieldname" type=hidden name="' + _index_p + '[segment]" value="'+ (segment ? segment : 'misc') +'">\
1194
+ <input class="mapping_fieldname" type=hidden name="' + _index_p + '[key]" value="'+ _index +'">\
1195
+ <input class="mapping_fieldname" type=hidden name="' + _index_p + '[label]" value="' + label + '">\
1196
+ <input class="mapping_fieldname" type=hidden name="' + _index_p + '[format]" value="' + format_field + '">\
1197
+ </div>\
1198
+ <div class="mapping_col_2" title="'+label+'">' + '<span class="field-prefix">' + label_prefix + '</span>' + label + '<a href="#" onclick="return remove_custom_field(this);" class="mapping_row-delete_custom_field" style="float: right;"><span class="ui-icon ui-icon-trash"></span></a></div>\
1199
+ <div class="mapping_col_3"><input class="mapping_fieldname" type=input name="' + _index_p + '[colname]" value="' + colname + '"></div>'+ delete_btn +'\
1200
+ </li>\
1201
+ ');
1202
+
1203
+ row.find('input').prop('disabled', 'disabled');
1204
+
1205
+ to.prepend( row );
1206
+
1207
+ activate_draggable_field(
1208
+ to.find('.segment_field').first(),
1209
+ segment,
1210
+ format
1211
+ );
1212
+
1213
+ to.find('.segment_field').first().addClass('blink');
1214
+
1215
+ var field = {
1216
+ key: label,
1217
+ colname: colname,
1218
+ 'default': 0,
1219
+ label: label,
1220
+ segment: segment,
1221
+ format: 'string',
1222
+ value: 'undefined',
1223
+ };
1224
+
1225
+ window.all_fields[segment].unshift(field);
1226
  }
1227
 
1228
  function scroll_to_added_field( to ) {
1239
  return item.text;
1240
  }
1241
 
1242
+ jQuery.fn.extend(
1243
+ {
1244
+ select2_i18n: function ($attrs) {
1245
+ if ( typeof $attrs !== 'object' ) {
1246
+ $attrs = {};
1247
+ }
1248
+ $attrs = Object.assign({ language: script_data.select2_locale }, $attrs);
1249
+ jQuery(this).select2($attrs);
1250
+ }
1251
+ } );
1252
+
1253
  function select2_inits()
1254
  {
1255
+ jQuery( "#from_status, #to_status" ).select2_i18n({multiple: true});
1256
+ jQuery( "#statuses" ).select2_i18n();
1257
+ jQuery( "#shipping_methods" ).select2_i18n();
1258
+ jQuery( "#user_roles" ).select2_i18n();
1259
+ jQuery( "#payment_methods" ).select2_i18n();
1260
+ jQuery( "#attributes" ).select2_i18n( {
 
 
1261
  width: 150
1262
  } );
1263
+ jQuery( "#attributes_check" ).select2_i18n(select2WODropdownOpts);
1264
+ jQuery( "#itemmeta" ).select2_i18n( {
1265
  width: 220
1266
  } );
1267
+ jQuery( "#itemmeta_check" ).select2_i18n(select2WODropdownOpts);
1268
 
1269
+ jQuery( "#custom_fields" ).select2_i18n( {
1270
  width: 150
1271
  } );
1272
+ jQuery( "#custom_fields_check" ).select2_i18n();
1273
 
1274
+ jQuery( "#product_custom_fields" ).select2_i18n( {
1275
  width: 150
1276
  } );
1277
+ jQuery( "#product_custom_fields_check" ).select2_i18n(select2WODropdownOpts);
1278
 
1279
+ jQuery( "#user_custom_fields" ).select2_i18n( {
1280
  width: 150
1281
  } );
1282
+ jQuery( "#user_custom_fields_check" ).select2_i18n();
1283
 
1284
+ jQuery( "#taxonomies" ).select2_i18n( {
1285
  width: 150
1286
  } );
1287
+ jQuery( "#taxonomies_check" ).select2_i18n(select2WODropdownOpts);
1288
 
1289
+ jQuery( "#shipping_locations" ).select2_i18n( {
1290
  width: 150
1291
  } );
1292
+ jQuery( "#shipping_locations_check" ).select2_i18n(select2WODropdownOpts);
1293
 
1294
+ jQuery( "#billing_locations" ).select2_i18n( {
1295
  width: 150
1296
  } );
1297
+ jQuery( "#billing_locations_check" ).select2_i18n(select2WODropdownOpts);
1298
 
1299
+ jQuery( "#item_names" ).select2_i18n( {
1300
  width: 150
1301
  } );
1302
+ jQuery( "#item_names_check" ).select2_i18n(select2WODropdownOpts);
1303
 
1304
+ jQuery( "#item_metadata" ).select2_i18n( {
1305
  width: 150
1306
  } );
1307
+ jQuery( "#item_metadata_check" ).select2_i18n(select2WODropdownOpts);
1308
 
1309
+ jQuery( "#product_categories" ).select2_i18n( {
1310
  ajax: {
1311
  url: ajaxurl,
1312
  dataType: 'json',
1337
  templateSelection: formatItemSelection // omitted for brevity, see the source of this page
1338
  } );
1339
 
1340
+ jQuery( "#product_vendors" ).select2_i18n( {
1341
  ajax: {
1342
  url: ajaxurl,
1343
  dataType: 'json',
1368
  templateSelection: formatItemSelection // omitted for brevity, see the source of this page
1369
  } );
1370
 
1371
+ jQuery( "#products" ).select2_i18n( {
1372
  ajax: {
1373
  url: ajaxurl,
1374
  dataType: 'json',
1399
  templateSelection: formatItemSelection // omitted for brevity, see the source of this page
1400
  } );
1401
 
1402
+ jQuery( "#user_names" ).select2_i18n( {
1403
  ajax: {
1404
  url: ajaxurl,
1405
  dataType: 'json',
1430
  templateSelection: formatItemSelection // omitted for brevity, see the source of this page
1431
  } );
1432
 
1433
+ jQuery( "#coupons" ).select2_i18n( {
1434
  ajax: {
1435
  url: ajaxurl,
1436
  dataType: 'json',
1487
  return expression.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~]/g, '\\$&');
1488
  }
1489
 
1490
+ //for warning
1491
  function setup_alert_date_filter() {
1492
  default_date_filter_color = jQuery( "#my-date-filter" ).css('color');
1493
  try_color_date_filter();
1495
  jQuery( '#to_date' ).change( function() { try_color_date_filter(); });
1496
  }
1497
  function try_color_date_filter() {
1498
+ var color = default_date_filter_color;
1499
+ if( jQuery( "#from_date" ).val() || jQuery( "#to_date" ).val() )
1500
+ color = 'red';
1501
  jQuery( "#my-date-filter" ).css('color', color);
1502
  }
1503
 
1505
 
1506
  $( "#the-list" ).sortable( { handle: '.woe-row-sort-handle' } );
1507
 
1508
+ $( '.check-column .order_part' ).hide();
1509
 
1510
  $start_reorder_button = $( '#start_reorder' );
1511
  $apply_reorder_button = $( '#apply_reorder' );
1517
  $apply_reorder_button.show();
1518
  $cancel_reorder_button.show();
1519
 
1520
+ $( '.check-column .cb_part' ).hide();
1521
+ $( '.check-column .order_part' ).show();
1522
+
1523
+
1524
  } );
1525
 
1526
  $apply_reorder_button.click( function ( e ) {
1528
  $apply_reorder_button.hide();
1529
  $cancel_reorder_button.hide();
1530
 
1531
+ $( '.check-column .cb_part' ).show();
1532
+ $( '.check-column .order_part' ).hide();
1533
 
1534
  jQuery.ajax({
1535
  url: ajaxurl,
1554
  $apply_reorder_button.hide();
1555
  $cancel_reorder_button.hide();
1556
 
1557
+ $( '.check-column .cb_part' ).show();
1558
+ $( '.check-column .order_part' ).hide();
1559
 
1560
  $( $order_ids ).each( function ( $key, $job_id ) {
1561
  $element = $( '[data-job_id="' + $job_id + '"' ).detach();
assets/js/select2/i18n/de.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */
2
+
3
+ (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/de",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum;return"Bitte "+t+" Zeichen weniger eingeben"},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Bitte "+t+" Zeichen mehr eingeben"},loadingMore:function(){return"Lade mehr Ergebnisse…"},maximumSelected:function(e){var t="Sie können nur "+e.maximum+" Eintr";return e.maximum===1?t+="ag":t+="äge",t+=" auswählen",t},noResults:function(){return"Keine Übereinstimmungen gefunden"},searching:function(){return"Suche…"}}}),{define:e.define,require:e.require}})();
assets/js/select2/i18n/es.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */
2
+
3
+ (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/es",[],function(){return{errorLoading:function(){return"La carga falló"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Por favor, elimine "+t+" car";return t==1?n+="ácter":n+="acteres",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Por favor, introduzca "+t+" car";return t==1?n+="ácter":n+="acteres",n},loadingMore:function(){return"Cargando más resultados…"},maximumSelected:function(e){var t="Sólo puede seleccionar "+e.maximum+" elemento";return e.maximum!=1&&(t+="s"),t},noResults:function(){return"No se encontraron resultados"},searching:function(){return"Buscando…"}}}),{define:e.define,require:e.require}})();
assets/js/select2/i18n/fr.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */
2
+
3
+ (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/fr",[],function(){return{errorLoading:function(){return"Les résultats ne peuvent pas être chargés."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Supprimez "+t+" caractère";return t!==1&&(n+="s"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Saisissez "+t+" caractère";return t!==1&&(n+="s"),n},loadingMore:function(){return"Chargement de résultats supplémentaires…"},maximumSelected:function(e){var t="Vous pouvez seulement sélectionner "+e.maximum+" élément";return e.maximum!==1&&(t+="s"),t},noResults:function(){return"Aucun résultat trouvé"},searching:function(){return"Recherche en cours…"}}}),{define:e.define,require:e.require}})();
assets/js/select2/i18n/pt-BR.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */
2
+
3
+ (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/pt-BR",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Apague "+t+" caracter";return t!=1&&(n+="es"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Digite "+t+" ou mais caracteres";return n},loadingMore:function(){return"Carregando mais resultados…"},maximumSelected:function(e){var t="Você só pode selecionar "+e.maximum+" ite";return e.maximum==1?t+="m":t+="ns",t},noResults:function(){return"Nenhum resultado encontrado"},searching:function(){return"Buscando…"}}}),{define:e.define,require:e.require}})();
assets/js/select2/i18n/pt.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */
2
+
3
+ (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/pt",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Por favor apague "+t+" ";return n+=t!=1?"caracteres":"carácter",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Introduza "+t+" ou mais caracteres";return n},loadingMore:function(){return"A carregar mais resultados…"},maximumSelected:function(e){var t="Apenas pode seleccionar "+e.maximum+" ";return t+=e.maximum!=1?"itens":"item",t},noResults:function(){return"Sem resultados"},searching:function(){return"A procurar…"}}}),{define:e.define,require:e.require}})();
assets/js/select2/i18n/ru.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */
2
+
3
+ (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ru",[],function(){function e(e,t,n,r){return e%10<5&&e%10>0&&e%100<5||e%100>20?e%10>1?n:t:r}return{errorLoading:function(){return"Невозможно загрузить результаты"},inputTooLong:function(t){var n=t.input.length-t.maximum,r="Пожалуйста, введите на "+n+" символ";return r+=e(n,"","a","ов"),r+=" меньше",r},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Пожалуйста, введите еще хотя бы "+n+" символ";return r+=e(n,"","a","ов"),r},loadingMore:function(){return"Загрузка данных…"},maximumSelected:function(t){var n="Вы можете выбрать не более "+t.maximum+" элемент";return n+=e(t.maximum,"","a","ов"),n},noResults:function(){return"Совпадений не найдено"},searching:function(){return"Поиск…"}}}),{define:e.define,require:e.require}})();
assets/js/select2/i18n/zh-CN.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ /*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */
2
+
3
+ (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/zh-CN",[],function(){return{errorLoading:function(){return"无法载入结果。"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="请删除"+t+"个字符";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="请再输入至少"+t+"个字符";return n},loadingMore:function(){return"载入更多结果…"},maximumSelected:function(e){var t="最多只能选择"+e.maximum+"个项目";return t},noResults:function(){return"未找到结果"},searching:function(){return"搜索中…"}}}),{define:e.define,require:e.require}})();
assets/js/select2/select2.full.js ADDED
@@ -0,0 +1,6436 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Select2 4.0.3
3
+ * https://select2.github.io
4
+ *
5
+ * Released under the MIT license
6
+ * https://github.com/select2/select2/blob/master/LICENSE.md
7
+ */
8
+ (function (factory) {
9
+ if (typeof define === 'function' && define.amd) {
10
+ // AMD. Register as an anonymous module.
11
+ define(['jquery'], factory);
12
+ } else if (typeof exports === 'object') {
13
+ // Node/CommonJS
14
+ factory(require('jquery'));
15
+ } else {
16
+ // Browser globals
17
+ factory(jQuery);
18
+ }
19
+ }(function (jQuery) {
20
+ // This is needed so we can catch the AMD loader configuration and use it
21
+ // The inner file should be wrapped (by `banner.start.js`) in a function that
22
+ // returns the AMD loader references.
23
+ var S2 =
24
+ (function () {
25
+ // Restore the Select2 AMD loader so it can be used
26
+ // Needed mostly in the language files, where the loader is not inserted
27
+ if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) {
28
+ var S2 = jQuery.fn.select2.amd;
29
+ }
30
+ var S2;(function () { if (!S2 || !S2.requirejs) {
31
+ if (!S2) { S2 = {}; } else { require = S2; }
32
+ /**
33
+ * @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.
34
+ * Available via the MIT or new BSD license.
35
+ * see: http://github.com/jrburke/almond for details
36
+ */
37
+ //Going sloppy to avoid 'use strict' string cost, but strict practices should
38
+ //be followed.
39
+ /*jslint sloppy: true */
40
+ /*global setTimeout: false */
41
+
42
+ var requirejs, require, define;
43
+ (function (undef) {
44
+ var main, req, makeMap, handlers,
45
+ defined = {},
46
+ waiting = {},
47
+ config = {},
48
+ defining = {},
49
+ hasOwn = Object.prototype.hasOwnProperty,
50
+ aps = [].slice,
51
+ jsSuffixRegExp = /\.js$/;
52
+
53
+ function hasProp(obj, prop) {
54
+ return hasOwn.call(obj, prop);
55
+ }
56
+
57
+ /**
58
+ * Given a relative module name, like ./something, normalize it to
59
+ * a real name that can be mapped to a path.
60
+ * @param {String} name the relative name
61
+ * @param {String} baseName a real name that the name arg is relative
62
+ * to.
63
+ * @returns {String} normalized name
64
+ */
65
+ function normalize(name, baseName) {
66
+ var nameParts, nameSegment, mapValue, foundMap, lastIndex,
67
+ foundI, foundStarMap, starI, i, j, part,
68
+ baseParts = baseName && baseName.split("/"),
69
+ map = config.map,
70
+ starMap = (map && map['*']) || {};
71
+
72
+ //Adjust any relative paths.
73
+ if (name && name.charAt(0) === ".") {
74
+ //If have a base name, try to normalize against it,
75
+ //otherwise, assume it is a top-level require that will
76
+ //be relative to baseUrl in the end.
77
+ if (baseName) {
78
+ name = name.split('/');
79
+ lastIndex = name.length - 1;
80
+
81
+ // Node .js allowance:
82
+ if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
83
+ name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
84
+ }
85
+
86
+ //Lop off the last part of baseParts, so that . matches the
87
+ //"directory" and not name of the baseName's module. For instance,
88
+ //baseName of "one/two/three", maps to "one/two/three.js", but we
89
+ //want the directory, "one/two" for this normalization.
90
+ name = baseParts.slice(0, baseParts.length - 1).concat(name);
91
+
92
+ //start trimDots
93
+ for (i = 0; i < name.length; i += 1) {
94
+ part = name[i];
95
+ if (part === ".") {
96
+ name.splice(i, 1);
97
+ i -= 1;
98
+ } else if (part === "..") {
99
+ if (i === 1 && (name[2] === '..' || name[0] === '..')) {
100
+ //End of the line. Keep at least one non-dot
101
+ //path segment at the front so it can be mapped
102
+ //correctly to disk. Otherwise, there is likely
103
+ //no path mapping for a path starting with '..'.
104
+ //This can still fail, but catches the most reasonable
105
+ //uses of ..
106
+ break;
107
+ } else if (i > 0) {
108
+ name.splice(i - 1, 2);
109
+ i -= 2;
110
+ }
111
+ }
112
+ }
113
+ //end trimDots
114
+
115
+ name = name.join("/");
116
+ } else if (name.indexOf('./') === 0) {
117
+ // No baseName, so this is ID is resolved relative
118
+ // to baseUrl, pull off the leading dot.
119
+ name = name.substring(2);
120
+ }
121
+ }
122
+
123
+ //Apply map config if available.
124
+ if ((baseParts || starMap) && map) {
125
+ nameParts = name.split('/');
126
+
127
+ for (i = nameParts.length; i > 0; i -= 1) {
128
+ nameSegment = nameParts.slice(0, i).join("/");
129
+
130
+ if (baseParts) {
131
+ //Find the longest baseName segment match in the config.
132
+ //So, do joins on the biggest to smallest lengths of baseParts.
133
+ for (j = baseParts.length; j > 0; j -= 1) {
134
+ mapValue = map[baseParts.slice(0, j).join('/')];
135
+
136
+ //baseName segment has config, find if it has one for
137
+ //this name.
138
+ if (mapValue) {
139
+ mapValue = mapValue[nameSegment];
140
+ if (mapValue) {
141
+ //Match, update name to the new value.
142
+ foundMap = mapValue;
143
+ foundI = i;
144
+ break;
145
+ }
146
+ }
147
+ }
148
+ }
149
+
150
+ if (foundMap) {
151
+ break;
152
+ }
153
+
154
+ //Check for a star map match, but just hold on to it,
155
+ //if there is a shorter segment match later in a matching
156
+ //config, then favor over this star map.
157
+ if (!foundStarMap && starMap && starMap[nameSegment]) {
158
+ foundStarMap = starMap[nameSegment];
159
+ starI = i;
160
+ }
161
+ }
162
+
163
+ if (!foundMap && foundStarMap) {
164
+ foundMap = foundStarMap;
165
+ foundI = starI;
166
+ }
167
+
168
+ if (foundMap) {
169
+ nameParts.splice(0, foundI, foundMap);
170
+ name = nameParts.join('/');
171
+ }
172
+ }
173
+
174
+ return name;
175
+ }
176
+
177
+ function makeRequire(relName, forceSync) {
178
+ return function () {
179
+ //A version of a require function that passes a moduleName
180
+ //value for items that may need to
181
+ //look up paths relative to the moduleName
182
+ var args = aps.call(arguments, 0);
183
+
184
+ //If first arg is not require('string'), and there is only
185
+ //one arg, it is the array form without a callback. Insert
186
+ //a null so that the following concat is correct.
187
+ if (typeof args[0] !== 'string' && args.length === 1) {
188
+ args.push(null);
189
+ }
190
+ return req.apply(undef, args.concat([relName, forceSync]));
191
+ };
192
+ }
193
+
194
+ function makeNormalize(relName) {
195
+ return function (name) {
196
+ return normalize(name, relName);
197
+ };
198
+ }
199
+
200
+ function makeLoad(depName) {
201
+ return function (value) {
202
+ defined[depName] = value;
203
+ };
204
+ }
205
+
206
+ function callDep(name) {
207
+ if (hasProp(waiting, name)) {
208
+ var args = waiting[name];
209
+ delete waiting[name];
210
+ defining[name] = true;
211
+ main.apply(undef, args);
212
+ }
213
+
214
+ if (!hasProp(defined, name) && !hasProp(defining, name)) {
215
+ throw new Error('No ' + name);
216
+ }
217
+ return defined[name];
218
+ }
219
+
220
+ //Turns a plugin!resource to [plugin, resource]
221
+ //with the plugin being undefined if the name
222
+ //did not have a plugin prefix.
223
+ function splitPrefix(name) {
224
+ var prefix,
225
+ index = name ? name.indexOf('!') : -1;
226
+ if (index > -1) {
227
+ prefix = name.substring(0, index);
228
+ name = name.substring(index + 1, name.length);
229
+ }
230
+ return [prefix, name];
231
+ }
232
+
233
+ /**
234
+ * Makes a name map, normalizing the name, and using a plugin
235
+ * for normalization if necessary. Grabs a ref to plugin
236
+ * too, as an optimization.
237
+ */
238
+ makeMap = function (name, relName) {
239
+ var plugin,
240
+ parts = splitPrefix(name),
241
+ prefix = parts[0];
242
+
243
+ name = parts[1];
244
+
245
+ if (prefix) {
246
+ prefix = normalize(prefix, relName);
247
+ plugin = callDep(prefix);
248
+ }
249
+
250
+ //Normalize according
251
+ if (prefix) {
252
+ if (plugin && plugin.normalize) {
253
+ name = plugin.normalize(name, makeNormalize(relName));
254
+ } else {
255
+ name = normalize(name, relName);
256
+ }
257
+ } else {
258
+ name = normalize(name, relName);
259
+ parts = splitPrefix(name);
260
+ prefix = parts[0];
261
+ name = parts[1];
262
+ if (prefix) {
263
+ plugin = callDep(prefix);
264
+ }
265
+ }
266
+
267
+ //Using ridiculous property names for space reasons
268
+ return {
269
+ f: prefix ? prefix + '!' + name : name, //fullName
270
+ n: name,
271
+ pr: prefix,
272
+ p: plugin
273
+ };
274
+ };
275
+
276
+ function makeConfig(name) {
277
+ return function () {
278
+ return (config && config.config && config.config[name]) || {};
279
+ };
280
+ }
281
+
282
+ handlers = {
283
+ require: function (name) {
284
+ return makeRequire(name);
285
+ },
286
+ exports: function (name) {
287
+ var e = defined[name];
288
+ if (typeof e !== 'undefined') {
289
+ return e;
290
+ } else {
291
+ return (defined[name] = {});
292
+ }
293
+ },
294
+ module: function (name) {
295
+ return {
296
+ id: name,
297
+ uri: '',
298
+ exports: defined[name],
299
+ config: makeConfig(name)
300
+ };
301
+ }
302
+ };
303
+
304
+ main = function (name, deps, callback, relName) {
305
+ var cjsModule, depName, ret, map, i,
306
+ args = [],
307
+ callbackType = typeof callback,
308
+ usingExports;
309
+
310
+ //Use name if no relName
311
+ relName = relName || name;
312
+
313
+ //Call the callback to define the module, if necessary.
314
+ if (callbackType === 'undefined' || callbackType === 'function') {
315
+ //Pull out the defined dependencies and pass the ordered
316
+ //values to the callback.
317
+ //Default to [require, exports, module] if no deps
318
+ deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
319
+ for (i = 0; i < deps.length; i += 1) {
320
+ map = makeMap(deps[i], relName);
321
+ depName = map.f;
322
+
323
+ //Fast path CommonJS standard dependencies.
324
+ if (depName === "require") {
325
+ args[i] = handlers.require(name);
326
+ } else if (depName === "exports") {
327
+ //CommonJS module spec 1.1
328
+ args[i] = handlers.exports(name);
329
+ usingExports = true;
330
+ } else if (depName === "module") {
331
+ //CommonJS module spec 1.1
332
+ cjsModule = args[i] = handlers.module(name);
333
+ } else if (hasProp(defined, depName) ||
334
+ hasProp(waiting, depName) ||
335
+ hasProp(defining, depName)) {
336
+ args[i] = callDep(depName);
337
+ } else if (map.p) {
338
+ map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
339
+ args[i] = defined[depName];
340
+ } else {
341
+ throw new Error(name + ' missing ' + depName);
342
+ }
343
+ }
344
+
345
+ ret = callback ? callback.apply(defined[name], args) : undefined;
346
+
347
+ if (name) {
348
+ //If setting exports via "module" is in play,
349
+ //favor that over return value and exports. After that,
350
+ //favor a non-undefined return value over exports use.
351
+ if (cjsModule && cjsModule.exports !== undef &&
352
+ cjsModule.exports !== defined[name]) {
353
+ defined[name] = cjsModule.exports;
354
+ } else if (ret !== undef || !usingExports) {
355
+ //Use the return value from the function.
356
+ defined[name] = ret;
357
+ }
358
+ }
359
+ } else if (name) {
360
+ //May just be an object definition for the module. Only
361
+ //worry about defining if have a module name.
362
+ defined[name] = callback;
363
+ }
364
+ };
365
+
366
+ requirejs = require = req = function (deps, callback, relName, forceSync, alt) {
367
+ if (typeof deps === "string") {
368
+ if (handlers[deps]) {
369
+ //callback in this case is really relName
370
+ return handlers[deps](callback);
371
+ }
372
+ //Just return the module wanted. In this scenario, the
373
+ //deps arg is the module name, and second arg (if passed)
374
+ //is just the relName.
375
+ //Normalize module name, if it contains . or ..
376
+ return callDep(makeMap(deps, callback).f);
377
+ } else if (!deps.splice) {
378
+ //deps is a config object, not an array.
379
+ config = deps;
380
+ if (config.deps) {
381
+ req(config.deps, config.callback);
382
+ }
383
+ if (!callback) {
384
+ return;
385
+ }
386
+
387
+ if (callback.splice) {
388
+ //callback is an array, which means it is a dependency list.
389
+ //Adjust args if there are dependencies
390
+ deps = callback;
391
+ callback = relName;
392
+ relName = null;
393
+ } else {
394
+ deps = undef;
395
+ }
396
+ }
397
+
398
+ //Support require(['a'])
399
+ callback = callback || function () {};
400
+
401
+ //If relName is a function, it is an errback handler,
402
+ //so remove it.
403
+ if (typeof relName === 'function') {
404
+ relName = forceSync;
405
+ forceSync = alt;
406
+ }
407
+
408
+ //Simulate async callback;
409
+ if (forceSync) {
410
+ main(undef, deps, callback, relName);
411
+ } else {
412
+ //Using a non-zero value because of concern for what old browsers
413
+ //do, and latest browsers "upgrade" to 4 if lower value is used:
414
+ //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:
415
+ //If want a value immediately, use require('id') instead -- something
416
+ //that works in almond on the global level, but not guaranteed and
417
+ //unlikely to work in other AMD implementations.
418
+ setTimeout(function () {
419
+ main(undef, deps, callback, relName);
420
+ }, 4);
421
+ }
422
+
423
+ return req;
424
+ };
425
+
426
+ /**
427
+ * Just drops the config on the floor, but returns req in case
428
+ * the config return value is used.
429
+ */
430
+ req.config = function (cfg) {
431
+ return req(cfg);
432
+ };
433
+
434
+ /**
435
+ * Expose module registry for debugging and tooling
436
+ */
437
+ requirejs._defined = defined;
438
+
439
+ define = function (name, deps, callback) {
440
+ if (typeof name !== 'string') {
441
+ throw new Error('See almond README: incorrect module build, no module name');
442
+ }
443
+
444
+ //This module may not have dependencies
445
+ if (!deps.splice) {
446
+ //deps is not an array, so probably means
447
+ //an object literal or factory function for
448
+ //the value. Adjust args.
449
+ callback = deps;
450
+ deps = [];
451
+ }
452
+
453
+ if (!hasProp(defined, name) && !hasProp(waiting, name)) {
454
+ waiting[name] = [name, deps, callback];
455
+ }
456
+ };
457
+
458
+ define.amd = {
459
+ jQuery: true
460
+ };
461
+ }());
462
+
463
+ S2.requirejs = requirejs;S2.require = require;S2.define = define;
464
+ }
465
+ }());
466
+ S2.define("almond", function(){});
467
+
468
+ /* global jQuery:false, $:false */
469
+ S2.define('jquery',[],function () {
470
+ var _$ = jQuery || $;
471
+
472
+ if (_$ == null && console && console.error) {
473
+ console.error(
474
+ 'Select2: An instance of jQuery or a jQuery-compatible library was not ' +
475
+ 'found. Make sure that you are including jQuery before Select2 on your ' +
476
+ 'web page.'
477
+ );
478
+ }
479
+
480
+ return _$;
481
+ });
482
+
483
+ S2.define('select2/utils',[
484
+ 'jquery'
485
+ ], function ($) {
486
+ var Utils = {};
487
+
488
+ Utils.Extend = function (ChildClass, SuperClass) {
489
+ var __hasProp = {}.hasOwnProperty;
490
+
491
+ function BaseConstructor () {
492
+ this.constructor = ChildClass;
493
+ }
494
+
495
+ for (var key in SuperClass) {
496
+ if (__hasProp.call(SuperClass, key)) {
497
+ ChildClass[key] = SuperClass[key];
498
+ }
499
+ }
500
+
501
+ BaseConstructor.prototype = SuperClass.prototype;
502
+ ChildClass.prototype = new BaseConstructor();
503
+ ChildClass.__super__ = SuperClass.prototype;
504
+
505
+ return ChildClass;
506
+ };
507
+
508
+ function getMethods (theClass) {
509
+ var proto = theClass.prototype;
510
+
511
+ var methods = [];
512
+
513
+ for (var methodName in proto) {
514
+ var m = proto[methodName];
515
+
516
+ if (typeof m !== 'function') {
517
+ continue;
518
+ }
519
+
520
+ if (methodName === 'constructor') {
521
+ continue;
522
+ }
523
+
524
+ methods.push(methodName);
525
+ }
526
+
527
+ return methods;
528
+ }
529
+
530
+ Utils.Decorate = function (SuperClass, DecoratorClass) {
531
+ var decoratedMethods = getMethods(DecoratorClass);
532
+ var superMethods = getMethods(SuperClass);
533
+
534
+ function DecoratedClass () {
535
+ var unshift = Array.prototype.unshift;
536
+
537
+ var argCount = DecoratorClass.prototype.constructor.length;
538
+
539
+ var calledConstructor = SuperClass.prototype.constructor;
540
+
541
+ if (argCount > 0) {
542
+ unshift.call(arguments, SuperClass.prototype.constructor);
543
+
544
+ calledConstructor = DecoratorClass.prototype.constructor;
545
+ }
546
+
547
+ calledConstructor.apply(this, arguments);
548
+ }
549
+
550
+ DecoratorClass.displayName = SuperClass.displayName;
551
+
552
+ function ctr () {
553
+ this.constructor = DecoratedClass;
554
+ }
555
+
556
+ DecoratedClass.prototype = new ctr();
557
+
558
+ for (var m = 0; m < superMethods.length; m++) {
559
+ var superMethod = superMethods[m];
560
+
561
+ DecoratedClass.prototype[superMethod] =
562
+ SuperClass.prototype[superMethod];
563
+ }
564
+
565
+ var calledMethod = function (methodName) {
566
+ // Stub out the original method if it's not decorating an actual method
567
+ var originalMethod = function () {};
568
+
569
+ if (methodName in DecoratedClass.prototype) {
570
+ originalMethod = DecoratedClass.prototype[methodName];
571
+ }
572
+
573
+ var decoratedMethod = DecoratorClass.prototype[methodName];
574
+
575
+ return function () {
576
+ var unshift = Array.prototype.unshift;
577
+
578
+ unshift.call(arguments, originalMethod);
579
+
580
+ return decoratedMethod.apply(this, arguments);
581
+ };
582
+ };
583
+
584
+ for (var d = 0; d < decoratedMethods.length; d++) {
585
+ var decoratedMethod = decoratedMethods[d];
586
+
587
+ DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod);
588
+ }
589
+
590
+ return DecoratedClass;
591
+ };
592
+
593
+ var Observable = function () {
594
+ this.listeners = {};
595
+ };
596
+
597
+ Observable.prototype.on = function (event, callback) {
598
+ this.listeners = this.listeners || {};
599
+
600
+ if (event in this.listeners) {
601
+ this.listeners[event].push(callback);
602
+ } else {
603
+ this.listeners[event] = [callback];
604
+ }
605
+ };
606
+
607
+ Observable.prototype.trigger = function (event) {
608
+ var slice = Array.prototype.slice;
609
+ var params = slice.call(arguments, 1);
610
+
611
+ this.listeners = this.listeners || {};
612
+
613
+ // Params should always come in as an array
614
+ if (params == null) {
615
+ params = [];
616
+ }
617
+
618
+ // If there are no arguments to the event, use a temporary object
619
+ if (params.length === 0) {
620
+ params.push({});
621
+ }
622
+
623
+ // Set the `_type` of the first object to the event
624
+ params[0]._type = event;
625
+
626
+ if (event in this.listeners) {
627
+ this.invoke(this.listeners[event], slice.call(arguments, 1));
628
+ }
629
+
630
+ if ('*' in this.listeners) {
631
+ this.invoke(this.listeners['*'], arguments);
632
+ }
633
+ };
634
+
635
+ Observable.prototype.invoke = function (listeners, params) {
636
+ for (var i = 0, len = listeners.length; i < len; i++) {
637
+ listeners[i].apply(this, params);
638
+ }
639
+ };
640
+
641
+ Utils.Observable = Observable;
642
+
643
+ Utils.generateChars = function (length) {
644
+ var chars = '';
645
+
646
+ for (var i = 0; i < length; i++) {
647
+ var randomChar = Math.floor(Math.random() * 36);
648
+ chars += randomChar.toString(36);
649
+ }
650
+
651
+ return chars;
652
+ };
653
+
654
+ Utils.bind = function (func, context) {
655
+ return function () {
656
+ func.apply(context, arguments);
657
+ };
658
+ };
659
+
660
+ Utils._convertData = function (data) {
661
+ for (var originalKey in data) {
662
+ var keys = originalKey.split('-');
663
+
664
+ var dataLevel = data;
665
+
666
+ if (keys.length === 1) {
667
+ continue;
668
+ }
669
+
670
+ for (var k = 0; k < keys.length; k++) {
671
+ var key = keys[k];
672
+
673
+ // Lowercase the first letter
674
+ // By default, dash-separated becomes camelCase
675
+ key = key.substring(0, 1).toLowerCase() + key.substring(1);
676
+
677
+ if (!(key in dataLevel)) {
678
+ dataLevel[key] = {};
679
+ }
680
+
681
+ if (k == keys.length - 1) {
682
+ dataLevel[key] = data[originalKey];
683
+ }
684
+
685
+ dataLevel = dataLevel[key];
686
+ }
687
+
688
+ delete data[originalKey];
689
+ }
690
+
691
+ return data;
692
+ };
693
+
694
+ Utils.hasScroll = function (index, el) {
695
+ // Adapted from the function created by @ShadowScripter
696
+ // and adapted by @BillBarry on the Stack Exchange Code Review website.
697
+ // The original code can be found at
698
+ // http://codereview.stackexchange.com/q/13338
699
+ // and was designed to be used with the Sizzle selector engine.
700
+
701
+ var $el = $(el);
702
+ var overflowX = el.style.overflowX;
703
+ var overflowY = el.style.overflowY;
704
+
705
+ //Check both x and y declarations
706
+ if (overflowX === overflowY &&
707
+ (overflowY === 'hidden' || overflowY === 'visible')) {
708
+ return false;
709
+ }
710
+
711
+ if (overflowX === 'scroll' || overflowY === 'scroll') {
712
+ return true;
713
+ }
714
+
715
+ return ($el.innerHeight() < el.scrollHeight ||
716
+ $el.innerWidth() < el.scrollWidth);
717
+ };
718
+
719
+ Utils.escapeMarkup = function (markup) {
720
+ var replaceMap = {
721
+ '\\': '&#92;',
722
+ '&': '&amp;',
723
+ '<': '&lt;',
724
+ '>': '&gt;',
725
+ '"': '&quot;',
726
+ '\'': '&#39;',
727
+ '/': '&#47;'
728
+ };
729
+
730
+ // Do not try to escape the markup if it's not a string
731
+ if (typeof markup !== 'string') {
732
+ return markup;
733
+ }
734
+
735
+ return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
736
+ return replaceMap[match];
737
+ });
738
+ };
739
+
740
+ // Append an array of jQuery nodes to a given element.
741
+ Utils.appendMany = function ($element, $nodes) {
742
+ // jQuery 1.7.x does not support $.fn.append() with an array
743
+ // Fall back to a jQuery object collection using $.fn.add()
744
+ if ($.fn.jquery.substr(0, 3) === '1.7') {
745
+ var $jqNodes = $();
746
+
747
+ $.map($nodes, function (node) {
748
+ $jqNodes = $jqNodes.add(node);
749
+ });
750
+
751
+ $nodes = $jqNodes;
752
+ }
753
+
754
+ $element.append($nodes);
755
+ };
756
+
757
+ return Utils;
758
+ });
759
+
760
+ S2.define('select2/results',[
761
+ 'jquery',
762
+ './utils'
763
+ ], function ($, Utils) {
764
+ function Results ($element, options, dataAdapter) {
765
+ this.$element = $element;
766
+ this.data = dataAdapter;
767
+ this.options = options;
768
+
769
+ Results.__super__.constructor.call(this);
770
+ }
771
+
772
+ Utils.Extend(Results, Utils.Observable);
773
+
774
+ Results.prototype.render = function () {
775
+ var $results = $(
776
+ '<ul class="select2-results__options" role="tree"></ul>'
777
+ );
778
+
779
+ if (this.options.get('multiple')) {
780
+ $results.attr('aria-multiselectable', 'true');
781
+ }
782
+
783
+ this.$results = $results;
784
+
785
+ return $results;
786
+ };
787
+
788
+ Results.prototype.clear = function () {
789
+ this.$results.empty();
790
+ };
791
+
792
+ Results.prototype.displayMessage = function (params) {
793
+ var escapeMarkup = this.options.get('escapeMarkup');
794
+
795
+ this.clear();
796
+ this.hideLoading();
797
+
798
+ var $message = $(
799
+ '<li role="treeitem" aria-live="assertive"' +
800
+ ' class="select2-results__option"></li>'
801
+ );
802
+
803
+ var message = this.options.get('translations').get(params.message);
804
+
805
+ $message.append(
806
+ escapeMarkup(
807
+ message(params.args)
808
+ )
809
+ );
810
+
811
+ $message[0].className += ' select2-results__message';
812
+
813
+ this.$results.append($message);
814
+ };
815
+
816
+ Results.prototype.hideMessages = function () {
817
+ this.$results.find('.select2-results__message').remove();
818
+ };
819
+
820
+ Results.prototype.append = function (data) {
821
+ this.hideLoading();
822
+
823
+ var $options = [];
824
+
825
+ if (data.results == null || data.results.length === 0) {
826
+ if (this.$results.children().length === 0) {
827
+ this.trigger('results:message', {
828
+ message: 'noResults'
829
+ });
830
+ }
831
+
832
+ return;
833
+ }
834
+
835
+ data.results = this.sort(data.results);
836
+
837
+ for (var d = 0; d < data.results.length; d++) {
838
+ var item = data.results[d];
839
+
840
+ var $option = this.option(item);
841
+
842
+ $options.push($option);
843
+ }
844
+
845
+ this.$results.append($options);
846
+ };
847
+
848
+ Results.prototype.position = function ($results, $dropdown) {
849
+ var $resultsContainer = $dropdown.find('.select2-results');
850
+ $resultsContainer.append($results);
851
+ };
852
+
853
+ Results.prototype.sort = function (data) {
854
+ var sorter = this.options.get('sorter');
855
+
856
+ return sorter(data);
857
+ };
858
+
859
+ Results.prototype.highlightFirstItem = function () {
860
+ var $options = this.$results
861
+ .find('.select2-results__option[aria-selected]');
862
+
863
+ var $selected = $options.filter('[aria-selected=true]');
864
+
865
+ // Check if there are any selected options
866
+ if ($selected.length > 0) {
867
+ // If there are selected options, highlight the first
868
+ $selected.first().trigger('mouseenter');
869
+ } else {
870
+ // If there are no selected options, highlight the first option
871
+ // in the dropdown
872
+ $options.first().trigger('mouseenter');
873
+ }
874
+
875
+ this.ensureHighlightVisible();
876
+ };
877
+
878
+ Results.prototype.setClasses = function () {
879
+ var self = this;
880
+
881
+ this.data.current(function (selected) {
882
+ var selectedIds = $.map(selected, function (s) {
883
+ return s.id.toString();
884
+ });
885
+
886
+ var $options = self.$results
887
+ .find('.select2-results__option[aria-selected]');
888
+
889
+ $options.each(function () {
890
+ var $option = $(this);
891
+
892
+ var item = $.data(this, 'data');
893
+
894
+ // id needs to be converted to a string when comparing
895
+ var id = '' + item.id;
896
+
897
+ if ((item.element != null && item.element.selected) ||
898
+ (item.element == null && $.inArray(id, selectedIds) > -1)) {
899
+ $option.attr('aria-selected', 'true');
900
+ } else {
901
+ $option.attr('aria-selected', 'false');
902
+ }
903
+ });
904
+
905
+ });
906
+ };
907
+
908
+ Results.prototype.showLoading = function (params) {
909
+ this.hideLoading();
910
+
911
+ var loadingMore = this.options.get('translations').get('searching');
912
+
913
+ var loading = {
914
+ disabled: true,
915
+ loading: true,
916
+ text: loadingMore(params)
917
+ };
918
+ var $loading = this.option(loading);
919
+ $loading.className += ' loading-results';
920
+
921
+ this.$results.prepend($loading);
922
+ };
923
+
924
+ Results.prototype.hideLoading = function () {
925
+ this.$results.find('.loading-results').remove();
926
+ };
927
+
928
+ Results.prototype.option = function (data) {
929
+ var option = document.createElement('li');
930
+ option.className = 'select2-results__option';
931
+
932
+ var attrs = {
933
+ 'role': 'treeitem',
934
+ 'aria-selected': 'false'
935
+ };
936
+
937
+ if (data.disabled) {
938
+ delete attrs['aria-selected'];
939
+ attrs['aria-disabled'] = 'true';
940
+ }
941
+
942
+ if (data.id == null) {
943
+ delete attrs['aria-selected'];
944
+ }
945
+
946
+ if (data._resultId != null) {
947
+ option.id = data._resultId;
948
+ }
949
+
950
+ if (data.title) {
951
+ option.title = data.title;
952
+ }
953
+
954
+ if (data.children) {
955
+ attrs.role = 'group';
956
+ attrs['aria-label'] = data.text;
957
+ delete attrs['aria-selected'];
958
+ }
959
+
960
+ for (var attr in attrs) {
961
+ var val = attrs[attr];
962
+
963
+ option.setAttribute(attr, val);
964
+ }
965
+
966
+ if (data.children) {
967
+ var $option = $(option);
968
+
969
+ var label = document.createElement('strong');
970
+ label.className = 'select2-results__group';
971
+
972
+ var $label = $(label);
973
+ this.template(data, label);
974
+
975
+ var $children = [];
976
+
977
+ for (var c = 0; c < data.children.length; c++) {
978
+ var child = data.children[c];
979
+
980
+ var $child = this.option(child);
981
+
982
+ $children.push($child);
983
+ }
984
+
985
+ var $childrenContainer = $('<ul></ul>', {
986
+ 'class': 'select2-results__options select2-results__options--nested'
987
+ });
988
+
989
+ $childrenContainer.append($children);
990
+
991
+ $option.append(label);
992
+ $option.append($childrenContainer);
993
+ } else {
994
+ this.template(data, option);
995
+ }
996
+
997
+ $.data(option, 'data', data);
998
+
999
+ return option;
1000
+ };
1001
+
1002
+ Results.prototype.bind = function (container, $container) {
1003
+ var self = this;
1004
+
1005
+ var id = container.id + '-results';
1006
+
1007
+ this.$results.attr('id', id);
1008
+
1009
+ container.on('results:all', function (params) {
1010
+ self.clear();
1011
+ self.append(params.data);
1012
+
1013
+ if (container.isOpen()) {
1014
+ self.setClasses();
1015
+ self.highlightFirstItem();
1016
+ }
1017
+ });
1018
+
1019
+ container.on('results:append', function (params) {
1020
+ self.append(params.data);
1021
+
1022
+ if (container.isOpen()) {
1023
+ self.setClasses();
1024
+ }
1025
+ });
1026
+
1027
+ container.on('query', function (params) {
1028
+ self.hideMessages();
1029
+ self.showLoading(params);
1030
+ });
1031
+
1032
+ container.on('select', function () {
1033
+ if (!container.isOpen()) {
1034
+ return;
1035
+ }
1036
+
1037
+ self.setClasses();
1038
+ self.highlightFirstItem();
1039
+ });
1040
+
1041
+ container.on('unselect', function () {
1042
+ if (!container.isOpen()) {
1043
+ return;
1044
+ }
1045
+
1046
+ self.setClasses();
1047
+ self.highlightFirstItem();
1048
+ });
1049
+
1050
+ container.on('open', function () {
1051
+ // When the dropdown is open, aria-expended="true"
1052
+ self.$results.attr('aria-expanded', 'true');
1053
+ self.$results.attr('aria-hidden', 'false');
1054
+
1055
+ self.setClasses();
1056
+ self.ensureHighlightVisible();
1057
+ });
1058
+
1059
+ container.on('close', function () {
1060
+ // When the dropdown is closed, aria-expended="false"
1061
+ self.$results.attr('aria-expanded', 'false');
1062
+ self.$results.attr('aria-hidden', 'true');
1063
+ self.$results.removeAttr('aria-activedescendant');
1064
+ });
1065
+
1066
+ container.on('results:toggle', function () {
1067
+ var $highlighted = self.getHighlightedResults();
1068
+
1069
+ if ($highlighted.length === 0) {
1070
+ return;
1071
+ }
1072
+
1073
+ $highlighted.trigger('mouseup');
1074
+ });
1075
+
1076
+ container.on('results:select', function () {
1077
+ var $highlighted = self.getHighlightedResults();
1078
+
1079
+ if ($highlighted.length === 0) {
1080
+ return;
1081
+ }
1082
+
1083
+ var data = $highlighted.data('data');
1084
+
1085
+ if ($highlighted.attr('aria-selected') == 'true') {
1086
+ self.trigger('close', {});
1087
+ } else {
1088
+ self.trigger('select', {
1089
+ data: data
1090
+ });
1091
+ }
1092
+ });
1093
+
1094
+ container.on('results:previous', function () {
1095
+ var $highlighted = self.getHighlightedResults();
1096
+
1097
+ var $options = self.$results.find('[aria-selected]');
1098
+
1099
+ var currentIndex = $options.index($highlighted);
1100
+
1101
+ // If we are already at te top, don't move further
1102
+ if (currentIndex === 0) {
1103
+ return;
1104
+ }
1105
+
1106
+ var nextIndex = currentIndex - 1;
1107
+
1108
+ // If none are highlighted, highlight the first
1109
+ if ($highlighted.length === 0) {
1110
+ nextIndex = 0;
1111
+ }
1112
+
1113
+ var $next = $options.eq(nextIndex);
1114
+
1115
+ $next.trigger('mouseenter');
1116
+
1117
+ var currentOffset = self.$results.offset().top;
1118
+ var nextTop = $next.offset().top;
1119
+ var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset);
1120
+
1121
+ if (nextIndex === 0) {
1122
+ self.$results.scrollTop(0);
1123
+ } else if (nextTop - currentOffset < 0) {
1124
+ self.$results.scrollTop(nextOffset);
1125
+ }
1126
+ });
1127
+
1128
+ container.on('results:next', function () {
1129
+ var $highlighted = self.getHighlightedResults();
1130
+
1131
+ var $options = self.$results.find('[aria-selected]');
1132
+
1133
+ var currentIndex = $options.index($highlighted);
1134
+
1135
+ var nextIndex = currentIndex + 1;
1136
+
1137
+ // If we are at the last option, stay there
1138
+ if (nextIndex >= $options.length) {
1139
+ return;
1140
+ }
1141
+
1142
+ var $next = $options.eq(nextIndex);
1143
+
1144
+ $next.trigger('mouseenter');
1145
+
1146
+ var currentOffset = self.$results.offset().top +
1147
+ self.$results.outerHeight(false);
1148
+ var nextBottom = $next.offset().top + $next.outerHeight(false);
1149
+ var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset;
1150
+
1151
+ if (nextIndex === 0) {
1152
+ self.$results.scrollTop(0);
1153
+ } else if (nextBottom > currentOffset) {
1154
+ self.$results.scrollTop(nextOffset);
1155
+ }
1156
+ });
1157
+
1158
+ container.on('results:focus', function (params) {
1159
+ params.element.addClass('select2-results__option--highlighted');
1160
+ });
1161
+
1162
+ container.on('results:message', function (params) {
1163
+ self.displayMessage(params);
1164
+ });
1165
+
1166
+ if ($.fn.mousewheel) {
1167
+ this.$results.on('mousewheel', function (e) {
1168
+ var top = self.$results.scrollTop();
1169
+
1170
+ var bottom = self.$results.get(0).scrollHeight - top + e.deltaY;
1171
+
1172
+ var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0;
1173
+ var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height();
1174
+
1175
+ if (isAtTop) {
1176
+ self.$results.scrollTop(0);
1177
+
1178
+ e.preventDefault();
1179
+ e.stopPropagation();
1180
+ } else if (isAtBottom) {
1181
+ self.$results.scrollTop(
1182
+ self.$results.get(0).scrollHeight - self.$results.height()
1183
+ );
1184
+
1185
+ e.preventDefault();
1186
+ e.stopPropagation();
1187
+ }
1188
+ });
1189
+ }
1190
+
1191
+ this.$results.on('mouseup', '.select2-results__option[aria-selected]',
1192
+ function (evt) {
1193
+ var $this = $(this);
1194
+
1195
+ var data = $this.data('data');
1196
+
1197
+ if ($this.attr('aria-selected') === 'true') {
1198
+ if (self.options.get('multiple')) {
1199
+ self.trigger('unselect', {
1200
+ originalEvent: evt,
1201
+ data: data
1202
+ });
1203
+ } else {
1204
+ self.trigger('close', {});
1205
+ }
1206
+
1207
+ return;
1208
+ }
1209
+
1210
+ self.trigger('select', {
1211
+ originalEvent: evt,
1212
+ data: data
1213
+ });
1214
+ });
1215
+
1216
+ this.$results.on('mouseenter', '.select2-results__option[aria-selected]',
1217
+ function (evt) {
1218
+ var data = $(this).data('data');
1219
+
1220
+ self.getHighlightedResults()
1221
+ .removeClass('select2-results__option--highlighted');
1222
+
1223
+ self.trigger('results:focus', {
1224
+ data: data,
1225
+ element: $(this)
1226
+ });
1227
+ });
1228
+ };
1229
+
1230
+ Results.prototype.getHighlightedResults = function () {
1231
+ var $highlighted = this.$results
1232
+ .find('.select2-results__option--highlighted');
1233
+
1234
+ return $highlighted;
1235
+ };
1236
+
1237
+ Results.prototype.destroy = function () {
1238
+ this.$results.remove();
1239
+ };
1240
+
1241
+ Results.prototype.ensureHighlightVisible = function () {
1242
+ var $highlighted = this.getHighlightedResults();
1243
+
1244
+ if ($highlighted.length === 0) {
1245
+ return;
1246
+ }
1247
+
1248
+ var $options = this.$results.find('[aria-selected]');
1249
+
1250
+ var currentIndex = $options.index($highlighted);
1251
+
1252
+ var currentOffset = this.$results.offset().top;
1253
+ var nextTop = $highlighted.offset().top;
1254
+ var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset);
1255
+
1256
+ var offsetDelta = nextTop - currentOffset;
1257
+ nextOffset -= $highlighted.outerHeight(false) * 2;
1258
+
1259
+ if (currentIndex <= 2) {
1260
+ this.$results.scrollTop(0);
1261
+ } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) {
1262
+ this.$results.scrollTop(nextOffset);
1263
+ }
1264
+ };
1265
+
1266
+ Results.prototype.template = function (result, container) {
1267
+ var template = this.options.get('templateResult');
1268
+ var escapeMarkup = this.options.get('escapeMarkup');
1269
+
1270
+ var content = template(result, container);
1271
+
1272
+ if (content == null) {
1273
+ container.style.display = 'none';
1274
+ } else if (typeof content === 'string') {
1275
+ container.innerHTML = escapeMarkup(content);
1276
+ } else {
1277
+ $(container).append(content);
1278
+ }
1279
+ };
1280
+
1281
+ return Results;
1282
+ });
1283
+
1284
+ S2.define('select2/keys',[
1285
+
1286
+ ], function () {
1287
+ var KEYS = {
1288
+ BACKSPACE: 8,
1289
+ TAB: 9,
1290
+ ENTER: 13,
1291
+ SHIFT: 16,
1292
+ CTRL: 17,
1293
+ ALT: 18,
1294
+ ESC: 27,
1295
+ SPACE: 32,
1296
+ PAGE_UP: 33,
1297
+ PAGE_DOWN: 34,
1298
+ END: 35,
1299
+ HOME: 36,
1300
+ LEFT: 37,
1301
+ UP: 38,
1302
+ RIGHT: 39,
1303
+ DOWN: 40,
1304
+ DELETE: 46
1305
+ };
1306
+
1307
+ return KEYS;
1308
+ });
1309
+
1310
+ S2.define('select2/selection/base',[
1311
+ 'jquery',
1312
+ '../utils',
1313
+ '../keys'
1314
+ ], function ($, Utils, KEYS) {
1315
+ function BaseSelection ($element, options) {
1316
+ this.$element = $element;
1317
+ this.options = options;
1318
+
1319
+ BaseSelection.__super__.constructor.call(this);
1320
+ }
1321
+
1322
+ Utils.Extend(BaseSelection, Utils.Observable);
1323
+
1324
+ BaseSelection.prototype.render = function () {
1325
+ var $selection = $(
1326
+ '<span class="select2-selection" role="combobox" ' +
1327
+ ' aria-haspopup="true" aria-expanded="false">' +
1328
+ '</span>'
1329
+ );
1330
+
1331
+ this._tabindex = 0;
1332
+
1333
+ if (this.$element.data('old-tabindex') != null) {
1334
+ this._tabindex = this.$element.data('old-tabindex');
1335
+ } else if (this.$element.attr('tabindex') != null) {
1336
+ this._tabindex = this.$element.attr('tabindex');
1337
+ }
1338
+
1339
+ $selection.attr('title', this.$element.attr('title'));
1340
+ $selection.attr('tabindex', this._tabindex);
1341
+
1342
+ this.$selection = $selection;
1343
+
1344
+ return $selection;
1345
+ };
1346
+
1347
+ BaseSelection.prototype.bind = function (container, $container) {
1348
+ var self = this;
1349
+
1350
+ var id = container.id + '-container';
1351
+ var resultsId = container.id + '-results';
1352
+
1353
+ this.container = container;
1354
+
1355
+ this.$selection.on('focus', function (evt) {
1356
+ self.trigger('focus', evt);
1357
+ });
1358
+
1359
+ this.$selection.on('blur', function (evt) {
1360
+ self._handleBlur(evt);
1361
+ });
1362
+
1363
+ this.$selection.on('keydown', function (evt) {
1364
+ self.trigger('keypress', evt);
1365
+
1366
+ if (evt.which === KEYS.SPACE) {
1367
+ evt.preventDefault();
1368
+ }
1369
+ });
1370
+
1371
+ container.on('results:focus', function (params) {
1372
+ self.$selection.attr('aria-activedescendant', params.data._resultId);
1373
+ });
1374
+
1375
+ container.on('selection:update', function (params) {
1376
+ self.update(params.data);
1377
+ });
1378
+
1379
+ container.on('open', function () {
1380
+ // When the dropdown is open, aria-expanded="true"
1381
+ self.$selection.attr('aria-expanded', 'true');
1382
+ self.$selection.attr('aria-owns', resultsId);
1383
+
1384
+ self._attachCloseHandler(container);
1385
+ });
1386
+
1387
+ container.on('close', function () {
1388
+ // When the dropdown is closed, aria-expanded="false"
1389
+ self.$selection.attr('aria-expanded', 'false');
1390
+ self.$selection.removeAttr('aria-activedescendant');
1391
+ self.$selection.removeAttr('aria-owns');
1392
+
1393
+ self.$selection.focus();
1394
+
1395
+ self._detachCloseHandler(container);
1396
+ });
1397
+
1398
+ container.on('enable', function () {
1399
+ self.$selection.attr('tabindex', self._tabindex);
1400
+ });
1401
+
1402
+ container.on('disable', function () {
1403
+ self.$selection.attr('tabindex', '-1');
1404
+ });
1405
+ };
1406
+
1407
+ BaseSelection.prototype._handleBlur = function (evt) {
1408
+ var self = this;
1409
+
1410
+ // This needs to be delayed as the active element is the body when the tab
1411
+ // key is pressed, possibly along with others.
1412
+ window.setTimeout(function () {
1413
+ // Don't trigger `blur` if the focus is still in the selection
1414
+ if (
1415
+ (document.activeElement == self.$selection[0]) ||
1416
+ ($.contains(self.$selection[0], document.activeElement))
1417
+ ) {
1418
+ return;
1419
+ }
1420
+
1421
+ self.trigger('blur', evt);
1422
+ }, 1);
1423
+ };
1424
+
1425
+ BaseSelection.prototype._attachCloseHandler = function (container) {
1426
+ var self = this;
1427
+
1428
+ $(document.body).on('mousedown.select2.' + container.id, function (e) {
1429
+ var $target = $(e.target);
1430
+
1431
+ var $select = $target.closest('.select2');
1432
+
1433
+ var $all = $('.select2.select2-container--open');
1434
+
1435
+ $all.each(function () {
1436
+ var $this = $(this);
1437
+
1438
+ if (this == $select[0]) {
1439
+ return;
1440
+ }
1441
+
1442
+ var $element = $this.data('element');
1443
+
1444
+ $element.select2('close');
1445
+ });
1446
+ });
1447
+ };
1448
+
1449
+ BaseSelection.prototype._detachCloseHandler = function (container) {
1450
+ $(document.body).off('mousedown.select2.' + container.id);
1451
+ };
1452
+
1453
+ BaseSelection.prototype.position = function ($selection, $container) {
1454
+ var $selectionContainer = $container.find('.selection');
1455
+ $selectionContainer.append($selection);
1456
+ };
1457
+
1458
+ BaseSelection.prototype.destroy = function () {
1459
+ this._detachCloseHandler(this.container);
1460
+ };
1461
+
1462
+ BaseSelection.prototype.update = function (data) {
1463
+ throw new Error('The `update` method must be defined in child classes.');
1464
+ };
1465
+
1466
+ return BaseSelection;
1467
+ });
1468
+
1469
+ S2.define('select2/selection/single',[
1470
+ 'jquery',
1471
+ './base',
1472
+ '../utils',
1473
+ '../keys'
1474
+ ], function ($, BaseSelection, Utils, KEYS) {
1475
+ function SingleSelection () {
1476
+ SingleSelection.__super__.constructor.apply(this, arguments);
1477
+ }
1478
+
1479
+ Utils.Extend(SingleSelection, BaseSelection);
1480
+
1481
+ SingleSelection.prototype.render = function () {
1482
+ var $selection = SingleSelection.__super__.render.call(this);
1483
+
1484
+ $selection.addClass('select2-selection--single');
1485
+
1486
+ $selection.html(
1487
+ '<span class="select2-selection__rendered"></span>' +
1488
+ '<span class="select2-selection__arrow" role="presentation">' +
1489
+ '<b role="presentation"></b>' +
1490
+ '</span>'
1491
+ );
1492
+
1493
+ return $selection;
1494
+ };
1495
+
1496
+ SingleSelection.prototype.bind = function (container, $container) {
1497
+ var self = this;
1498
+
1499
+ SingleSelection.__super__.bind.apply(this, arguments);
1500
+
1501
+ var id = container.id + '-container';
1502
+
1503
+ this.$selection.find('.select2-selection__rendered').attr('id', id);
1504
+ this.$selection.attr('aria-labelledby', id);
1505
+
1506
+ this.$selection.on('mousedown', function (evt) {
1507
+ // Only respond to left clicks
1508
+ if (evt.which !== 1) {
1509
+ return;
1510
+ }
1511
+
1512
+ self.trigger('toggle', {
1513
+ originalEvent: evt
1514
+ });
1515
+ });
1516
+
1517
+ this.$selection.on('focus', function (evt) {
1518
+ // User focuses on the container
1519
+ });
1520
+
1521
+ this.$selection.on('blur', function (evt) {
1522
+ // User exits the container
1523
+ });
1524
+
1525
+ container.on('focus', function (evt) {
1526
+ if (!container.isOpen()) {
1527
+ self.$selection.focus();
1528
+ }
1529
+ });
1530
+
1531
+ container.on('selection:update', function (params) {
1532
+ self.update(params.data);
1533
+ });
1534
+ };
1535
+
1536
+ SingleSelection.prototype.clear = function () {
1537
+ this.$selection.find('.select2-selection__rendered').empty();
1538
+ };
1539
+
1540
+ SingleSelection.prototype.display = function (data, container) {
1541
+ var template = this.options.get('templateSelection');
1542
+ var escapeMarkup = this.options.get('escapeMarkup');
1543
+
1544
+ return escapeMarkup(template(data, container));
1545
+ };
1546
+
1547
+ SingleSelection.prototype.selectionContainer = function () {
1548
+ return $('<span></span>');
1549
+ };
1550
+
1551
+ SingleSelection.prototype.update = function (data) {
1552
+ if (data.length === 0) {
1553
+ this.clear();
1554
+ return;
1555
+ }
1556
+
1557
+ var selection = data[0];
1558
+
1559
+ var $rendered = this.$selection.find('.select2-selection__rendered');
1560
+ var formatted = this.display(selection, $rendered);
1561
+
1562
+ $rendered.empty().append(formatted);
1563
+ $rendered.prop('title', selection.title || selection.text);
1564
+ };
1565
+
1566
+ return SingleSelection;
1567
+ });
1568
+
1569
+ S2.define('select2/selection/multiple',[
1570
+ 'jquery',
1571
+ './base',
1572
+ '../utils'
1573
+ ], function ($, BaseSelection, Utils) {
1574
+ function MultipleSelection ($element, options) {
1575
+ MultipleSelection.__super__.constructor.apply(this, arguments);
1576
+ }
1577
+
1578
+ Utils.Extend(MultipleSelection, BaseSelection);
1579
+
1580
+ MultipleSelection.prototype.render = function () {
1581
+ var $selection = MultipleSelection.__super__.render.call(this);
1582
+
1583
+ $selection.addClass('select2-selection--multiple');
1584
+
1585
+ $selection.html(
1586
+ '<ul class="select2-selection__rendered"></ul>'
1587
+ );
1588
+
1589
+ return $selection;
1590
+ };
1591
+
1592
+ MultipleSelection.prototype.bind = function (container, $container) {
1593
+ var self = this;
1594
+
1595
+ MultipleSelection.__super__.bind.apply(this, arguments);
1596
+
1597
+ this.$selection.on('click', function (evt) {
1598
+ self.trigger('toggle', {
1599
+ originalEvent: evt
1600
+ });
1601
+ });
1602
+
1603
+ this.$selection.on(
1604
+ 'click',
1605
+ '.select2-selection__choice__remove',
1606
+ function (evt) {
1607
+ // Ignore the event if it is disabled
1608
+ if (self.options.get('disabled')) {
1609
+ return;
1610
+ }
1611
+
1612
+ var $remove = $(this);
1613
+ var $selection = $remove.parent();
1614
+
1615
+ var data = $selection.data('data');
1616
+
1617
+ self.trigger('unselect', {
1618
+ originalEvent: evt,
1619
+ data: data
1620
+ });
1621
+ }
1622
+ );
1623
+ };
1624
+
1625
+ MultipleSelection.prototype.clear = function () {
1626
+ this.$selection.find('.select2-selection__rendered').empty();
1627
+ };
1628
+
1629
+ MultipleSelection.prototype.display = function (data, container) {
1630
+ var template = this.options.get('templateSelection');
1631
+ var escapeMarkup = this.options.get('escapeMarkup');
1632
+
1633
+ return escapeMarkup(template(data, container));
1634
+ };
1635
+
1636
+ MultipleSelection.prototype.selectionContainer = function () {
1637
+ var $container = $(
1638
+ '<li class="select2-selection__choice">' +
1639
+ '<span class="select2-selection__choice__remove" role="presentation">' +
1640
+ '&times;' +
1641
+ '</span>' +
1642
+ '</li>'
1643
+ );
1644
+
1645
+ return $container;
1646
+ };
1647
+
1648
+ MultipleSelection.prototype.update = function (data) {
1649
+ this.clear();
1650
+
1651
+ if (data.length === 0) {
1652
+ return;
1653
+ }
1654
+
1655
+ var $selections = [];
1656
+
1657
+ for (var d = 0; d < data.length; d++) {
1658
+ var selection = data[d];
1659
+
1660
+ var $selection = this.selectionContainer();
1661
+ var formatted = this.display(selection, $selection);
1662
+
1663
+ $selection.append(formatted);
1664
+ $selection.prop('title', selection.title || selection.text);
1665
+
1666
+ $selection.data('data', selection);
1667
+
1668
+ $selections.push($selection);
1669
+ }
1670
+
1671
+ var $rendered = this.$selection.find('.select2-selection__rendered');
1672
+
1673
+ Utils.appendMany($rendered, $selections);
1674
+ };
1675
+
1676
+ return MultipleSelection;
1677
+ });
1678
+
1679
+ S2.define('select2/selection/placeholder',[
1680
+ '../utils'
1681
+ ], function (Utils) {
1682
+ function Placeholder (decorated, $element, options) {
1683
+ this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
1684
+
1685
+ decorated.call(this, $element, options);
1686
+ }
1687
+
1688
+ Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
1689
+ if (typeof placeholder === 'string') {
1690
+ placeholder = {
1691
+ id: '',
1692
+ text: placeholder
1693
+ };
1694
+ }
1695
+
1696
+ return placeholder;
1697
+ };
1698
+
1699
+ Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
1700
+ var $placeholder = this.selectionContainer();
1701
+
1702
+ $placeholder.html(this.display(placeholder));
1703
+ $placeholder.addClass('select2-selection__placeholder')
1704
+ .removeClass('select2-selection__choice');
1705
+
1706
+ return $placeholder;
1707
+ };
1708
+
1709
+ Placeholder.prototype.update = function (decorated, data) {
1710
+ var singlePlaceholder = (
1711
+ data.length == 1 && data[0].id != this.placeholder.id
1712
+ );
1713
+ var multipleSelections = data.length > 1;
1714
+
1715
+ if (multipleSelections || singlePlaceholder) {
1716
+ return decorated.call(this, data);
1717
+ }
1718
+
1719
+ this.clear();
1720
+
1721
+ var $placeholder = this.createPlaceholder(this.placeholder);
1722
+
1723
+ this.$selection.find('.select2-selection__rendered').append($placeholder);
1724
+ };
1725
+
1726
+ return Placeholder;
1727
+ });
1728
+
1729
+ S2.define('select2/selection/allowClear',[
1730
+ 'jquery',
1731
+ '../keys'
1732
+ ], function ($, KEYS) {
1733
+ function AllowClear () { }
1734
+
1735
+ AllowClear.prototype.bind = function (decorated, container, $container) {
1736
+ var self = this;
1737
+
1738
+ decorated.call(this, container, $container);
1739
+
1740
+ if (this.placeholder == null) {
1741
+ if (this.options.get('debug') && window.console && console.error) {
1742
+ console.error(
1743
+ 'Select2: The `allowClear` option should be used in combination ' +
1744
+ 'with the `placeholder` option.'
1745
+ );
1746
+ }
1747
+ }
1748
+
1749
+ this.$selection.on('mousedown', '.select2-selection__clear',
1750
+ function (evt) {
1751
+ self._handleClear(evt);
1752
+ });
1753
+
1754
+ container.on('keypress', function (evt) {
1755
+ self._handleKeyboardClear(evt, container);
1756
+ });
1757
+ };
1758
+
1759
+ AllowClear.prototype._handleClear = function (_, evt) {
1760
+ // Ignore the event if it is disabled
1761
+ if (this.options.get('disabled')) {
1762
+ return;
1763
+ }
1764
+
1765
+ var $clear = this.$selection.find('.select2-selection__clear');
1766
+
1767
+ // Ignore the event if nothing has been selected
1768
+ if ($clear.length === 0) {
1769
+ return;
1770
+ }
1771
+
1772
+ evt.stopPropagation();
1773
+
1774
+ var data = $clear.data('data');
1775
+
1776
+ for (var d = 0; d < data.length; d++) {
1777
+ var unselectData = {
1778
+ data: data[d]
1779
+ };
1780
+
1781
+ // Trigger the `unselect` event, so people can prevent it from being
1782
+ // cleared.
1783
+ this.trigger('unselect', unselectData);
1784
+
1785
+ // If the event was prevented, don't clear it out.
1786
+ if (unselectData.prevented) {
1787
+ return;
1788
+ }
1789
+ }
1790
+
1791
+ this.$element.val(this.placeholder.id).trigger('change');
1792
+
1793
+ this.trigger('toggle', {});
1794
+ };
1795
+
1796
+ AllowClear.prototype._handleKeyboardClear = function (_, evt, container) {
1797
+ if (container.isOpen()) {
1798
+ return;
1799
+ }
1800
+
1801
+ if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) {
1802
+ this._handleClear(evt);
1803
+ }
1804
+ };
1805
+
1806
+ AllowClear.prototype.update = function (decorated, data) {
1807
+ decorated.call(this, data);
1808
+
1809
+ if (this.$selection.find('.select2-selection__placeholder').length > 0 ||
1810
+ data.length === 0) {
1811
+ return;
1812
+ }
1813
+
1814
+ var $remove = $(
1815
+ '<span class="select2-selection__clear">' +
1816
+ '&times;' +
1817
+ '</span>'
1818
+ );
1819
+ $remove.data('data', data);
1820
+
1821
+ this.$selection.find('.select2-selection__rendered').prepend($remove);
1822
+ };
1823
+
1824
+ return AllowClear;
1825
+ });
1826
+
1827
+ S2.define('select2/selection/search',[
1828
+ 'jquery',
1829
+ '../utils',
1830
+ '../keys'
1831
+ ], function ($, Utils, KEYS) {
1832
+ function Search (decorated, $element, options) {
1833
+ decorated.call(this, $element, options);
1834
+ }
1835
+
1836
+ Search.prototype.render = function (decorated) {
1837
+ var $search = $(
1838
+ '<li class="select2-search select2-search--inline">' +
1839
+ '<input class="select2-search__field" type="search" tabindex="-1"' +
1840
+ ' autocomplete="off" autocorrect="off" autocapitalize="off"' +
1841
+ ' spellcheck="false" role="textbox" aria-autocomplete="list" />' +
1842
+ '</li>'
1843
+ );
1844
+
1845
+ this.$searchContainer = $search;
1846
+ this.$search = $search.find('input');
1847
+
1848
+ var $rendered = decorated.call(this);
1849
+
1850
+ this._transferTabIndex();
1851
+
1852
+ return $rendered;
1853
+ };
1854
+
1855
+ Search.prototype.bind = function (decorated, container, $container) {
1856
+ var self = this;
1857
+
1858
+ decorated.call(this, container, $container);
1859
+
1860
+ container.on('open', function () {
1861
+ self.$search.trigger('focus');
1862
+ });
1863
+
1864
+ container.on('close', function () {
1865
+ self.$search.val('');
1866
+ self.$search.removeAttr('aria-activedescendant');
1867
+ self.$search.trigger('focus');
1868
+ });
1869
+
1870
+ container.on('enable', function () {
1871
+ self.$search.prop('disabled', false);
1872
+
1873
+ self._transferTabIndex();
1874
+ });
1875
+
1876
+ container.on('disable', function () {
1877
+ self.$search.prop('disabled', true);
1878
+ });
1879
+
1880
+ container.on('focus', function (evt) {
1881
+ self.$search.trigger('focus');
1882
+ });
1883
+
1884
+ container.on('results:focus', function (params) {
1885
+ self.$search.attr('aria-activedescendant', params.id);
1886
+ });
1887
+
1888
+ this.$selection.on('focusin', '.select2-search--inline', function (evt) {
1889
+ self.trigger('focus', evt);
1890
+ });
1891
+
1892
+ this.$selection.on('focusout', '.select2-search--inline', function (evt) {
1893
+ self._handleBlur(evt);
1894
+ });
1895
+
1896
+ this.$selection.on('keydown', '.select2-search--inline', function (evt) {
1897
+ evt.stopPropagation();
1898
+
1899
+ self.trigger('keypress', evt);
1900
+
1901
+ self._keyUpPrevented = evt.isDefaultPrevented();
1902
+
1903
+ var key = evt.which;
1904
+
1905
+ if (key === KEYS.BACKSPACE && self.$search.val() === '') {
1906
+ var $previousChoice = self.$searchContainer
1907
+ .prev('.select2-selection__choice');
1908
+
1909
+ if ($previousChoice.length > 0) {
1910
+ var item = $previousChoice.data('data');
1911
+
1912
+ self.searchRemoveChoice(item);
1913
+
1914
+ evt.preventDefault();
1915
+ }
1916
+ }
1917
+ });
1918
+
1919
+ // Try to detect the IE version should the `documentMode` property that
1920
+ // is stored on the document. This is only implemented in IE and is
1921
+ // slightly cleaner than doing a user agent check.
1922
+ // This property is not available in Edge, but Edge also doesn't have
1923
+ // this bug.
1924
+ var msie = document.documentMode;
1925
+ var disableInputEvents = msie && msie <= 11;
1926
+
1927
+ // Workaround for browsers which do not support the `input` event
1928
+ // This will prevent double-triggering of events for browsers which support
1929
+ // both the `keyup` and `input` events.
1930
+ this.$selection.on(
1931
+ 'input.searchcheck',
1932
+ '.select2-search--inline',
1933
+ function (evt) {
1934
+ // IE will trigger the `input` event when a placeholder is used on a
1935
+ // search box. To get around this issue, we are forced to ignore all
1936
+ // `input` events in IE and keep using `keyup`.
1937
+ if (disableInputEvents) {
1938
+ self.$selection.off('input.search input.searchcheck');
1939
+ return;
1940
+ }
1941
+
1942
+ // Unbind the duplicated `keyup` event
1943
+ self.$selection.off('keyup.search');
1944
+ }
1945
+ );
1946
+
1947
+ this.$selection.on(
1948
+ 'keyup.search input.search',
1949
+ '.select2-search--inline',
1950
+ function (evt) {
1951
+ // IE will trigger the `input` event when a placeholder is used on a
1952
+ // search box. To get around this issue, we are forced to ignore all
1953
+ // `input` events in IE and keep using `keyup`.
1954
+ if (disableInputEvents && evt.type === 'input') {
1955
+ self.$selection.off('input.search input.searchcheck');
1956
+ return;
1957
+ }
1958
+
1959
+ var key = evt.which;
1960
+
1961
+ // We can freely ignore events from modifier keys
1962
+ if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) {
1963
+ return;
1964
+ }
1965
+
1966
+ // Tabbing will be handled during the `keydown` phase
1967
+ if (key == KEYS.TAB) {
1968
+ return;
1969
+ }
1970
+
1971
+ self.handleSearch(evt);
1972
+ }
1973
+ );
1974
+ };
1975
+
1976
+ /**
1977
+ * This method will transfer the tabindex attribute from the rendered
1978
+ * selection to the search box. This allows for the search box to be used as
1979
+ * the primary focus instead of the selection container.
1980
+ *
1981
+ * @private
1982
+ */
1983
+ Search.prototype._transferTabIndex = function (decorated) {
1984
+ this.$search.attr('tabindex', this.$selection.attr('tabindex'));
1985
+ this.$selection.attr('tabindex', '-1');
1986
+ };
1987
+
1988
+ Search.prototype.createPlaceholder = function (decorated, placeholder) {
1989
+ this.$search.attr('placeholder', placeholder.text);
1990
+ };
1991
+
1992
+ Search.prototype.update = function (decorated, data) {
1993
+ var searchHadFocus = this.$search[0] == document.activeElement;
1994
+
1995
+ this.$search.attr('placeholder', '');
1996
+
1997
+ decorated.call(this, data);
1998
+
1999
+ this.$selection.find('.select2-selection__rendered')
2000
+ .append(this.$searchContainer);
2001
+
2002
+ this.resizeSearch();
2003
+ if (searchHadFocus) {
2004
+ this.$search.focus();
2005
+ }
2006
+ };
2007
+
2008
+ Search.prototype.handleSearch = function () {
2009
+ this.resizeSearch();
2010
+
2011
+ if (!this._keyUpPrevented) {
2012
+ var input = this.$search.val();
2013
+
2014
+ this.trigger('query', {
2015
+ term: input
2016
+ });
2017
+ }
2018
+
2019
+ this._keyUpPrevented = false;
2020
+ };
2021
+
2022
+ Search.prototype.searchRemoveChoice = function (decorated, item) {
2023
+ this.trigger('unselect', {
2024
+ data: item
2025
+ });
2026
+
2027
+ this.$search.val(item.text);
2028
+ this.handleSearch();
2029
+ };
2030
+
2031
+ Search.prototype.resizeSearch = function () {
2032
+ this.$search.css('width', '25px');
2033
+
2034
+ var width = '';
2035
+
2036
+ if (this.$search.attr('placeholder') !== '') {
2037
+ width = this.$selection.find('.select2-selection__rendered').innerWidth();
2038
+ } else {
2039
+ var minimumWidth = this.$search.val().length + 1;
2040
+
2041
+ width = (minimumWidth * 0.75) + 'em';
2042
+ }
2043
+
2044
+ this.$search.css('width', width);
2045
+ };
2046
+
2047
+ return Search;
2048
+ });
2049
+
2050
+ S2.define('select2/selection/eventRelay',[
2051
+ 'jquery'
2052
+ ], function ($) {
2053
+ function EventRelay () { }
2054
+
2055
+ EventRelay.prototype.bind = function (decorated, container, $container) {
2056
+ var self = this;
2057
+ var relayEvents = [
2058
+ 'open', 'opening',
2059
+ 'close', 'closing',
2060
+ 'select', 'selecting',
2061
+ 'unselect', 'unselecting'
2062
+ ];
2063
+
2064
+ var preventableEvents = ['opening', 'closing', 'selecting', 'unselecting'];
2065
+
2066
+ decorated.call(this, container, $container);
2067
+
2068
+ container.on('*', function (name, params) {
2069
+ // Ignore events that should not be relayed
2070
+ if ($.inArray(name, relayEvents) === -1) {
2071
+ return;
2072
+ }
2073
+
2074
+ // The parameters should always be an object
2075
+ params = params || {};
2076
+
2077
+ // Generate the jQuery event for the Select2 event
2078
+ var evt = $.Event('select2:' + name, {
2079
+ params: params
2080
+ });
2081
+
2082
+ self.$element.trigger(evt);
2083
+
2084
+ // Only handle preventable events if it was one
2085
+ if ($.inArray(name, preventableEvents) === -1) {
2086
+ return;
2087
+ }
2088
+
2089
+ params.prevented = evt.isDefaultPrevented();
2090
+ });
2091
+ };
2092
+
2093
+ return EventRelay;
2094
+ });
2095
+
2096
+ S2.define('select2/translation',[
2097
+ 'jquery',
2098
+ 'require'
2099
+ ], function ($, require) {
2100
+ function Translation (dict) {
2101
+ this.dict = dict || {};
2102
+ }
2103
+
2104
+ Translation.prototype.all = function () {
2105
+ return this.dict;
2106
+ };
2107
+
2108
+ Translation.prototype.get = function (key) {
2109
+ return this.dict[key];
2110
+ };
2111
+
2112
+ Translation.prototype.extend = function (translation) {
2113
+ this.dict = $.extend({}, translation.all(), this.dict);
2114
+ };
2115
+
2116
+ // Static functions
2117
+
2118
+ Translation._cache = {};
2119
+
2120
+ Translation.loadPath = function (path) {
2121
+ if (!(path in Translation._cache)) {
2122
+ var translations = require(path);
2123
+
2124
+ Translation._cache[path] = translations;
2125
+ }
2126
+
2127
+ return new Translation(Translation._cache[path]);
2128
+ };
2129
+
2130
+ return Translation;
2131
+ });
2132
+
2133
+ S2.define('select2/diacritics',[
2134
+
2135
+ ], function () {
2136
+ var diacritics = {
2137
+ '\u24B6': 'A',
2138
+ '\uFF21': 'A',
2139
+ '\u00C0': 'A',
2140
+ '\u00C1': 'A',
2141
+ '\u00C2': 'A',
2142
+ '\u1EA6': 'A',
2143
+ '\u1EA4': 'A',
2144
+ '\u1EAA': 'A',
2145
+ '\u1EA8': 'A',
2146
+ '\u00C3': 'A',
2147
+ '\u0100': 'A',
2148
+ '\u0102': 'A',
2149
+ '\u1EB0': 'A',
2150
+ '\u1EAE': 'A',
2151
+ '\u1EB4': 'A',
2152
+ '\u1EB2': 'A',
2153
+ '\u0226': 'A',
2154
+ '\u01E0': 'A',
2155
+ '\u00C4': 'A',
2156
+ '\u01DE': 'A',
2157
+ '\u1EA2': 'A',
2158
+ '\u00C5': 'A',
2159
+ '\u01FA': 'A',
2160
+ '\u01CD': 'A',
2161
+ '\u0200': 'A',
2162
+ '\u0202': 'A',
2163
+ '\u1EA0': 'A',
2164
+ '\u1EAC': 'A',
2165
+ '\u1EB6': 'A',
2166
+ '\u1E00': 'A',
2167
+ '\u0104': 'A',
2168
+ '\u023A': 'A',
2169
+ '\u2C6F': 'A',
2170
+ '\uA732': 'AA',
2171
+ '\u00C6': 'AE',
2172
+ '\u01FC': 'AE',
2173
+ '\u01E2': 'AE',
2174
+ '\uA734': 'AO',
2175
+ '\uA736': 'AU',
2176
+ '\uA738': 'AV',
2177
+ '\uA73A': 'AV',
2178
+ '\uA73C': 'AY',
2179
+ '\u24B7': 'B',
2180
+ '\uFF22': 'B',
2181
+ '\u1E02': 'B',
2182
+ '\u1E04': 'B',
2183
+ '\u1E06': 'B',
2184
+ '\u0243': 'B',
2185
+ '\u0182': 'B',
2186
+ '\u0181': 'B',
2187
+ '\u24B8': 'C',
2188
+ '\uFF23': 'C',
2189
+ '\u0106': 'C',
2190
+ '\u0108': 'C',
2191
+ '\u010A': 'C',
2192
+ '\u010C': 'C',
2193
+ '\u00C7': 'C',
2194
+ '\u1E08': 'C',
2195
+ '\u0187': 'C',
2196
+ '\u023B': 'C',
2197
+ '\uA73E': 'C',
2198
+ '\u24B9': 'D',
2199
+ '\uFF24': 'D',
2200
+ '\u1E0A': 'D',
2201
+ '\u010E': 'D',
2202
+ '\u1E0C': 'D',
2203
+ '\u1E10': 'D',
2204
+ '\u1E12': 'D',
2205
+ '\u1E0E': 'D',
2206
+ '\u0110': 'D',
2207
+ '\u018B': 'D',
2208
+ '\u018A': 'D',
2209
+ '\u0189': 'D',
2210
+ '\uA779': 'D',
2211
+ '\u01F1': 'DZ',
2212
+ '\u01C4': 'DZ',
2213
+ '\u01F2': 'Dz',
2214
+ '\u01C5': 'Dz',
2215
+ '\u24BA': 'E',
2216
+ '\uFF25': 'E',
2217
+ '\u00C8': 'E',
2218
+ '\u00C9': 'E',
2219
+ '\u00CA': 'E',
2220
+ '\u1EC0': 'E',
2221
+ '\u1EBE': 'E',
2222
+ '\u1EC4': 'E',
2223
+ '\u1EC2': 'E',
2224
+ '\u1EBC': 'E',
2225
+ '\u0112': 'E',
2226
+ '\u1E14': 'E',
2227
+ '\u1E16': 'E',
2228
+ '\u0114': 'E',
2229
+ '\u0116': 'E',
2230
+ '\u00CB': 'E',
2231
+ '\u1EBA': 'E',
2232
+ '\u011A': 'E',
2233
+ '\u0204': 'E',
2234
+ '\u0206': 'E',
2235
+ '\u1EB8': 'E',
2236
+ '\u1EC6': 'E',
2237
+ '\u0228': 'E',
2238
+ '\u1E1C': 'E',
2239
+ '\u0118': 'E',
2240
+ '\u1E18': 'E',
2241
+ '\u1E1A': 'E',
2242
+ '\u0190': 'E',
2243
+ '\u018E': 'E',
2244
+ '\u24BB': 'F',
2245
+ '\uFF26': 'F',
2246
+ '\u1E1E': 'F',
2247
+ '\u0191': 'F',
2248
+ '\uA77B': 'F',
2249
+ '\u24BC': 'G',
2250
+ '\uFF27': 'G',
2251
+ '\u01F4': 'G',
2252
+ '\u011C': 'G',
2253
+ '\u1E20': 'G',
2254
+ '\u011E': 'G',
2255
+ '\u0120': 'G',
2256
+ '\u01E6': 'G',
2257
+ '\u0122': 'G',
2258
+ '\u01E4': 'G',
2259
+ '\u0193': 'G',
2260
+ '\uA7A0': 'G',
2261
+ '\uA77D': 'G',
2262
+ '\uA77E': 'G',
2263
+ '\u24BD': 'H',
2264
+ '\uFF28': 'H',
2265
+ '\u0124': 'H',
2266
+ '\u1E22': 'H',
2267
+ '\u1E26': 'H',
2268
+ '\u021E': 'H',
2269
+ '\u1E24': 'H',
2270
+ '\u1E28': 'H',
2271
+ '\u1E2A': 'H',
2272
+ '\u0126': 'H',
2273
+ '\u2C67': 'H',
2274
+ '\u2C75': 'H',
2275
+ '\uA78D': 'H',
2276
+ '\u24BE': 'I',
2277
+ '\uFF29': 'I',
2278
+ '\u00CC': 'I',
2279
+ '\u00CD': 'I',
2280
+ '\u00CE': 'I',
2281
+ '\u0128': 'I',
2282
+ '\u012A': 'I',
2283
+ '\u012C': 'I',
2284
+ '\u0130': 'I',
2285
+ '\u00CF': 'I',
2286
+ '\u1E2E': 'I',
2287
+ '\u1EC8': 'I',
2288
+ '\u01CF': 'I',
2289
+ '\u0208': 'I',
2290
+ '\u020A': 'I',
2291
+ '\u1ECA': 'I',
2292
+ '\u012E': 'I',
2293
+ '\u1E2C': 'I',
2294
+ '\u0197': 'I',
2295
+ '\u24BF': 'J',
2296
+ '\uFF2A': 'J',
2297
+ '\u0134': 'J',
2298
+ '\u0248': 'J',
2299
+ '\u24C0': 'K',
2300
+ '\uFF2B': 'K',
2301
+ '\u1E30': 'K',
2302
+ '\u01E8': 'K',
2303
+ '\u1E32': 'K',
2304
+ '\u0136': 'K',
2305
+ '\u1E34': 'K',
2306
+ '\u0198': 'K',
2307
+ '\u2C69': 'K',
2308
+ '\uA740': 'K',
2309
+ '\uA742': 'K',
2310
+ '\uA744': 'K',
2311
+ '\uA7A2': 'K',
2312
+ '\u24C1': 'L',
2313
+ '\uFF2C': 'L',
2314
+ '\u013F': 'L',
2315
+ '\u0139': 'L',
2316
+ '\u013D': 'L',
2317
+ '\u1E36': 'L',
2318
+ '\u1E38': 'L',
2319
+ '\u013B': 'L',
2320
+ '\u1E3C': 'L',
2321
+ '\u1E3A': 'L',
2322
+ '\u0141': 'L',
2323
+ '\u023D': 'L',
2324
+ '\u2C62': 'L',
2325
+ '\u2C60': 'L',
2326
+ '\uA748': 'L',
2327
+ '\uA746': 'L',
2328
+ '\uA780': 'L',
2329
+ '\u01C7': 'LJ',
2330
+ '\u01C8': 'Lj',
2331
+ '\u24C2': 'M',
2332
+ '\uFF2D': 'M',
2333
+ '\u1E3E': 'M',
2334
+ '\u1E40': 'M',
2335
+ '\u1E42': 'M',
2336
+ '\u2C6E': 'M',
2337
+ '\u019C': 'M',
2338
+ '\u24C3': 'N',
2339
+ '\uFF2E': 'N',
2340
+ '\u01F8': 'N',
2341
+ '\u0143': 'N',
2342
+ '\u00D1': 'N',
2343
+ '\u1E44': 'N',
2344
+ '\u0147': 'N',
2345
+ '\u1E46': 'N',
2346
+ '\u0145': 'N',
2347
+ '\u1E4A': 'N',
2348
+ '\u1E48': 'N',
2349
+ '\u0220': 'N',
2350
+ '\u019D': 'N',
2351
+ '\uA790': 'N',
2352
+ '\uA7A4': 'N',
2353
+ '\u01CA': 'NJ',
2354
+ '\u01CB': 'Nj',
2355
+ '\u24C4': 'O',
2356
+ '\uFF2F': 'O',
2357
+ '\u00D2': 'O',
2358
+ '\u00D3': 'O',
2359
+ '\u00D4': 'O',
2360
+ '\u1ED2': 'O',
2361
+ '\u1ED0': 'O',
2362
+ '\u1ED6': 'O',
2363
+ '\u1ED4': 'O',
2364
+ '\u00D5': 'O',
2365
+ '\u1E4C': 'O',
2366
+ '\u022C': 'O',
2367
+ '\u1E4E': 'O',
2368
+ '\u014C': 'O',
2369
+ '\u1E50': 'O',
2370
+ '\u1E52': 'O',
2371
+ '\u014E': 'O',
2372
+ '\u022E': 'O',
2373
+ '\u0230': 'O',
2374
+ '\u00D6': 'O',
2375
+ '\u022A': 'O',
2376
+ '\u1ECE': 'O',
2377
+ '\u0150': 'O',
2378
+ '\u01D1': 'O',
2379
+ '\u020C': 'O',
2380
+ '\u020E': 'O',
2381
+ '\u01A0': 'O',
2382
+ '\u1EDC': 'O',
2383
+ '\u1EDA': 'O',
2384
+ '\u1EE0': 'O',
2385
+ '\u1EDE': 'O',
2386
+ '\u1EE2': 'O',
2387
+ '\u1ECC': 'O',
2388
+ '\u1ED8': 'O',
2389
+ '\u01EA': 'O',
2390
+ '\u01EC': 'O',
2391
+ '\u00D8': 'O',
2392
+ '\u01FE': 'O',
2393
+ '\u0186': 'O',
2394
+ '\u019F': 'O',
2395
+ '\uA74A': 'O',
2396
+ '\uA74C': 'O',
2397
+ '\u01A2': 'OI',
2398
+ '\uA74E': 'OO',
2399
+ '\u0222': 'OU',
2400
+ '\u24C5': 'P',
2401
+ '\uFF30': 'P',
2402
+ '\u1E54': 'P',
2403
+ '\u1E56': 'P',
2404
+ '\u01A4': 'P',
2405
+ '\u2C63': 'P',
2406
+ '\uA750': 'P',
2407
+ '\uA752': 'P',
2408
+ '\uA754': 'P',
2409
+ '\u24C6': 'Q',
2410
+ '\uFF31': 'Q',
2411
+ '\uA756': 'Q',
2412
+ '\uA758': 'Q',
2413
+ '\u024A': 'Q',
2414
+ '\u24C7': 'R',
2415
+ '\uFF32': 'R',
2416
+ '\u0154': 'R',
2417
+ '\u1E58': 'R',
2418
+ '\u0158': 'R',
2419
+ '\u0210': 'R',
2420
+ '\u0212': 'R',
2421
+ '\u1E5A': 'R',
2422
+ '\u1E5C': 'R',
2423
+ '\u0156': 'R',
2424
+ '\u1E5E': 'R',
2425
+ '\u024C': 'R',
2426
+ '\u2C64': 'R',
2427
+ '\uA75A': 'R',
2428
+ '\uA7A6': 'R',
2429
+ '\uA782': 'R',
2430
+ '\u24C8': 'S',
2431
+ '\uFF33': 'S',
2432
+ '\u1E9E': 'S',
2433
+ '\u015A': 'S',
2434
+ '\u1E64': 'S',
2435
+ '\u015C': 'S',
2436
+ '\u1E60': 'S',
2437
+ '\u0160': 'S',
2438
+ '\u1E66': 'S',
2439
+ '\u1E62': 'S',
2440
+ '\u1E68': 'S',
2441
+ '\u0218': 'S',
2442
+ '\u015E': 'S',
2443
+ '\u2C7E': 'S',
2444
+ '\uA7A8': 'S',
2445
+ '\uA784': 'S',
2446
+ '\u24C9': 'T',
2447
+ '\uFF34': 'T',
2448
+ '\u1E6A': 'T',
2449
+ '\u0164': 'T',
2450
+ '\u1E6C': 'T',
2451
+ '\u021A': 'T',
2452
+ '\u0162': 'T',
2453
+ '\u1E70': 'T',
2454
+ '\u1E6E': 'T',
2455
+ '\u0166': 'T',
2456
+ '\u01AC': 'T',
2457
+ '\u01AE': 'T',
2458
+ '\u023E': 'T',
2459
+ '\uA786': 'T',
2460
+ '\uA728': 'TZ',
2461
+ '\u24CA': 'U',
2462
+ '\uFF35': 'U',
2463
+ '\u00D9': 'U',
2464
+ '\u00DA': 'U',
2465
+ '\u00DB': 'U',
2466
+ '\u0168': 'U',
2467
+ '\u1E78': 'U',
2468
+ '\u016A': 'U',
2469
+ '\u1E7A': 'U',
2470
+ '\u016C': 'U',
2471
+ '\u00DC': 'U',
2472
+ '\u01DB': 'U',
2473
+ '\u01D7': 'U',
2474
+ '\u01D5': 'U',
2475
+ '\u01D9': 'U',
2476
+ '\u1EE6': 'U',
2477
+ '\u016E': 'U',
2478
+ '\u0170': 'U',
2479
+ '\u01D3': 'U',
2480
+ '\u0214': 'U',
2481
+ '\u0216': 'U',
2482
+ '\u01AF': 'U',
2483
+ '\u1EEA': 'U',
2484
+ '\u1EE8': 'U',
2485
+ '\u1EEE': 'U',
2486
+ '\u1EEC': 'U',
2487
+ '\u1EF0': 'U',
2488
+ '\u1EE4': 'U',
2489
+ '\u1E72': 'U',
2490
+ '\u0172': 'U',
2491
+ '\u1E76': 'U',
2492
+ '\u1E74': 'U',
2493
+ '\u0244': 'U',
2494
+ '\u24CB': 'V',
2495
+ '\uFF36': 'V',
2496
+ '\u1E7C': 'V',
2497
+ '\u1E7E': 'V',
2498
+ '\u01B2': 'V',
2499
+ '\uA75E': 'V',
2500
+ '\u0245': 'V',
2501
+ '\uA760': 'VY',
2502
+ '\u24CC': 'W',
2503
+ '\uFF37': 'W',
2504
+ '\u1E80': 'W',
2505
+ '\u1E82': 'W',
2506
+ '\u0174': 'W',
2507
+ '\u1E86': 'W',
2508
+ '\u1E84': 'W',
2509
+ '\u1E88': 'W',
2510
+ '\u2C72': 'W',
2511
+ '\u24CD': 'X',
2512
+ '\uFF38': 'X',
2513
+ '\u1E8A': 'X',
2514
+ '\u1E8C': 'X',
2515
+ '\u24CE': 'Y',
2516
+ '\uFF39': 'Y',
2517
+ '\u1EF2': 'Y',
2518
+ '\u00DD': 'Y',
2519
+ '\u0176': 'Y',
2520
+ '\u1EF8': 'Y',
2521
+ '\u0232': 'Y',
2522
+ '\u1E8E': 'Y',
2523
+ '\u0178': 'Y',
2524
+ '\u1EF6': 'Y',
2525
+ '\u1EF4': 'Y',
2526
+ '\u01B3': 'Y',
2527
+ '\u024E': 'Y',
2528
+ '\u1EFE': 'Y',
2529
+ '\u24CF': 'Z',
2530
+ '\uFF3A': 'Z',
2531
+ '\u0179': 'Z',
2532
+ '\u1E90': 'Z',
2533
+ '\u017B': 'Z',
2534
+ '\u017D': 'Z',
2535
+ '\u1E92': 'Z',
2536
+ '\u1E94': 'Z',
2537
+ '\u01B5': 'Z',
2538
+ '\u0224': 'Z',
2539
+ '\u2C7F': 'Z',
2540
+ '\u2C6B': 'Z',
2541
+ '\uA762': 'Z',
2542
+ '\u24D0': 'a',
2543
+ '\uFF41': 'a',
2544
+ '\u1E9A': 'a',
2545
+ '\u00E0': 'a',
2546
+ '\u00E1': 'a',
2547
+ '\u00E2': 'a',
2548
+ '\u1EA7': 'a',
2549
+ '\u1EA5': 'a',
2550
+ '\u1EAB': 'a',
2551
+ '\u1EA9': 'a',
2552
+ '\u00E3': 'a',
2553
+ '\u0101': 'a',
2554
+ '\u0103': 'a',
2555
+ '\u1EB1': 'a',
2556
+ '\u1EAF': 'a',
2557
+ '\u1EB5': 'a',
2558
+ '\u1EB3': 'a',
2559
+ '\u0227': 'a',
2560
+ '\u01E1': 'a',
2561
+ '\u00E4': 'a',
2562
+ '\u01DF': 'a',
2563
+ '\u1EA3': 'a',
2564
+ '\u00E5': 'a',
2565
+ '\u01FB': 'a',
2566
+ '\u01CE': 'a',
2567
+ '\u0201': 'a',
2568
+ '\u0203': 'a',
2569
+ '\u1EA1': 'a',
2570
+ '\u1EAD': 'a',
2571
+ '\u1EB7': 'a',
2572
+ '\u1E01': 'a',
2573
+ '\u0105': 'a',
2574
+ '\u2C65': 'a',
2575
+ '\u0250': 'a',
2576
+ '\uA733': 'aa',
2577
+ '\u00E6': 'ae',
2578
+ '\u01FD': 'ae',
2579
+ '\u01E3': 'ae',
2580
+ '\uA735': 'ao',
2581
+ '\uA737': 'au',
2582
+ '\uA739': 'av',
2583
+ '\uA73B': 'av',
2584
+ '\uA73D': 'ay',
2585
+ '\u24D1': 'b',
2586
+ '\uFF42': 'b',
2587
+ '\u1E03': 'b',
2588
+ '\u1E05': 'b',
2589
+ '\u1E07': 'b',
2590
+ '\u0180': 'b',
2591
+ '\u0183': 'b',
2592
+ '\u0253': 'b',
2593
+ '\u24D2': 'c',
2594
+ '\uFF43': 'c',
2595
+ '\u0107': 'c',
2596
+ '\u0109': 'c',
2597
+ '\u010B': 'c',
2598
+ '\u010D': 'c',
2599
+ '\u00E7': 'c',
2600
+ '\u1E09': 'c',
2601
+ '\u0188': 'c',
2602
+ '\u023C': 'c',
2603
+ '\uA73F': 'c',
2604
+ '\u2184': 'c',
2605
+ '\u24D3': 'd',
2606
+ '\uFF44': 'd',
2607
+ '\u1E0B': 'd',
2608
+ '\u010F': 'd',
2609
+ '\u1E0D': 'd',
2610
+ '\u1E11': 'd',
2611
+ '\u1E13': 'd',
2612
+ '\u1E0F': 'd',
2613
+ '\u0111': 'd',
2614
+ '\u018C': 'd',
2615
+ '\u0256': 'd',
2616
+ '\u0257': 'd',
2617
+ '\uA77A': 'd',
2618
+ '\u01F3': 'dz',
2619
+ '\u01C6': 'dz',
2620
+ '\u24D4': 'e',
2621
+ '\uFF45': 'e',
2622
+ '\u00E8': 'e',
2623
+ '\u00E9': 'e',
2624
+ '\u00EA': 'e',
2625
+ '\u1EC1': 'e',
2626
+ '\u1EBF': 'e',
2627
+ '\u1EC5': 'e',
2628
+ '\u1EC3': 'e',
2629
+ '\u1EBD': 'e',
2630
+ '\u0113': 'e',
2631
+ '\u1E15': 'e',
2632
+ '\u1E17': 'e',
2633
+ '\u0115': 'e',
2634
+ '\u0117': 'e',
2635
+ '\u00EB': 'e',
2636
+ '\u1EBB': 'e',
2637
+ '\u011B': 'e',
2638
+ '\u0205': 'e',
2639
+ '\u0207': 'e',
2640
+ '\u1EB9': 'e',
2641
+ '\u1EC7': 'e',
2642
+ '\u0229': 'e',
2643
+ '\u1E1D': 'e',
2644
+ '\u0119': 'e',
2645
+ '\u1E19': 'e',
2646
+ '\u1E1B': 'e',
2647
+ '\u0247': 'e',
2648
+ '\u025B': 'e',
2649
+ '\u01DD': 'e',
2650
+ '\u24D5': 'f',
2651
+ '\uFF46': 'f',
2652
+ '\u1E1F': 'f',
2653
+ '\u0192': 'f',
2654
+ '\uA77C': 'f',
2655
+ '\u24D6': 'g',
2656
+ '\uFF47': 'g',
2657
+ '\u01F5': 'g',
2658
+ '\u011D': 'g',
2659
+ '\u1E21': 'g',
2660
+ '\u011F': 'g',
2661
+ '\u0121': 'g',
2662
+ '\u01E7': 'g',
2663
+ '\u0123': 'g',
2664
+ '\u01E5': 'g',
2665
+ '\u0260': 'g',
2666
+ '\uA7A1': 'g',
2667
+ '\u1D79': 'g',
2668
+ '\uA77F': 'g',
2669
+ '\u24D7': 'h',
2670
+ '\uFF48': 'h',
2671
+ '\u0125': 'h',
2672
+ '\u1E23': 'h',
2673
+ '\u1E27': 'h',
2674
+ '\u021F': 'h',
2675
+ '\u1E25': 'h',
2676
+ '\u1E29': 'h',
2677
+ '\u1E2B': 'h',
2678
+ '\u1E96': 'h',
2679
+ '\u0127': 'h',
2680
+ '\u2C68': 'h',
2681
+ '\u2C76': 'h',
2682
+ '\u0265': 'h',
2683
+ '\u0195': 'hv',
2684
+ '\u24D8': 'i',
2685
+ '\uFF49': 'i',
2686
+ '\u00EC': 'i',
2687
+ '\u00ED': 'i',
2688
+ '\u00EE': 'i',
2689
+ '\u0129': 'i',
2690
+ '\u012B': 'i',
2691
+ '\u012D': 'i',
2692
+ '\u00EF': 'i',
2693
+ '\u1E2F': 'i',
2694
+ '\u1EC9': 'i',
2695
+ '\u01D0': 'i',
2696
+ '\u0209': 'i',
2697
+ '\u020B': 'i',
2698
+ '\u1ECB': 'i',
2699
+ '\u012F': 'i',
2700
+ '\u1E2D': 'i',
2701
+ '\u0268': 'i',
2702
+ '\u0131': 'i',
2703
+ '\u24D9': 'j',
2704
+ '\uFF4A': 'j',
2705
+ '\u0135': 'j',
2706
+ '\u01F0': 'j',
2707
+ '\u0249': 'j',
2708
+ '\u24DA': 'k',
2709
+ '\uFF4B': 'k',
2710
+ '\u1E31': 'k',
2711
+ '\u01E9': 'k',
2712
+ '\u1E33': 'k',
2713
+ '\u0137': 'k',
2714
+ '\u1E35': 'k',
2715
+ '\u0199': 'k',
2716
+ '\u2C6A': 'k',
2717
+ '\uA741': 'k',
2718
+ '\uA743': 'k',
2719
+ '\uA745': 'k',
2720
+ '\uA7A3': 'k',
2721
+ '\u24DB': 'l',
2722
+ '\uFF4C': 'l',
2723
+ '\u0140': 'l',
2724
+ '\u013A': 'l',
2725
+ '\u013E': 'l',
2726
+ '\u1E37': 'l',
2727
+ '\u1E39': 'l',
2728
+ '\u013C': 'l',
2729
+ '\u1E3D': 'l',
2730
+ '\u1E3B': 'l',
2731
+ '\u017F': 'l',
2732
+ '\u0142': 'l',
2733
+ '\u019A': 'l',
2734
+ '\u026B': 'l',
2735
+ '\u2C61': 'l',
2736
+ '\uA749': 'l',
2737
+ '\uA781': 'l',
2738
+ '\uA747': 'l',
2739
+ '\u01C9': 'lj',
2740
+ '\u24DC': 'm',
2741
+ '\uFF4D': 'm',
2742
+ '\u1E3F': 'm',
2743
+ '\u1E41': 'm',
2744
+ '\u1E43': 'm',
2745
+ '\u0271': 'm',
2746
+ '\u026F': 'm',
2747
+ '\u24DD': 'n',
2748
+ '\uFF4E': 'n',
2749
+ '\u01F9': 'n',
2750
+ '\u0144': 'n',
2751
+ '\u00F1': 'n',
2752
+ '\u1E45': 'n',
2753
+ '\u0148': 'n',
2754
+ '\u1E47': 'n',
2755
+ '\u0146': 'n',
2756
+ '\u1E4B': 'n',
2757
+ '\u1E49': 'n',
2758
+ '\u019E': 'n',
2759
+ '\u0272': 'n',
2760
+ '\u0149': 'n',
2761
+ '\uA791': 'n',
2762
+ '\uA7A5': 'n',
2763
+ '\u01CC': 'nj',
2764
+ '\u24DE': 'o',
2765
+ '\uFF4F': 'o',
2766
+ '\u00F2': 'o',
2767
+ '\u00F3': 'o',
2768
+ '\u00F4': 'o',
2769
+ '\u1ED3': 'o',
2770
+ '\u1ED1': 'o',
2771
+ '\u1ED7': 'o',
2772
+ '\u1ED5': 'o',
2773
+ '\u00F5': 'o',
2774
+ '\u1E4D': 'o',
2775
+ '\u022D': 'o',
2776
+ '\u1E4F': 'o',
2777
+ '\u014D': 'o',
2778
+ '\u1E51': 'o',
2779
+ '\u1E53': 'o',
2780
+ '\u014F': 'o',
2781
+ '\u022F': 'o',
2782
+ '\u0231': 'o',
2783
+ '\u00F6': 'o',
2784
+ '\u022B': 'o',
2785
+ '\u1ECF': 'o',
2786
+ '\u0151': 'o',
2787
+ '\u01D2': 'o',
2788
+ '\u020D': 'o',
2789
+ '\u020F': 'o',
2790
+ '\u01A1': 'o',
2791
+ '\u1EDD': 'o',
2792
+ '\u1EDB': 'o',
2793
+ '\u1EE1': 'o',
2794
+ '\u1EDF': 'o',
2795
+ '\u1EE3': 'o',
2796
+ '\u1ECD': 'o',
2797
+ '\u1ED9': 'o',
2798
+ '\u01EB': 'o',
2799
+ '\u01ED': 'o',
2800
+ '\u00F8': 'o',
2801
+ '\u01FF': 'o',
2802
+ '\u0254': 'o',
2803
+ '\uA74B': 'o',
2804
+ '\uA74D': 'o',
2805
+ '\u0275': 'o',
2806
+ '\u01A3': 'oi',
2807
+ '\u0223': 'ou',
2808
+ '\uA74F': 'oo',
2809
+ '\u24DF': 'p',
2810
+ '\uFF50': 'p',
2811
+ '\u1E55': 'p',
2812
+ '\u1E57': 'p',
2813
+ '\u01A5': 'p',
2814
+ '\u1D7D': 'p',
2815
+ '\uA751': 'p',
2816
+ '\uA753': 'p',
2817
+ '\uA755': 'p',
2818
+ '\u24E0': 'q',
2819
+ '\uFF51': 'q',
2820
+ '\u024B': 'q',
2821
+ '\uA757': 'q',
2822
+ '\uA759': 'q',
2823
+ '\u24E1': 'r',
2824
+ '\uFF52': 'r',
2825
+ '\u0155': 'r',
2826
+ '\u1E59': 'r',
2827
+ '\u0159': 'r',
2828
+ '\u0211': 'r',
2829
+ '\u0213': 'r',
2830
+ '\u1E5B': 'r',
2831
+ '\u1E5D': 'r',
2832
+ '\u0157': 'r',
2833
+ '\u1E5F': 'r',
2834
+ '\u024D': 'r',
2835
+ '\u027D': 'r',
2836
+ '\uA75B': 'r',
2837
+ '\uA7A7': 'r',
2838
+ '\uA783': 'r',
2839
+ '\u24E2': 's',
2840
+ '\uFF53': 's',
2841
+ '\u00DF': 's',
2842
+ '\u015B': 's',
2843
+ '\u1E65': 's',
2844
+ '\u015D': 's',
2845
+ '\u1E61': 's',
2846
+ '\u0161': 's',
2847
+ '\u1E67': 's',
2848
+ '\u1E63': 's',
2849
+ '\u1E69': 's',
2850
+ '\u0219': 's',
2851
+ '\u015F': 's',
2852
+ '\u023F': 's',
2853
+ '\uA7A9': 's',
2854
+ '\uA785': 's',
2855
+ '\u1E9B': 's',
2856
+ '\u24E3': 't',
2857
+ '\uFF54': 't',
2858
+ '\u1E6B': 't',
2859
+ '\u1E97': 't',
2860
+ '\u0165': 't',
2861
+ '\u1E6D': 't',
2862
+ '\u021B': 't',
2863
+ '\u0163': 't',
2864
+ '\u1E71': 't',
2865
+ '\u1E6F': 't',
2866
+ '\u0167': 't',
2867
+ '\u01AD': 't',
2868
+ '\u0288': 't',
2869
+ '\u2C66': 't',
2870
+ '\uA787': 't',
2871
+ '\uA729': 'tz',
2872
+ '\u24E4': 'u',
2873
+ '\uFF55': 'u',
2874
+ '\u00F9': 'u',
2875
+ '\u00FA': 'u',
2876
+ '\u00FB': 'u',
2877
+ '\u0169': 'u',
2878
+ '\u1E79': 'u',
2879
+ '\u016B': 'u',
2880
+ '\u1E7B': 'u',
2881
+ '\u016D': 'u',
2882
+ '\u00FC': 'u',
2883
+ '\u01DC': 'u',
2884
+ '\u01D8': 'u',
2885
+ '\u01D6': 'u',
2886
+ '\u01DA': 'u',
2887
+ '\u1EE7': 'u',
2888
+ '\u016F': 'u',
2889
+ '\u0171': 'u',
2890
+ '\u01D4': 'u',
2891
+ '\u0215': 'u',
2892
+ '\u0217': 'u',
2893
+ '\u01B0': 'u',
2894
+ '\u1EEB': 'u',
2895
+ '\u1EE9': 'u',
2896
+ '\u1EEF': 'u',
2897
+ '\u1EED': 'u',
2898
+ '\u1EF1': 'u',
2899
+ '\u1EE5': 'u',
2900
+ '\u1E73': 'u',
2901
+ '\u0173': 'u',
2902
+ '\u1E77': 'u',
2903
+ '\u1E75': 'u',
2904
+ '\u0289': 'u',
2905
+ '\u24E5': 'v',
2906
+ '\uFF56': 'v',
2907
+ '\u1E7D': 'v',
2908
+ '\u1E7F': 'v',
2909
+ '\u028B': 'v',
2910
+ '\uA75F': 'v',
2911
+ '\u028C': 'v',
2912
+ '\uA761': 'vy',
2913
+ '\u24E6': 'w',
2914
+ '\uFF57': 'w',
2915
+ '\u1E81': 'w',
2916
+ '\u1E83': 'w',
2917
+ '\u0175': 'w',
2918
+ '\u1E87': 'w',
2919
+ '\u1E85': 'w',
2920
+ '\u1E98': 'w',
2921
+ '\u1E89': 'w',
2922
+ '\u2C73': 'w',
2923
+ '\u24E7': 'x',
2924
+ '\uFF58': 'x',
2925
+ '\u1E8B': 'x',
2926
+ '\u1E8D': 'x',
2927
+ '\u24E8': 'y',
2928
+ '\uFF59': 'y',
2929
+ '\u1EF3': 'y',
2930
+ '\u00FD': 'y',
2931
+ '\u0177': 'y',
2932
+ '\u1EF9': 'y',
2933
+ '\u0233': 'y',
2934
+ '\u1E8F': 'y',
2935
+ '\u00FF': 'y',
2936
+ '\u1EF7': 'y',
2937
+ '\u1E99': 'y',
2938
+ '\u1EF5': 'y',
2939
+ '\u01B4': 'y',
2940
+ '\u024F': 'y',
2941
+ '\u1EFF': 'y',
2942
+ '\u24E9': 'z',
2943
+ '\uFF5A': 'z',
2944
+ '\u017A': 'z',
2945
+ '\u1E91': 'z',
2946
+ '\u017C': 'z',
2947
+ '\u017E': 'z',
2948
+ '\u1E93': 'z',
2949
+ '\u1E95': 'z',
2950
+ '\u01B6': 'z',
2951
+ '\u0225': 'z',
2952
+ '\u0240': 'z',
2953
+ '\u2C6C': 'z',
2954
+ '\uA763': 'z',
2955
+ '\u0386': '\u0391',
2956
+ '\u0388': '\u0395',
2957
+ '\u0389': '\u0397',
2958
+ '\u038A': '\u0399',
2959
+ '\u03AA': '\u0399',
2960
+ '\u038C': '\u039F',
2961
+ '\u038E': '\u03A5',
2962
+ '\u03AB': '\u03A5',
2963
+ '\u038F': '\u03A9',
2964
+ '\u03AC': '\u03B1',
2965
+ '\u03AD': '\u03B5',
2966
+ '\u03AE': '\u03B7',
2967
+ '\u03AF': '\u03B9',
2968
+ '\u03CA': '\u03B9',
2969
+ '\u0390': '\u03B9',
2970
+ '\u03CC': '\u03BF',
2971
+ '\u03CD': '\u03C5',
2972
+ '\u03CB': '\u03C5',
2973
+ '\u03B0': '\u03C5',
2974
+ '\u03C9': '\u03C9',
2975
+ '\u03C2': '\u03C3'
2976
+ };
2977
+
2978
+ return diacritics;
2979
+ });
2980
+
2981
+ S2.define('select2/data/base',[
2982
+ '../utils'
2983
+ ], function (Utils) {
2984
+ function BaseAdapter ($element, options) {
2985
+ BaseAdapter.__super__.constructor.call(this);
2986
+ }
2987
+
2988
+ Utils.Extend(BaseAdapter, Utils.Observable);
2989
+
2990
+ BaseAdapter.prototype.current = function (callback) {
2991
+ throw new Error('The `current` method must be defined in child classes.');
2992
+ };
2993
+
2994
+ BaseAdapter.prototype.query = function (params, callback) {
2995
+ throw new Error('The `query` method must be defined in child classes.');
2996
+ };
2997
+
2998
+ BaseAdapter.prototype.bind = function (container, $container) {
2999
+ // Can be implemented in subclasses
3000
+ };
3001
+
3002
+ BaseAdapter.prototype.destroy = function () {
3003
+ // Can be implemented in subclasses
3004
+ };
3005
+
3006
+ BaseAdapter.prototype.generateResultId = function (container, data) {
3007
+ var id = container.id + '-result-';
3008
+
3009
+ id += Utils.generateChars(4);
3010
+
3011
+ if (data.id != null) {
3012
+ id += '-' + data.id.toString();
3013
+ } else {
3014
+ id += '-' + Utils.generateChars(4);
3015
+ }
3016
+ return id;
3017
+ };
3018
+
3019
+ return BaseAdapter;
3020
+ });
3021
+
3022
+ S2.define('select2/data/select',[
3023
+ './base',
3024
+ '../utils',
3025
+ 'jquery'
3026
+ ], function (BaseAdapter, Utils, $) {
3027
+ function SelectAdapter ($element, options) {
3028
+ this.$element = $element;
3029
+ this.options = options;
3030
+
3031
+ SelectAdapter.__super__.constructor.call(this);
3032
+ }
3033
+
3034
+ Utils.Extend(SelectAdapter, BaseAdapter);
3035
+
3036
+ SelectAdapter.prototype.current = function (callback) {
3037
+ var data = [];
3038
+ var self = this;
3039
+
3040
+ this.$element.find(':selected').each(function () {
3041
+ var $option = $(this);
3042
+
3043
+ var option = self.item($option);
3044
+
3045
+ data.push(option);
3046
+ });
3047
+
3048
+ callback(data);
3049
+ };
3050
+
3051
+ SelectAdapter.prototype.select = function (data) {
3052
+ var self = this;
3053
+
3054
+ data.selected = true;
3055
+
3056
+ // If data.element is a DOM node, use it instead
3057
+ if ($(data.element).is('option')) {
3058
+ data.element.selected = true;
3059
+
3060
+ this.$element.trigger('change');
3061
+
3062
+ return;
3063
+ }
3064
+
3065
+ if (this.$element.prop('multiple')) {
3066
+ this.current(function (currentData) {
3067
+ var val = [];
3068
+
3069
+ data = [data];
3070
+ data.push.apply(data, currentData);
3071
+
3072
+ for (var d = 0; d < data.length; d++) {
3073
+ var id = data[d].id;
3074
+
3075
+ if ($.inArray(id, val) === -1) {
3076
+ val.push(id);
3077
+ }
3078
+ }
3079
+
3080
+ self.$element.val(val);
3081
+ self.$element.trigger('change');
3082
+ });
3083
+ } else {
3084
+ var val = data.id;
3085
+
3086
+ this.$element.val(val);
3087
+ this.$element.trigger('change');
3088
+ }
3089
+ };
3090
+
3091
+ SelectAdapter.prototype.unselect = function (data) {
3092
+ var self = this;
3093
+
3094
+ if (!this.$element.prop('multiple')) {
3095
+ return;
3096
+ }
3097
+
3098
+ data.selected = false;
3099
+
3100
+ if ($(data.element).is('option')) {
3101
+ data.element.selected = false;
3102
+
3103
+ this.$element.trigger('change');
3104
+
3105
+ return;
3106
+ }
3107
+
3108
+ this.current(function (currentData) {
3109
+ var val = [];
3110
+
3111
+ for (var d = 0; d < currentData.length; d++) {
3112
+ var id = currentData[d].id;
3113
+
3114
+ if (id !== data.id && $.inArray(id, val) === -1) {
3115
+ val.push(id);
3116
+ }
3117
+ }
3118
+
3119
+ self.$element.val(val);
3120
+
3121
+ self.$element.trigger('change');
3122
+ });
3123
+ };
3124
+
3125
+ SelectAdapter.prototype.bind = function (container, $container) {
3126
+ var self = this;
3127
+
3128
+ this.container = container;
3129
+
3130
+ container.on('select', function (params) {
3131
+ self.select(params.data);
3132
+ });
3133
+
3134
+ container.on('unselect', function (params) {
3135
+ self.unselect(params.data);
3136
+ });
3137
+ };
3138
+
3139
+ SelectAdapter.prototype.destroy = function () {
3140
+ // Remove anything added to child elements
3141
+ this.$element.find('*').each(function () {
3142
+ // Remove any custom data set by Select2
3143
+ $.removeData(this, 'data');
3144
+ });
3145
+ };
3146
+
3147
+ SelectAdapter.prototype.query = function (params, callback) {
3148
+ var data = [];
3149
+ var self = this;
3150
+
3151
+ var $options = this.$element.children();
3152
+
3153
+ $options.each(function () {
3154
+ var $option = $(this);
3155
+
3156
+ if (!$option.is('option') && !$option.is('optgroup')) {
3157
+ return;
3158
+ }
3159
+
3160
+ var option = self.item($option);
3161
+
3162
+ var matches = self.matches(params, option);
3163
+
3164
+ if (matches !== null) {
3165
+ data.push(matches);
3166
+ }
3167
+ });
3168
+
3169
+ callback({
3170
+ results: data
3171
+ });
3172
+ };
3173
+
3174
+ SelectAdapter.prototype.addOptions = function ($options) {
3175
+ Utils.appendMany(this.$element, $options);
3176
+ };
3177
+
3178
+ SelectAdapter.prototype.option = function (data) {
3179
+ var option;
3180
+
3181
+ if (data.children) {
3182
+ option = document.createElement('optgroup');
3183
+ option.label = data.text;
3184
+ } else {
3185
+ option = document.createElement('option');
3186
+
3187
+ if (option.textContent !== undefined) {
3188
+ option.textContent = data.text;
3189
+ } else {
3190
+ option.innerText = data.text;
3191
+ }
3192
+ }
3193
+
3194
+ if (data.id) {
3195
+ option.value = data.id;
3196
+ }
3197
+
3198
+ if (data.disabled) {
3199
+ option.disabled = true;
3200
+ }
3201
+
3202
+ if (data.selected) {
3203
+ option.selected = true;
3204
+ }
3205
+
3206
+ if (data.title) {
3207
+ option.title = data.title;
3208
+ }
3209
+
3210
+ var $option = $(option);
3211
+
3212
+ var normalizedData = this._normalizeItem(data);
3213
+ normalizedData.element = option;
3214
+
3215
+ // Override the option's data with the combined data
3216
+ $.data(option, 'data', normalizedData);
3217
+
3218
+ return $option;
3219
+ };
3220
+
3221
+ SelectAdapter.prototype.item = function ($option) {
3222
+ var data = {};
3223
+
3224
+ data = $.data($option[0], 'data');
3225
+
3226
+ if (data != null) {
3227
+ return data;
3228
+ }
3229
+
3230
+ if ($option.is('option')) {
3231
+ data = {
3232
+ id: $option.val(),
3233
+ text: $option.text(),
3234
+ disabled: $option.prop('disabled'),
3235
+ selected: $option.prop('selected'),
3236
+ title: $option.prop('title')
3237
+ };
3238
+ } else if ($option.is('optgroup')) {
3239
+ data = {
3240
+ text: $option.prop('label'),
3241
+ children: [],
3242
+ title: $option.prop('title')
3243
+ };
3244
+
3245
+ var $children = $option.children('option');
3246
+ var children = [];
3247
+
3248
+ for (var c = 0; c < $children.length; c++) {
3249
+ var $child = $($children[c]);
3250
+
3251
+ var child = this.item($child);
3252
+
3253
+ children.push(child);
3254
+ }
3255
+
3256
+ data.children = children;
3257
+ }
3258
+
3259
+ data = this._normalizeItem(data);
3260
+ data.element = $option[0];
3261
+
3262
+ $.data($option[0], 'data', data);
3263
+
3264
+ return data;
3265
+ };
3266
+
3267
+ SelectAdapter.prototype._normalizeItem = function (item) {
3268
+ if (!$.isPlainObject(item)) {
3269
+ item = {
3270
+ id: item,
3271
+ text: item
3272
+ };
3273
+ }
3274
+
3275
+ item = $.extend({}, {
3276
+ text: ''
3277
+ }, item);
3278
+
3279
+ var defaults = {
3280
+ selected: false,
3281
+ disabled: false
3282
+ };
3283
+
3284
+ if (item.id != null) {
3285
+ item.id = item.id.toString();
3286
+ }
3287
+
3288
+ if (item.text != null) {
3289
+ item.text = item.text.toString();
3290
+ }
3291
+
3292
+ if (item._resultId == null && item.id && this.container != null) {
3293
+ item._resultId = this.generateResultId(this.container, item);
3294
+ }
3295
+
3296
+ return $.extend({}, defaults, item);
3297
+ };
3298
+
3299
+ SelectAdapter.prototype.matches = function (params, data) {
3300
+ var matcher = this.options.get('matcher');
3301
+
3302
+ return matcher(params, data);
3303
+ };
3304
+
3305
+ return SelectAdapter;
3306
+ });
3307
+
3308
+ S2.define('select2/data/array',[
3309
+ './select',
3310
+ '../utils',
3311
+ 'jquery'
3312
+ ], function (SelectAdapter, Utils, $) {
3313
+ function ArrayAdapter ($element, options) {
3314
+ var data = options.get('data') || [];
3315
+
3316
+ ArrayAdapter.__super__.constructor.call(this, $element, options);
3317
+
3318
+ this.addOptions(this.convertToOptions(data));
3319
+ }
3320
+
3321
+ Utils.Extend(ArrayAdapter, SelectAdapter);
3322
+
3323
+ ArrayAdapter.prototype.select = function (data) {
3324
+ var $option = this.$element.find('option').filter(function (i, elm) {
3325
+ return elm.value == data.id.toString();
3326
+ });
3327
+
3328
+ if ($option.length === 0) {
3329
+ $option = this.option(data);
3330
+
3331
+ this.addOptions($option);
3332
+ }
3333
+
3334
+ ArrayAdapter.__super__.select.call(this, data);
3335
+ };
3336
+
3337
+ ArrayAdapter.prototype.convertToOptions = function (data) {
3338
+ var self = this;
3339
+
3340
+ var $existing = this.$element.find('option');
3341
+ var existingIds = $existing.map(function () {
3342
+ return self.item($(this)).id;
3343
+ }).get();
3344
+
3345
+ var $options = [];
3346
+
3347
+ // Filter out all items except for the one passed in the argument
3348
+ function onlyItem (item) {
3349
+ return function () {
3350
+ return $(this).val() == item.id;
3351
+ };
3352
+ }
3353
+
3354
+ for (var d = 0; d < data.length; d++) {
3355
+ var item = this._normalizeItem(data[d]);
3356
+
3357
+ // Skip items which were pre-loaded, only merge the data
3358
+ if ($.inArray(item.id, existingIds) >= 0) {
3359
+ var $existingOption = $existing.filter(onlyItem(item));
3360
+
3361
+ var existingData = this.item($existingOption);
3362
+ var newData = $.extend(true, {}, item, existingData);
3363
+
3364
+ var $newOption = this.option(newData);
3365
+
3366
+ $existingOption.replaceWith($newOption);
3367
+
3368
+ continue;
3369
+ }
3370
+
3371
+ var $option = this.option(item);
3372
+
3373
+ if (item.children) {
3374
+ var $children = this.convertToOptions(item.children);
3375
+
3376
+ Utils.appendMany($option, $children);
3377
+ }
3378
+
3379
+ $options.push($option);
3380
+ }
3381
+
3382
+ return $options;
3383
+ };
3384
+
3385
+ return ArrayAdapter;
3386
+ });
3387
+
3388
+ S2.define('select2/data/ajax',[
3389
+ './array',
3390
+ '../utils',
3391
+ 'jquery'
3392
+ ], function (ArrayAdapter, Utils, $) {
3393
+ function AjaxAdapter ($element, options) {
3394
+ this.ajaxOptions = this._applyDefaults(options.get('ajax'));
3395
+
3396
+ if (this.ajaxOptions.processResults != null) {
3397
+ this.processResults = this.ajaxOptions.processResults;
3398
+ }
3399
+
3400
+ AjaxAdapter.__super__.constructor.call(this, $element, options);
3401
+ }
3402
+
3403
+ Utils.Extend(AjaxAdapter, ArrayAdapter);
3404
+
3405
+ AjaxAdapter.prototype._applyDefaults = function (options) {
3406
+ var defaults = {
3407
+ data: function (params) {
3408
+ return $.extend({}, params, {
3409
+ q: params.term
3410
+ });
3411
+ },
3412
+ transport: function (params, success, failure) {
3413
+ var $request = $.ajax(params);
3414
+
3415
+ $request.then(success);
3416
+ $request.fail(failure);
3417
+
3418
+ return $request;
3419
+ }
3420
+ };
3421
+
3422
+ return $.extend({}, defaults, options, true);
3423
+ };
3424
+
3425
+ AjaxAdapter.prototype.processResults = function (results) {
3426
+ return results;
3427
+ };
3428
+
3429
+ AjaxAdapter.prototype.query = function (params, callback) {
3430
+ var matches = [];
3431
+ var self = this;
3432
+
3433
+ if (this._request != null) {
3434
+ // JSONP requests cannot always be aborted
3435
+ if ($.isFunction(this._request.abort)) {
3436
+ this._request.abort();
3437
+ }
3438
+
3439
+ this._request = null;
3440
+ }
3441
+
3442
+ var options = $.extend({
3443
+ type: 'GET'
3444
+ }, this.ajaxOptions);
3445
+
3446
+ if (typeof options.url === 'function') {
3447
+ options.url = options.url.call(this.$element, params);
3448
+ }
3449
+
3450
+ if (typeof options.data === 'function') {
3451
+ options.data = options.data.call(this.$element, params);
3452
+ }
3453
+
3454
+ function request () {
3455
+ var $request = options.transport(options, function (data) {
3456
+ var results = self.processResults(data, params);
3457
+
3458
+ if (self.options.get('debug') && window.console && console.error) {
3459
+ // Check to make sure that the response included a `results` key.
3460
+ if (!results || !results.results || !$.isArray(results.results)) {
3461
+ console.error(
3462
+ 'Select2: The AJAX results did not return an array in the ' +
3463
+ '`results` key of the response.'
3464
+ );
3465
+ }
3466
+ }
3467
+
3468
+ callback(results);
3469
+ }, function () {
3470
+ // Attempt to detect if a request was aborted
3471
+ // Only works if the transport exposes a status property
3472
+ if ($request.status && $request.status === '0') {
3473
+ return;
3474
+ }
3475
+
3476
+ self.trigger('results:message', {
3477
+ message: 'errorLoading'
3478
+ });
3479
+ });
3480
+
3481
+ self._request = $request;
3482
+ }
3483
+
3484
+ if (this.ajaxOptions.delay && params.term != null) {
3485
+ if (this._queryTimeout) {
3486
+ window.clearTimeout(this._queryTimeout);
3487
+ }
3488
+
3489
+ this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay);
3490
+ } else {
3491
+ request();
3492
+ }
3493
+ };
3494
+
3495
+ return AjaxAdapter;
3496
+ });
3497
+
3498
+ S2.define('select2/data/tags',[
3499
+ 'jquery'
3500
+ ], function ($) {
3501
+ function Tags (decorated, $element, options) {
3502
+ var tags = options.get('tags');
3503
+
3504
+ var createTag = options.get('createTag');
3505
+
3506
+ if (createTag !== undefined) {
3507
+ this.createTag = createTag;
3508
+ }
3509
+
3510
+ var insertTag = options.get('insertTag');
3511
+
3512
+ if (insertTag !== undefined) {
3513
+ this.insertTag = insertTag;
3514
+ }
3515
+
3516
+ decorated.call(this, $element, options);
3517
+
3518
+ if ($.isArray(tags)) {
3519
+ for (var t = 0; t < tags.length; t++) {
3520
+ var tag = tags[t];
3521
+ var item = this._normalizeItem(tag);
3522
+
3523
+ var $option = this.option(item);
3524
+
3525
+ this.$element.append($option);
3526
+ }
3527
+ }
3528
+ }
3529
+
3530
+ Tags.prototype.query = function (decorated, params, callback) {
3531
+ var self = this;
3532
+
3533
+ this._removeOldTags();
3534
+
3535
+ if (params.term == null || params.page != null) {
3536
+ decorated.call(this, params, callback);
3537
+ return;
3538
+ }
3539
+
3540
+ function wrapper (obj, child) {
3541
+ var data = obj.results;
3542
+
3543
+ for (var i = 0; i < data.length; i++) {
3544
+ var option = data[i];
3545
+
3546
+ var checkChildren = (
3547
+ option.children != null &&
3548
+ !wrapper({
3549
+ results: option.children
3550
+ }, true)
3551
+ );
3552
+
3553
+ var checkText = option.text === params.term;
3554
+
3555
+ if (checkText || checkChildren) {
3556
+ if (child) {
3557
+ return false;
3558
+ }
3559
+
3560
+ obj.data = data;
3561
+ callback(obj);
3562
+
3563
+ return;
3564
+ }
3565
+ }
3566
+
3567
+ if (child) {
3568
+ return true;
3569
+ }
3570
+
3571
+ var tag = self.createTag(params);
3572
+
3573
+ if (tag != null) {
3574
+ var $option = self.option(tag);
3575
+ $option.attr('data-select2-tag', true);
3576
+
3577
+ self.addOptions([$option]);
3578
+
3579
+ self.insertTag(data, tag);
3580
+ }
3581
+
3582
+ obj.results = data;
3583
+
3584
+ callback(obj);
3585
+ }
3586
+
3587
+ decorated.call(this, params, wrapper);
3588
+ };
3589
+
3590
+ Tags.prototype.createTag = function (decorated, params) {
3591
+ var term = $.trim(params.term);
3592
+
3593
+ if (term === '') {
3594
+ return null;
3595
+ }
3596
+
3597
+ return {
3598
+ id: term,
3599
+ text: term
3600
+ };
3601
+ };
3602
+
3603
+ Tags.prototype.insertTag = function (_, data, tag) {
3604
+ data.unshift(tag);
3605
+ };
3606
+
3607
+ Tags.prototype._removeOldTags = function (_) {
3608
+ var tag = this._lastTag;
3609
+
3610
+ var $options = this.$element.find('option[data-select2-tag]');
3611
+
3612
+ $options.each(function () {
3613
+ if (this.selected) {
3614
+ return;
3615
+ }
3616
+
3617
+ $(this).remove();
3618
+ });
3619
+ };
3620
+
3621
+ return Tags;
3622
+ });
3623
+
3624
+ S2.define('select2/data/tokenizer',[
3625
+ 'jquery'
3626
+ ], function ($) {
3627
+ function Tokenizer (decorated, $element, options) {
3628
+ var tokenizer = options.get('tokenizer');
3629
+
3630
+ if (tokenizer !== undefined) {
3631
+ this.tokenizer = tokenizer;
3632
+ }
3633
+
3634
+ decorated.call(this, $element, options);
3635
+ }
3636
+
3637
+ Tokenizer.prototype.bind = function (decorated, container, $container) {
3638
+ decorated.call(this, container, $container);
3639
+
3640
+ this.$search = container.dropdown.$search || container.selection.$search ||
3641
+ $container.find('.select2-search__field');
3642
+ };
3643
+
3644
+ Tokenizer.prototype.query = function (decorated, params, callback) {
3645
+ var self = this;
3646
+
3647
+ function createAndSelect (data) {
3648
+ // Normalize the data object so we can use it for checks
3649
+ var item = self._normalizeItem(data);
3650
+
3651
+ // Check if the data object already exists as a tag
3652
+ // Select it if it doesn't
3653
+ var $existingOptions = self.$element.find('option').filter(function () {
3654
+ return $(this).val() === item.id;
3655
+ });
3656
+
3657
+ // If an existing option wasn't found for it, create the option
3658
+ if (!$existingOptions.length) {
3659
+ var $option = self.option(item);
3660
+ $option.attr('data-select2-tag', true);
3661
+
3662
+ self._removeOldTags();
3663
+ self.addOptions([$option]);
3664
+ }
3665
+
3666
+ // Select the item, now that we know there is an option for it
3667
+ select(item);
3668
+ }
3669
+
3670
+ function select (data) {
3671
+ self.trigger('select', {
3672
+ data: data
3673
+ });
3674
+ }
3675
+
3676
+ params.term = params.term || '';
3677
+
3678
+ var tokenData = this.tokenizer(params, this.options, createAndSelect);
3679
+
3680
+ if (tokenData.term !== params.term) {
3681
+ // Replace the search term if we have the search box
3682
+ if (this.$search.length) {
3683
+ this.$search.val(tokenData.term);
3684
+ this.$search.focus();
3685
+ }
3686
+
3687
+ params.term = tokenData.term;
3688
+ }
3689
+
3690
+ decorated.call(this, params, callback);
3691
+ };
3692
+
3693
+ Tokenizer.prototype.tokenizer = function (_, params, options, callback) {
3694
+ var separators = options.get('tokenSeparators') || [];
3695
+ var term = params.term;
3696
+ var i = 0;
3697
+
3698
+ var createTag = this.createTag || function (params) {
3699
+ return {
3700
+ id: params.term,
3701
+ text: params.term
3702
+ };
3703
+ };
3704
+
3705
+ while (i < term.length) {
3706
+ var termChar = term[i];
3707
+
3708
+ if ($.inArray(termChar, separators) === -1) {
3709
+ i++;
3710
+
3711
+ continue;
3712
+ }
3713
+
3714
+ var part = term.substr(0, i);
3715
+ var partParams = $.extend({}, params, {
3716
+ term: part
3717
+ });
3718
+
3719
+ var data = createTag(partParams);
3720
+
3721
+ if (data == null) {
3722
+ i++;
3723
+ continue;
3724
+ }
3725
+
3726
+ callback(data);
3727
+
3728
+ // Reset the term to not include the tokenized portion
3729
+ term = term.substr(i + 1) || '';
3730
+ i = 0;
3731
+ }
3732
+
3733
+ return {
3734
+ term: term
3735
+ };
3736
+ };
3737
+
3738
+ return Tokenizer;
3739
+ });
3740
+
3741
+ S2.define('select2/data/minimumInputLength',[
3742
+
3743
+ ], function () {
3744
+ function MinimumInputLength (decorated, $e, options) {
3745
+ this.minimumInputLength = options.get('minimumInputLength');
3746
+
3747
+ decorated.call(this, $e, options);
3748
+ }
3749
+
3750
+ MinimumInputLength.prototype.query = function (decorated, params, callback) {
3751
+ params.term = params.term || '';
3752
+
3753
+ if (params.term.length < this.minimumInputLength) {
3754
+ this.trigger('results:message', {
3755
+ message: 'inputTooShort',
3756
+ args: {
3757
+ minimum: this.minimumInputLength,
3758
+ input: params.term,
3759
+ params: params
3760
+ }
3761
+ });
3762
+
3763
+ return;
3764
+ }
3765
+
3766
+ decorated.call(this, params, callback);
3767
+ };
3768
+
3769
+ return MinimumInputLength;
3770
+ });
3771
+
3772
+ S2.define('select2/data/maximumInputLength',[
3773
+
3774
+ ], function () {
3775
+ function MaximumInputLength (decorated, $e, options) {
3776
+ this.maximumInputLength = options.get('maximumInputLength');
3777
+
3778
+ decorated.call(this, $e, options);
3779
+ }
3780
+
3781
+ MaximumInputLength.prototype.query = function (decorated, params, callback) {
3782
+ params.term = params.term || '';
3783
+
3784
+ if (this.maximumInputLength > 0 &&
3785
+ params.term.length > this.maximumInputLength) {
3786
+ this.trigger('results:message', {
3787
+ message: 'inputTooLong',
3788
+ args: {
3789
+ maximum: this.maximumInputLength,
3790
+ input: params.term,
3791
+ params: params
3792
+ }
3793
+ });
3794
+
3795
+ return;
3796
+ }
3797
+
3798
+ decorated.call(this, params, callback);
3799
+ };
3800
+
3801
+ return MaximumInputLength;
3802
+ });
3803
+
3804
+ S2.define('select2/data/maximumSelectionLength',[
3805
+
3806
+ ], function (){
3807
+ function MaximumSelectionLength (decorated, $e, options) {
3808
+ this.maximumSelectionLength = options.get('maximumSelectionLength');
3809
+
3810
+ decorated.call(this, $e, options);
3811
+ }
3812
+
3813
+ MaximumSelectionLength.prototype.query =
3814
+ function (decorated, params, callback) {
3815
+ var self = this;
3816
+
3817
+ this.current(function (currentData) {
3818
+ var count = currentData != null ? currentData.length : 0;
3819
+ if (self.maximumSelectionLength > 0 &&
3820
+ count >= self.maximumSelectionLength) {
3821
+ self.trigger('results:message', {
3822
+ message: 'maximumSelected',
3823
+ args: {
3824
+ maximum: self.maximumSelectionLength
3825
+ }
3826
+ });
3827
+ return;
3828
+ }
3829
+ decorated.call(self, params, callback);
3830
+ });
3831
+ };
3832
+
3833
+ return MaximumSelectionLength;
3834
+ });
3835
+
3836
+ S2.define('select2/dropdown',[
3837
+ 'jquery',
3838
+ './utils'
3839
+ ], function ($, Utils) {
3840
+ function Dropdown ($element, options) {
3841
+ this.$element = $element;
3842
+ this.options = options;
3843
+
3844
+ Dropdown.__super__.constructor.call(this);
3845
+ }
3846
+
3847
+ Utils.Extend(Dropdown, Utils.Observable);
3848
+
3849
+ Dropdown.prototype.render = function () {
3850
+ var $dropdown = $(
3851
+ '<span class="select2-dropdown">' +
3852
+ '<span class="select2-results"></span>' +
3853
+ '</span>'
3854
+ );
3855
+
3856
+ $dropdown.attr('dir', this.options.get('dir'));
3857
+
3858
+ this.$dropdown = $dropdown;
3859
+
3860
+ return $dropdown;
3861
+ };
3862
+
3863
+ Dropdown.prototype.bind = function () {
3864
+ // Should be implemented in subclasses
3865
+ };
3866
+
3867
+ Dropdown.prototype.position = function ($dropdown, $container) {
3868
+ // Should be implmented in subclasses
3869
+ };
3870
+
3871
+ Dropdown.prototype.destroy = function () {
3872
+ // Remove the dropdown from the DOM
3873
+ this.$dropdown.remove();
3874
+ };
3875
+
3876
+ return Dropdown;
3877
+ });
3878
+
3879
+ S2.define('select2/dropdown/search',[
3880
+ 'jquery',
3881
+ '../utils'
3882
+ ], function ($, Utils) {
3883
+ function Search () { }
3884
+
3885
+ Search.prototype.render = function (decorated) {
3886
+ var $rendered = decorated.call(this);
3887
+
3888
+ var $search = $(
3889
+ '<span class="select2-search select2-search--dropdown">' +
3890
+ '<input class="select2-search__field" type="search" tabindex="-1"' +
3891
+ ' autocomplete="off" autocorrect="off" autocapitalize="off"' +
3892
+ ' spellcheck="false" role="textbox" />' +
3893
+ '</span>'
3894
+ );
3895
+
3896
+ this.$searchContainer = $search;
3897
+ this.$search = $search.find('input');
3898
+
3899
+ $rendered.prepend($search);
3900
+
3901
+ return $rendered;
3902
+ };
3903
+
3904
+ Search.prototype.bind = function (decorated, container, $container) {
3905
+ var self = this;
3906
+
3907
+ decorated.call(this, container, $container);
3908
+
3909
+ this.$search.on('keydown', function (evt) {
3910
+ self.trigger('keypress', evt);
3911
+
3912
+ self._keyUpPrevented = evt.isDefaultPrevented();
3913
+ });
3914
+
3915
+ // Workaround for browsers which do not support the `input` event
3916
+ // This will prevent double-triggering of events for browsers which support
3917
+ // both the `keyup` and `input` events.
3918
+ this.$search.on('input', function (evt) {
3919
+ // Unbind the duplicated `keyup` event
3920
+ $(this).off('keyup');
3921
+ });
3922
+
3923
+ this.$search.on('keyup input', function (evt) {
3924
+ self.handleSearch(evt);
3925
+ });
3926
+
3927
+ container.on('open', function () {
3928
+ self.$search.attr('tabindex', 0);
3929
+
3930
+ self.$search.focus();
3931
+
3932
+ window.setTimeout(function () {
3933
+ self.$search.focus();
3934
+ }, 0);
3935
+ });
3936
+
3937
+ container.on('close', function () {
3938
+ self.$search.attr('tabindex', -1);
3939
+
3940
+ self.$search.val('');
3941
+ });
3942
+
3943
+ container.on('focus', function () {
3944
+ if (container.isOpen()) {
3945
+ self.$search.focus();
3946
+ }
3947
+ });
3948
+
3949
+ container.on('results:all', function (params) {
3950
+ if (params.query.term == null || params.query.term === '') {
3951
+ var showSearch = self.showSearch(params);
3952
+
3953
+ if (showSearch) {
3954
+ self.$searchContainer.removeClass('select2-search--hide');
3955
+ } else {
3956
+ self.$searchContainer.addClass('select2-search--hide');
3957
+ }
3958
+ }
3959
+ });
3960
+ };
3961
+
3962
+ Search.prototype.handleSearch = function (evt) {
3963
+ if (!this._keyUpPrevented) {
3964
+ var input = this.$search.val();
3965
+
3966
+ this.trigger('query', {
3967
+ term: input
3968
+ });
3969
+ }
3970
+
3971
+ this._keyUpPrevented = false;
3972
+ };
3973
+
3974
+ Search.prototype.showSearch = function (_, params) {
3975
+ return true;
3976
+ };
3977
+
3978
+ return Search;
3979
+ });
3980
+
3981
+ S2.define('select2/dropdown/hidePlaceholder',[
3982
+
3983
+ ], function () {
3984
+ function HidePlaceholder (decorated, $element, options, dataAdapter) {
3985
+ this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
3986
+
3987
+ decorated.call(this, $element, options, dataAdapter);
3988
+ }
3989
+
3990
+ HidePlaceholder.prototype.append = function (decorated, data) {
3991
+ data.results = this.removePlaceholder(data.results);
3992
+
3993
+ decorated.call(this, data);
3994
+ };
3995
+
3996
+ HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) {
3997
+ if (typeof placeholder === 'string') {
3998
+ placeholder = {
3999
+ id: '',
4000
+ text: placeholder
4001
+ };
4002
+ }
4003
+
4004
+ return placeholder;
4005
+ };
4006
+
4007
+ HidePlaceholder.prototype.removePlaceholder = function (_, data) {
4008
+ var modifiedData = data.slice(0);
4009
+
4010
+ for (var d = data.length - 1; d >= 0; d--) {
4011
+ var item = data[d];
4012
+
4013
+ if (this.placeholder.id === item.id) {
4014
+ modifiedData.splice(d, 1);
4015
+ }
4016
+ }
4017
+
4018
+ return modifiedData;
4019
+ };
4020
+
4021
+ return HidePlaceholder;
4022
+ });
4023
+
4024
+ S2.define('select2/dropdown/infiniteScroll',[
4025
+ 'jquery'
4026
+ ], function ($) {
4027
+ function InfiniteScroll (decorated, $element, options, dataAdapter) {
4028
+ this.lastParams = {};
4029
+
4030
+ decorated.call(this, $element, options, dataAdapter);
4031
+
4032
+ this.$loadingMore = this.createLoadingMore();
4033
+ this.loading = false;
4034
+ }
4035
+
4036
+ InfiniteScroll.prototype.append = function (decorated, data) {
4037
+ this.$loadingMore.remove();
4038
+ this.loading = false;
4039
+
4040
+ decorated.call(this, data);
4041
+
4042
+ if (this.showLoadingMore(data)) {
4043
+ this.$results.append(this.$loadingMore);
4044
+ }
4045
+ };
4046
+
4047
+ InfiniteScroll.prototype.bind = function (decorated, container, $container) {
4048
+ var self = this;
4049
+
4050
+ decorated.call(this, container, $container);
4051
+
4052
+ container.on('query', function (params) {
4053
+ self.lastParams = params;
4054
+ self.loading = true;
4055
+ });
4056
+
4057
+ container.on('query:append', function (params) {
4058
+ self.lastParams = params;
4059
+ self.loading = true;
4060
+ });
4061
+
4062
+ this.$results.on('scroll', function () {
4063
+ var isLoadMoreVisible = $.contains(
4064
+ document.documentElement,
4065
+ self.$loadingMore[0]
4066
+ );
4067
+
4068
+ if (self.loading || !isLoadMoreVisible) {
4069
+ return;
4070
+ }
4071
+
4072
+ var currentOffset = self.$results.offset().top +
4073
+ self.$results.outerHeight(false);
4074
+ var loadingMoreOffset = self.$loadingMore.offset().top +
4075
+ self.$loadingMore.outerHeight(false);
4076
+
4077
+ if (currentOffset + 50 >= loadingMoreOffset) {
4078
+ self.loadMore();
4079
+ }
4080
+ });
4081
+ };
4082
+
4083
+ InfiniteScroll.prototype.loadMore = function () {
4084
+ this.loading = true;
4085
+
4086
+ var params = $.extend({}, {page: 1}, this.lastParams);
4087
+
4088
+ params.page++;
4089
+
4090
+ this.trigger('query:append', params);
4091
+ };
4092
+
4093
+ InfiniteScroll.prototype.showLoadingMore = function (_, data) {
4094
+ return data.pagination && data.pagination.more;
4095
+ };
4096
+
4097
+ InfiniteScroll.prototype.createLoadingMore = function () {
4098
+ var $option = $(
4099
+ '<li ' +
4100
+ 'class="select2-results__option select2-results__option--load-more"' +
4101
+ 'role="treeitem" aria-disabled="true"></li>'
4102
+ );
4103
+
4104
+ var message = this.options.get('translations').get('loadingMore');
4105
+
4106
+ $option.html(message(this.lastParams));
4107
+
4108
+ return $option;
4109
+ };
4110
+
4111
+ return InfiniteScroll;
4112
+ });
4113
+
4114
+ S2.define('select2/dropdown/attachBody',[
4115
+ 'jquery',
4116
+ '../utils'
4117
+ ], function ($, Utils) {
4118
+ function AttachBody (decorated, $element, options) {
4119
+ this.$dropdownParent = options.get('dropdownParent') || $(document.body);
4120
+
4121
+ decorated.call(this, $element, options);
4122
+ }
4123
+
4124
+ AttachBody.prototype.bind = function (decorated, container, $container) {
4125
+ var self = this;
4126
+
4127
+ var setupResultsEvents = false;
4128
+
4129
+ decorated.call(this, container, $container);
4130
+
4131
+ container.on('open', function () {
4132
+ self._showDropdown();
4133
+ self._attachPositioningHandler(container);
4134
+
4135
+ if (!setupResultsEvents) {
4136
+ setupResultsEvents = true;
4137
+
4138
+ container.on('results:all', function () {
4139
+ self._positionDropdown();
4140
+ self._resizeDropdown();
4141
+ });
4142
+
4143
+ container.on('results:append', function () {
4144
+ self._positionDropdown();
4145
+ self._resizeDropdown();
4146
+ });
4147
+ }
4148
+ });
4149
+
4150
+ container.on('close', function () {
4151
+ self._hideDropdown();
4152
+ self._detachPositioningHandler(container);
4153
+ });
4154
+
4155
+ this.$dropdownContainer.on('mousedown', function (evt) {
4156
+ evt.stopPropagation();
4157
+ });
4158
+ };
4159
+
4160
+ AttachBody.prototype.destroy = function (decorated) {
4161
+ decorated.call(this);
4162
+
4163
+ this.$dropdownContainer.remove();
4164
+ };
4165
+
4166
+ AttachBody.prototype.position = function (decorated, $dropdown, $container) {
4167
+ // Clone all of the container classes
4168
+ $dropdown.attr('class', $container.attr('class'));
4169
+
4170
+ $dropdown.removeClass('select2');
4171
+ $dropdown.addClass('select2-container--open');
4172
+
4173
+ $dropdown.css({
4174
+ position: 'absolute',
4175
+ top: -999999
4176
+ });
4177
+
4178
+ this.$container = $container;
4179
+ };
4180
+
4181
+ AttachBody.prototype.render = function (decorated) {
4182
+ var $container = $('<span></span>');
4183
+
4184
+ var $dropdown = decorated.call(this);
4185
+ $container.append($dropdown);
4186
+
4187
+ this.$dropdownContainer = $container;
4188
+
4189
+ return $container;
4190
+ };
4191
+
4192
+ AttachBody.prototype._hideDropdown = function (decorated) {
4193
+ this.$dropdownContainer.detach();
4194
+ };
4195
+
4196
+ AttachBody.prototype._attachPositioningHandler =
4197
+ function (decorated, container) {
4198
+ var self = this;
4199
+
4200
+ var scrollEvent = 'scroll.select2.' + container.id;
4201
+ var resizeEvent = 'resize.select2.' + container.id;
4202
+ var orientationEvent = 'orientationchange.select2.' + container.id;
4203
+
4204
+ var $watchers = this.$container.parents().filter(Utils.hasScroll);
4205
+ $watchers.each(function () {
4206
+ $(this).data('select2-scroll-position', {
4207
+ x: $(this).scrollLeft(),
4208
+ y: $(this).scrollTop()
4209
+ });
4210
+ });
4211
+
4212
+ $watchers.on(scrollEvent, function (ev) {
4213
+ var position = $(this).data('select2-scroll-position');
4214
+ $(this).scrollTop(position.y);
4215
+ });
4216
+
4217
+ $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent,
4218
+ function (e) {
4219
+ self._positionDropdown();
4220
+ self._resizeDropdown();
4221
+ });
4222
+ };
4223
+
4224
+ AttachBody.prototype._detachPositioningHandler =
4225
+ function (decorated, container) {
4226
+ var scrollEvent = 'scroll.select2.' + container.id;
4227
+ var resizeEvent = 'resize.select2.' + container.id;
4228
+ var orientationEvent = 'orientationchange.select2.' + container.id;
4229
+
4230
+ var $watchers = this.$container.parents().filter(Utils.hasScroll);
4231
+ $watchers.off(scrollEvent);
4232
+
4233
+ $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent);
4234
+ };
4235
+
4236
+ AttachBody.prototype._positionDropdown = function () {
4237
+ var $window = $(window);
4238
+
4239
+ var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above');
4240
+ var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below');
4241
+
4242
+ var newDirection = null;
4243
+
4244
+ var offset = this.$container.offset();
4245
+
4246
+ offset.bottom = offset.top + this.$container.outerHeight(false);
4247
+
4248
+ var container = {
4249
+ height: this.$container.outerHeight(false)
4250
+ };
4251
+
4252
+ container.top = offset.top;
4253
+ container.bottom = offset.top + container.height;
4254
+
4255
+ var dropdown = {
4256
+ height: this.$dropdown.outerHeight(false)
4257
+ };
4258
+
4259
+ var viewport = {
4260
+ top: $window.scrollTop(),
4261
+ bottom: $window.scrollTop() + $window.height()
4262
+ };
4263
+
4264
+ var enoughRoomAbove = viewport.top < (offset.top - dropdown.height);
4265
+ var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height);
4266
+
4267
+ var css = {
4268
+ left: offset.left,
4269
+ top: container.bottom
4270
+ };
4271
+
4272
+ // Determine what the parent element is to use for calciulating the offset
4273
+ var $offsetParent = this.$dropdownParent;
4274
+
4275
+ // For statically positoned elements, we need to get the element
4276
+ // that is determining the offset
4277
+ if ($offsetParent.css('position') === 'static') {
4278
+ $offsetParent = $offsetParent.offsetParent();
4279
+ }
4280
+
4281
+ var parentOffset = $offsetParent.offset();
4282
+
4283
+ css.top -= parentOffset.top;
4284
+ css.left -= parentOffset.left;
4285
+
4286
+ if (!isCurrentlyAbove && !isCurrentlyBelow) {
4287
+ newDirection = 'below';
4288
+ }
4289
+
4290
+ if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {
4291
+ newDirection = 'above';
4292
+ } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {
4293
+ newDirection = 'below';
4294
+ }
4295
+
4296
+ if (newDirection == 'above' ||
4297
+ (isCurrentlyAbove && newDirection !== 'below')) {
4298
+ css.top = container.top - parentOffset.top - dropdown.height;
4299
+ }
4300
+
4301
+ if (newDirection != null) {
4302
+ this.$dropdown
4303
+ .removeClass('select2-dropdown--below select2-dropdown--above')
4304
+ .addClass('select2-dropdown--' + newDirection);
4305
+ this.$container
4306
+ .removeClass('select2-container--below select2-container--above')
4307
+ .addClass('select2-container--' + newDirection);
4308
+ }
4309
+
4310
+ this.$dropdownContainer.css(css);
4311
+ };
4312
+
4313
+ AttachBody.prototype._resizeDropdown = function () {
4314
+ var css = {
4315
+ width: this.$container.outerWidth(false) + 'px'
4316
+ };
4317
+
4318
+ if (this.options.get('dropdownAutoWidth')) {
4319
+ css.minWidth = css.width;
4320
+ css.position = 'relative';
4321
+ css.width = 'auto';
4322
+ }
4323
+
4324
+ this.$dropdown.css(css);
4325
+ };
4326
+
4327
+ AttachBody.prototype._showDropdown = function (decorated) {
4328
+ this.$dropdownContainer.appendTo(this.$dropdownParent);
4329
+
4330
+ this._positionDropdown();
4331
+ this._resizeDropdown();
4332
+ };
4333
+
4334
+ return AttachBody;
4335
+ });
4336
+
4337
+ S2.define('select2/dropdown/minimumResultsForSearch',[
4338
+
4339
+ ], function () {
4340
+ function countResults (data) {
4341
+ var count = 0;
4342
+
4343
+ for (var d = 0; d < data.length; d++) {
4344
+ var item = data[d];
4345
+
4346
+ if (item.children) {
4347
+ count += countResults(item.children);
4348
+ } else {
4349
+ count++;
4350
+ }
4351
+ }
4352
+
4353
+ return count;
4354
+ }
4355
+
4356
+ function MinimumResultsForSearch (decorated, $element, options, dataAdapter) {
4357
+ this.minimumResultsForSearch = options.get('minimumResultsForSearch');
4358
+
4359
+ if (this.minimumResultsForSearch < 0) {
4360
+ this.minimumResultsForSearch = Infinity;
4361
+ }
4362
+
4363
+ decorated.call(this, $element, options, dataAdapter);
4364
+ }
4365
+
4366
+ MinimumResultsForSearch.prototype.showSearch = function (decorated, params) {
4367
+ if (countResults(params.data.results) < this.minimumResultsForSearch) {
4368
+ return false;
4369
+ }
4370
+
4371
+ return decorated.call(this, params);
4372
+ };
4373
+
4374
+ return MinimumResultsForSearch;
4375
+ });
4376
+
4377
+ S2.define('select2/dropdown/selectOnClose',[
4378
+
4379
+ ], function () {
4380
+ function SelectOnClose () { }
4381
+
4382
+ SelectOnClose.prototype.bind = function (decorated, container, $container) {
4383
+ var self = this;
4384
+
4385
+ decorated.call(this, container, $container);
4386
+
4387
+ container.on('close', function (params) {
4388
+ self._handleSelectOnClose(params);
4389
+ });
4390
+ };
4391
+
4392
+ SelectOnClose.prototype._handleSelectOnClose = function (_, params) {
4393
+ if (params && params.originalSelect2Event != null) {
4394
+ var event = params.originalSelect2Event;
4395
+
4396
+ // Don't select an item if the close event was triggered from a select or
4397
+ // unselect event
4398
+ if (event._type === 'select' || event._type === 'unselect') {
4399
+ return;
4400
+ }
4401
+ }
4402
+
4403
+ var $highlightedResults = this.getHighlightedResults();
4404
+
4405
+ // Only select highlighted results
4406
+ if ($highlightedResults.length < 1) {
4407
+ return;
4408
+ }
4409
+
4410
+ var data = $highlightedResults.data('data');
4411
+
4412
+ // Don't re-select already selected resulte
4413
+ if (
4414
+ (data.element != null && data.element.selected) ||
4415
+ (data.element == null && data.selected)
4416
+ ) {
4417
+ return;
4418
+ }
4419
+
4420
+ this.trigger('select', {
4421
+ data: data
4422
+ });
4423
+ };
4424
+
4425
+ return SelectOnClose;
4426
+ });
4427
+
4428
+ S2.define('select2/dropdown/closeOnSelect',[
4429
+
4430
+ ], function () {
4431
+ function CloseOnSelect () { }
4432
+
4433
+ CloseOnSelect.prototype.bind = function (decorated, container, $container) {
4434
+ var self = this;
4435
+
4436
+ decorated.call(this, container, $container);
4437
+
4438
+ container.on('select', function (evt) {
4439
+ self._selectTriggered(evt);
4440
+ });
4441
+
4442
+ container.on('unselect', function (evt) {
4443
+ self._selectTriggered(evt);
4444
+ });
4445
+ };
4446
+
4447
+ CloseOnSelect.prototype._selectTriggered = function (_, evt) {
4448
+ var originalEvent = evt.originalEvent;
4449
+
4450
+ // Don't close if the control key is being held
4451
+ if (originalEvent && originalEvent.ctrlKey) {
4452
+ return;
4453
+ }
4454
+
4455
+ this.trigger('close', {
4456
+ originalEvent: originalEvent,
4457
+ originalSelect2Event: evt
4458
+ });
4459
+ };
4460
+
4461
+ return CloseOnSelect;
4462
+ });
4463
+
4464
+ S2.define('select2/i18n/en',[],function () {
4465
+ // English
4466
+ return {
4467
+ errorLoading: function () {
4468
+ return 'The results could not be loaded.';
4469
+ },
4470
+ inputTooLong: function (args) {
4471
+ var overChars = args.input.length - args.maximum;
4472
+
4473
+ var message = 'Please delete ' + overChars + ' character';
4474
+
4475
+ if (overChars != 1) {
4476
+ message += 's';
4477
+ }
4478
+
4479
+ return message;
4480
+ },
4481
+ inputTooShort: function (args) {
4482
+ var remainingChars = args.minimum - args.input.length;
4483
+
4484
+ var message = 'Please enter ' + remainingChars + ' or more characters';
4485
+
4486
+ return message;
4487
+ },
4488
+ loadingMore: function () {
4489
+ return 'Loading more results…';
4490
+ },
4491
+ maximumSelected: function (args) {
4492
+ var message = 'You can only select ' + args.maximum + ' item';
4493
+
4494
+ if (args.maximum != 1) {
4495
+ message += 's';
4496
+ }
4497
+
4498
+ return message;
4499
+ },
4500
+ noResults: function () {
4501
+ return 'No results found';
4502
+ },
4503
+ searching: function () {
4504
+ return 'Searching…';
4505
+ }
4506
+ };
4507
+ });
4508
+
4509
+ S2.define('select2/defaults',[
4510
+ 'jquery',
4511
+ 'require',
4512
+
4513
+ './results',
4514
+
4515
+ './selection/single',
4516
+ './selection/multiple',
4517
+ './selection/placeholder',
4518
+ './selection/allowClear',
4519
+ './selection/search',
4520
+ './selection/eventRelay',
4521
+
4522
+ './utils',
4523
+ './translation',
4524
+ './diacritics',
4525
+
4526
+ './data/select',
4527
+ './data/array',
4528
+ './data/ajax',
4529
+ './data/tags',
4530
+ './data/tokenizer',
4531
+ './data/minimumInputLength',
4532
+ './data/maximumInputLength',
4533
+ './data/maximumSelectionLength',
4534
+
4535
+ './dropdown',
4536
+ './dropdown/search',
4537
+ './dropdown/hidePlaceholder',
4538
+ './dropdown/infiniteScroll',
4539
+ './dropdown/attachBody',
4540
+ './dropdown/minimumResultsForSearch',
4541
+ './dropdown/selectOnClose',
4542
+ './dropdown/closeOnSelect',
4543
+
4544
+ './i18n/en'
4545
+ ], function ($, require,
4546
+
4547
+ ResultsList,
4548
+
4549
+ SingleSelection, MultipleSelection, Placeholder, AllowClear,
4550
+ SelectionSearch, EventRelay,
4551
+
4552
+ Utils, Translation, DIACRITICS,
4553
+
4554
+ SelectData, ArrayData, AjaxData, Tags, Tokenizer,
4555
+ MinimumInputLength, MaximumInputLength, MaximumSelectionLength,
4556
+
4557
+ Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
4558
+ AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect,
4559
+
4560
+ EnglishTranslation) {
4561
+ function Defaults () {
4562
+ this.reset();
4563
+ }
4564
+
4565
+ Defaults.prototype.apply = function (options) {
4566
+ options = $.extend(true, {}, this.defaults, options);
4567
+
4568
+ if (options.dataAdapter == null) {
4569
+ if (options.ajax != null) {
4570
+ options.dataAdapter = AjaxData;
4571
+ } else if (options.data != null) {
4572
+ options.dataAdapter = ArrayData;
4573
+ } else {
4574
+ options.dataAdapter = SelectData;
4575
+ }
4576
+
4577
+ if (options.minimumInputLength > 0) {
4578
+ options.dataAdapter = Utils.Decorate(
4579
+ options.dataAdapter,
4580
+ MinimumInputLength
4581
+ );
4582
+ }
4583
+
4584
+ if (options.maximumInputLength > 0) {
4585
+ options.dataAdapter = Utils.Decorate(
4586
+ options.dataAdapter,
4587
+ MaximumInputLength
4588
+ );
4589
+ }
4590
+
4591
+ if (options.maximumSelectionLength > 0) {
4592
+ options.dataAdapter = Utils.Decorate(
4593
+ options.dataAdapter,
4594
+ MaximumSelectionLength
4595
+ );
4596
+ }
4597
+
4598
+ if (options.tags) {
4599
+ options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
4600
+ }
4601
+
4602
+ if (options.tokenSeparators != null || options.tokenizer != null) {
4603
+ options.dataAdapter = Utils.Decorate(
4604
+ options.dataAdapter,
4605
+ Tokenizer
4606
+ );
4607
+ }
4608
+
4609
+ if (options.query != null) {
4610
+ var Query = require(options.amdBase + 'compat/query');
4611
+
4612
+ options.dataAdapter = Utils.Decorate(
4613
+ options.dataAdapter,
4614
+ Query
4615
+ );
4616
+ }
4617
+
4618
+ if (options.initSelection != null) {
4619
+ var InitSelection = require(options.amdBase + 'compat/initSelection');
4620
+
4621
+ options.dataAdapter = Utils.Decorate(
4622
+ options.dataAdapter,
4623
+ InitSelection
4624
+ );
4625
+ }
4626
+ }
4627
+
4628
+ if (options.resultsAdapter == null) {
4629
+ options.resultsAdapter = ResultsList;
4630
+
4631
+ if (options.ajax != null) {
4632
+ options.resultsAdapter = Utils.Decorate(
4633
+ options.resultsAdapter,
4634
+ InfiniteScroll
4635
+ );
4636
+ }
4637
+
4638
+ if (options.placeholder != null) {
4639
+ options.resultsAdapter = Utils.Decorate(
4640
+ options.resultsAdapter,
4641
+ HidePlaceholder
4642
+ );
4643
+ }
4644
+
4645
+ if (options.selectOnClose) {
4646
+ options.resultsAdapter = Utils.Decorate(
4647
+ options.resultsAdapter,
4648
+ SelectOnClose
4649
+ );
4650
+ }
4651
+ }
4652
+
4653
+ if (options.dropdownAdapter == null) {
4654
+ if (options.multiple) {
4655
+ options.dropdownAdapter = Dropdown;
4656
+ } else {
4657
+ var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);
4658
+
4659
+ options.dropdownAdapter = SearchableDropdown;
4660
+ }
4661
+
4662
+ if (options.minimumResultsForSearch !== 0) {
4663
+ options.dropdownAdapter = Utils.Decorate(
4664
+ options.dropdownAdapter,
4665
+ MinimumResultsForSearch
4666
+ );
4667
+ }
4668
+
4669
+ if (options.closeOnSelect) {
4670
+ options.dropdownAdapter = Utils.Decorate(
4671
+ options.dropdownAdapter,
4672
+ CloseOnSelect
4673
+ );
4674
+ }
4675
+
4676
+ if (
4677
+ options.dropdownCssClass != null ||
4678
+ options.dropdownCss != null ||
4679
+ options.adaptDropdownCssClass != null
4680
+ ) {
4681
+ var DropdownCSS = require(options.amdBase + 'compat/dropdownCss');
4682
+
4683
+ options.dropdownAdapter = Utils.Decorate(
4684
+ options.dropdownAdapter,
4685
+ DropdownCSS
4686
+ );
4687
+ }
4688
+
4689
+ options.dropdownAdapter = Utils.Decorate(
4690
+ options.dropdownAdapter,
4691
+ AttachBody
4692
+ );
4693
+ }
4694
+
4695
+ if (options.selectionAdapter == null) {
4696
+ if (options.multiple) {
4697
+ options.selectionAdapter = MultipleSelection;
4698
+ } else {
4699
+ options.selectionAdapter = SingleSelection;
4700
+ }
4701
+
4702
+ // Add the placeholder mixin if a placeholder was specified
4703
+ if (options.placeholder != null) {
4704
+ options.selectionAdapter = Utils.Decorate(
4705
+ options.selectionAdapter,
4706
+ Placeholder
4707
+ );
4708
+ }
4709
+
4710
+ if (options.allowClear) {
4711
+ options.selectionAdapter = Utils.Decorate(
4712
+ options.selectionAdapter,
4713
+ AllowClear
4714
+ );
4715
+ }
4716
+
4717
+ if (options.multiple) {
4718
+ options.selectionAdapter = Utils.Decorate(
4719
+ options.selectionAdapter,
4720
+ SelectionSearch
4721
+ );
4722
+ }
4723
+
4724
+ if (
4725
+ options.containerCssClass != null ||
4726
+ options.containerCss != null ||
4727
+ options.adaptContainerCssClass != null
4728
+ ) {
4729
+ var ContainerCSS = require(options.amdBase + 'compat/containerCss');
4730
+
4731
+ options.selectionAdapter = Utils.Decorate(
4732
+ options.selectionAdapter,
4733
+ ContainerCSS
4734
+ );
4735
+ }
4736
+
4737
+ options.selectionAdapter = Utils.Decorate(
4738
+ options.selectionAdapter,
4739
+ EventRelay
4740
+ );
4741
+ }
4742
+
4743
+ if (typeof options.language === 'string') {
4744
+ // Check if the language is specified with a region
4745
+ if (options.language.indexOf('-') > 0) {
4746
+ // Extract the region information if it is included
4747
+ var languageParts = options.language.split('-');
4748
+ var baseLanguage = languageParts[0];
4749
+
4750
+ options.language = [options.language, baseLanguage];
4751
+ } else {
4752
+ options.language = [options.language];
4753
+ }
4754
+ }
4755
+
4756
+ if ($.isArray(options.language)) {
4757
+ var languages = new Translation();
4758
+ options.language.push('en');
4759
+
4760
+ var languageNames = options.language;
4761
+
4762
+ for (var l = 0; l < languageNames.length; l++) {
4763
+ var name = languageNames[l];
4764
+ var language = {};
4765
+
4766
+ try {
4767
+ // Try to load it with the original name
4768
+ language = Translation.loadPath(name);
4769
+ } catch (e) {
4770
+ try {
4771
+ // If we couldn't load it, check if it wasn't the full path
4772
+ name = this.defaults.amdLanguageBase + name;
4773
+ language = Translation.loadPath(name);
4774
+ } catch (ex) {
4775
+ // The translation could not be loaded at all. Sometimes this is
4776
+ // because of a configuration problem, other times this can be
4777
+ // because of how Select2 helps load all possible translation files.
4778
+ if (options.debug && window.console && console.warn) {
4779
+ console.warn(
4780
+ 'Select2: The language file for "' + name + '" could not be ' +
4781
+ 'automatically loaded. A fallback will be used instead.'
4782
+ );
4783
+ }
4784
+
4785
+ continue;
4786
+ }
4787
+ }
4788
+
4789
+ languages.extend(language);
4790
+ }
4791
+
4792
+ options.translations = languages;
4793
+ } else {
4794
+ var baseTranslation = Translation.loadPath(
4795
+ this.defaults.amdLanguageBase + 'en'
4796
+ );
4797
+ var customTranslation = new Translation(options.language);
4798
+
4799
+ customTranslation.extend(baseTranslation);
4800
+
4801
+ options.translations = customTranslation;
4802
+ }
4803
+
4804
+ return options;
4805
+ };
4806
+
4807
+ Defaults.prototype.reset = function () {
4808
+ function stripDiacritics (text) {
4809
+ // Used 'uni range + named function' from http://jsperf.com/diacritics/18
4810
+ function match(a) {
4811
+ return DIACRITICS[a] || a;
4812
+ }
4813
+
4814
+ return text.replace(/[^\u0000-\u007E]/g, match);
4815
+ }
4816
+
4817
+ function matcher (params, data) {
4818
+ // Always return the object if there is nothing to compare
4819
+ if ($.trim(params.term) === '') {
4820
+ return data;
4821
+ }
4822
+
4823
+ // Do a recursive check for options with children
4824
+ if (data.children && data.children.length > 0) {
4825
+ // Clone the data object if there are children
4826
+ // This is required as we modify the object to remove any non-matches
4827
+ var match = $.extend(true, {}, data);
4828
+
4829
+ // Check each child of the option
4830
+ for (var c = data.children.length - 1; c >= 0; c--) {
4831
+ var child = data.children[c];
4832
+
4833
+ var matches = matcher(params, child);
4834
+
4835
+ // If there wasn't a match, remove the object in the array
4836
+ if (matches == null) {
4837
+ match.children.splice(c, 1);
4838
+ }
4839
+ }
4840
+
4841
+ // If any children matched, return the new object
4842
+ if (match.children.length > 0) {
4843
+ return match;
4844
+ }
4845
+
4846
+ // If there were no matching children, check just the plain object
4847
+ return matcher(params, match);
4848
+ }
4849
+
4850
+ var original = stripDiacritics(data.text).toUpperCase();
4851
+ var term = stripDiacritics(params.term).toUpperCase();
4852
+
4853
+ // Check if the text contains the term
4854
+ if (original.indexOf(term) > -1) {
4855
+ return data;
4856
+ }
4857
+
4858
+ // If it doesn't contain the term, don't return anything
4859
+ return null;
4860
+ }
4861
+
4862
+ this.defaults = {
4863
+ amdBase: './',
4864
+ amdLanguageBase: './i18n/',
4865
+ closeOnSelect: true,
4866
+ debug: false,
4867
+ dropdownAutoWidth: false,
4868
+ escapeMarkup: Utils.escapeMarkup,
4869
+ language: EnglishTranslation,
4870
+ matcher: matcher,
4871
+ minimumInputLength: 0,
4872
+ maximumInputLength: 0,
4873
+ maximumSelectionLength: 0,
4874
+ minimumResultsForSearch: 0,
4875
+ selectOnClose: false,
4876
+ sorter: function (data) {
4877
+ return data;
4878
+ },
4879
+ templateResult: function (result) {
4880
+ return result.text;
4881
+ },
4882
+ templateSelection: function (selection) {
4883
+ return selection.text;
4884
+ },
4885
+ theme: 'default',
4886
+ width: 'resolve'
4887
+ };
4888
+ };
4889
+
4890
+ Defaults.prototype.set = function (key, value) {
4891
+ var camelKey = $.camelCase(key);
4892
+
4893
+ var data = {};
4894
+ data[camelKey] = value;
4895
+
4896
+ var convertedData = Utils._convertData(data);
4897
+
4898
+ $.extend(this.defaults, convertedData);
4899
+ };
4900
+
4901
+ var defaults = new Defaults();
4902
+
4903
+ return defaults;
4904
+ });
4905
+
4906
+ S2.define('select2/options',[
4907
+ 'require',
4908
+ 'jquery',
4909
+ './defaults',
4910
+ './utils'
4911
+ ], function (require, $, Defaults, Utils) {
4912
+ function Options (options, $element) {
4913
+ this.options = options;
4914
+
4915
+ if ($element != null) {
4916
+ this.fromElement($element);
4917
+ }
4918
+
4919
+ this.options = Defaults.apply(this.options);
4920
+
4921
+ if ($element && $element.is('input')) {
4922
+ var InputCompat = require(this.get('amdBase') + 'compat/inputData');
4923
+
4924
+ this.options.dataAdapter = Utils.Decorate(
4925
+ this.options.dataAdapter,
4926
+ InputCompat
4927
+ );
4928
+ }
4929
+ }
4930
+
4931
+ Options.prototype.fromElement = function ($e) {
4932
+ var excludedData = ['select2'];
4933
+
4934
+ if (this.options.multiple == null) {
4935
+ this.options.multiple = $e.prop('multiple');
4936
+ }
4937
+
4938
+ if (this.options.disabled == null) {
4939
+ this.options.disabled = $e.prop('disabled');
4940
+ }
4941
+
4942
+ if (this.options.language == null) {
4943
+ if ($e.prop('lang')) {
4944
+ this.options.language = $e.prop('lang').toLowerCase();
4945
+ } else if ($e.closest('[lang]').prop('lang')) {
4946
+ this.options.language = $e.closest('[lang]').prop('lang');
4947
+ }
4948
+ }
4949
+
4950
+ if (this.options.dir == null) {
4951
+ if ($e.prop('dir')) {
4952
+ this.options.dir = $e.prop('dir');
4953
+ } else if ($e.closest('[dir]').prop('dir')) {
4954
+ this.options.dir = $e.closest('[dir]').prop('dir');
4955
+ } else {
4956
+ this.options.dir = 'ltr';
4957
+ }
4958
+ }
4959
+
4960
+ $e.prop('disabled', this.options.disabled);
4961
+ $e.prop('multiple', this.options.multiple);
4962
+
4963
+ if ($e.data('select2Tags')) {
4964
+ if (this.options.debug && window.console && console.warn) {
4965
+ console.warn(
4966
+ 'Select2: The `data-select2-tags` attribute has been changed to ' +
4967
+ 'use the `data-data` and `data-tags="true"` attributes and will be ' +
4968
+ 'removed in future versions of Select2.'
4969
+ );
4970
+ }
4971
+
4972
+ $e.data('data', $e.data('select2Tags'));
4973
+ $e.data('tags', true);
4974
+ }
4975
+
4976
+ if ($e.data('ajaxUrl')) {
4977
+ if (this.options.debug && window.console && console.warn) {
4978
+ console.warn(
4979
+ 'Select2: The `data-ajax-url` attribute has been changed to ' +
4980
+ '`data-ajax--url` and support for the old attribute will be removed' +
4981
+ ' in future versions of Select2.'
4982
+ );
4983
+ }
4984
+
4985
+ $e.attr('ajax--url', $e.data('ajaxUrl'));
4986
+ $e.data('ajax--url', $e.data('ajaxUrl'));
4987
+ }
4988
+
4989
+ var dataset = {};
4990
+
4991
+ // Prefer the element's `dataset` attribute if it exists
4992
+ // jQuery 1.x does not correctly handle data attributes with multiple dashes
4993
+ if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {
4994
+ dataset = $.extend(true, {}, $e[0].dataset, $e.data());
4995
+ } else {
4996
+ dataset = $e.data();
4997
+ }
4998
+
4999
+ var data = $.extend(true, {}, dataset);
5000
+
5001
+ data = Utils._convertData(data);
5002
+
5003
+ for (var key in data) {
5004
+ if ($.inArray(key, excludedData) > -1) {
5005
+ continue;
5006
+ }
5007
+
5008
+ if ($.isPlainObject(this.options[key])) {
5009
+ $.extend(this.options[key], data[key]);
5010
+ } else {
5011
+ this.options[key] = data[key];
5012
+ }
5013
+ }
5014
+
5015
+ return this;
5016
+ };
5017
+
5018
+ Options.prototype.get = function (key) {
5019
+ return this.options[key];
5020
+ };
5021
+
5022
+ Options.prototype.set = function (key, val) {
5023
+ this.options[key] = val;
5024
+ };
5025
+
5026
+ return Options;
5027
+ });
5028
+
5029
+ S2.define('select2/core',[
5030
+ 'jquery',
5031
+ './options',
5032
+ './utils',
5033
+ './keys'
5034
+ ], function ($, Options, Utils, KEYS) {
5035
+ var Select2 = function ($element, options) {
5036
+ if ($element.data('select2') != null) {
5037
+ $element.data('select2').destroy();
5038
+ }
5039
+
5040
+ this.$element = $element;
5041
+
5042
+ this.id = this._generateId($element);
5043
+
5044
+ options = options || {};
5045
+
5046
+ this.options = new Options(options, $element);
5047
+
5048
+ Select2.__super__.constructor.call(this);
5049
+
5050
+ // Set up the tabindex
5051
+
5052
+ var tabindex = $element.attr('tabindex') || 0;
5053
+ $element.data('old-tabindex', tabindex);
5054
+ $element.attr('tabindex', '-1');
5055
+
5056
+ // Set up containers and adapters
5057
+
5058
+ var DataAdapter = this.options.get('dataAdapter');
5059
+ this.dataAdapter = new DataAdapter($element, this.options);
5060
+
5061
+ var $container = this.render();
5062
+
5063
+ this._placeContainer($container);
5064
+
5065
+ var SelectionAdapter = this.options.get('selectionAdapter');
5066
+ this.selection = new SelectionAdapter($element, this.options);
5067
+ this.$selection = this.selection.render();
5068
+
5069
+ this.selection.position(this.$selection, $container);
5070
+
5071
+ var DropdownAdapter = this.options.get('dropdownAdapter');
5072
+ this.dropdown = new DropdownAdapter($element, this.options);
5073
+ this.$dropdown = this.dropdown.render();
5074
+
5075
+ this.dropdown.position(this.$dropdown, $container);
5076
+
5077
+ var ResultsAdapter = this.options.get('resultsAdapter');
5078
+ this.results = new ResultsAdapter($element, this.options, this.dataAdapter);
5079
+ this.$results = this.results.render();
5080
+
5081
+ this.results.position(this.$results, this.$dropdown);
5082
+
5083
+ // Bind events
5084
+
5085
+ var self = this;
5086
+
5087
+ // Bind the container to all of the adapters
5088
+ this._bindAdapters();
5089
+
5090
+ // Register any DOM event handlers
5091
+ this._registerDomEvents();
5092
+
5093
+ // Register any internal event handlers
5094
+ this._registerDataEvents();
5095
+ this._registerSelectionEvents();
5096
+ this._registerDropdownEvents();
5097
+ this._registerResultsEvents();
5098
+ this._registerEvents();
5099
+
5100
+ // Set the initial state
5101
+ this.dataAdapter.current(function (initialData) {
5102
+ self.trigger('selection:update', {
5103
+ data: initialData
5104
+ });
5105
+ });
5106
+
5107
+ // Hide the original select
5108
+ $element.addClass('select2-hidden-accessible');
5109
+ $element.attr('aria-hidden', 'true');
5110
+
5111
+ // Synchronize any monitored attributes
5112
+ this._syncAttributes();
5113
+
5114
+ $element.data('select2', this);
5115
+ };
5116
+
5117
+ Utils.Extend(Select2, Utils.Observable);
5118
+
5119
+ Select2.prototype._generateId = function ($element) {
5120
+ var id = '';
5121
+
5122
+ if ($element.attr('id') != null) {
5123
+ id = $element.attr('id');
5124
+ } else if ($element.attr('name') != null) {
5125
+ id = $element.attr('name') + '-' + Utils.generateChars(2);
5126
+ } else {
5127
+ id = Utils.generateChars(4);
5128
+ }
5129
+
5130
+ id = id.replace(/(:|\.|\[|\]|,)/g, '');
5131
+ id = 'select2-' + id;
5132
+
5133
+ return id;
5134
+ };
5135
+
5136
+ Select2.prototype._placeContainer = function ($container) {
5137
+ $container.insertAfter(this.$element);
5138
+
5139
+ var width = this._resolveWidth(this.$element, this.options.get('width'));
5140
+
5141
+ if (width != null) {
5142
+ $container.css('width', width);
5143
+ }
5144
+ };
5145
+
5146
+ Select2.prototype._resolveWidth = function ($element, method) {
5147
+ var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;
5148
+
5149
+ if (method == 'resolve') {
5150
+ var styleWidth = this._resolveWidth($element, 'style');
5151
+
5152
+ if (styleWidth != null) {
5153
+ return styleWidth;
5154
+ }
5155
+
5156
+ return this._resolveWidth($element, 'element');
5157
+ }
5158
+
5159
+ if (method == 'element') {
5160
+ var elementWidth = $element.outerWidth(false);
5161
+
5162
+ if (elementWidth <= 0) {
5163
+ return 'auto';
5164
+ }
5165
+
5166
+ return elementWidth + 'px';
5167
+ }
5168
+
5169
+ if (method == 'style') {
5170
+ var style = $element.attr('style');
5171
+
5172
+ if (typeof(style) !== 'string') {
5173
+ return null;
5174
+ }
5175
+
5176
+ var attrs = style.split(';');
5177
+
5178
+ for (var i = 0, l = attrs.length; i < l; i = i + 1) {
5179
+ var attr = attrs[i].replace(/\s/g, '');
5180
+ var matches = attr.match(WIDTH);
5181
+
5182
+ if (matches !== null && matches.length >= 1) {
5183
+ return matches[1];
5184
+ }
5185
+ }
5186
+
5187
+ return null;
5188
+ }
5189
+
5190
+ return method;
5191
+ };
5192
+
5193
+ Select2.prototype._bindAdapters = function () {
5194
+ this.dataAdapter.bind(this, this.$container);
5195
+ this.selection.bind(this, this.$container);
5196
+
5197
+ this.dropdown.bind(this, this.$container);
5198
+ this.results.bind(this, this.$container);
5199
+ };
5200
+
5201
+ Select2.prototype._registerDomEvents = function () {
5202
+ var self = this;
5203
+
5204
+ this.$element.on('change.select2', function () {
5205
+ self.dataAdapter.current(function (data) {
5206
+ self.trigger('selection:update', {
5207
+ data: data
5208
+ });
5209
+ });
5210
+ });
5211
+
5212
+ this.$element.on('focus.select2', function (evt) {
5213
+ self.trigger('focus', evt);
5214
+ });
5215
+
5216
+ this._syncA = Utils.bind(this._syncAttributes, this);
5217
+ this._syncS = Utils.bind(this._syncSubtree, this);
5218
+
5219
+ if (this.$element[0].attachEvent) {
5220
+ this.$element[0].attachEvent('onpropertychange', this._syncA);
5221
+ }
5222
+
5223
+ var observer = window.MutationObserver ||
5224
+ window.WebKitMutationObserver ||
5225
+ window.MozMutationObserver
5226
+ ;
5227
+
5228
+ if (observer != null) {
5229
+ this._observer = new observer(function (mutations) {
5230
+ $.each(mutations, self._syncA);
5231
+ $.each(mutations, self._syncS);
5232
+ });
5233
+ this._observer.observe(this.$element[0], {
5234
+ attributes: true,
5235
+ childList: true,
5236
+ subtree: false
5237
+ });
5238
+ } else if (this.$element[0].addEventListener) {
5239
+ this.$element[0].addEventListener(
5240
+ 'DOMAttrModified',
5241
+ self._syncA,
5242
+ false
5243
+ );
5244
+ this.$element[0].addEventListener(
5245
+ 'DOMNodeInserted',
5246
+ self._syncS,
5247
+ false
5248
+ );
5249
+ this.$element[0].addEventListener(
5250
+ 'DOMNodeRemoved',
5251
+ self._syncS,
5252
+ false
5253
+ );
5254
+ }
5255
+ };
5256
+
5257
+ Select2.prototype._registerDataEvents = function () {
5258
+ var self = this;
5259
+
5260
+ this.dataAdapter.on('*', function (name, params) {
5261
+ self.trigger(name, params);
5262
+ });
5263
+ };
5264
+
5265
+ Select2.prototype._registerSelectionEvents = function () {
5266
+ var self = this;
5267
+ var nonRelayEvents = ['toggle', 'focus'];
5268
+
5269
+ this.selection.on('toggle', function () {
5270
+ self.toggleDropdown();
5271
+ });
5272
+
5273
+ this.selection.on('focus', function (params) {
5274
+ self.focus(params);
5275
+ });
5276
+
5277
+ this.selection.on('*', function (name, params) {
5278
+ if ($.inArray(name, nonRelayEvents) !== -1) {
5279
+ return;
5280
+ }
5281
+
5282
+ self.trigger(name, params);
5283
+ });
5284
+ };
5285
+
5286
+ Select2.prototype._registerDropdownEvents = function () {
5287
+ var self = this;
5288
+
5289
+ this.dropdown.on('*', function (name, params) {
5290
+ self.trigger(name, params);
5291
+ });
5292
+ };
5293
+
5294
+ Select2.prototype._registerResultsEvents = function () {
5295
+ var self = this;
5296
+
5297
+ this.results.on('*', function (name, params) {
5298
+ self.trigger(name, params);
5299
+ });
5300
+ };
5301
+
5302
+ Select2.prototype._registerEvents = function () {
5303
+ var self = this;
5304
+
5305
+ this.on('open', function () {
5306
+ self.$container.addClass('select2-container--open');
5307
+ });
5308
+
5309
+ this.on('close', function () {
5310
+ self.$container.removeClass('select2-container--open');
5311
+ });
5312
+
5313
+ this.on('enable', function () {
5314
+ self.$container.removeClass('select2-container--disabled');
5315
+ });
5316
+
5317
+ this.on('disable', function () {
5318
+ self.$container.addClass('select2-container--disabled');
5319
+ });
5320
+
5321
+ this.on('blur', function () {
5322
+ self.$container.removeClass('select2-container--focus');
5323
+ });
5324
+
5325
+ this.on('query', function (params) {
5326
+ if (!self.isOpen()) {
5327
+ self.trigger('open', {});
5328
+ }
5329
+
5330
+ this.dataAdapter.query(params, function (data) {
5331
+ self.trigger('results:all', {
5332
+ data: data,
5333
+ query: params
5334
+ });
5335
+ });
5336
+ });
5337
+
5338
+ this.on('query:append', function (params) {
5339
+ this.dataAdapter.query(params, function (data) {
5340
+ self.trigger('results:append', {
5341
+ data: data,
5342
+ query: params
5343
+ });
5344
+ });
5345
+ });
5346
+
5347
+ this.on('keypress', function (evt) {
5348
+ var key = evt.which;
5349
+
5350
+ if (self.isOpen()) {
5351
+ if (key === KEYS.ESC || key === KEYS.TAB ||
5352
+ (key === KEYS.UP && evt.altKey)) {
5353
+ self.close();
5354
+
5355
+ evt.preventDefault();
5356
+ } else if (key === KEYS.ENTER) {
5357
+ self.trigger('results:select', {});
5358
+
5359
+ evt.preventDefault();
5360
+ } else if ((key === KEYS.SPACE && evt.ctrlKey)) {
5361
+ self.trigger('results:toggle', {});
5362
+
5363
+ evt.preventDefault();
5364
+ } else if (key === KEYS.UP) {
5365
+ self.trigger('results:previous', {});
5366
+
5367
+ evt.preventDefault();
5368
+ } else if (key === KEYS.DOWN) {
5369
+ self.trigger('results:next', {});
5370
+
5371
+ evt.preventDefault();
5372
+ }
5373
+ } else {
5374
+ if (key === KEYS.ENTER || key === KEYS.SPACE ||
5375
+ (key === KEYS.DOWN && evt.altKey)) {
5376
+ self.open();
5377
+
5378
+ evt.preventDefault();
5379
+ }
5380
+ }
5381
+ });
5382
+ };
5383
+
5384
+ Select2.prototype._syncAttributes = function () {
5385
+ this.options.set('disabled', this.$element.prop('disabled'));
5386
+
5387
+ if (this.options.get('disabled')) {
5388
+ if (this.isOpen()) {
5389
+ this.close();
5390
+ }
5391
+
5392
+ this.trigger('disable', {});
5393
+ } else {
5394
+ this.trigger('enable', {});
5395
+ }
5396
+ };
5397
+
5398
+ Select2.prototype._syncSubtree = function (evt, mutations) {
5399
+ var changed = false;
5400
+ var self = this;
5401
+
5402
+ // Ignore any mutation events raised for elements that aren't options or
5403
+ // optgroups. This handles the case when the select element is destroyed
5404
+ if (
5405
+ evt && evt.target && (
5406
+ evt.target.nodeName !== 'OPTION' && evt.target.nodeName !== 'OPTGROUP'
5407
+ )
5408
+ ) {
5409
+ return;
5410
+ }
5411
+
5412
+ if (!mutations) {
5413
+ // If mutation events aren't supported, then we can only assume that the
5414
+ // change affected the selections
5415
+ changed = true;
5416
+ } else if (mutations.addedNodes && mutations.addedNodes.length > 0) {
5417
+ for (var n = 0; n < mutations.addedNodes.length; n++) {
5418
+ var node = mutations.addedNodes[n];
5419
+
5420
+ if (node.selected) {
5421
+ changed = true;
5422
+ }
5423
+ }
5424
+ } else if (mutations.removedNodes && mutations.removedNodes.length > 0) {
5425
+ changed = true;
5426
+ }
5427
+
5428
+ // Only re-pull the data if we think there is a change
5429
+ if (changed) {
5430
+ this.dataAdapter.current(function (currentData) {
5431
+ self.trigger('selection:update', {
5432
+ data: currentData
5433
+ });
5434
+ });
5435
+ }
5436
+ };
5437
+
5438
+ /**
5439
+ * Override the trigger method to automatically trigger pre-events when
5440
+ * there are events that can be prevented.
5441
+ */
5442
+ Select2.prototype.trigger = function (name, args) {
5443
+ var actualTrigger = Select2.__super__.trigger;
5444
+ var preTriggerMap = {
5445
+ 'open': 'opening',
5446
+ 'close': 'closing',
5447
+ 'select': 'selecting',
5448
+ 'unselect': 'unselecting'
5449
+ };
5450
+
5451
+ if (args === undefined) {
5452
+ args = {};
5453
+ }
5454
+
5455
+ if (name in preTriggerMap) {
5456
+ var preTriggerName = preTriggerMap[name];
5457
+ var preTriggerArgs = {
5458
+ prevented: false,
5459
+ name: name,
5460
+ args: args
5461
+ };
5462
+
5463
+ actualTrigger.call(this, preTriggerName, preTriggerArgs);
5464
+
5465
+ if (preTriggerArgs.prevented) {
5466
+ args.prevented = true;
5467
+
5468
+ return;
5469
+ }
5470
+ }
5471
+
5472
+ actualTrigger.call(this, name, args);
5473
+ };
5474
+
5475
+ Select2.prototype.toggleDropdown = function () {
5476
+ if (this.options.get('disabled')) {
5477
+ return;
5478
+ }
5479
+
5480
+ if (this.isOpen()) {
5481
+ this.close();
5482
+ } else {
5483
+ this.open();
5484
+ }
5485
+ };
5486
+
5487
+ Select2.prototype.open = function () {
5488
+ if (this.isOpen()) {
5489
+ return;
5490
+ }
5491
+
5492
+ this.trigger('query', {});
5493
+ };
5494
+
5495
+ Select2.prototype.close = function () {
5496
+ if (!this.isOpen()) {
5497
+ return;
5498
+ }
5499
+
5500
+ this.trigger('close', {});
5501
+ };
5502
+
5503
+ Select2.prototype.isOpen = function () {
5504
+ return this.$container.hasClass('select2-container--open');
5505
+ };
5506
+
5507
+ Select2.prototype.hasFocus = function () {
5508
+ return this.$container.hasClass('select2-container--focus');
5509
+ };
5510
+
5511
+ Select2.prototype.focus = function (data) {
5512
+ // No need to re-trigger focus events if we are already focused
5513
+ if (this.hasFocus()) {
5514
+ return;
5515
+ }
5516
+
5517
+ this.$container.addClass('select2-container--focus');
5518
+ this.trigger('focus', {});
5519
+ };
5520
+
5521
+ Select2.prototype.enable = function (args) {
5522
+ if (this.options.get('debug') && window.console && console.warn) {
5523
+ console.warn(
5524
+ 'Select2: The `select2("enable")` method has been deprecated and will' +
5525
+ ' be removed in later Select2 versions. Use $element.prop("disabled")' +
5526
+ ' instead.'
5527
+ );
5528
+ }
5529
+
5530
+ if (args == null || args.length === 0) {
5531
+ args = [true];
5532
+ }
5533
+
5534
+ var disabled = !args[0];
5535
+
5536
+ this.$element.prop('disabled', disabled);
5537
+ };
5538
+
5539
+ Select2.prototype.data = function () {
5540
+ if (this.options.get('debug') &&
5541
+ arguments.length > 0 && window.console && console.warn) {
5542
+ console.warn(
5543
+ 'Select2: Data can no longer be set using `select2("data")`. You ' +
5544
+ 'should consider setting the value instead using `$element.val()`.'
5545
+ );
5546
+ }
5547
+
5548
+ var data = [];
5549
+
5550
+ this.dataAdapter.current(function (currentData) {
5551
+ data = currentData;
5552
+ });
5553
+
5554
+ return data;
5555
+ };
5556
+
5557
+ Select2.prototype.val = function (args) {
5558
+ if (this.options.get('debug') && window.console && console.warn) {
5559
+ console.warn(
5560
+ 'Select2: The `select2("val")` method has been deprecated and will be' +
5561
+ ' removed in later Select2 versions. Use $element.val() instead.'
5562
+ );
5563
+ }
5564
+
5565
+ if (args == null || args.length === 0) {
5566
+ return this.$element.val();
5567
+ }
5568
+
5569
+ var newVal = args[0];
5570
+
5571
+ if ($.isArray(newVal)) {
5572
+ newVal = $.map(newVal, function (obj) {
5573
+ return obj.toString();
5574
+ });
5575
+ }
5576
+
5577
+ this.$element.val(newVal).trigger('change');
5578
+ };
5579
+
5580
+ Select2.prototype.destroy = function () {
5581
+ this.$container.remove();
5582
+
5583
+ if (this.$element[0].detachEvent) {
5584
+ this.$element[0].detachEvent('onpropertychange', this._syncA);
5585
+ }
5586
+
5587
+ if (this._observer != null) {
5588
+ this._observer.disconnect();
5589
+ this._observer = null;
5590
+ } else if (this.$element[0].removeEventListener) {
5591
+ this.$element[0]
5592
+ .removeEventListener('DOMAttrModified', this._syncA, false);
5593
+ this.$element[0]
5594
+ .removeEventListener('DOMNodeInserted', this._syncS, false);
5595
+ this.$element[0]
5596
+ .removeEventListener('DOMNodeRemoved', this._syncS, false);
5597
+ }
5598
+
5599
+ this._syncA = null;
5600
+ this._syncS = null;
5601
+
5602
+ this.$element.off('.select2');
5603
+ this.$element.attr('tabindex', this.$element.data('old-tabindex'));
5604
+
5605
+ this.$element.removeClass('select2-hidden-accessible');
5606
+ this.$element.attr('aria-hidden', 'false');
5607
+ this.$element.removeData('select2');
5608
+
5609
+ this.dataAdapter.destroy();
5610
+ this.selection.destroy();
5611
+ this.dropdown.destroy();
5612
+ this.results.destroy();
5613
+
5614
+ this.dataAdapter = null;
5615
+ this.selection = null;
5616
+ this.dropdown = null;
5617
+ this.results = null;
5618
+ };
5619
+
5620
+ Select2.prototype.render = function () {
5621
+ var $container = $(
5622
+ '<span class="select2 select2-container">' +
5623
+ '<span class="selection"></span>' +
5624
+ '<span class="dropdown-wrapper" aria-hidden="true"></span>' +
5625
+ '</span>'
5626
+ );
5627
+
5628
+ $container.attr('dir', this.options.get('dir'));
5629
+
5630
+ this.$container = $container;
5631
+
5632
+ this.$container.addClass('select2-container--' + this.options.get('theme'));
5633
+
5634
+ $container.data('element', this.$element);
5635
+
5636
+ return $container;
5637
+ };
5638
+
5639
+ return Select2;
5640
+ });
5641
+
5642
+ S2.define('select2/compat/utils',[
5643
+ 'jquery'
5644
+ ], function ($) {
5645
+ function syncCssClasses ($dest, $src, adapter) {
5646
+ var classes, replacements = [], adapted;
5647
+
5648
+ classes = $.trim($dest.attr('class'));
5649
+
5650
+ if (classes) {
5651
+ classes = '' + classes; // for IE which returns object
5652
+
5653
+ $(classes.split(/\s+/)).each(function () {
5654
+ // Save all Select2 classes
5655
+ if (this.indexOf('select2-') === 0) {
5656
+ replacements.push(this);
5657
+ }
5658
+ });
5659
+ }
5660
+
5661
+ classes = $.trim($src.attr('class'));
5662
+
5663
+ if (classes) {
5664
+ classes = '' + classes; // for IE which returns object
5665
+
5666
+ $(classes.split(/\s+/)).each(function () {
5667
+ // Only adapt non-Select2 classes
5668
+ if (this.indexOf('select2-') !== 0) {
5669
+ adapted = adapter(this);
5670
+
5671
+ if (adapted != null) {
5672
+ replacements.push(adapted);
5673
+ }
5674
+ }
5675
+ });
5676
+ }
5677
+
5678
+ $dest.attr('class', replacements.join(' '));
5679
+ }
5680
+
5681
+ return {
5682
+ syncCssClasses: syncCssClasses
5683
+ };
5684
+ });
5685
+
5686
+ S2.define('select2/compat/containerCss',[
5687
+ 'jquery',
5688
+ './utils'
5689
+ ], function ($, CompatUtils) {
5690
+ // No-op CSS adapter that discards all classes by default
5691
+ function _containerAdapter (clazz) {
5692
+ return null;
5693
+ }
5694
+
5695
+ function ContainerCSS () { }
5696
+
5697
+ ContainerCSS.prototype.render = function (decorated) {
5698
+ var $container = decorated.call(this);
5699
+
5700
+ var containerCssClass = this.options.get('containerCssClass') || '';
5701
+
5702
+ if ($.isFunction(containerCssClass)) {
5703
+ containerCssClass = containerCssClass(this.$element);
5704
+ }
5705
+
5706
+ var containerCssAdapter = this.options.get('adaptContainerCssClass');
5707
+ containerCssAdapter = containerCssAdapter || _containerAdapter;
5708
+
5709
+ if (containerCssClass.indexOf(':all:') !== -1) {
5710
+ containerCssClass = containerCssClass.replace(':all:', '');
5711
+
5712
+ var _cssAdapter = containerCssAdapter;
5713
+
5714
+ containerCssAdapter = function (clazz) {
5715
+ var adapted = _cssAdapter(clazz);
5716
+
5717
+ if (adapted != null) {
5718
+ // Append the old one along with the adapted one
5719
+ return adapted + ' ' + clazz;
5720
+ }
5721
+
5722
+ return clazz;
5723
+ };
5724
+ }
5725
+
5726
+ var containerCss = this.options.get('containerCss') || {};
5727
+
5728
+ if ($.isFunction(containerCss)) {
5729
+ containerCss = containerCss(this.$element);
5730
+ }
5731
+
5732
+ CompatUtils.syncCssClasses($container, this.$element, containerCssAdapter);
5733
+
5734
+ $container.css(containerCss);
5735
+ $container.addClass(containerCssClass);
5736
+
5737
+ return $container;
5738
+ };
5739
+
5740
+ return ContainerCSS;
5741
+ });
5742
+
5743
+ S2.define('select2/compat/dropdownCss',[
5744
+ 'jquery',
5745
+ './utils'
5746
+ ], function ($, CompatUtils) {
5747
+ // No-op CSS adapter that discards all classes by default
5748
+ function _dropdownAdapter (clazz) {
5749
+ return null;
5750
+ }
5751
+
5752
+ function DropdownCSS () { }
5753
+
5754
+ DropdownCSS.prototype.render = function (decorated) {
5755
+ var $dropdown = decorated.call(this);
5756
+
5757
+ var dropdownCssClass = this.options.get('dropdownCssClass') || '';
5758
+
5759
+ if ($.isFunction(dropdownCssClass)) {
5760
+ dropdownCssClass = dropdownCssClass(this.$element);
5761
+ }
5762
+
5763
+ var dropdownCssAdapter = this.options.get('adaptDropdownCssClass');
5764
+ dropdownCssAdapter = dropdownCssAdapter || _dropdownAdapter;
5765
+
5766
+ if (dropdownCssClass.indexOf(':all:') !== -1) {
5767
+ dropdownCssClass = dropdownCssClass.replace(':all:', '');
5768
+
5769
+ var _cssAdapter = dropdownCssAdapter;
5770
+
5771
+ dropdownCssAdapter = function (clazz) {
5772
+ var adapted = _cssAdapter(clazz);
5773
+
5774
+ if (adapted != null) {
5775
+ // Append the old one along with the adapted one
5776
+ return adapted + ' ' + clazz;
5777
+ }
5778
+
5779
+ return clazz;
5780
+ };
5781
+ }
5782
+
5783
+ var dropdownCss = this.options.get('dropdownCss') || {};
5784
+
5785
+ if ($.isFunction(dropdownCss)) {
5786
+ dropdownCss = dropdownCss(this.$element);
5787
+ }
5788
+
5789
+ CompatUtils.syncCssClasses($dropdown, this.$element, dropdownCssAdapter);
5790
+
5791
+ $dropdown.css(dropdownCss);
5792
+ $dropdown.addClass(dropdownCssClass);
5793
+
5794
+ return $dropdown;
5795
+ };
5796
+
5797
+ return DropdownCSS;
5798
+ });
5799
+
5800
+ S2.define('select2/compat/initSelection',[
5801
+ 'jquery'
5802
+ ], function ($) {
5803
+ function InitSelection (decorated, $element, options) {
5804
+ if (options.get('debug') && window.console && console.warn) {
5805
+ console.warn(
5806
+ 'Select2: The `initSelection` option has been deprecated in favor' +
5807
+ ' of a custom data adapter that overrides the `current` method. ' +
5808
+ 'This method is now called multiple times instead of a single ' +
5809
+ 'time when the instance is initialized. Support will be removed ' +
5810
+ 'for the `initSelection` option in future versions of Select2'
5811
+ );
5812
+ }
5813
+
5814
+ this.initSelection = options.get('initSelection');
5815
+ this._isInitialized = false;
5816
+
5817
+ decorated.call(this, $element, options);
5818
+ }
5819
+
5820
+ InitSelection.prototype.current = function (decorated, callback) {
5821
+ var self = this;
5822
+
5823
+ if (this._isInitialized) {
5824
+ decorated.call(this, callback);
5825
+
5826
+ return;
5827
+ }
5828
+
5829
+ this.initSelection.call(null, this.$element, function (data) {
5830
+ self._isInitialized = true;
5831
+
5832
+ if (!$.isArray(data)) {
5833
+ data = [data];
5834
+ }
5835
+
5836
+ callback(data);
5837
+ });
5838
+ };
5839
+
5840
+ return InitSelection;
5841
+ });
5842
+
5843
+ S2.define('select2/compat/inputData',[
5844
+ 'jquery'
5845
+ ], function ($) {
5846
+ function InputData (decorated, $element, options) {
5847
+ this._currentData = [];
5848
+ this._valueSeparator = options.get('valueSeparator') || ',';
5849
+
5850
+ if ($element.prop('type') === 'hidden') {
5851
+ if (options.get('debug') && console && console.warn) {
5852
+ console.warn(
5853
+ 'Select2: Using a hidden input with Select2 is no longer ' +
5854
+ 'supported and may stop working in the future. It is recommended ' +
5855
+ 'to use a `<select>` element instead.'
5856
+ );
5857
+ }
5858
+ }
5859
+
5860
+ decorated.call(this, $element, options);
5861
+ }
5862
+
5863
+ InputData.prototype.current = function (_, callback) {
5864
+ function getSelected (data, selectedIds) {
5865
+ var selected = [];
5866
+
5867
+ if (data.selected || $.inArray(data.id, selectedIds) !== -1) {
5868
+ data.selected = true;
5869
+ selected.push(data);
5870
+ } else {
5871
+ data.selected = false;
5872
+ }
5873
+
5874
+ if (data.children) {
5875
+ selected.push.apply(selected, getSelected(data.children, selectedIds));
5876
+ }
5877
+
5878
+ return selected;
5879
+ }
5880
+
5881
+ var selected = [];
5882
+
5883
+ for (var d = 0; d < this._currentData.length; d++) {
5884
+ var data = this._currentData[d];
5885
+
5886
+ selected.push.apply(
5887
+ selected,
5888
+ getSelected(
5889
+ data,
5890
+ this.$element.val().split(
5891
+ this._valueSeparator
5892
+ )
5893
+ )
5894
+ );
5895
+ }
5896
+
5897
+ callback(selected);
5898
+ };
5899
+
5900
+ InputData.prototype.select = function (_, data) {
5901
+ if (!this.options.get('multiple')) {
5902
+ this.current(function (allData) {
5903
+ $.map(allData, function (data) {
5904
+ data.selected = false;
5905
+ });
5906
+ });
5907
+
5908
+ this.$element.val(data.id);
5909
+ this.$element.trigger('change');
5910
+ } else {
5911
+ var value = this.$element.val();
5912
+ value += this._valueSeparator + data.id;
5913
+
5914
+ this.$element.val(value);
5915
+ this.$element.trigger('change');
5916
+ }
5917
+ };
5918
+
5919
+ InputData.prototype.unselect = function (_, data) {
5920
+ var self = this;
5921
+
5922
+ data.selected = false;
5923
+
5924
+ this.current(function (allData) {
5925
+ var values = [];
5926
+
5927
+ for (var d = 0; d < allData.length; d++) {
5928
+ var item = allData[d];
5929
+
5930
+ if (data.id == item.id) {
5931
+ continue;
5932
+ }
5933
+
5934
+ values.push(item.id);
5935
+ }
5936
+
5937
+ self.$element.val(values.join(self._valueSeparator));
5938
+ self.$element.trigger('change');
5939
+ });
5940
+ };
5941
+
5942
+ InputData.prototype.query = function (_, params, callback) {
5943
+ var results = [];
5944
+
5945
+ for (var d = 0; d < this._currentData.length; d++) {
5946
+ var data = this._currentData[d];
5947
+
5948
+ var matches = this.matches(params, data);
5949
+
5950
+ if (matches !== null) {
5951
+ results.push(matches);
5952
+ }
5953
+ }
5954
+
5955
+ callback({
5956
+ results: results
5957
+ });
5958
+ };
5959
+
5960
+ InputData.prototype.addOptions = function (_, $options) {
5961
+ var options = $.map($options, function ($option) {
5962
+ return $.data($option[0], 'data');
5963
+ });
5964
+
5965
+ this._currentData.push.apply(this._currentData, options);
5966
+ };
5967
+
5968
+ return InputData;
5969
+ });
5970
+
5971
+ S2.define('select2/compat/matcher',[
5972
+ 'jquery'
5973
+ ], function ($) {
5974
+ function oldMatcher (matcher) {
5975
+ function wrappedMatcher (params, data) {
5976
+ var match = $.extend(true, {}, data);
5977
+
5978
+ if (params.term == null || $.trim(params.term) === '') {
5979
+ return match;
5980
+ }
5981
+
5982
+ if (data.children) {
5983
+ for (var c = data.children.length - 1; c >= 0; c--) {
5984
+ var child = data.children[c];
5985
+
5986
+ // Check if the child object matches
5987
+ // The old matcher returned a boolean true or false
5988
+ var doesMatch = matcher(params.term, child.text, child);
5989
+
5990
+ // If the child didn't match, pop it off
5991
+ if (!doesMatch) {
5992
+ match.children.splice(c, 1);
5993
+ }
5994
+ }
5995
+
5996
+ if (match.children.length > 0) {
5997
+ return match;
5998
+ }
5999
+ }
6000
+
6001
+ if (matcher(params.term, data.text, data)) {
6002
+ return match;
6003
+ }
6004
+
6005
+ return null;
6006
+ }
6007
+
6008
+ return wrappedMatcher;
6009
+ }
6010
+
6011
+ return oldMatcher;
6012
+ });
6013
+
6014
+ S2.define('select2/compat/query',[
6015
+
6016
+ ], function () {
6017
+ function Query (decorated, $element, options) {
6018
+ if (options.get('debug') && window.console && console.warn) {
6019
+ console.warn(
6020
+ 'Select2: The `query` option has been deprecated in favor of a ' +
6021
+ 'custom data adapter that overrides the `query` method. Support ' +
6022
+ 'will be removed for the `query` option in future versions of ' +
6023
+ 'Select2.'
6024
+ );
6025
+ }
6026
+
6027
+ decorated.call(this, $element, options);
6028
+ }
6029
+
6030
+ Query.prototype.query = function (_, params, callback) {
6031
+ params.callback = callback;
6032
+
6033
+ var query = this.options.get('query');
6034
+
6035
+ query.call(null, params);
6036
+ };
6037
+
6038
+ return Query;
6039
+ });
6040
+
6041
+ S2.define('select2/dropdown/attachContainer',[
6042
+
6043
+ ], function () {
6044
+ function AttachContainer (decorated, $element, options) {
6045
+ decorated.call(this, $element, options);
6046
+ }
6047
+
6048
+ AttachContainer.prototype.position =
6049
+ function (decorated, $dropdown, $container) {
6050
+ var $dropdownContainer = $container.find('.dropdown-wrapper');
6051
+ $dropdownContainer.append($dropdown);
6052
+
6053
+ $dropdown.addClass('select2-dropdown--below');
6054
+ $container.addClass('select2-container--below');
6055
+ };
6056
+
6057
+ return AttachContainer;
6058
+ });
6059
+
6060
+ S2.define('select2/dropdown/stopPropagation',[
6061
+
6062
+ ], function () {
6063
+ function StopPropagation () { }
6064
+
6065
+ StopPropagation.prototype.bind = function (decorated, container, $container) {
6066
+ decorated.call(this, container, $container);
6067
+
6068
+ var stoppedEvents = [
6069
+ 'blur',
6070
+ 'change',
6071
+ 'click',
6072
+ 'dblclick',
6073
+ 'focus',
6074
+ 'focusin',
6075
+ 'focusout',
6076
+ 'input',
6077
+ 'keydown',
6078
+ 'keyup',
6079
+ 'keypress',
6080
+ 'mousedown',
6081
+ 'mouseenter',
6082
+ 'mouseleave',
6083
+ 'mousemove',
6084
+ 'mouseover',
6085
+ 'mouseup',
6086
+ 'search',
6087
+ 'touchend',
6088
+ 'touchstart'
6089
+ ];
6090
+
6091
+ this.$dropdown.on(stoppedEvents.join(' '), function (evt) {
6092
+ evt.stopPropagation();
6093
+ });
6094
+ };
6095
+
6096
+ return StopPropagation;
6097
+ });
6098
+
6099
+ S2.define('select2/selection/stopPropagation',[
6100
+
6101
+ ], function () {
6102
+ function StopPropagation () { }
6103
+
6104
+ StopPropagation.prototype.bind = function (decorated, container, $container) {
6105
+ decorated.call(this, container, $container);
6106
+
6107
+ var stoppedEvents = [
6108
+ 'blur',
6109
+ 'change',
6110
+ 'click',
6111
+ 'dblclick',
6112
+ 'focus',
6113
+ 'focusin',
6114
+ 'focusout',
6115
+ 'input',
6116
+ 'keydown',
6117
+ 'keyup',
6118
+ 'keypress',
6119
+ 'mousedown',
6120
+ 'mouseenter',
6121
+ 'mouseleave',
6122
+ 'mousemove',
6123
+ 'mouseover',
6124
+ 'mouseup',
6125
+ 'search',
6126
+ 'touchend',
6127
+ 'touchstart'
6128
+ ];
6129
+
6130
+ this.$selection.on(stoppedEvents.join(' '), function (evt) {
6131
+ evt.stopPropagation();
6132
+ });
6133
+ };
6134
+
6135
+ return StopPropagation;
6136
+ });
6137
+
6138
+ /*!
6139
+ * jQuery Mousewheel 3.1.13
6140
+ *
6141
+ * Copyright jQuery Foundation and other contributors
6142
+ * Released under the MIT license
6143
+ * http://jquery.org/license
6144
+ */
6145
+
6146
+ (function (factory) {
6147
+ if ( typeof S2.define === 'function' && S2.define.amd ) {
6148
+ // AMD. Register as an anonymous module.
6149
+ S2.define('jquery-mousewheel',['jquery'], factory);
6150
+ } else if (typeof exports === 'object') {
6151
+ // Node/CommonJS style for Browserify
6152
+ module.exports = factory;
6153
+ } else {
6154
+ // Browser globals
6155
+ factory(jQuery);
6156
+ }
6157
+ }(function ($) {
6158
+
6159
+ var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
6160
+ toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
6161
+ ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
6162
+ slice = Array.prototype.slice,
6163
+ nullLowestDeltaTimeout, lowestDelta;
6164
+
6165
+ if ( $.event.fixHooks ) {
6166
+ for ( var i = toFix.length; i; ) {
6167
+ $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
6168
+ }
6169
+ }
6170
+
6171
+ var special = $.event.special.mousewheel = {
6172
+ version: '3.1.12',
6173
+
6174
+ setup: function() {
6175
+ if ( this.addEventListener ) {
6176
+ for ( var i = toBind.length; i; ) {
6177
+ this.addEventListener( toBind[--i], handler, false );
6178
+ }
6179
+ } else {
6180
+ this.onmousewheel = handler;
6181
+ }
6182
+ // Store the line height and page height for this particular element
6183
+ $.data(this, 'mousewheel-line-height', special.getLineHeight(this));
6184
+ $.data(this, 'mousewheel-page-height', special.getPageHeight(this));
6185
+ },
6186
+
6187
+ teardown: function() {
6188
+ if ( this.removeEventListener ) {
6189
+ for ( var i = toBind.length; i; ) {
6190
+ this.removeEventListener( toBind[--i], handler, false );
6191
+ }
6192
+ } else {
6193
+ this.onmousewheel = null;
6194
+ }
6195
+ // Clean up the data we added to the element
6196
+ $.removeData(this, 'mousewheel-line-height');
6197
+ $.removeData(this, 'mousewheel-page-height');
6198
+ },
6199
+
6200
+ getLineHeight: function(elem) {
6201
+ var $elem = $(elem),
6202
+ $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();
6203
+ if (!$parent.length) {
6204
+ $parent = $('body');
6205
+ }
6206
+ return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;
6207
+ },
6208
+
6209
+ getPageHeight: function(elem) {
6210
+ return $(elem).height();
6211
+ },
6212
+
6213
+ settings: {
6214
+ adjustOldDeltas: true, // see shouldAdjustOldDeltas() below
6215
+ normalizeOffset: true // calls getBoundingClientRect for each event
6216
+ }
6217
+ };
6218
+
6219
+ $.fn.extend({
6220
+ mousewheel: function(fn) {
6221
+ return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
6222
+ },
6223
+
6224
+ unmousewheel: function(fn) {
6225
+ return this.unbind('mousewheel', fn);
6226
+ }
6227
+ });
6228
+
6229
+
6230
+ function handler(event) {
6231
+ var orgEvent = event || window.event,
6232
+ args = slice.call(arguments, 1),
6233
+ delta = 0,
6234
+ deltaX = 0,
6235
+ deltaY = 0,
6236
+ absDelta = 0,
6237
+ offsetX = 0,
6238
+ offsetY = 0;
6239
+ event = $.event.fix(orgEvent);
6240
+ event.type = 'mousewheel';
6241
+
6242
+ // Old school scrollwheel delta
6243
+ if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; }
6244
+ if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; }
6245
+ if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; }
6246
+ if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
6247
+
6248
+ // Firefox < 17 horizontal scrolling related to DOMMouseScroll event
6249
+ if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
6250
+ deltaX = deltaY * -1;
6251
+ deltaY = 0;
6252
+ }
6253
+
6254
+ // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
6255
+ delta = deltaY === 0 ? deltaX : deltaY;
6256
+
6257
+ // New school wheel delta (wheel event)
6258
+ if ( 'deltaY' in orgEvent ) {
6259
+ deltaY = orgEvent.deltaY * -1;
6260
+ delta = deltaY;
6261
+ }
6262
+ if ( 'deltaX' in orgEvent ) {
6263
+ deltaX = orgEvent.deltaX;
6264
+ if ( deltaY === 0 ) { delta = deltaX * -1; }
6265
+ }
6266
+
6267
+ // No change actually happened, no reason to go any further
6268
+ if ( deltaY === 0 && deltaX === 0 ) { return; }
6269
+
6270
+ // Need to convert lines and pages to pixels if we aren't already in pixels
6271
+ // There are three delta modes:
6272
+ // * deltaMode 0 is by pixels, nothing to do
6273
+ // * deltaMode 1 is by lines
6274
+ // * deltaMode 2 is by pages
6275
+ if ( orgEvent.deltaMode === 1 ) {
6276
+ var lineHeight = $.data(this, 'mousewheel-line-height');
6277
+ delta *= lineHeight;
6278
+ deltaY *= lineHeight;
6279
+ deltaX *= lineHeight;
6280
+ } else if ( orgEvent.deltaMode === 2 ) {
6281
+ var pageHeight = $.data(this, 'mousewheel-page-height');
6282
+ delta *= pageHeight;
6283
+ deltaY *= pageHeight;
6284
+ deltaX *= pageHeight;
6285
+ }
6286
+
6287
+ // Store lowest absolute delta to normalize the delta values
6288
+ absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
6289
+
6290
+ if ( !lowestDelta || absDelta < lowestDelta ) {
6291
+ lowestDelta = absDelta;
6292
+
6293
+ // Adjust older deltas if necessary
6294
+ if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
6295
+ lowestDelta /= 40;
6296
+ }
6297
+ }
6298
+
6299
+ // Adjust older deltas if necessary
6300
+ if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
6301
+ // Divide all the things by 40!
6302
+ delta /= 40;
6303
+ deltaX /= 40;
6304
+ deltaY /= 40;
6305
+ }
6306
+
6307
+ // Get a whole, normalized value for the deltas
6308
+ delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta);
6309
+ deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
6310
+ deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
6311
+
6312
+ // Normalise offsetX and offsetY properties
6313
+ if ( special.settings.normalizeOffset && this.getBoundingClientRect ) {
6314
+ var boundingRect = this.getBoundingClientRect();
6315
+ offsetX = event.clientX - boundingRect.left;
6316
+ offsetY = event.clientY - boundingRect.top;
6317
+ }
6318
+
6319
+ // Add information to the event object
6320
+ event.deltaX = deltaX;
6321
+ event.deltaY = deltaY;
6322
+ event.deltaFactor = lowestDelta;
6323
+ event.offsetX = offsetX;
6324
+ event.offsetY = offsetY;
6325
+ // Go ahead and set deltaMode to 0 since we converted to pixels
6326
+ // Although this is a little odd since we overwrite the deltaX/Y
6327
+ // properties with normalized deltas.
6328
+ event.deltaMode = 0;
6329
+
6330
+ // Add event and delta to the front of the arguments
6331
+ args.unshift(event, delta, deltaX, deltaY);
6332
+
6333
+ // Clearout lowestDelta after sometime to better
6334
+ // handle multiple device types that give different
6335
+ // a different lowestDelta
6336
+ // Ex: trackpad = 3 and mouse wheel = 120
6337
+ if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
6338
+ nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
6339
+
6340
+ return ($.event.dispatch || $.event.handle).apply(this, args);
6341
+ }
6342
+
6343
+ function nullLowestDelta() {
6344
+ lowestDelta = null;
6345
+ }
6346
+
6347
+ function shouldAdjustOldDeltas(orgEvent, absDelta) {
6348
+ // If this is an older event and the delta is divisable by 120,
6349
+ // then we are assuming that the browser is treating this as an
6350
+ // older mouse wheel event and that we should divide the deltas
6351
+ // by 40 to try and get a more usable deltaFactor.
6352
+ // Side note, this actually impacts the reported scroll distance
6353
+ // in older browsers and can cause scrolling to be slower than native.
6354
+ // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
6355
+ return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
6356
+ }
6357
+
6358
+ }));
6359
+
6360
+ S2.define('jquery.select2',[
6361
+ 'jquery',
6362
+ 'jquery-mousewheel',
6363
+
6364
+ './select2/core',
6365
+ './select2/defaults'
6366
+ ], function ($, _, Select2, Defaults) {
6367
+ if ($.fn.select2 == null) {
6368
+ // All methods that should return the element
6369
+ var thisMethods = ['open', 'close', 'destroy'];
6370
+
6371
+ $.fn.select2 = function (options) {
6372
+ options = options || {};
6373
+
6374
+ if (typeof options === 'object') {
6375
+ this.each(function () {
6376
+ var instanceOptions = $.extend(true, {}, options);
6377
+
6378
+ var instance = new Select2($(this), instanceOptions);
6379
+ });
6380
+
6381
+ return this;
6382
+ } else if (typeof options === 'string') {
6383
+ var ret;
6384
+ var args = Array.prototype.slice.call(arguments, 1);
6385
+
6386
+ this.each(function () {
6387
+ var instance = $(this).data('select2');
6388
+
6389
+ if (instance == null && window.console && console.error) {
6390
+ console.error(
6391
+ 'The select2(\'' + options + '\') method was called on an ' +
6392
+ 'element that is not using Select2.'
6393
+ );
6394
+ }
6395
+
6396
+ ret = instance[options].apply(instance, args);
6397
+ });
6398
+
6399
+ // Check if we should be returning `this`
6400
+ if ($.inArray(options, thisMethods) > -1) {
6401
+ return this;
6402
+ }
6403
+
6404
+ return ret;
6405
+ } else {
6406
+ throw new Error('Invalid arguments for Select2: ' + options);
6407
+ }
6408
+ };
6409
+ }
6410
+
6411
+ if ($.fn.select2.defaults == null) {
6412
+ $.fn.select2.defaults = Defaults;
6413
+ }
6414
+
6415
+ return Select2;
6416
+ });
6417
+
6418
+ // Return the AMD loader configuration so it can be used outside of this file
6419
+ return {
6420
+ define: S2.define,
6421
+ require: S2.require
6422
+ };
6423
+ }());
6424
+
6425
+ // Autoload the jQuery bindings
6426
+ // We know that all of the modules exist above this, so we're safe
6427
+ var select2 = S2.require('jquery.select2');
6428
+
6429
+ // Hold the AMD module references on the jQuery function that was just loaded
6430
+ // This allows Select2 to use the internal loader outside of this file, such
6431
+ // as in the language files.
6432
+ jQuery.fn.select2.amd = S2;
6433
+
6434
+ // Return the Select2 instance for anyone who is importing it.
6435
+ return select2;
6436
+ }));
assets/js/settings-form.js CHANGED
@@ -271,6 +271,52 @@ jQuery( document ).ready( function( $ ) {
271
  } )
272
  } )
273
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
  } )
275
 
276
  function remove_custom_field( item ) {
@@ -278,153 +324,276 @@ function remove_custom_field( item ) {
278
  return false;
279
  }
280
 
281
- function create_fields( format , format_changed) {
282
- jQuery( '#export_job_settings' ).prepend( jQuery( "#fields_control_products" ) );
283
- jQuery( '#export_job_settings' ).prepend( jQuery( "#fields_control_coupons" ) );
284
- jQuery( "#order_fields" ).html();
285
- jQuery( "#modal_content" ).html( "" );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
286
 
287
  var html = '';
288
- jQuery.each( window['order_fields'], function( index, value ) {
289
- var checked = ( value.checked == 1 ) ? 'checked' : '';
290
- var colname = value.colname;
291
-
292
- colname = escapeStr(colname);
293
- value.label = escapeStr(value.label);
294
- index = escapeStr(index);
295
- value.value = escapeStr(value.value);
296
-
297
- // console.log(index);
298
- // console.log(value);
299
-
300
- if(format_changed) {
301
- if( is_flat_format( format ) )
302
- colname = value.label;
303
- else if ( is_xml_format( format ) )
304
- colname = to_xml_tags( index );
305
- else
306
- colname = index;;
307
- }
308
-
309
-
310
- if ( index == 'products' || index == 'coupons' ) {
311
- var sel_rows = ( value.repeat == 'rows' ) ? 'checked' : '';
312
- var sel_cols = ( value.repeat == 'columns' ) ? 'checked' : '';
313
- var max_cols = ( typeof(value.max_cols) !== 'undefined' ) ? value.max_cols : "10";
314
- var modal = '<div id="modal-manage-' + index + '" style="display:none;"><p>';
315
- modal += create_modal_fields( format, index, format_changed);
316
- modal += '</p></div>';
317
- jQuery( "#modal_content" ).append( modal );
318
- var row = '<li class="mapping_row segment_' + value.segment + '">\
319
- <div class="mapping_col_1">\
320
- <input type=hidden name="orders[segment][' + index + ']" value="' + value.segment + '">\
321
- <input type=hidden name="orders[label][' + index + ']" value="' + value.label + '">\
322
- <input type=hidden name="orders[exported][' + index + ']" value="0">\
323
- <input type=checkbox name="orders[exported][' + index + ']" ' + checked + ' value="1">\
324
- </div>\
325
- <div class="mapping_col_2">' + value.label + '</div>\
326
- <div class="mapping_col_3">';
327
- if ( is_flat_format( format ) ) {
328
-
329
- var popup_options = localize_settings_form.js_tpl_popup;
330
- popup_options = popup_options.replace('%s', '<input type=radio name="orders[repeat][' + index + ']" value="columns" ' + sel_cols + ' >')
331
- popup_options = popup_options.replace('%s', '<input type=text size=2 name="orders[max_cols][' + index + ']" value="'+max_cols+'">')
332
- popup_options = popup_options.replace('%s', '<input type=radio name="orders[repeat][' + index + ']" value="rows" ' + sel_rows + ' >')
333
- row += popup_options;
334
- }
335
- row += '<input class="mapping_fieldname" type=input name="orders[colname][' + index + ']" value="' + colname + '">\
336
- <input type="button" class="button-primary" id="btn_modal_manage_' + index + '" value="' + localize_settings_form.set_up_fields_to_export + '" /><a href="#TB_inline?width=600&height=550&inlineId=modal-manage-' + index + '" class="thickbox " id="link_modal_manage_' + index + '"> </a></div>\
337
- </li>\
338
- ';
339
- }
340
- else {
341
- var value_part = ''
342
- var label_part = '';
343
- if ( index.indexOf( 'custom_field' ) >= 0 ) {
344
- value_part = '<div class="mapping_col_3"><input class="mapping_fieldname" type=input name="orders[value][' + index + ']" value="' + value.value + '"></div>';
345
- label_part = '<a href="#" onclick="return remove_custom_field(this);" style="float: right;"><span class="ui-icon ui-icon-trash"></span></a>';
346
- }
347
- else if ( index.charAt( 0 ) == '_' || !value.default) {
348
- label_part = '<a href="#" onclick="return remove_custom_field(this);" style="float: right;"><span class="ui-icon ui-icon-trash"></span></a>';
349
- }
350
 
351
- var row = '<li class="mapping_row segment_' + value.segment + '">\
352
- <div class="mapping_col_1">\
353
- <input type=hidden name="orders[segment][' + index + ']" value="' + value.segment + '">\
354
- <input type=hidden name="orders[label][' + index + ']" value="' + value.label + '">\
355
- <input type=hidden name="orders[exported][' + index + ']" value="0">\
356
- <input type=checkbox name="orders[exported][' + index + ']" ' + checked + ' value="1">\
357
- </div>\
358
- <div class="mapping_col_2">' + value.label + label_part + '</div>\
359
- <div class="mapping_col_3"><input class="mapping_fieldname" type=input name="orders[colname][' + index + ']" value="' + colname + '"></div> ' + value_part + '\
360
- </li>\
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
361
  ';
362
- }
363
- html += row;
 
 
364
  } );
365
 
366
  jQuery( "#order_fields" ).html( html );
367
- jQuery( '#modal-manage-products' ).prepend( jQuery( "#fields_control_products" ) );
368
- jQuery( '#modal-manage-coupons' ).prepend( jQuery( "#fields_control_coupons" ) );
369
- jQuery( "#fields_control_products" ).css( 'display', 'inline-block' );
370
- jQuery( "#fields_control_coupons" ).css( 'display', 'inline-block' );
371
- add_bind_for_custom_fields( 'products', output_format, jQuery( "#sort_products" ) );
372
- add_bind_for_custom_fields( 'coupons', output_format, jQuery( "#sort_coupons" ) );
373
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
374
  }
375
 
 
376
 
 
377
 
378
- function create_modal_fields( format, index_p, format_changed ) {
379
- //console.log( 'order_' + index_p + '_fields', window['order_' + index_p + '_fields'] );
380
 
381
- var modal = "<div id='sort_" + index_p + "'>";
382
- jQuery.each( window['order_' + index_p + '_fields'], function( index, value ) {
383
- var checked = ( value.checked == 1 ) ? 'checked' : '';
384
- var colname = value.colname;
385
 
386
- // console.log(index);
387
- // console.log(value);
 
 
388
 
 
 
 
 
 
 
 
 
 
389
 
390
- colname = escapeStr(colname);
391
- value.label = escapeStr(value.label);
392
- index = escapeStr(index);
393
- value.value = escapeStr(value.value);
394
 
395
- if(format_changed) {
396
- if( is_flat_format( format ) )
397
- colname = value.label;
398
- else if ( is_xml_format( format ) )
399
- colname = to_xml_tags( index );
400
- else
401
- colname = index;;
402
- }
403
 
404
- var value_part = ''
405
- var label_part = '';
406
- if ( index.indexOf( 'custom_field' ) >= 0 ) {
407
- value_part = '<div class="mapping_col_3"><input class="mapping_fieldname" type=input name="' + index_p + '[value][' + index + ']" value="' + value.value + '"></div>';
408
- label_part = '<a href="#" onclick="return remove_custom_field(this);" style="float: right;"><span class="ui-icon ui-icon-trash"></span></a>';
409
- }
410
- else if ( index.charAt( 0 ) == '_' || index.substr( 0,3 ) == 'pa_' || !value.default) {
411
- label_part = '<a href="#" onclick="return remove_custom_field(this);" style="float: right;"><span class="ui-icon ui-icon-trash"></span></a>';
412
- }
 
 
413
 
414
- var row = '<li class="mapping_row segment_modal_' + index + '">\
415
- <div class="mapping_col_1">\
416
- <input type=hidden name="' + index_p + '[label][' + index + ']" value="' + value.label + '">\
417
- <input type=hidden name="' + index_p + '[exported][' + index + ']" value="0">\
418
- <input type=checkbox name="' + index_p + '[exported][' + index + ']" ' + checked + ' value="1">\
419
- </div>\
420
- <div class="mapping_col_2">' + value.label + label_part + '</div>\
421
- <div class="mapping_col_3"><input class="mapping_fieldname" type=input name="' + index_p + '[colname][' + index + ']" value="' + colname + '"></div>' + value_part + '\
422
- </li>\
423
- ';
424
- modal += row;
425
- } );
426
- modal += "</div>";
427
- return modal;
428
  }
429
 
430
  //for XML labels
@@ -458,30 +627,15 @@ function show_summary_report(ext) {
458
  } else {
459
  jQuery( '#summary_report_by_products' ).hide();
460
  jQuery( '#summary_setup_fields' ).hide();
461
- jQuery( '#summary_report_by_products_checkbox' ).prop('checked', false);
462
  }
463
  }
464
 
465
  function modal_buttons()
466
  {
467
- jQuery('body').on('click', '#btn_modal_manage_products', function() {
468
-
469
- jQuery('input[name=custom_meta_products_mode]').change();
470
- jQuery('#link_modal_manage_products').click();
471
-
472
- return false;
473
- });
474
-
475
- jQuery('body').on('click', '#btn_modal_manage_coupons', function() {
476
-
477
- jQuery('#custom_meta_coupons_mode_all').attr('checked', 'checked');
478
- jQuery('#custom_meta_coupons_mode_all').change();
479
- jQuery('#custom_meta_coupons_mode_all').change();
480
- jQuery('#link_modal_manage_coupons').click();
481
-
482
- return false;
483
- });
484
-
485
  }
486
 
487
  jQuery( document ).ready( function( $ ) {
@@ -511,13 +665,20 @@ jQuery( document ).ready( function( $ ) {
511
  // jQuery( '#' + output_format + '_options' ).show();
512
 
513
  //jQuery('#fields').toggle(); //debug
514
- create_fields( output_format, false );
515
  $( '#test_reply_div' ).hide();
516
  // jQuery( '#' + output_format + '_options' ).hide();
517
 
518
  jQuery( "#sort_products" ).sortable()/*.disableSelection()*/;
519
  jQuery( "#sort_coupons" ).sortable()/*.disableSelection()*/;
520
- jQuery( "#order_fields" ).sortable({ scroll: true, scrollSensitivity: 100, scrollSpeed: 100 });/*.disableSelection()*/;
 
 
 
 
 
 
 
521
 
522
 
523
  modal_buttons();
@@ -559,8 +720,11 @@ jQuery( document ).ready( function( $ ) {
559
  jQuery( this ).next().addClass( 'ui-icon-triangle-1-n' );
560
  jQuery( '#' + output_format + '_options' ).hide();
561
  jQuery( '#' + new_format + '_options' ).show();
 
562
  output_format = new_format;
563
- create_fields( output_format, true )
 
 
564
  jQuery( '#output_preview, #output_preview_csv' ).hide();
565
  // jQuery( '#fields' ).hide();
566
  // jQuery( '#fields_control' ).hide();
@@ -579,6 +743,7 @@ jQuery( document ).ready( function( $ ) {
579
  }
580
  }
581
 
 
582
  } );
583
 
584
  $( '#date_format_block select' ).change( function() {
@@ -842,7 +1007,7 @@ jQuery( document ).ready( function( $ ) {
842
  return false;
843
  }
844
  }
845
- if ( $( '#order_fields input[type=checkbox]:checked' ).size() == 0 )
846
  {
847
  alert( export_messages.no_fields );
848
  return false;
@@ -873,7 +1038,7 @@ jQuery( document ).ready( function( $ ) {
873
  }
874
  }
875
 
876
- if ( $( '#order_fields input[type=checkbox]:checked' ).size() == 0 )
877
  {
878
  alert( export_messages.no_fields );
879
  return false;
@@ -910,23 +1075,26 @@ jQuery( document ).ready( function( $ ) {
910
  return false;
911
  }
912
  setFormSubmitting();
913
-
914
  var data = 'json=' + makeJsonVar( $( '#export_job_settings' ) )
915
  data = data + "&action=order_exporter&method=save_settings&mode=" + mode + "&id=" + job_id;
916
  $.post( ajaxurl, data, function( response ) {
917
- // if ( mode == '<?php echo WC_Order_Export_Manage::EXPORT_SCHEDULE; ?>' ) {
918
- // document.location = '<?php echo admin_url( 'admin.php?page=wc-order-export&tab=schedules&save=y' ) ?>';
919
- // } else if ( mode == '<?php echo WC_Order_Export_Manage::EXPORT_PROFILE; ?>' ) {
920
- // document.location = '<?php echo admin_url( 'admin.php?page=wc-order-export&tab=profiles&save=y' ) ?>';
921
- // } else if ( mode == '<?php echo WC_Order_Export_Manage::EXPORT_ORDER_ACTION; ?>' ) {
922
- // document.location = '<?php echo admin_url( 'admin.php?page=wc-order-export&tab=order_actions&save=y' ) ?>';
923
- // } else {
924
- // document.location = '<?php echo admin_url( 'admin.php?page=wc-order-export&tab=export&save=y' ) ?>';
925
- // }
926
  document.location = settings_form.save_settings_url;
927
  }, "json" );
928
  return false;
929
  } );
 
 
 
 
 
 
 
 
 
 
 
 
 
930
  $( "#copy-to-profiles" ).click( function() {
931
  if (!validateExport()) {
932
  return false;
@@ -964,16 +1132,131 @@ jQuery( document ).ready( function( $ ) {
964
  show_summary_report( output_format );
965
  if( !summary_mode )
966
  jQuery('#summary_setup_fields').hide();
 
967
  //logic for setup link
968
  jQuery( "#summary_report_by_products_checkbox" ).change( function() {
969
- if( jQuery(this).prop('checked') )
970
- jQuery('#summary_setup_fields').show();
971
- else
972
- jQuery('#summary_setup_fields').hide();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
973
  });
974
 
 
 
 
 
975
  // this line must be last , we don't have any errors
976
  jQuery('#JS_error_onload').hide();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
977
  } );
978
 
979
  function is_flat_format(format) {
@@ -991,4 +1274,370 @@ function reset_date_filter_for_cron() {
991
  jQuery( "#to_date" ).val("");
992
  try_color_date_filter();
993
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
994
  }
271
  } )
272
  } )
273
 
274
+
275
+
276
+ $( '.segment_choice' ).click( function () {
277
+
278
+ $('.segment_choice').removeClass('active');
279
+ $(this).addClass('active');
280
+
281
+ $('.settings-segment').removeClass('active');
282
+ $( '#' + $( this ).data( 'segment' ) + '_unselected_segment' ).addClass('active');
283
+
284
+ window.location.href = $(this).attr('href');
285
+
286
+ jQuery('.tab-actions-forms .segment-form').removeClass('active').find('input,select').val('');
287
+ } );
288
+
289
+ setTimeout( function () {
290
+ if (window.location.hash.indexOf('segment') !== -1) {
291
+ $('.segment_choice[href="'+ window.location.hash +'"]').click()
292
+ } else {
293
+ $('.segment_choice').first().click()
294
+ }
295
+ }, 1000 );
296
+
297
+
298
+ let text_area = $( '#destination-email-body' );
299
+
300
+ $( '#show-email-body' ).click( function () {
301
+ text_area.toggle();
302
+ } );
303
+
304
+ setTimeout( function ( ) {
305
+ if ( ! $( '#destination-email-body textarea' ).val() ) {
306
+ text_area.hide();
307
+ }
308
+ }, 0);
309
+
310
+
311
+ $( '#clear_selected_fields' ).click( function () {
312
+ var confirm = window.confirm(localize_settings_form.remove_all_fields_confirm);
313
+ if ( confirm ) {
314
+ if ( $( '#order_fields .mapping_row-delete_field' ).length > 0 ) {
315
+ $( '#order_fields .mapping_row-delete_field' ).click();
316
+ }
317
+ }
318
+ } );
319
+
320
  } )
321
 
322
  function remove_custom_field( item ) {
324
  return false;
325
  }
326
 
327
+ function make_repeat_options( index ) {
328
+ var repeat_select = jQuery( '<select name="duplicated_fields_settings[' + index + '][repeat]"></select>' );
329
+ var repeat_options_html = {};
330
+
331
+ jQuery.each(localize_settings_form.repeats, function(key, currentValue) {
332
+ repeat_select.append( '<option value="' + key + '">' + currentValue + '</option>' );
333
+ repeat_options_html[key] = [];
334
+ });
335
+
336
+ var duplicate_settings = window.duplicated_fields_settings[index] || {};
337
+ repeat_select.val(duplicate_settings.repeat);
338
+
339
+ // rows options
340
+ if ( index === 'products' ) {
341
+ var populate_check_on = duplicate_settings.populate_other_columns === '1' ? 'checked' : '';
342
+ var populate_check_off = duplicate_settings.populate_other_columns === '1' ? '' : 'checked';
343
+ var populate_check_html = '<div class="">' +
344
+ '<label>' + localize_settings_form.js_tpl_popup.fill_order_columns_label + '</label>' +
345
+ '<label>' +
346
+ '<input type=radio name="duplicated_fields_settings[' + index + '][populate_other_columns]" value=1 ' + populate_check_on + ' >' +
347
+ localize_settings_form.js_tpl_popup.for_all_rows_label + '</label>' +
348
+ '<label>' +
349
+ '<input type=radio name="duplicated_fields_settings[' + index + '][populate_other_columns]" value=0 ' + populate_check_off + ' >' +
350
+ localize_settings_form.js_tpl_popup.for_first_row_only_label + '</label>' +
351
+ '</div>';
352
+ repeat_options_html['rows'].push(populate_check_html);
353
+ }
354
+
355
+ // columns options
356
+ var max_cols = ( typeof(duplicate_settings.max_cols) !== 'undefined' ) ? duplicate_settings.max_cols : "10";
357
+
358
+ var max_cols_html = '<div class="">' +
359
+ '<label>' + localize_settings_form.js_tpl_popup.add + '</label>' +
360
+ '<input type=text size=2 name="duplicated_fields_settings['+ index +'][max_cols]" value="'+ max_cols +'"> ' +
361
+ '<label>' + localize_settings_form.repeats.columns + '</label>' +
362
+ '</div>';
363
+
364
+ var grouping_by_product_check = duplicate_settings.group_by === 'product' ? 'checked' : '';
365
+ var group_by_item_check_html = '<div class="">' +
366
+ '<input type="hidden" name="duplicated_fields_settings[' + index + '][group_by]" value="as_independent_columns" >' +
367
+ '<input type="checkbox" name="duplicated_fields_settings[' + index + '][group_by]" value="product" ' + grouping_by_product_check +'>' +
368
+ '<label>' + localize_settings_form.js_tpl_popup.grouping_by[index] +'</label>' +
369
+ '</div>';
370
+ repeat_options_html['columns'].push(max_cols_html);
371
+ repeat_options_html['columns'].push(group_by_item_check_html);
372
+
373
+ // inside one cell options
374
+ var line_delimiter = ( typeof(duplicate_settings.line_delimiter) !== 'undefined' ) ? duplicate_settings.line_delimiter : '\\n';
375
+ var line_delimiter_html = '<div class="">' +
376
+ '<label>' + localize_settings_form.js_tpl_popup.split_values_by +
377
+ '<input class="input-delimiter" type=text size=1 name="duplicated_fields_settings['+ index +'][line_delimiter]" value="'+ line_delimiter +'">' +
378
+ '</label>' +
379
+ '</div>';
380
+ repeat_options_html['inside_one_cell'].push(line_delimiter_html);
381
+
382
+ var popup_options = jQuery('<div class=""></div>');
383
+ popup_options.append(jQuery('<div class="segment-header">' + '<label>' + localize_settings_form.js_tpl_popup.add + ' ' + index + ' ' + localize_settings_form.js_tpl_popup.as + '</label>' + '</div>').append(repeat_select) );
384
+
385
+ jQuery.each(repeat_options_html, function(key, currentValue) {
386
+ popup_options.append(jQuery('<div class="display_as duplicate_' + key + '_options"></div>').append(currentValue));
387
+ });
388
+
389
+ popup_options.append("<hr>");
390
+
391
+ repeat_select.off('change').on('change', function(){
392
+ jQuery(this).parent().siblings('.display_as').removeClass('active');
393
+ jQuery(this).parent().siblings('.duplicate_' + this.value + '_options').addClass('active');
394
+ }).trigger('change');
395
+
396
+ return popup_options;
397
+ }
398
+
399
+ function create_selected_fields( old_output_format, format , format_changed) {
400
+
401
+ var $old_format_order_fields = jQuery( "#order_fields" ).clone();
402
+
403
+ setTimeout(function () {
404
+ create_unselected_fields( old_output_format, format , format_changed, $old_format_order_fields );
405
+ }, 0);
406
+
407
+ //jQuery( '#export_job_settings' ).prepend( jQuery( "#fields_control_products" ) );
408
+ //jQuery( '#export_job_settings' ).prepend( jQuery( "#fields_control_coupons" ) );
409
+
410
+ jQuery( "#fields .fields-control-block").addClass('hidden');
411
+ jQuery( "#order_fields").addClass('non_flat_height');
412
+
413
+ /*
414
+ Clone elements for using in create_modal_fields ($old_format_order_fields) and
415
+ before insert fields in 'order_fields' element ($old_format_modal_content) for
416
+ able to migrate checkbox values from pop up to 'order_fields' element and vice versa
417
+ */
418
 
419
  var html = '';
420
+ var fields_control_block_elements = [];
421
+
422
+ if ( is_flat_format( format ) ) {
423
+ fields_control_block_elements.push( make_repeat_options( 'products' ) );
424
+ fields_control_block_elements.push( make_repeat_options( 'coupons' ) );
425
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
426
 
427
+ jQuery.each( window['selected_order_fields'], function( i, value ) {
428
+
429
+ var index = value.key;
430
+ var colname = value.colname;
431
+
432
+ colname = escapeStr(colname);
433
+ value.label = escapeStr(value.label);
434
+ index = escapeStr(index);
435
+ value.value = escapeStr(value.value);
436
+
437
+ if(format_changed) {
438
+ if( is_flat_format( format ) )
439
+ colname = value.label;
440
+ else if ( is_xml_format( format ) )
441
+ colname = to_xml_tags( index );
442
+ else
443
+ colname = index;
444
+ }
445
+
446
+ if ( index == 'products' || index == 'coupons' ) {
447
+
448
+ var row = '';
449
+
450
+ jQuery( "#fields_control .segment_" + index ).remove();
451
+
452
+ if( ! is_flat_format( format ) ) {
453
+ // TODO fix segment names for product and coupon fields
454
+ row = '<li class="mapping_row segment_' + value.segment + 's' + ' flat-'+ index +'-group" style="display: none">\
455
+ <div class="mapping_col_1" style="width: 10px">\
456
+ <input type=hidden name="orders[][segment]" value="' + value.segment + '">\
457
+ <input type=hidden name="orders[][key]" value="' + index + '">\
458
+ <input type=hidden name="orders[][label]" value="' + value.label + '">\
459
+ <input type=hidden name="orders[][format]" value="'+ value.format +'">\
460
+ </div>\
461
+ <div class="mapping_col_2">' + value.label + '</div>\
462
+ <div class="mapping_col_3">';
463
+ row += '<div class="segment_' + index + '">';
464
+ row += '<input class="mapping_fieldname" type=input name="orders[][colname]" value="' + colname + '">';
465
+ row += '</div>';
466
+ row += '</div>';
467
+ row += '<ul id="sortable_'+ index +'">'+ create_group_fields( format, index, format_changed, old_output_format, $old_format_order_fields) +'</ul>';
468
+ row += '</li>';
469
+ } else {
470
+ row = '<div class="hide flat-'+ index +'-group">';
471
+ row += '<input type=hidden name="orders[][segment]" value="' + value.segment + '">';
472
+ row += '<input type=hidden name="orders[][key]" value="' + index + '">';
473
+ row += '<input class="mapping_fieldname" type=hidden name="orders[][colname]" value="' + colname + '">';
474
+ row += '<input type=hidden name="orders[][label]" value="' + value.label + '">';
475
+ row += '<input type=hidden name="orders[][format]" value="'+ value.format +'"></div>';
476
+
477
+ }
478
+
479
+ }
480
+ else {
481
+
482
+ if ( ! is_flat_format( format ) && ( value.segment === "products" || value.segment === "coupons" ) ) {
483
+ return true;
484
+ }
485
+
486
+ var value_part = ''
487
+ var label_part = '';
488
+ var delete_btn = '<div class="mapping_col_3 mapping_row-delete_field_block"><a href="" class="mapping_row-delete_field"><span class="dashicons dashicons-trash"></span></a></div>';
489
+ var label_prefix = '';
490
+ var index_api = index;
491
+
492
+ if ( index.indexOf( 'static_field' ) >= 0 ) {
493
+ value_part = '<div class="mapping_col_3"><input class="mapping_fieldname" type=input name="orders[][value]" value="' + value.value + '"></div>';
494
+ }
495
+
496
+ // label prefix for products and coupons
497
+ if ( is_flat_format(format) ) {
498
+ if ( value.segment === 'products' ) {
499
+ label_prefix = '[P] ';
500
+ index_api = index_api.replace("plain_products_", "");
501
+ }
502
+ if ( value.segment === 'coupons' ) {
503
+ label_prefix = '[C] ';
504
+ index_api = index_api.replace("plain_coupons_", "");
505
+ }
506
+ }
507
+ var row = '<li class="mapping_row segment_' + value.segment + '">\
508
+ <div class="mapping_col_1" style="width: 10px">\
509
+ <input type=hidden name="orders[][segment]" value="' + value.segment + '">\
510
+ <input type=hidden name="orders[][key]" value="' + index + '">\
511
+ <input type=hidden name="orders[][label]" value="' + value.label + '">\
512
+ <input type=hidden name="orders[][format]" value="' + value.format + '">\
513
+ </div>\
514
+ <div class="mapping_col_2" title="'+index_api+'">' + '<span class="field-prefix">' + label_prefix + '</span>' + value.label + label_part + '</div>\
515
+ <div class="mapping_col_3"><input class="mapping_fieldname" type=input name="orders[][colname]" value="' + colname + '"></div> ' + value_part + delete_btn + '\
516
+ </li>\
517
  ';
518
+ }
519
+
520
+ html += row;
521
+
522
  } );
523
 
524
  jQuery( "#order_fields" ).html( html );
 
 
 
 
 
 
525
 
526
+ if ( ! jQuery( "#fields .fields-control-block").html() ) {
527
+ fields_control_block_elements.forEach(function(currentValue){
528
+ jQuery( "#fields .fields-control-block").append(currentValue);
529
+ });
530
+ }
531
+
532
+ if ( fields_control_block_elements.length > 0 ) {
533
+ jQuery( "#fields .fields-control-block").removeClass('hidden');
534
+ jQuery( "#order_fields").removeClass('non_flat_height');
535
+ }
536
+
537
+ add_bind_for_custom_fields( 'products', output_format, jQuery( "#order_fields" ) );
538
+ add_bind_for_custom_fields( 'coupons', output_format, jQuery( "#order_fields" ) );
539
+
540
+ jQuery( "#sortable_products" ).sortable();
541
+ jQuery( "#sortable_coupons" ).sortable();
542
+
543
+ check_sortable_groups();
544
+
545
+ moving_products_and_coupons_group_blocks_to_first_item(output_format);
546
  }
547
 
548
+ function create_group_fields( format, index_p, format_changed ) {
549
 
550
+ var html = '';
551
 
552
+ jQuery.each( window['selected_order_' + index_p + '_fields'], function( i, value ) {
 
553
 
554
+ var index = value.key;
555
+ var colname = value.colname;
 
 
556
 
557
+ colname = escapeStr(colname);
558
+ value.label = escapeStr(value.label);
559
+ index = escapeStr(index);
560
+ value.value = escapeStr(value.value);
561
 
562
+ if(format_changed) {
563
+ if( is_flat_format( format ) ) {
564
+ colname = value.label;
565
+ } else {
566
+ colname = index.replace('plain_' + index_p + '_', '');
567
+ if ( is_xml_format( format ) )
568
+ colname = to_xml_tags( colname );
569
+ }
570
+ }
571
 
572
+ var value_part = '';
573
+ var label_part = '';
574
+ var delete_btn = '<div class="mapping_col_3 mapping_row-delete_field_block"><a href="#" class="mapping_row-delete_field"><span class="dashicons dashicons-trash"></span></a></div>';
 
575
 
576
+ if ( index.indexOf( 'static_field' ) >= 0 ) {
577
+ value_part = '<div class="mapping_col_3"><input class="mapping_fieldname" type=input name="' + index_p + '[][value]" value="' + value.value + '"></div>';
578
+ }
 
 
 
 
 
579
 
580
+ var row = '<li class="mapping_row segment_' + index_p + '">\
581
+ <div class="mapping_col_1" style="width: 10px">\
582
+ <input type=hidden name="'+ index_p +'[][label]" value="' + value.label + '">\
583
+ <input type=hidden name="'+ index_p +'[][key]" value="' + index + '">\
584
+ <input type=hidden name="'+ index_p +'[][segment]" value="' + index_p + '">\
585
+ <input type=hidden name="'+ index_p +'[][format]" value="' + value.format + '">\
586
+ </div>\
587
+ <div class="mapping_col_2" title="'+index+'">' + value.label + label_part + '</div>\
588
+ <div class="mapping_col_3"><input class="mapping_fieldname" type=input name="'+ index_p +'[][colname]" value="' + colname + '"></div> ' + value_part + delete_btn + '\
589
+ </li>\
590
+ ';
591
 
592
+ html += row;
593
+
594
+ } );
595
+
596
+ return html;
 
 
 
 
 
 
 
 
 
597
  }
598
 
599
  //for XML labels
627
  } else {
628
  jQuery( '#summary_report_by_products' ).hide();
629
  jQuery( '#summary_setup_fields' ).hide();
630
+ jQuery( '#summary_report_by_products_checkbox' ).prop('checked', false).trigger('change');
631
  }
632
  }
633
 
634
  function modal_buttons()
635
  {
636
+ jQuery('input[name=custom_meta_products_mode]').change();
637
+ jQuery('#custom_meta_coupons_mode_all').attr('checked', 'checked');
638
+ jQuery('#custom_meta_coupons_mode_all').change();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
639
  }
640
 
641
  jQuery( document ).ready( function( $ ) {
665
  // jQuery( '#' + output_format + '_options' ).show();
666
 
667
  //jQuery('#fields').toggle(); //debug
668
+ create_selected_fields( null, output_format, false );
669
  $( '#test_reply_div' ).hide();
670
  // jQuery( '#' + output_format + '_options' ).hide();
671
 
672
  jQuery( "#sort_products" ).sortable()/*.disableSelection()*/;
673
  jQuery( "#sort_coupons" ).sortable()/*.disableSelection()*/;
674
+ jQuery( "#order_fields" ).sortable({
675
+ scroll: true,
676
+ scrollSensitivity: 100,
677
+ scrollSpeed: 100,
678
+ stop: function ( event, ui ) {
679
+ moving_products_and_coupons_group_blocks_to_first_item(jQuery( '.output_format:checked' ).val());
680
+ }
681
+ });
682
 
683
 
684
  modal_buttons();
720
  jQuery( this ).next().addClass( 'ui-icon-triangle-1-n' );
721
  jQuery( '#' + output_format + '_options' ).hide();
722
  jQuery( '#' + new_format + '_options' ).show();
723
+ old_output_format = output_format;
724
  output_format = new_format;
725
+ synch_selected_fields(old_output_format, output_format);
726
+ create_selected_fields( old_output_format, output_format, true );
727
+ jQuery( '.field_section' ).prop('checked', true);
728
  jQuery( '#output_preview, #output_preview_csv' ).hide();
729
  // jQuery( '#fields' ).hide();
730
  // jQuery( '#fields_control' ).hide();
743
  }
744
  }
745
 
746
+ check_sortable_groups();
747
  } );
748
 
749
  $( '#date_format_block select' ).change( function() {
1007
  return false;
1008
  }
1009
  }
1010
+ if ( $( '#order_fields > li' ).size() == 0 )
1011
  {
1012
  alert( export_messages.no_fields );
1013
  return false;
1038
  }
1039
  }
1040
 
1041
+ if ( $( '#order_fields > li' ).size() == 0 )
1042
  {
1043
  alert( export_messages.no_fields );
1044
  return false;
1075
  return false;
1076
  }
1077
  setFormSubmitting();
 
1078
  var data = 'json=' + makeJsonVar( $( '#export_job_settings' ) )
1079
  data = data + "&action=order_exporter&method=save_settings&mode=" + mode + "&id=" + job_id;
1080
  $.post( ajaxurl, data, function( response ) {
 
 
 
 
 
 
 
 
 
1081
  document.location = settings_form.save_settings_url;
1082
  }, "json" );
1083
  return false;
1084
  } );
1085
+ $( "#save-only-btn" ).click( function() {
1086
+ if (!validateExport()) {
1087
+ return false;
1088
+ }
1089
+ setFormSubmitting();
1090
+ var data = 'json=' + makeJsonVar( $( '#export_job_settings' ) )
1091
+ data = data + "&action=order_exporter&method=save_settings&mode=" + mode + "&id=" + job_id;
1092
+ $('#Settings_updated').hide();
1093
+ $.post( ajaxurl, data, function( response ) {
1094
+ $('#Settings_updated').show().delay(5000).fadeOut();
1095
+ }, "json" );
1096
+ return false;
1097
+ } );
1098
  $( "#copy-to-profiles" ).click( function() {
1099
  if (!validateExport()) {
1100
  return false;
1132
  show_summary_report( output_format );
1133
  if( !summary_mode )
1134
  jQuery('#summary_setup_fields').hide();
1135
+
1136
  //logic for setup link
1137
  jQuery( "#summary_report_by_products_checkbox" ).change( function() {
1138
+ var summary_report_fields = [];
1139
+ summary_report_fields.push($('#products_unselected_segment input[value="plain_products_summary_report_total_qty"]').parents('li'));
1140
+ summary_report_fields.push($('#products_unselected_segment input[value="plain_products_summary_report_total_amount"]').parents('li'));
1141
+
1142
+ jQuery('#manage_fields').toggleClass('summary-products-report', !!jQuery(this).prop('checked'));
1143
+
1144
+ $('#unselected_fields .segment_choice').removeClass('active');
1145
+ $('#unselected_fields_list .settings-segment').removeClass('active');
1146
+
1147
+ if (jQuery(this).prop('checked')) {
1148
+ var segment = 'products';
1149
+
1150
+ // hide product fields starts with 'line' and 'qty'
1151
+ $( '#products_unselected_segment input, #order_fields input' ).map( function () {
1152
+ var matches = $( this ).attr( 'value' ).match( /plain_products_(line|qty).*/ );
1153
+ if ( matches ) {
1154
+ $( this ).closest( '.mapping_row' ).hide();
1155
+ }
1156
+ } );
1157
+
1158
+ // purge summary report fields before insert
1159
+ $('#order_fields input[value="plain_products_summary_report_total_qty"]').closest('.mapping_row').remove();
1160
+ $('#order_fields input[value="plain_products_summary_report_total_amount"]').closest('.mapping_row').remove();
1161
+
1162
+ // insert summary report fields
1163
+ jQuery.each( summary_report_fields, function( i, value ) {
1164
+ $(value).show();
1165
+ var $field_to_copy = $(value).clone();
1166
+ $field_to_copy
1167
+ .attr('style', '')
1168
+ .addClass('ui-draggabled')
1169
+ .removeClass('segment_field')
1170
+ .find('input').prop('disabled', false);
1171
+
1172
+ jQuery('#manage_fields #order_fields').append($field_to_copy);
1173
+ } );
1174
+
1175
+ } else {
1176
+ var segment = window.location.hash.replace('#segment=', '');
1177
+
1178
+ // show product fields starts with 'line' and 'qty'
1179
+ $( '#products_unselected_segment input, #order_fields input' ).map( function () {
1180
+ var matches = $( this ).attr( 'value' ).match( /plain_products_(line|qty).*/ );
1181
+ if ( matches ) {
1182
+ $( this ).closest( '.mapping_row' ).show();
1183
+ }
1184
+ } );
1185
+
1186
+ // purge summary report fields
1187
+ $('#order_fields input[value="plain_products_summary_report_total_qty"]').closest('.mapping_row').remove();
1188
+ $('#order_fields input[value="plain_products_summary_report_total_amount"]').closest('.mapping_row').remove();
1189
+
1190
+ jQuery.each( summary_report_fields, function( i, value ) {
1191
+ $(value).hide();
1192
+ } );
1193
+ }
1194
+
1195
+ $('#unselected_fields .segment_choice[data-segment="'+ segment +'"]').addClass('active');
1196
+ $('#unselected_fields_list .settings-segment#'+ segment +'_unselected_segment').addClass('active');
1197
+
1198
  });
1199
 
1200
+ setTimeout(function () {
1201
+ jQuery( "#summary_report_by_products_checkbox" ).trigger('change');
1202
+ }, 1)
1203
+
1204
  // this line must be last , we don't have any errors
1205
  jQuery('#JS_error_onload').hide();
1206
+
1207
+ jQuery('#order_fields').on('click', '.mapping_row-delete_field', function () {
1208
+
1209
+ $(this).closest('.mapping_row').remove();
1210
+
1211
+ check_sortable_groups();
1212
+
1213
+ return false;
1214
+ });
1215
+
1216
+ jQuery('.tab-controls .tab-actions-buttons .add-meta').on('click', function () {
1217
+
1218
+ jQuery('.tab-actions-forms .segment-form').removeClass('active');
1219
+
1220
+ if (jQuery('.tab-actions-forms .div_meta.segment-form.' +
1221
+ jQuery('#unselected_fields .segment_choice.active').attr('data-segment') + '-segment'
1222
+ ).length) {
1223
+ jQuery('.tab-actions-forms .div_meta.segment-form.' +
1224
+ jQuery('#unselected_fields .segment_choice.active').attr('data-segment') + '-segment'
1225
+ ).addClass('active');
1226
+ } else {
1227
+ jQuery('.tab-actions-forms .div_meta.segment-form.all-segments').addClass('active');
1228
+ }
1229
+
1230
+ return false;
1231
+ });
1232
+
1233
+ jQuery('.tab-controls .tab-actions-buttons .add-custom').on('click', function () {
1234
+
1235
+ jQuery('.tab-actions-forms .segment-form').removeClass('active');
1236
+
1237
+ if (jQuery('.tab-actions-forms .div_custom.segment-form.' +
1238
+ jQuery('#unselected_fields .segment_choice.active').attr('data-segment') + '-segment'
1239
+ ).length) {
1240
+ jQuery('.tab-actions-forms .div_custom.segment-form.' +
1241
+ jQuery('#unselected_fields .segment_choice.active').attr('data-segment') + '-segment'
1242
+ ).addClass('active');
1243
+ } else {
1244
+ jQuery('.tab-actions-forms .div_custom.segment-form.all-segments').addClass('active');
1245
+ }
1246
+
1247
+ return false;
1248
+ });
1249
+
1250
+ jQuery('.tab-controls .button-cancel').on('click', function () {
1251
+
1252
+ jQuery(this).closest('.segment-form')
1253
+ .removeClass('active')
1254
+ .find('input,select').val('');
1255
+
1256
+ return false;
1257
+ });
1258
+
1259
+
1260
  } );
1261
 
1262
  function is_flat_format(format) {
1274
  jQuery( "#to_date" ).val("");
1275
  try_color_date_filter();
1276
  }
1277
+ }
1278
+
1279
+ function create_unselected_fields( old_output_format, format , format_changed, old_format_order_fields ) {
1280
+
1281
+ var $unselected_fields_list = jQuery('#unselected_fields_list');
1282
+
1283
+ var $unselected_segment_id = '%s_unselected_segment';
1284
+
1285
+ var active_segment_id = $unselected_fields_list.find('.section.active').attr('id');
1286
+
1287
+ $unselected_fields_list.html("");
1288
+ $unselected_fields_list.append( make_segments( $unselected_segment_id ) );
1289
+
1290
+ if (active_segment_id) {
1291
+ jQuery('#unselected_fields_list #' + active_segment_id).addClass('active');
1292
+ }
1293
+
1294
+ jQuery.each( window['all_fields'], function( segment, fields ) {
1295
+
1296
+ fields.forEach(function (value) {
1297
+
1298
+ var $unselected_field_segment = jQuery( '#' + sprintf( $unselected_segment_id, segment ) );
1299
+ var index = value.key;
1300
+
1301
+ $unselected_field_segment.append(
1302
+ make_unselected_field( index, value, format, format_changed, segment )
1303
+ );
1304
+
1305
+ activate_draggable_field(
1306
+ $unselected_field_segment.find('.segment_field'),
1307
+ segment,
1308
+ format
1309
+ );
1310
+ })
1311
+
1312
+ });
1313
+ }
1314
+
1315
+ function make_segments($segment_id) {
1316
+
1317
+ var $segments_list = jQuery('<ul></ul>');
1318
+
1319
+ jQuery.each( window['order_segments'], function( index, label ) {
1320
+ var $segment = jQuery('<div id="' + sprintf($segment_id, index) + '" class="section settings-segment"></div>')
1321
+ $segments_list.append($segment);
1322
+ });
1323
+
1324
+ return $segments_list;
1325
+ }
1326
+
1327
+ function sprintf( format ) {
1328
+ for ( var i = 1; i < arguments.length; i ++ ) {
1329
+ format = format.replace( /%s/, arguments[i] );
1330
+ }
1331
+ return format;
1332
+ }
1333
+
1334
+ function make_unselected_field($index, $field_data, $format, $format_changed, $segment ) {
1335
+
1336
+ var label_part = '';
1337
+ var label_prefix = '';
1338
+ var value_part = '';
1339
+
1340
+ var $mapping_col_1 = jQuery('<div class="mapping_col_1" style="width: 10px"></div>');
1341
+
1342
+ var $mapping_col_2 = jQuery('<div class="mapping_col_2" title="'+escapeStr($index)+'"></div>');
1343
+ var $mapping_col_3 = jQuery('<div class="mapping_col_3"></div>');
1344
+
1345
+ var colname = escapeStr($field_data.colname);
1346
+
1347
+ var _index = $index;
1348
+
1349
+ if ( is_flat_format($format) && ['products', 'coupons'].indexOf($segment) > -1 ) {
1350
+ _index = 'plain_' + $segment + '_' + $index;
1351
+ }
1352
+
1353
+ if($format_changed) {
1354
+ if( is_flat_format( $format ) )
1355
+ colname = $field_data.label;
1356
+ else {
1357
+
1358
+ colname = $index;
1359
+
1360
+ if ( is_xml_format( $format ) )
1361
+ colname = to_xml_tags( colname );
1362
+ }
1363
+ }
1364
+
1365
+ if ( ! is_flat_format($format) && ['products', 'coupons'].indexOf($segment) > -1 ) {
1366
+
1367
+ $mapping_col_1
1368
+ .append( make_input( 'hidden', null, $segment + '[][label]' , $field_data.label, false ) )
1369
+ .append( make_input( 'hidden', null, $segment + '[][format]' , $field_data.format, false ) )
1370
+ .append( make_input( 'hidden', null, $segment + '[][segment]' , $segment, false ) )
1371
+ .append( make_input( 'hidden', null, $segment + '[][key]' , $index, false ) );
1372
+
1373
+ $mapping_col_3.append( make_input( 'input', 'mapping_fieldname', $segment + '[][colname]', colname ) );
1374
+
1375
+ if ( $index.indexOf( 'static_field' ) >= 0 ) {
1376
+ value_part = '<div class="mapping_col_3 custom-field-value"><input class="mapping_fieldname" type=input name="' + $segment + '[][value]" value="' + $field_data.value + '"></div>';
1377
+ }
1378
+
1379
+ } else {
1380
+
1381
+ if ( $segment === 'products' ) {
1382
+ label_prefix = '[P] '
1383
+ }
1384
+
1385
+ if ( $segment === 'coupons' ) {
1386
+ label_prefix = '[C] '
1387
+ }
1388
+
1389
+ $mapping_col_1
1390
+ .append( make_input( 'hidden', null, 'orders[][segment]' , $segment, false ) )
1391
+ .append( make_input( 'hidden', null, 'orders[][key]' , _index, false ) )
1392
+ .append( make_input( 'hidden', null, 'orders[][label]' , $field_data.label, false ) )
1393
+ .append( make_input( 'hidden', null, 'orders[][format]' , $field_data.format, false ) );
1394
+
1395
+ $mapping_col_3.append( make_input( 'input', 'mapping_fieldname', 'orders[][colname]', colname ) );
1396
+
1397
+ if ( $index.indexOf( 'static_field' ) >= 0 ) {
1398
+ value_part = '<div class="mapping_col_3 custom-field-value"><input class="mapping_fieldname" type=input name="' + 'orders[][value]" value="' + $field_data.value + '"></div>';
1399
+ }
1400
+
1401
+ }
1402
+ var delete_btn = '<div class="mapping_col_3 mapping_row-delete_field_block"><a href="#" class="mapping_row-delete_field"><span class="dashicons dashicons-trash"></span></a></div>';
1403
+
1404
+ $mapping_col_2.append( '<span class="field-prefix">' + label_prefix + '</span>' + $field_data.label + label_part );
1405
+
1406
+ if ( $index.charAt( 0 ) === '_' || $index.substr( 0,3 ) === 'pa_' || !$field_data.default || $index.indexOf( 'static_field' ) > -1) {
1407
+ $mapping_col_2.append( '<a href="#" onclick="return remove_custom_field(this);" class="mapping_row-delete_custom_field" style="float: right;"><span class="ui-icon ui-icon-trash"></span></a>' );
1408
+ }
1409
+
1410
+ var $field = jQuery('<li class="mapping_row segment_field segment_'+ $segment +'"></li>');
1411
+
1412
+ $field
1413
+ .append( $mapping_col_1 )
1414
+ .append( $mapping_col_2 )
1415
+ .append( $mapping_col_3 )
1416
+ .append( value_part )
1417
+ .append( delete_btn );
1418
+
1419
+ $field.find('input').prop('disabled', 'disabled');
1420
+
1421
+ return $field;
1422
+ }
1423
+
1424
+ function make_input( $type, $classes, $name, $field_data, $is_checked ) {
1425
+
1426
+ var $input = jQuery('<input>');
1427
+
1428
+ $input.prop('type', $type);
1429
+
1430
+ if ( $classes && jQuery.isArray($classes) ) {
1431
+ $input.addClass($classes.join(' '));
1432
+ }
1433
+
1434
+ $input.prop('name', $name);
1435
+ $input.attr('value', $field_data);
1436
+
1437
+ if ( $is_checked ) {
1438
+ $input.prop('checked', 'checked');
1439
+ }
1440
+
1441
+ return $input;
1442
+ }
1443
+
1444
+ function check_sortable_groups () {
1445
+ jQuery('#sortable_products').closest('.mapping_row').toggle(!!jQuery('#sortable_products li').length);
1446
+ jQuery('#sortable_coupons').closest('.mapping_row').toggle(!!jQuery('#sortable_coupons li').length);
1447
+ }
1448
+
1449
+ function activate_draggable_field (el, segment, format) {
1450
+
1451
+ var no_flat_sortable_selector = '#manage_fields #order_fields #sortable_' + segment;
1452
+ var flat_sortable_selector = '#manage_fields #order_fields';
1453
+
1454
+ el.draggable({
1455
+ connectToSortable: [no_flat_sortable_selector, flat_sortable_selector].join(','),
1456
+ helper: "clone",
1457
+ revert: "invalid",
1458
+ start: function ( event, ui ) {
1459
+ jQuery(ui.helper[0]).removeClass( 'blink' );
1460
+ },
1461
+ stop: function ( event, ui ) {
1462
+ el.removeClass( 'blink' );
1463
+
1464
+ var moved_to_sortable = jQuery(ui.helper[0]).closest(flat_sortable_selector).length;
1465
+ var move_to_sortable_group = jQuery(ui.helper[0]).closest(no_flat_sortable_selector).length;
1466
+
1467
+ if (!moved_to_sortable) {
1468
+ return;
1469
+ }
1470
+
1471
+ moving_products_and_coupons_group_blocks_to_first_item(format);
1472
+
1473
+ // change static field key index to prevent fields with identical keys
1474
+ var tmp_prefix = ['products', 'coupons'].indexOf(segment) === -1 ? '' : 'plain_' + segment + '_';
1475
+ if ( jQuery(ui.helper[0]).find('input[value*="' + tmp_prefix + 'static_field"]').length > 0 ) {
1476
+ var suffix = 0;
1477
+ jQuery('#order_fields input[value*="' + tmp_prefix + 'static_field_"]').each(function () {
1478
+
1479
+ var match = jQuery(this).attr('value').match(/.*static_field_(\d+)/);
1480
+
1481
+ if (!match) {
1482
+ return true;
1483
+ }
1484
+
1485
+ var n = parseInt(match[1]);
1486
+
1487
+ if(n > suffix) {
1488
+ suffix = n;
1489
+ }
1490
+ });
1491
+
1492
+ var field_key = tmp_prefix + 'static_field_' + (suffix + 1);
1493
+ jQuery(ui.helper[0]).find('input[name="orders[][key]"]').first().val(field_key);
1494
+ }
1495
+ // end change static field key
1496
+
1497
+ var moving_copy_original_el = jQuery(ui.helper[0]);
1498
+
1499
+ moving_copy_original_el
1500
+ .attr('style', '')
1501
+ .addClass('ui-draggabled')
1502
+ .removeClass('segment_field')
1503
+ .find('input').prop('disabled', false);
1504
+
1505
+
1506
+ if (is_flat_format(format) || move_to_sortable_group || ['products', 'coupons'].indexOf(segment) === -1) {
1507
+ return;
1508
+ }
1509
+
1510
+ jQuery(no_flat_sortable_selector).append(moving_copy_original_el.clone());
1511
+
1512
+ moving_copy_original_el.remove();
1513
+
1514
+ check_sortable_groups();
1515
+ },
1516
+ });
1517
+
1518
+ }
1519
+
1520
+ function moving_products_and_coupons_group_blocks_to_first_item(format) {
1521
+
1522
+ if ( is_flat_format ( format ) ) {
1523
+
1524
+ var first_products_field = jQuery('#order_fields [value*="plain_products_"]').first().closest('li');
1525
+ var first_coupons_field = jQuery('#order_fields [value*="plain_coupons_"]').first().closest('li');
1526
+
1527
+ if (first_products_field.length) {
1528
+ var products_group_block = jQuery('#order_fields .flat-products-group').clone();
1529
+ jQuery('#order_fields .flat-products-group').remove();
1530
+ first_products_field.before(products_group_block);
1531
+ }
1532
+
1533
+ if (first_coupons_field.length) {
1534
+ var coupons_group_block = jQuery('#order_fields .flat-coupons-group').clone();
1535
+ jQuery('#order_fields .flat-coupons-group').remove();
1536
+ first_coupons_field.before(coupons_group_block);
1537
+ }
1538
+
1539
+ return;
1540
+ }
1541
+
1542
+ var first_products_field = jQuery('#order_fields [name="products[][key]"]').first().closest('li');
1543
+
1544
+ if (!jQuery('#sortable_products > li').length && first_products_field.length) {
1545
+ var products_group_block = jQuery('#order_fields .flat-products-group').clone();
1546
+ jQuery('#order_fields .flat-products-group').remove();
1547
+ first_products_field.before(products_group_block);
1548
+ }
1549
+
1550
+ var first_coupons_field = jQuery('#order_fields [name="coupons[][key]"]').first().closest('li');
1551
+
1552
+ if (!jQuery('#sortable_coupons > li').length && first_coupons_field.length) {
1553
+ var coupons_group_block = jQuery('#order_fields .flat-coupons-group').clone();
1554
+ jQuery('#order_fields .flat-coupons-group').remove();
1555
+ first_coupons_field.before(coupons_group_block);
1556
+ }
1557
+ }
1558
+
1559
+ function synch_selected_fields (old_format, new_format) {
1560
+
1561
+ var settings = jQuery('#export_job_settings').serializeJSON();
1562
+
1563
+ if (is_flat_format(old_format) && is_flat_format(new_format)) {
1564
+ window['selected_order_fields'] = settings.orders || [];
1565
+ window['selected_order_products_fields'] = [];
1566
+ window['selected_order_coupons_fields'] = [];
1567
+ return;
1568
+ }
1569
+
1570
+ if (!is_flat_format(old_format) && !is_flat_format(new_format)) {
1571
+ window['selected_order_fields'] = settings.orders || [];
1572
+ window['selected_order_products_fields'] = settings.products || [];
1573
+ window['selected_order_coupons_fields'] = settings.coupons || [];
1574
+ return;
1575
+ }
1576
+
1577
+ if (is_flat_format(old_format) && !is_flat_format(new_format)) {
1578
+
1579
+ var products = [];
1580
+ var coupons = [];
1581
+ var orders = [];
1582
+
1583
+ (settings.orders || []).forEach(function (item) {
1584
+
1585
+ if (item.key.indexOf('plain_products') > -1) {
1586
+ item.key = item.key.replace('plain_products_', '');
1587
+ products.push(item);
1588
+ return true;
1589
+ }
1590
+
1591
+ if (item.key.indexOf('plain_coupons') > -1) {
1592
+ item.key = item.key.replace('plain_coupons_', '');
1593
+ coupons.push(item);
1594
+ return true;
1595
+ }
1596
+
1597
+ orders.push(item);
1598
+ });
1599
+
1600
+ window['selected_order_fields'] = orders;
1601
+ window['selected_order_products_fields'] = products;
1602
+ window['selected_order_coupons_fields'] = coupons;
1603
+
1604
+ return;
1605
+ }
1606
+
1607
+ if (!is_flat_format(old_format) && is_flat_format(new_format)) {
1608
+
1609
+ var products = [];
1610
+ var coupons = [];
1611
+ var orders = [];
1612
+
1613
+ (settings.products || []).forEach(function (item) {
1614
+ item.key = 'plain_products_' + item.key;
1615
+ products.push(item);
1616
+ });
1617
+
1618
+ (settings.coupons || []).forEach(function (item) {
1619
+ item.key = 'plain_coupons_' + item.key;
1620
+ coupons.push(item);
1621
+ });
1622
+
1623
+ (settings.orders || []).forEach(function (item) {
1624
+
1625
+ orders.push(item);
1626
+
1627
+ if (item.key === 'products') {
1628
+ orders = orders.concat(products);
1629
+ }
1630
+
1631
+ if (item.key === 'coupons') {
1632
+ orders = orders.concat(coupons);
1633
+ }
1634
+ });
1635
+
1636
+ window['selected_order_fields'] = orders;
1637
+ window['selected_order_products_fields'] = [];
1638
+ window['selected_order_coupons_fields'] = [];
1639
+
1640
+ return;
1641
+ }
1642
+
1643
  }
classes/admin/class-wc-order-export-ajax.php CHANGED
@@ -316,7 +316,7 @@ class WC_Order_Export_Ajax {
316
  $format = basename( $_GET['format'] );
317
  $filename = $this->get_temp_file_name();
318
  delete_transient( $this->tempfile_prefix . $_GET['file_id'] );
319
-
320
  $download_name = get_transient( $this->tempfile_prefix . 'download_filename' );
321
  $this->send_headers( $format, $download_name );
322
  $this->send_contents_delete_file( $filename );
316
  $format = basename( $_GET['format'] );
317
  $filename = $this->get_temp_file_name();
318
  delete_transient( $this->tempfile_prefix . $_GET['file_id'] );
319
+
320
  $download_name = get_transient( $this->tempfile_prefix . 'download_filename' );
321
  $this->send_headers( $format, $download_name );
322
  $this->send_contents_delete_file( $filename );
classes/admin/class-wc-order-export-labels.php ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ exit; // Exit if accessed directly
4
+ }
5
+
6
+
7
+ class WC_Order_Export_Labels {
8
+
9
+ private $labels;
10
+
11
+ public function __get($key) {
12
+ if ( ! $key || empty($this->labels) ) {
13
+ return false;
14
+ }
15
+
16
+ foreach ( $this->labels as $label_data ) {
17
+ if ( $label_data['key'] == $key ) {
18
+ return $label_data;
19
+ }
20
+ }
21
+
22
+ return false;
23
+ }
24
+
25
+ public function __isset($key) {
26
+ if ( ! $key || empty($this->labels) ) {
27
+ return false;
28
+ }
29
+
30
+ foreach ( $this->labels as $label_data ) {
31
+ if ( $label_data['key'] == $key ) {
32
+ return $label_data;
33
+ }
34
+ }
35
+
36
+ return false;
37
+ }
38
+
39
+ public function __unset($key) {
40
+ if ( ! $key || empty($this->labels) ) {
41
+ return false;
42
+ }
43
+
44
+ foreach ( $this->labels as $num_index => $label_data ) {
45
+ if ( $label_data['key'] === $key || $label_data['parent_key'] === $key ) {
46
+ unset($this->labels[$num_index]);
47
+ }
48
+ }
49
+
50
+ $this->labels = array_values($this->labels);
51
+ }
52
+
53
+ public function __set( $key, $label ) {
54
+ if ( ! $key ) {
55
+ return;
56
+ }
57
+
58
+ $temp_index = 0;
59
+ $new_key = $key;
60
+ while ( $this->__isset( $new_key ) ) {
61
+ $new_key = $temp_index ? $key . '_' . $temp_index : $new_key;
62
+ $temp_index ++;
63
+ }
64
+
65
+ $parent_key = $new_key !== $key ? $key : false;
66
+
67
+ $this->labels[] = array(
68
+ 'key' => $new_key,
69
+ 'label' => $label,
70
+ 'parent_key' => $parent_key,
71
+ );
72
+ }
73
+
74
+ public function get_keys() {
75
+ return array_map( function($label_data) {
76
+ return $label_data['key'];
77
+ }, $this->labels );
78
+ }
79
+
80
+ public function is_not_empty() {
81
+ return (boolean)$this->labels;
82
+ }
83
+
84
+ public function to_Array() {
85
+ return array_combine(
86
+ array_map(function ($label_data){
87
+ return $label_data['key'];
88
+ }, $this->labels),
89
+ array_map(function ($label_data){
90
+ return $label_data['label'];
91
+ }, $this->labels)
92
+ );
93
+ }
94
+
95
+ public function unique_keys() {
96
+ $unique_keys = array();
97
+ foreach ( $this->labels as $label_data ) {
98
+ if ( ! $label_data['parent_key'] ) {
99
+ $unique_keys[] = $label_data['key'];
100
+ }
101
+ }
102
+
103
+ return $unique_keys;
104
+ }
105
+
106
+ public function get_childs($key) {
107
+ $child_labels = array();
108
+ foreach ( $this->labels as $label_data ) {
109
+ if ( $label_data['parent_key'] == $key ) {
110
+ $child_labels[] = $label_data;
111
+ }
112
+ }
113
+
114
+ return $child_labels;
115
+ }
116
+
117
+ public function get_parent($key) {
118
+ foreach ( $this->labels as $label_data ) {
119
+ if ( $label_data['key'] == $key ) {
120
+ return $label_data['parent_key'];
121
+ }
122
+ }
123
+
124
+ return false;
125
+ }
126
+
127
+ public function replace_label($key, $new_label) {
128
+ if ( ! $key || empty($this->labels) ) {
129
+ return;
130
+ }
131
+
132
+ foreach ( $this->labels as &$label_data ) {
133
+ if ( $label_data['key'] == $key || $label_data['parent_key'] === $key ) {
134
+ $label_data['label'] = $new_label;
135
+ }
136
+ }
137
+ }
138
+
139
+ public function get_labels(){
140
+ return $this->labels;
141
+ }
142
+
143
+ public function get_fetch_fields() {
144
+ $fetch_fields = array();
145
+ foreach ( $this->labels as $label_data ) {
146
+ if ( ! $label_data['parent_key'] AND ! preg_match( '/^plain_(products|coupons)_.+/',
147
+ $label_data['key'] ) ) {
148
+ $fetch_fields[] = $label_data['key'];
149
+ }
150
+ }
151
+
152
+ return $fetch_fields;
153
+ }
154
+
155
+ public function get_legacy_labels() {
156
+ $unique_keys = array();
157
+ foreach ( $this->labels as $label_data ) {
158
+ if ( ! $label_data['parent_key'] ) {
159
+ $unique_keys[ $label_data["key"] ] = $label_data["label"];
160
+ }
161
+ }
162
+
163
+ return $unique_keys;
164
+ }
165
+ }
classes/admin/class-wc-order-export-manage.php CHANGED
@@ -14,7 +14,7 @@ class WC_Order_Export_Manage {
14
  const EXPORT_SCHEDULE = 'cron';
15
  const EXPORT_ORDER_ACTION = 'order-action';
16
 
17
- public static $edit_existing_job = false;
18
 
19
  static function get_days() {
20
  return array(
@@ -69,6 +69,7 @@ class WC_Order_Export_Manage {
69
  return update_option( $name, $jobs, false );
70
  }
71
 
 
72
  static function make_new_settings( $in ) {
73
  $new_settings = $in['settings'];
74
 
@@ -91,7 +92,7 @@ class WC_Order_Export_Manage {
91
  'shipping_methods',
92
  'user_roles',
93
  'user_names',
94
- 'user_custom_fields',
95
  'coupons',
96
  'billing_locations',
97
  'payment_methods',
@@ -109,6 +110,8 @@ class WC_Order_Export_Manage {
109
 
110
  $settings = self::get( $in['mode'], $in['id'] );
111
  $settings['id'] = $in['id'];
 
 
112
  // setup new values for same keys
113
  foreach ( $new_settings as $key => $val ) {
114
  $settings[ $key ] = $val;
@@ -116,49 +119,30 @@ class WC_Order_Export_Manage {
116
 
117
  $sections = array(
118
  'orders' => 'order_fields',
119
- 'products' => 'order_product_fields',
120
- 'coupons' => 'order_coupon_fields',
121
  );
122
- foreach ( $sections as $section => $fieldset ) {
123
- $new_order_fields = array();
124
- $in_sec = $in[ $section ];
125
-
126
- if ( $in_sec['colname'] ) {
127
- foreach ( $in_sec['colname'] as $field => $colname ) {
128
- $opts = array(
129
- "checked" => $in_sec['exported'][ $field ],
130
- "colname" => $colname,
131
- "label" => $in_sec['label'][ $field ],
132
- );
133
- // for products & coupons
134
- if ( isset( $in_sec['repeat'][ $field ] ) ) {
135
- $opts["repeat"] = $in_sec['repeat'][ $field ];
136
- }
137
- if ( isset( $in_sec['max_cols'][ $field ] ) ) {
138
- $opts["max_cols"] = $in_sec['max_cols'][ $field ];
139
- }
140
- //for orders
141
- if ( isset( $in_sec['segment'][ $field ] ) ) {
142
- $opts["segment"] = $in_sec['segment'][ $field ];
143
- }
144
- //for static fields
145
- if ( isset( $in_sec['value'][ $field ] ) ) {
146
- $opts["value"] = $in_sec['value'][ $field ];
147
- }
148
- $new_order_fields[ $field ] = $opts;
149
- }
150
- }
151
 
152
- $settings[ $fieldset ] = $new_order_fields;
 
 
 
 
 
 
 
 
153
  }
154
 
155
  return self::apply_defaults( $in['mode'], $settings );
156
  }
157
 
158
  static function get( $mode, $id = false ) {
159
- $all_jobs = self::get_export_settings_collection( $mode );
 
160
 
161
  if ( $mode == self::EXPORT_NOW ) { // one job
 
 
 
162
  return self::apply_defaults( $mode, $all_jobs );
163
  } elseif ( $id === false ) {
164
  if ( empty( $all_jobs ) OR ! is_array( $all_jobs ) ) {
@@ -166,20 +150,27 @@ class WC_Order_Export_Manage {
166
  }
167
 
168
  return array_map( function ( $item ) use ( $mode ) {
 
 
 
 
 
169
  return WC_Order_Export_Manage::apply_defaults( $mode, $item );
170
  }, $all_jobs );
171
  }
172
 
173
  $settings = isset( $all_jobs[ $id ] ) ? $all_jobs[ $id ] : array();
174
 
 
 
 
 
175
  return self::apply_defaults( $mode, $settings );
176
  }
177
 
178
- static function apply_defaults( $mode, $settings ) {
179
-
180
- $settings = apply_filters( "woe_before_apply_default_settings", $settings, $mode );
181
-
182
- $defaults = array(
183
  'mode' => $mode,
184
  'title' => '',
185
  'skip_empty_file' => true,
@@ -214,21 +205,18 @@ class WC_Order_Export_Manage {
214
  'format_xls_sheet_name' => __( 'Orders', 'woo-order-export-lite' ),
215
  'format_xls_display_column_names' => 1,
216
  'format_xls_auto_width' => 1,
217
- 'format_xls_populate_other_columns_product_rows' => 1,
218
  'format_xls_direction_rtl' => 0,
219
  'format_csv_enclosure' => '"',
220
  'format_csv_delimiter' => ',',
221
  'format_csv_linebreak' => '\r\n',
222
  'format_csv_display_column_names' => 1,
223
  'format_csv_add_utf8_bom' => 0,
224
- 'format_csv_populate_other_columns_product_rows' => 1,
225
  'format_csv_item_rows_start_from_new_line' => 0,
226
  'format_csv_encoding' => 'UTF-8',
227
  'format_csv_delete_linebreaks' => 0,
228
  'format_tsv_linebreak' => '\r\n',
229
  'format_tsv_display_column_names' => 1,
230
  'format_tsv_add_utf8_bom' => 0,
231
- 'format_tsv_populate_other_columns_product_rows' => 1,
232
  'format_tsv_encoding' => 'UTF-8',
233
  'format_xml_root_tag' => 'Orders',
234
  'format_xml_order_tag' => 'Order',
@@ -259,7 +247,30 @@ class WC_Order_Export_Manage {
259
  'export_unmarked_orders' => 0,
260
 
261
  'summary_report_by_products' => 0,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
262
  );
 
 
 
 
 
 
263
 
264
  if ( ! isset( $settings['format'] ) ) {
265
  $settings['format'] = 'XLS';
@@ -269,25 +280,156 @@ class WC_Order_Export_Manage {
269
  $settings['export_rule_field'] = 'modified';
270
  }
271
 
272
- if ( ! isset( $settings['order_fields'] ) ) {
273
- $settings['order_fields'] = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
  }
275
- self::merge_settings_and_default( $settings['order_fields'],
276
- WC_Order_Export_Data_Extractor_UI::get_order_fields( $settings['format'] ) );
277
 
278
- if ( ! isset( $settings['order_product_fields'] ) ) {
279
- $settings['order_product_fields'] = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
  }
281
- self::merge_settings_and_default( $settings['order_product_fields'],
282
- WC_Order_Export_Data_Extractor_UI::get_order_product_fields( $settings['format'] ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
283
 
284
- if ( ! isset( $settings['order_coupon_fields'] ) ) {
285
- $settings['order_coupon_fields'] = array();
286
  }
287
- self::merge_settings_and_default( $settings['order_coupon_fields'],
288
- WC_Order_Export_Data_Extractor_UI::get_order_coupon_fields( $settings['format'] ) );
289
 
290
- return array_merge( $defaults, $settings );
 
 
 
 
 
 
 
 
 
 
 
291
  }
292
 
293
  static function merge_settings_and_default( &$opt, $defaults ) {
@@ -301,7 +443,7 @@ class WC_Order_Export_Manage {
301
  if ( isset( $v['format'] ) ) {
302
  $opt[ $k ]['format'] = $v['format'];
303
  }
304
- // overwrite labels for localization
305
  $opt[ $k ]['label'] = $v['label'];
306
  } else {
307
  if ( self::$edit_existing_job AND $v['checked'] == "1" ) {
@@ -464,4 +606,207 @@ class WC_Order_Export_Manage {
464
 
465
  return $data;
466
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
467
  }
14
  const EXPORT_SCHEDULE = 'cron';
15
  const EXPORT_ORDER_ACTION = 'order-action';
16
 
17
+ public static $edit_existing_job = false;
18
 
19
  static function get_days() {
20
  return array(
69
  return update_option( $name, $jobs, false );
70
  }
71
 
72
+
73
  static function make_new_settings( $in ) {
74
  $new_settings = $in['settings'];
75
 
92
  'shipping_methods',
93
  'user_roles',
94
  'user_names',
95
+ 'user_custom_fields',
96
  'coupons',
97
  'billing_locations',
98
  'payment_methods',
110
 
111
  $settings = self::get( $in['mode'], $in['id'] );
112
  $settings['id'] = $in['id'];
113
+ $settings['duplicated_fields_settings'] = isset( $in['duplicated_fields_settings'] ) ? $in['duplicated_fields_settings'] : array();
114
+
115
  // setup new values for same keys
116
  foreach ( $new_settings as $key => $val ) {
117
  $settings[ $key ] = $val;
119
 
120
  $sections = array(
121
  'orders' => 'order_fields',
 
 
122
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
 
124
+ $flat_formats = array( 'XLS', 'CSV', 'TSV' );
125
+ if ( ! in_array($new_settings['format'], $flat_formats) ) {
126
+ $sections[ 'products' ] = 'order_product_fields';
127
+ $sections[ 'coupons' ] = 'order_coupon_fields';
128
+ }
129
+
130
+ foreach ( $sections as $section => $fieldset ) {
131
+ $section_fields = isset( $in[ $section ] ) ? $in[ $section ] : array();
132
+ $settings[ $fieldset ] = $section_fields;
133
  }
134
 
135
  return self::apply_defaults( $in['mode'], $settings );
136
  }
137
 
138
  static function get( $mode, $id = false ) {
139
+
140
+ $all_jobs = self::get_export_settings_collection( $mode );
141
 
142
  if ( $mode == self::EXPORT_NOW ) { // one job
143
+ if ( ! isset( $all_jobs['version'] ) ) {
144
+ $all_jobs = self::convert_settings_to_version_2($mode, $all_jobs);
145
+ }
146
  return self::apply_defaults( $mode, $all_jobs );
147
  } elseif ( $id === false ) {
148
  if ( empty( $all_jobs ) OR ! is_array( $all_jobs ) ) {
150
  }
151
 
152
  return array_map( function ( $item ) use ( $mode ) {
153
+
154
+ if ( ! isset( $item['version'] ) ) {
155
+ $item = self::convert_settings_to_version_2($mode, $item);
156
+ }
157
+
158
  return WC_Order_Export_Manage::apply_defaults( $mode, $item );
159
  }, $all_jobs );
160
  }
161
 
162
  $settings = isset( $all_jobs[ $id ] ) ? $all_jobs[ $id ] : array();
163
 
164
+ if ( ! isset( $settings['version'] ) ) {
165
+ $settings = self::convert_settings_to_version_2($mode, $settings);
166
+ }
167
+
168
  return self::apply_defaults( $mode, $settings );
169
  }
170
 
171
+ private static function get_defaults( $mode ) {
172
+ return array(
173
+ 'version' => '2.0',
 
 
174
  'mode' => $mode,
175
  'title' => '',
176
  'skip_empty_file' => true,
205
  'format_xls_sheet_name' => __( 'Orders', 'woo-order-export-lite' ),
206
  'format_xls_display_column_names' => 1,
207
  'format_xls_auto_width' => 1,
 
208
  'format_xls_direction_rtl' => 0,
209
  'format_csv_enclosure' => '"',
210
  'format_csv_delimiter' => ',',
211
  'format_csv_linebreak' => '\r\n',
212
  'format_csv_display_column_names' => 1,
213
  'format_csv_add_utf8_bom' => 0,
 
214
  'format_csv_item_rows_start_from_new_line' => 0,
215
  'format_csv_encoding' => 'UTF-8',
216
  'format_csv_delete_linebreaks' => 0,
217
  'format_tsv_linebreak' => '\r\n',
218
  'format_tsv_display_column_names' => 1,
219
  'format_tsv_add_utf8_bom' => 0,
 
220
  'format_tsv_encoding' => 'UTF-8',
221
  'format_xml_root_tag' => 'Orders',
222
  'format_xml_order_tag' => 'Order',
247
  'export_unmarked_orders' => 0,
248
 
249
  'summary_report_by_products' => 0,
250
+ 'duplicated_fields_settings' => array(
251
+ 'products' =>
252
+ array(
253
+ 'repeat' => 'rows',
254
+ 'populate_other_columns' => '1',
255
+ 'max_cols' => '10',
256
+ 'line_delimiter' => '\\n',
257
+ 'group_by' => 'product',
258
+ ),
259
+ 'coupons' =>
260
+ array(
261
+ 'repeat' => 'rows',
262
+ 'max_cols' => '10',
263
+ 'line_delimiter' => '\\n',
264
+ 'group_by' => 'product',
265
+ ),
266
+ ),
267
  );
268
+ }
269
+
270
+ static function apply_defaults( $mode, $settings ) {
271
+ $settings = apply_filters( "woe_before_apply_default_settings", $settings, $mode );
272
+
273
+ $defaults = self::get_defaults( $mode );
274
 
275
  if ( ! isset( $settings['format'] ) ) {
276
  $settings['format'] = 'XLS';
280
  $settings['export_rule_field'] = 'modified';
281
  }
282
 
283
+ foreach ( array( 'order_fields', 'order_product_fields', 'order_coupon_fields' ) as $index ) {
284
+ if ( ! isset( $settings[ $index ] ) ) {
285
+ $additional_fields = self::move_fields_key( self::get_default_fields( $index, $settings['format'] ) );
286
+ self::remove_unchecked_fields($additional_fields);
287
+ $settings[ $index ] = $additional_fields;
288
+ if ( 'order_fields' !== $index ) {
289
+ $map_segment = array(
290
+ 'order_product_fields' => 'products',
291
+ 'order_coupon_fields' => 'coupons',
292
+ );
293
+
294
+ $settings['order_fields'] = array_merge(
295
+ $settings['order_fields'],
296
+ array_map( function ( $value ) use ( $map_segment, $index ) {
297
+ $value['segment'] = $map_segment[ $index ];
298
+ $value['key'] = 'plain_' . $map_segment[ $index ] . '_' . $value['key'];
299
+
300
+ return $value;
301
+ }, $additional_fields )
302
+ );
303
+ }
304
+ }
305
  }
 
 
306
 
307
+ return array_merge( $defaults, $settings );
308
+ }
309
+
310
+ private static function get_default_fields($index, $format) {
311
+ $result = array();
312
+ switch ($index) {
313
+ case 'order_fields':
314
+ $result = WC_Order_Export_Data_Extractor_UI::get_order_fields( $format );
315
+ break;
316
+ case 'order_product_fields':
317
+ $result = WC_Order_Export_Data_Extractor_UI::get_order_product_fields( $format );
318
+ break;
319
+ case 'order_coupon_fields':
320
+ $result = WC_Order_Export_Data_Extractor_UI::get_order_coupon_fields( $format );
321
+ break;
322
+ };
323
+
324
+ return $result;
325
+ }
326
+
327
+ private static function remove_unchecked_fields(&$fields) {
328
+ foreach ( $fields as $key => $field ) {
329
+ if (empty($field['checked'])){
330
+ unset($fields[$key]);
331
+ } elseif ( isset($field['checked']) ) {
332
+ unset($fields[$key]['checked']);
333
+ }
334
  }
335
+ $fields = array_values($fields);
336
+ }
337
+
338
+ private static function move_fields_key( $fields ) {
339
+
340
+ return array_map( function ( $key, $value ) {
341
+ if ( ! key_exists( 'key', $value ) ) {
342
+ $value['key'] = $key;
343
+ }
344
+
345
+ return $value;
346
+ }, array_keys( $fields ), $fields );
347
+ }
348
+
349
+ static function merge_settings_and_default_new( &$opt, $defaults ) {
350
+
351
+ $opt = self::move_fields_key($opt);
352
+ $defaults = self::move_fields_key($defaults);
353
+
354
+
355
+ foreach ( $defaults as $v ) {
356
+ $exists = false;
357
+ foreach ( $opt as $num_index => $option ) {
358
+ if ( $v['key'] == $option['key'] ) {
359
+ //set default attribute OR add to option
360
+ if ( isset( $v['default'] ) ) {
361
+ $option['default'] = $v['default'];
362
+ }
363
+ //set default format OR add to option
364
+ if ( isset( $v['format'] ) ) {
365
+ $option['format'] = $v['format'];
366
+ }
367
+ // overwrite labels for localization
368
+ $option['label'] = $v['label'];
369
+
370
+ $exists = true;
371
+ break;
372
+ }
373
+ };
374
+
375
+ if ( ! $exists ) {
376
+ if ( self::$edit_existing_job AND $v['checked'] == "1" ) {
377
+ $v['checked'] = "0";
378
+ }
379
+ $opt[] = $v;
380
+ }
381
+ };
382
+ }
383
+
384
+ public static function make_all_fields( $format ) {
385
+ $order_fields = array();
386
+ foreach ( array_keys( WC_Order_Export_Data_Extractor_UI::get_order_segments() ) as $segment ) {
387
+ if ( 'products' == $segment ) {
388
+ $method = "get_order_product_fields";
389
+ $filter = "woe_get_order_product_fields";
390
+ } elseif ( 'coupons' == $segment ) {
391
+ $method = "get_order_coupon_fields";
392
+ $filter = "woe_get_order_coupon_fields";
393
+ } elseif ( 'misc' == $segment ) {
394
+ $method = "get_order_fields_misc";
395
+ $filter = "woe_get_order_fields"; //add ALL custom Order fields to last tab
396
+ } else {
397
+ $method = "get_order_fields_" . $segment;
398
+ $filter = "woe_get_order_fields_" . $segment;
399
+ }
400
+
401
+ if ( method_exists( 'WC_Order_Export_Data_Extractor_UI', $method ) ) {
402
+ // woe_get_order_fields_common filter
403
+ $segment_fields = array();
404
+ $default_segment_fields = array_merge(
405
+ WC_Order_Export_Data_Extractor_UI::$method( $format ),
406
+ apply_filters( $filter, array(), $format )
407
+ );
408
+ foreach ( $default_segment_fields as $key => $value ) {
409
+ $order_field = $value;
410
+ $order_field['colname'] = $value['label'];
411
+ $order_field['key'] = $key;
412
+ $order_field['default'] = 1;
413
+ unset( $order_field['checked'] );
414
+ $segment_fields[] = $order_field;
415
+ }
416
 
417
+ $order_fields[ $segment ] = $segment_fields;
418
+ }
419
  }
 
 
420
 
421
+ return $order_fields;
422
+ }
423
+
424
+ private static function process_fields( $fields ) {
425
+
426
+ return array_map( function ( $key, $value ) {
427
+ if ( ! key_exists( 'key', $value ) ) {
428
+ $value['key'] = $key;
429
+ }
430
+
431
+ return $value;
432
+ }, array_keys( $fields ), $fields );
433
  }
434
 
435
  static function merge_settings_and_default( &$opt, $defaults ) {
443
  if ( isset( $v['format'] ) ) {
444
  $opt[ $k ]['format'] = $v['format'];
445
  }
446
+ // overwrite labels for localization
447
  $opt[ $k ]['label'] = $v['label'];
448
  } else {
449
  if ( self::$edit_existing_job AND $v['checked'] == "1" ) {
606
 
607
  return $data;
608
  }
609
+
610
+ //backup only existing settings
611
+ private static function backup_settings_before_version_2( $mode ){
612
+ $name = self::get_settings_name_for_mode( $mode );
613
+ $current_settings = get_option( $name, array() );
614
+ $new_settings = get_option( $name."-V1", array() );
615
+ // backup only once!
616
+ if( !empty($current_settings) AND empty($new_settings) ) {
617
+ update_option( $name."-V1", $current_settings, false );
618
+ }
619
+ }
620
+
621
+ protected static function convert_settings_to_version_2 ( $mode, $settings ) {
622
+
623
+ if ( ! $settings ) {
624
+ return $settings;
625
+ }
626
+ self::backup_settings_before_version_2($mode);
627
+
628
+ $flat_formats = array( 'XLS', 'CSV', 'TSV' );
629
+ $is_flat_format = in_array($settings['format'], $flat_formats);
630
+ $is_json_format = $settings['format'] === 'JSON';
631
+
632
+ $order_fields = array();
633
+ $order_coupon_fields = array();
634
+ $order_product_fields = array();
635
+ $duplicated_fields_settings = array();
636
+
637
+ if ( ! empty($settings['order_fields']['products']['checked']) ) {
638
+ if (isset($settings['order_product_fields'])) {
639
+
640
+ foreach ($settings['order_product_fields'] as $key => $values) {
641
+
642
+ if ( ! $values['checked'] ) {
643
+ continue;
644
+ }
645
+
646
+ $field = array(
647
+ 'key' => $key,
648
+ 'label' => $values['label'],
649
+ 'colname' => $values['colname'],
650
+ 'format' => isset($values['format']) ? $values['format'] : 'string',
651
+ );
652
+
653
+ if ( $is_flat_format ) {
654
+ $field['key'] = 'plain_products_' . $key;
655
+ $field['segment'] = 'products';
656
+ }
657
+
658
+ // start FOR STATIC FIELDS
659
+ if ( isset( $values['value'] ) ) {
660
+ $field['value'] = $values['value'];
661
+ }
662
+ // end FOR STATIC FIELDS
663
+
664
+
665
+ $order_product_fields[] = $field;
666
+ }
667
+ }
668
+ } else {
669
+ $order_fields[] = array(
670
+ 'key' => 'products',
671
+ 'label' => __( 'Products', 'woo-order-export-lite' ),
672
+ 'colname' => $is_json_format ? 'products' : 'Products',
673
+ 'segment' => 'product',
674
+ 'format' => 'string',
675
+ );
676
+ }
677
+
678
+
679
+ if ( ! empty($settings['order_fields']['coupons']['checked']) ) {
680
+ if ( isset( $settings['order_coupon_fields'] ) ) {
681
+ foreach ($settings['order_coupon_fields'] as $key => $values) {
682
+
683
+ if ( ! $values['checked'] ) {
684
+ continue;
685
+ }
686
+
687
+ $field = array(
688
+ 'key' => $key,
689
+ 'label' => $values['label'],
690
+ 'colname' => $values['colname'],
691
+ 'format' => isset($values['format']) ? $values['format'] : 'string',
692
+ );
693
+
694
+ if ( $is_flat_format ) {
695
+ $field['key'] = 'plain_coupons_' . $key;
696
+ $field['segment'] = 'coupons';
697
+ }
698
+
699
+ // start FOR STATIC FIELDS
700
+ if ( isset( $values['value'] ) ) {
701
+ $field['value'] = $values['value'];
702
+ }
703
+ if ( preg_match( '/^custom_field_(\d+)/', $key, $matches ) ) {
704
+ $field['key'] = "static_field_" . $matches[1];
705
+ }
706
+ // end FOR STATIC FIELDS
707
+
708
+ $order_coupon_fields[] = $field;
709
+ }
710
+ }
711
+ } else {
712
+ $order_fields[] = array(
713
+ 'key' => 'coupons',
714
+ 'label' => __( 'Coupons', 'woo-order-export-lite' ),
715
+ 'colname' => $is_json_format ? 'coupons' : 'Coupons',
716
+ 'segment' => 'coupon',
717
+ 'format' => 'string',
718
+ );
719
+ }
720
+
721
+
722
+ if ( isset( $settings['format'] ) ) {
723
+ $old_populate_option_values = array(
724
+ isset( $settings['format_xls_populate_other_columns_product_rows'] ) && $settings['format_xls_populate_other_columns_product_rows'] == '1' && $settings['format'] == 'XLS',
725
+ isset( $settings['format_csv_populate_other_columns_product_rows'] ) && $settings['format_csv_populate_other_columns_product_rows'] == '1' && $settings['format'] == 'CSV',
726
+ isset( $settings['format_tsv_populate_other_columns_product_rows'] ) && $settings['format_tsv_populate_other_columns_product_rows'] == '1' && $settings['format'] == 'TSV',
727
+ );
728
+
729
+ $old_populate_option_values = array_filter( $old_populate_option_values );
730
+
731
+ $populate = ! empty( $old_populate_option_values );
732
+ } else {
733
+ // by default
734
+ $populate = true;
735
+ }
736
+
737
+ if (isset($settings['order_fields'])) {
738
+ foreach ($settings['order_fields'] as $key => $values) {
739
+
740
+ if ( ! $values['checked'] ) {
741
+ continue;
742
+ }
743
+ if ( ! isset($values['segment']) ) {
744
+ $values['segment'] = 'common';
745
+ }
746
+ $order_field = array(
747
+ 'key' => $key,
748
+ 'label' => $values['label'],
749
+ 'colname' => $values['colname'],
750
+ 'segment' => $values['segment'],
751
+ 'format' => isset($values['format']) ? $values['format'] : 'string',
752
+ );
753
+
754
+ // start FOR STATIC FIELDS
755
+ if ( isset( $values['value'] ) ) {
756
+ $order_field['value'] = $values['value'];
757
+ }
758
+ if ( $is_flat_format ) {
759
+ if ( preg_match( '/^custom_field_(\d+)/', $key, $matches ) ) {
760
+ $order_field['key'] = "static_field_" . $matches[1];
761
+ }
762
+ }
763
+ // end FOR STATIC FIELDS
764
+
765
+ $order_fields[] = $order_field;
766
+
767
+
768
+ if ( $key === 'products' && $is_flat_format) {
769
+ $order_fields = array_merge($order_fields, $order_product_fields);
770
+ }
771
+
772
+ if ( $key === 'coupons' && $is_flat_format) {
773
+ $order_fields = array_merge($order_fields, $order_coupon_fields);
774
+ }
775
+
776
+ if ( in_array( $key, array( 'products', 'coupons' ) ) ) {
777
+ $duplicated_fields_settings[$key] = array(
778
+ 'repeat' => isset($values['repeat']) ? $values['repeat'] : 'rows',
779
+ 'max_cols' => isset($values['max_cols']) ? $values['max_cols'] : '10',
780
+ 'line_delimiter' => '\\n',
781
+ );
782
+ if ( $key == 'products' ) {
783
+ $duplicated_fields_settings[$key]['populate_other_columns'] = $populate ? '1' : '0';
784
+ }
785
+ }
786
+ }
787
+ }
788
+
789
+ if ( $duplicated_fields_settings ) {
790
+ $settings['duplicated_fields_settings'] = $duplicated_fields_settings;
791
+ }
792
+
793
+ $defaults = self::get_defaults( $settings['mode'] );
794
+ if ( ! isset( $duplicated_fields_settings['products'] ) ) {
795
+ $settings['duplicated_fields_settings']['products'] = $defaults['duplicated_fields_settings']['products'];
796
+ }
797
+ if ( ! isset( $duplicated_fields_settings['coupons'] ) ) {
798
+ $settings['duplicated_fields_settings']['coupons'] = $defaults['duplicated_fields_settings']['coupons'];
799
+ }
800
+
801
+ $settings['order_fields'] = $order_fields;
802
+
803
+ $settings['order_product_fields'] = $is_flat_format ? array() : $order_product_fields;
804
+ $settings['order_coupon_fields'] = $is_flat_format ? array() : $order_coupon_fields;
805
+
806
+ unset($duplicated_fields_settings, $order_coupon_fields, $order_product_fields, $order_fields);
807
+
808
+ return $settings;
809
+ }
810
+
811
+
812
  }
classes/class-wc-order-export-admin.php CHANGED
@@ -552,6 +552,7 @@ class WC_Order_Export_Admin {
552
  public function thematic_enqueue_scripts() {
553
  wp_enqueue_script( 'jquery-ui-datepicker' );
554
  wp_enqueue_script( 'jquery-ui-sortable' );
 
555
  wp_enqueue_style( 'jquery-style',
556
  '//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css' );
557
  $this->enqueue_select2_scripts();
@@ -569,10 +570,34 @@ class WC_Order_Export_Admin {
569
  WOE_VERSION );
570
 
571
  $localize_settings_form = array(
572
- 'set_up_fields_to_export' => __( 'Set up fields to export', 'woo-order-export-lite' ),
573
- 'js_tpl_popup' => __( 'Add %s as %s columns %s as rows', 'woo-order-export-lite' ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
574
  );
575
- wp_localize_script( 'settings-form', 'localize_settings_form', $localize_settings_form );
576
 
577
 
578
  $settings_form = array(
@@ -624,11 +649,16 @@ class WC_Order_Export_Admin {
624
  'empty' => __( 'empty', 'woo-order-export-lite' ),
625
  );
626
  wp_localize_script( 'export', 'export_messages', $translation_array );
 
 
 
 
 
 
 
627
  }
628
 
629
- private function enqueue_select2_scripts() {
630
- wp_enqueue_script( 'select22', 'https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.full.js',
631
- array( 'jquery' ), '4.0.3' );
632
  $locale = get_locale();
633
  $select2_locales = array(
634
  'de_DE' => 'de',
@@ -640,12 +670,24 @@ class WC_Order_Export_Admin {
640
  'fr_FR' => 'fr',
641
  'es_ES' => 'es',
642
  );
643
- if ( array_key_exists( $locale, $select2_locales ) ) {
644
- $select2_locale = $select2_locales[ $locale ];
645
- wp_enqueue_script( "select22-{$select2_locale}",
646
- "https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/i18n/{$select2_locale}.js" );
 
 
 
 
 
 
 
 
 
 
 
647
  }
648
- wp_enqueue_style( 'select2-css', 'https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css',
 
649
  array(), WC_VERSION );
650
  }
651
 
@@ -772,7 +814,7 @@ class WC_Order_Export_Admin {
772
  die();
773
  }
774
 
775
- //Works since Wordpress 4.7
776
  function export_orders_bulk_action( $actions ) {
777
  $settings = WC_Order_Export_Manage::get( WC_Order_Export_Manage::EXPORT_NOW );
778
  WC_Order_Export_Manage::set_correct_file_ext( $settings );
552
  public function thematic_enqueue_scripts() {
553
  wp_enqueue_script( 'jquery-ui-datepicker' );
554
  wp_enqueue_script( 'jquery-ui-sortable' );
555
+ wp_enqueue_script( 'jquery-ui-draggable' );
556
  wp_enqueue_style( 'jquery-style',
557
  '//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css' );
558
  $this->enqueue_select2_scripts();
570
  WOE_VERSION );
571
 
572
  $localize_settings_form = array(
573
+ 'add_fields_to_export' => __('Add %s fields', 'woo-order-export-lite'),
574
+ 'repeats' => array(
575
+ 'rows' => __( 'rows', 'woo-order-export-lite' ),
576
+ 'columns' => __( 'columns', 'woo-order-export-lite' ),
577
+ 'inside_one_cell' => __( 'one row', 'woo-order-export-lite' ),
578
+ ),
579
+ 'js_tpl_popup' => array(
580
+ 'add' => __( 'Add', 'woo-order-export-lite' ),
581
+ 'as' => __( 'as', 'woo-order-export-lite' ),
582
+ 'split_values_by' => __( 'Split values by', 'woo-order-export-lite' ),
583
+ 'fill_order_columns_label' => __( 'Fill order columns for', 'woo-order-export-lite' ),
584
+ 'for_all_rows_label' => __( 'all rows', 'woo-order-export-lite' ),
585
+ 'for_first_row_only_label' => __( '1st row only', 'woo-order-export-lite' ),
586
+ 'grouping_by' => array(
587
+ 'products' => __( 'Grouping by product', 'woo-order-export-lite' ),
588
+ 'coupons' => __( 'Grouping by coupon', 'woo-order-export-lite' ),
589
+ ),
590
+ ),
591
+ 'index' => array(
592
+ 'product_pop_up_title' => __('Set up product fields', 'woo-order-export-lite'),
593
+ 'coupon_pop_up_title' => __('Set up coupon fields', 'woo-order-export-lite'),
594
+ 'products' => __('products', 'woo-order-export-lite'),
595
+ 'coupons' => __('coupons', 'woo-order-export-lite'),
596
+ ),
597
+ 'remove_all_fields_confirm' => __('Remove all fields?', 'woo-order-export-lite'),
598
+
599
  );
600
+ wp_localize_script( 'settings-form', 'localize_settings_form', $localize_settings_form );
601
 
602
 
603
  $settings_form = array(
649
  'empty' => __( 'empty', 'woo-order-export-lite' ),
650
  );
651
  wp_localize_script( 'export', 'export_messages', $translation_array );
652
+
653
+ $script_data = array(
654
+ 'locale'=> get_locale(),
655
+ 'select2_locale'=> $this->get_select2_locale(),
656
+ );
657
+
658
+ wp_localize_script( 'export', 'script_data', $script_data );
659
  }
660
 
661
+ private function get_select2_locale() {
 
 
662
  $locale = get_locale();
663
  $select2_locales = array(
664
  'de_DE' => 'de',
670
  'fr_FR' => 'fr',
671
  'es_ES' => 'es',
672
  );
673
+
674
+ return isset( $select2_locales[ $locale ] ) ? $select2_locales[ $locale ] : 'en';
675
+ }
676
+
677
+ private function enqueue_select2_scripts() {
678
+ wp_enqueue_script( 'select22', $this->url_plugin . 'assets/js/select2/select2.full.js',
679
+ array( 'jquery' ), '4.0.3' );
680
+
681
+
682
+ if ( $select2_locale = $this->get_select2_locale() ) {
683
+ // enable by default
684
+ if ( $select2_locale !== 'en' ) {
685
+ wp_enqueue_script( "select22-i18n-{$select2_locale}",
686
+ $this->url_plugin . "assets/js/select2/i18n/{$select2_locale}.js", array( 'jquery', 'select22' ) );
687
+ }
688
  }
689
+
690
+ wp_enqueue_style( 'select2-css', $this->url_plugin . 'assets/css/select2/select2.min.css',
691
  array(), WC_VERSION );
692
  }
693
 
814
  die();
815
  }
816
 
817
+ //Works since Wordpress 4.7
818
  function export_orders_bulk_action( $actions ) {
819
  $settings = WC_Order_Export_Manage::get( WC_Order_Export_Manage::EXPORT_NOW );
820
  WC_Order_Export_Manage::set_correct_file_ext( $settings );
classes/core/class-wc-order-export-data-extractor-ui.php CHANGED
@@ -343,40 +343,57 @@ class WC_Order_Export_Data_Extractor_UI extends WC_Order_Export_Data_Extractor {
343
  'item_id' => array(
344
  'label' => __( 'Item ID', 'woo-order-export-lite' ),
345
  'checked' => 0,
 
 
 
 
 
 
 
 
 
 
 
346
  ),
347
- 'line_id' => array( 'label' => __( 'Item #', 'woo-order-export-lite' ), 'checked' => 1 ),
348
- 'sku' => array( 'label' => __( 'SKU', 'woo-order-export-lite' ), 'checked' => 1 ),
349
  'name' => array(
350
  'label' => __( 'Item Name', 'woo-order-export-lite' ),
351
  'checked' => 1,
 
352
  ),
353
  'product_id' => array(
354
  'label' => __( 'Product Id', 'woo-order-export-lite' ),
355
  'checked' => 0,
 
356
  ),
357
  'product_name' => array(
358
  'label' => __( 'Product Name', 'woo-order-export-lite' ),
359
  'checked' => 0,
 
360
  ),
361
  'variation_id' => array(
362
  'label' => __( 'Variation Id', 'woo-order-export-lite' ),
363
  'checked' => 0,
 
364
  ),
365
  'product_variation' => array(
366
  'label' => __( 'Product Variation', 'woo-order-export-lite' ),
367
  'checked' => 0,
 
368
  ),
369
  'seller' => array(
370
  'label' => __( 'Item Seller', 'woo-order-export-lite' ),
371
  'checked' => 0,
 
372
  ),
373
  'qty' => array(
374
  'label' => __( 'Quantity', 'woo-order-export-lite' ),
375
  'checked' => 1,
 
376
  ),
377
  'qty_minus_refund' => array(
378
  'label' => __( 'Quantity (- Refund)', 'woo-order-export-lite' ),
379
  'checked' => 0,
 
380
  ),
381
  'item_price' => array(
382
  'label' => __( 'Item Cost', 'woo-order-export-lite' ),
@@ -477,30 +494,47 @@ class WC_Order_Export_Data_Extractor_UI extends WC_Order_Export_Data_Extractor {
477
  'product_url' => array(
478
  'label' => __( 'Product URL', 'woo-order-export-lite' ),
479
  'checked' => 0,
 
480
  ),
481
  'download_url' => array(
482
  'label' => __( 'Download URL', 'woo-order-export-lite' ),
483
  'checked' => 0,
 
484
  ),
485
  'image_url' => array(
486
  'label' => __( 'Image URL', 'woo-order-export-lite' ),
487
  'checked' => 0,
 
488
  ),
489
  'product_shipping_class' => array(
490
  'label' => __( 'Product Shipping Class', 'woo-order-export-lite' ),
491
  'checked' => 0,
 
492
  ),
493
  'post_content' => array(
494
  'label' => __( 'Description', 'woo-order-export-lite' ),
495
  'checked' => 0,
 
496
  ),
497
  'post_excerpt' => array(
498
  'label' => __( 'Short Description', 'woo-order-export-lite' ),
499
  'checked' => 0,
 
500
  ),
501
  'full_category_names' => array(
502
  'label' => __( 'Full names for categories', 'woo-order-export-lite' ),
503
  'checked' => 0,
 
 
 
 
 
 
 
 
 
 
 
504
  ),
505
  );
506
 
@@ -517,6 +551,7 @@ class WC_Order_Export_Data_Extractor_UI extends WC_Order_Export_Data_Extractor {
517
  'code' => array(
518
  'label' => __( 'Coupon Code', 'woo-order-export-lite' ),
519
  'checked' => 1,
 
520
  ),
521
  'discount_amount' => array(
522
  'label' => __( 'Discount Amount', 'woo-order-export-lite' ),
@@ -531,6 +566,7 @@ class WC_Order_Export_Data_Extractor_UI extends WC_Order_Export_Data_Extractor {
531
  'discount_amount_plus_tax' => array(
532
  'label' => __( 'Discount Amount + Tax', 'woo-order-export-lite' ),
533
  'checked' => 0,
 
534
  ),
535
  'excerpt' => array(
536
  'label' => __( 'Coupon Description', 'woo-order-export-lite' ),
@@ -539,6 +575,7 @@ class WC_Order_Export_Data_Extractor_UI extends WC_Order_Export_Data_Extractor {
539
  'discount_type' => array(
540
  'label' => __( 'Coupon Type', 'woo-order-export-lite' ),
541
  'checked' => 0,
 
542
  ),
543
  'coupon_amount' => array(
544
  'label' => __( 'Coupon Amount', 'woo-order-export-lite' ),
@@ -558,7 +595,7 @@ class WC_Order_Export_Data_Extractor_UI extends WC_Order_Export_Data_Extractor {
558
 
559
  public static function get_order_fields( $format ) {
560
  $map = array();
561
- foreach ( array( 'common', 'user', 'billing', 'shipping', 'product', 'coupon', 'cart', 'misc' ) as $segment ) {
562
  $method = "get_order_fields_" . $segment;
563
  $map_segment = self::$method();
564
 
@@ -577,10 +614,26 @@ class WC_Order_Export_Data_Extractor_UI extends WC_Order_Export_Data_Extractor {
577
 
578
  public static function get_order_fields_common() {
579
  return array(
580
- 'line_number' => array( 'label' => __( 'Line number', 'woo-order-export-lite' ), 'checked' => 0 ),
581
- 'order_id' => array( 'label' => __( 'Order ID', 'woo-order-export-lite' ), 'checked' => 0 ),
582
- 'order_number' => array( 'label' => __( 'Order Number', 'woo-order-export-lite' ), 'checked' => 1 ),
583
- 'order_status' => array( 'label' => __( 'Order Status', 'woo-order-export-lite' ), 'checked' => 1 ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
584
  'order_date' => array(
585
  'label' => __( 'Order Date', 'woo-order-export-lite' ),
586
  'checked' => 1,
@@ -594,6 +647,12 @@ class WC_Order_Export_Data_Extractor_UI extends WC_Order_Export_Data_Extractor {
594
  'transaction_id' => array(
595
  'label' => __( 'Transaction ID', 'woo-order-export-lite' ),
596
  'checked' => 0,
 
 
 
 
 
 
597
  ),
598
  'completed_date' => array(
599
  'label' => __( 'Completed Date', 'woo-order-export-lite' ),
@@ -628,30 +687,37 @@ class WC_Order_Export_Data_Extractor_UI extends WC_Order_Export_Data_Extractor {
628
  'customer_ip_address' => array(
629
  'label' => __( 'Customer IP address', 'woo-order-export-lite' ),
630
  'checked' => 0,
 
631
  ),
632
  'customer_user' => array(
633
  'label' => __( 'Customer User ID', 'woo-order-export-lite' ),
634
  'checked' => 0,
 
635
  ),
636
  'user_login' => array(
637
  'label' => __( 'Customer Username', 'woo-order-export-lite' ),
638
  'checked' => 0,
 
639
  ),
640
  'user_url' => array(
641
  'label' => __( 'User Website', 'woo-order-export-lite' ),
642
  'checked' => 0,
 
643
  ),
644
  'user_email' => array(
645
  'label' => __( 'Customer User Email', 'woo-order-export-lite' ),
646
  'checked' => 0,
 
647
  ),
648
  'user_role' => array(
649
  'label' => __( 'Customer Role', 'woo-order-export-lite' ),
650
  'checked' => 0,
 
651
  ),
652
  'customer_total_orders' => array(
653
  'label' => __( 'Customer Total Orders', 'woo-order-export-lite' ),
654
  'checked' => 0,
 
655
  ),
656
  );
657
  }
@@ -883,9 +949,9 @@ class WC_Order_Export_Data_Extractor_UI extends WC_Order_Export_Data_Extractor {
883
  'format' => 'money',
884
  ),
885
  'order_subtotal_minus_discount' => array(
886
- 'label' => 'Order Subtotal - Cart Discount',
887
- 'colname' => 'Order Subtotal - Cart Discount',
888
  'checked' => 0,
 
889
  ),
890
  'order_subtotal_refunded' => array(
891
  'label' => __( 'Order Subtotal Amount Refunded', 'woo-order-export-lite' ),
@@ -902,11 +968,21 @@ class WC_Order_Export_Data_Extractor_UI extends WC_Order_Export_Data_Extractor {
902
  'checked' => 0,
903
  'format' => 'money',
904
  ),
 
 
 
 
 
905
  'order_shipping' => array(
906
  'label' => __( 'Order Shipping Amount', 'woo-order-export-lite' ),
907
  'checked' => 1,
908
  'format' => 'money',
909
  ),
 
 
 
 
 
910
  'order_shipping_refunded' => array(
911
  'label' => __( 'Order Shipping Amount Refunded', 'woo-order-export-lite' ),
912
  'checked' => 0,
@@ -932,6 +1008,16 @@ class WC_Order_Export_Data_Extractor_UI extends WC_Order_Export_Data_Extractor {
932
  'checked' => 0,
933
  'format' => 'money',
934
  ),
 
 
 
 
 
 
 
 
 
 
935
  'order_refund' => array(
936
  'label' => __( 'Order Refund Amount', 'woo-order-export-lite' ),
937
  'checked' => 1,
@@ -967,11 +1053,6 @@ class WC_Order_Export_Data_Extractor_UI extends WC_Order_Export_Data_Extractor {
967
  'checked' => 0,
968
  'format' => 'money',
969
  ),
970
- 'order_currency' => array(
971
- 'label' => __( 'Currency', 'woo-order-export-lite' ),
972
- 'checked' => 0,
973
- 'format' => 'string',
974
- ),
975
  );
976
  }
977
 
@@ -985,14 +1066,17 @@ class WC_Order_Export_Data_Extractor_UI extends WC_Order_Export_Data_Extractor {
985
  'count_total_items' => array(
986
  'label' => __( 'Total items', 'woo-order-export-lite' ),
987
  'checked' => 0,
 
988
  ),
989
  'count_exported_items' => array(
990
  'label' => __( 'Exported items', 'woo-order-export-lite' ),
991
  'checked' => 0,
 
992
  ),
993
  'count_unique_products' => array(
994
  'label' => __( 'Total products', 'woo-order-export-lite' ),
995
  'checked' => 0,
 
996
  ),
997
  );
998
  }
@@ -1013,12 +1097,23 @@ class WC_Order_Export_Data_Extractor_UI extends WC_Order_Export_Data_Extractor {
1013
  return array(
1014
  'common' => __( 'Common', 'woo-order-export-lite' ),
1015
  'user' => __( 'User', 'woo-order-export-lite' ),
1016
- 'billing' => __( 'Billing', 'woo-order-export-lite' ),
1017
- 'shipping' => __( 'Shipping', 'woo-order-export-lite' ),
1018
- 'product' => __( 'Products', 'woo-order-export-lite' ),
1019
- 'coupon' => __( 'Coupons', 'woo-order-export-lite' ),
1020
- 'cart' => __( 'Cart', 'woo-order-export-lite' ),
1021
- 'misc' => __( 'Others', 'woo-order-export-lite' ),
 
 
 
 
 
 
 
 
 
 
 
1022
  );
1023
  }
1024
 
343
  'item_id' => array(
344
  'label' => __( 'Item ID', 'woo-order-export-lite' ),
345
  'checked' => 0,
346
+ 'format' => 'number',
347
+ ),
348
+ 'line_id' => array(
349
+ 'label' => __( 'Item #', 'woo-order-export-lite' ),
350
+ 'checked' => 1,
351
+ 'format' => 'number',
352
+ ),
353
+ 'sku' => array(
354
+ 'label' => __( 'SKU', 'woo-order-export-lite' ),
355
+ 'checked' => 1,
356
+ 'format' =>'string',
357
  ),
 
 
358
  'name' => array(
359
  'label' => __( 'Item Name', 'woo-order-export-lite' ),
360
  'checked' => 1,
361
+ 'format' =>'string',
362
  ),
363
  'product_id' => array(
364
  'label' => __( 'Product Id', 'woo-order-export-lite' ),
365
  'checked' => 0,
366
+ 'format' => 'number',
367
  ),
368
  'product_name' => array(
369
  'label' => __( 'Product Name', 'woo-order-export-lite' ),
370
  'checked' => 0,
371
+ 'format' =>'string',
372
  ),
373
  'variation_id' => array(
374
  'label' => __( 'Variation Id', 'woo-order-export-lite' ),
375
  'checked' => 0,
376
+ 'format' =>'number',
377
  ),
378
  'product_variation' => array(
379
  'label' => __( 'Product Variation', 'woo-order-export-lite' ),
380
  'checked' => 0,
381
+ 'format' =>'string',
382
  ),
383
  'seller' => array(
384
  'label' => __( 'Item Seller', 'woo-order-export-lite' ),
385
  'checked' => 0,
386
+ 'format' =>'string',
387
  ),
388
  'qty' => array(
389
  'label' => __( 'Quantity', 'woo-order-export-lite' ),
390
  'checked' => 1,
391
+ 'format' =>'number',
392
  ),
393
  'qty_minus_refund' => array(
394
  'label' => __( 'Quantity (- Refund)', 'woo-order-export-lite' ),
395
  'checked' => 0,
396
+ 'format' =>'number',
397
  ),
398
  'item_price' => array(
399
  'label' => __( 'Item Cost', 'woo-order-export-lite' ),
494
  'product_url' => array(
495
  'label' => __( 'Product URL', 'woo-order-export-lite' ),
496
  'checked' => 0,
497
+ 'format' =>'string',
498
  ),
499
  'download_url' => array(
500
  'label' => __( 'Download URL', 'woo-order-export-lite' ),
501
  'checked' => 0,
502
+ 'format' =>'string',
503
  ),
504
  'image_url' => array(
505
  'label' => __( 'Image URL', 'woo-order-export-lite' ),
506
  'checked' => 0,
507
+ 'format' =>'string',
508
  ),
509
  'product_shipping_class' => array(
510
  'label' => __( 'Product Shipping Class', 'woo-order-export-lite' ),
511
  'checked' => 0,
512
+ 'format' =>'string',
513
  ),
514
  'post_content' => array(
515
  'label' => __( 'Description', 'woo-order-export-lite' ),
516
  'checked' => 0,
517
+ 'format' =>'string',
518
  ),
519
  'post_excerpt' => array(
520
  'label' => __( 'Short Description', 'woo-order-export-lite' ),
521
  'checked' => 0,
522
+ 'format' =>'string',
523
  ),
524
  'full_category_names' => array(
525
  'label' => __( 'Full names for categories', 'woo-order-export-lite' ),
526
  'checked' => 0,
527
+ 'format' =>'string',
528
+ ),
529
+ 'summary_report_total_qty' => array(
530
+ 'label' => __( 'Summary Report Total Quantity', 'woo-order-export-lite' ),
531
+ 'checked' => 0,
532
+ 'format' =>'number',
533
+ ),
534
+ 'summary_report_total_amount' => array(
535
+ 'label' => __( 'Summary Report Total Amount', 'woo-order-export-lite' ),
536
+ 'checked' => 0,
537
+ 'format' =>'money',
538
  ),
539
  );
540
 
551
  'code' => array(
552
  'label' => __( 'Coupon Code', 'woo-order-export-lite' ),
553
  'checked' => 1,
554
+ 'format' =>'string',
555
  ),
556
  'discount_amount' => array(
557
  'label' => __( 'Discount Amount', 'woo-order-export-lite' ),
566
  'discount_amount_plus_tax' => array(
567
  'label' => __( 'Discount Amount + Tax', 'woo-order-export-lite' ),
568
  'checked' => 0,
569
+ 'format' => 'money',
570
  ),
571
  'excerpt' => array(
572
  'label' => __( 'Coupon Description', 'woo-order-export-lite' ),
575
  'discount_type' => array(
576
  'label' => __( 'Coupon Type', 'woo-order-export-lite' ),
577
  'checked' => 0,
578
+ 'format' =>'string',
579
  ),
580
  'coupon_amount' => array(
581
  'label' => __( 'Coupon Amount', 'woo-order-export-lite' ),
595
 
596
  public static function get_order_fields( $format ) {
597
  $map = array();
598
+ foreach ( array( 'common', 'user', 'billing', 'shipping', 'product', 'coupon', 'cart', 'ship_calc', 'totals', 'misc' ) as $segment ) {
599
  $method = "get_order_fields_" . $segment;
600
  $map_segment = self::$method();
601
 
614
 
615
  public static function get_order_fields_common() {
616
  return array(
617
+ 'line_number' => array(
618
+ 'label' => __( 'Line number', 'woo-order-export-lite' ),
619
+ 'checked' => 0,
620
+ 'format' => 'number',
621
+ ),
622
+ 'order_id' => array(
623
+ 'label' => __( 'Order ID', 'woo-order-export-lite' ),
624
+ 'checked' => 0,
625
+ 'format' => 'number',
626
+ ),
627
+ 'order_number' => array(
628
+ 'label' => __( 'Order Number', 'woo-order-export-lite' ),
629
+ 'checked' => 1,
630
+ 'format' => 'string',
631
+ ),
632
+ 'order_status' => array(
633
+ 'label' => __( 'Order Status', 'woo-order-export-lite' ),
634
+ 'checked' => 1,
635
+ 'format' => 'string',
636
+ ),
637
  'order_date' => array(
638
  'label' => __( 'Order Date', 'woo-order-export-lite' ),
639
  'checked' => 1,
647
  'transaction_id' => array(
648
  'label' => __( 'Transaction ID', 'woo-order-export-lite' ),
649
  'checked' => 0,
650
+ 'format' => 'string',
651
+ ),
652
+ 'order_currency' => array(
653
+ 'label' => __( 'Currency', 'woo-order-export-lite' ),
654
+ 'checked' => 0,
655
+ 'format' => 'string',
656
  ),
657
  'completed_date' => array(
658
  'label' => __( 'Completed Date', 'woo-order-export-lite' ),
687
  'customer_ip_address' => array(
688
  'label' => __( 'Customer IP address', 'woo-order-export-lite' ),
689
  'checked' => 0,
690
+ 'format' => 'string',
691
  ),
692
  'customer_user' => array(
693
  'label' => __( 'Customer User ID', 'woo-order-export-lite' ),
694
  'checked' => 0,
695
+ 'format' => 'number',
696
  ),
697
  'user_login' => array(
698
  'label' => __( 'Customer Username', 'woo-order-export-lite' ),
699
  'checked' => 0,
700
+ 'format' => 'string',
701
  ),
702
  'user_url' => array(
703
  'label' => __( 'User Website', 'woo-order-export-lite' ),
704
  'checked' => 0,
705
+ 'format' => 'string',
706
  ),
707
  'user_email' => array(
708
  'label' => __( 'Customer User Email', 'woo-order-export-lite' ),
709
  'checked' => 0,
710
+ 'format' => 'string',
711
  ),
712
  'user_role' => array(
713
  'label' => __( 'Customer Role', 'woo-order-export-lite' ),
714
  'checked' => 0,
715
+ 'format' => 'string',
716
  ),
717
  'customer_total_orders' => array(
718
  'label' => __( 'Customer Total Orders', 'woo-order-export-lite' ),
719
  'checked' => 0,
720
+ 'format' => 'number',
721
  ),
722
  );
723
  }
949
  'format' => 'money',
950
  ),
951
  'order_subtotal_minus_discount' => array(
952
+ 'label' => __( 'Order Subtotal - Cart Discount', 'woo-order-export-lite' ),
 
953
  'checked' => 0,
954
+ 'format' => 'money',
955
  ),
956
  'order_subtotal_refunded' => array(
957
  'label' => __( 'Order Subtotal Amount Refunded', 'woo-order-export-lite' ),
968
  'checked' => 0,
969
  'format' => 'money',
970
  ),
971
+ );
972
+ }
973
+
974
+ public static function get_order_fields_ship_calc() {
975
+ return array(
976
  'order_shipping' => array(
977
  'label' => __( 'Order Shipping Amount', 'woo-order-export-lite' ),
978
  'checked' => 1,
979
  'format' => 'money',
980
  ),
981
+ 'order_shipping_plus_tax' => array(
982
+ 'label' => __( 'Order Shipping + Tax Amount', 'woo-order-export-lite' ),
983
+ 'checked' => 0,
984
+ 'format' => 'money',
985
+ ),
986
  'order_shipping_refunded' => array(
987
  'label' => __( 'Order Shipping Amount Refunded', 'woo-order-export-lite' ),
988
  'checked' => 0,
1008
  'checked' => 0,
1009
  'format' => 'money',
1010
  ),
1011
+ );
1012
+ }
1013
+
1014
+ public static function get_order_fields_totals() {
1015
+ return array(
1016
+ 'order_total_fee' => array(
1017
+ 'label' => __( 'Order Total Fee', 'woo-order-export-lite' ),
1018
+ 'checked' => 0,
1019
+ 'format' => 'money',
1020
+ ),
1021
  'order_refund' => array(
1022
  'label' => __( 'Order Refund Amount', 'woo-order-export-lite' ),
1023
  'checked' => 1,
1053
  'checked' => 0,
1054
  'format' => 'money',
1055
  ),
 
 
 
 
 
1056
  );
1057
  }
1058
 
1066
  'count_total_items' => array(
1067
  'label' => __( 'Total items', 'woo-order-export-lite' ),
1068
  'checked' => 0,
1069
+ 'format' => 'number',
1070
  ),
1071
  'count_exported_items' => array(
1072
  'label' => __( 'Exported items', 'woo-order-export-lite' ),
1073
  'checked' => 0,
1074
+ 'format' => 'number',
1075
  ),
1076
  'count_unique_products' => array(
1077
  'label' => __( 'Total products', 'woo-order-export-lite' ),
1078
  'checked' => 0,
1079
+ 'format' => 'number',
1080
  ),
1081
  );
1082
  }
1097
  return array(
1098
  'common' => __( 'Common', 'woo-order-export-lite' ),
1099
  'user' => __( 'User', 'woo-order-export-lite' ),
1100
+ 'billing' => __( 'Billing Address', 'woo-order-export-lite' ),
1101
+ 'shipping' => __( 'Shipping Address', 'woo-order-export-lite' ),
1102
+ 'products' => __( 'Products', 'woo-order-export-lite' ),
1103
+ 'coupons' => __( 'Coupons', 'woo-order-export-lite' ),
1104
+ 'cart' => __( 'Cart', 'woo-order-export-lite'),
1105
+ 'ship_calc'=> __( 'Shipping', 'woo-order-export-lite'),
1106
+ 'totals' => __( 'Totals', 'woo-order-export-lite'),
1107
+ 'misc' => __( 'Others', 'woo-order-export-lite' )
1108
+ );
1109
+ }
1110
+
1111
+ public static function get_format_fields() {
1112
+ return array(
1113
+ 'string' => __( 'String', 'woo-order-export-lite' ),
1114
+ 'money' => __( 'Money', 'woo-order-export-lite' ),
1115
+ 'number' => __( 'Number', 'woo-order-export-lite' ),
1116
+ 'date' => __( 'Date', 'woo-order-export-lite' ),
1117
  );
1118
  }
1119
 
classes/core/class-wc-order-export-data-extractor.php CHANGED
@@ -7,11 +7,7 @@ class WC_Order_Export_Data_Extractor {
7
  static $statuses;
8
  static $countries;
9
  static $prices_include_tax;
10
- static $decimal_separator;
11
- static $decimals;
12
- static $thousands_separator;
13
  static $current_order;
14
- static $date_format;
15
  static $object_type = 'shop_order';
16
  static $export_subcategories_separator;
17
  static $export_line_categories_separator;
@@ -433,6 +429,8 @@ class WC_Order_Export_Data_Extractor {
433
  $product_where = join( " AND ", $product_where );
434
  $sql = "SELECT DISTINCT ID FROM {$wpdb->posts} AS products $left_join_product_meta WHERE products.post_type in ('product','product_variation') AND products.post_status<>'trash' AND $product_where ";
435
  $settings['products'] = $wpdb->get_col( $sql );
 
 
436
  }
437
 
438
  // we have to use variations , if user sets product attributes
@@ -440,6 +438,8 @@ class WC_Order_Export_Data_Extractor {
440
  $values = self::sql_subset( $settings['products'] );
441
  $sql = "SELECT DISTINCT ID FROM {$wpdb->posts} AS products WHERE products.post_type in ('product','product_variation') AND products.post_status<>'trash' AND post_parent IN ($values)";
442
  $settings['products'] = $wpdb->get_col( $sql );
 
 
443
  }
444
  if ( ! empty( $sql ) AND self::$track_sql_queries ) {
445
  self::$sql_queries[] = $sql;
@@ -741,7 +741,7 @@ class WC_Order_Export_Data_Extractor {
741
  }
742
  }
743
  }
744
- if ( $settings['user_custom_fields'] ) {
745
  $cf_names = self::get_user_custom_fields();
746
  $filters = self::parse_complex_pairs( $settings['user_custom_fields'], $cf_names );
747
  $pos = 1;
@@ -1125,9 +1125,6 @@ class WC_Order_Export_Data_Extractor {
1125
  self::$statuses = wc_get_order_statuses();
1126
  self::$countries = WC()->countries->countries;
1127
  self::$prices_include_tax = get_option( 'woocommerce_prices_include_tax' ) == 'yes' ? true : false;
1128
- self::$decimal_separator = wc_get_price_decimal_separator();
1129
- self::$thousands_separator = apply_filters( 'woe_thousands_separator', '' );
1130
- self::$decimals = wc_get_price_decimals();
1131
  self::$export_subcategories_separator = apply_filters( 'woe_export_subcategories_separator', ">" );
1132
  self::$export_line_categories_separator = apply_filters( 'woe_export_line_categories_separator', ",\n" );
1133
  self::$export_itemmeta_values_separator = apply_filters( 'woe_export_itemmeta_values_separator', ", " );
@@ -1171,16 +1168,15 @@ class WC_Order_Export_Data_Extractor {
1171
  public static function fetch_order_coupons(
1172
  $order,
1173
  $labels,
1174
- $format,
1175
- $filters_active,
1176
- $get_coupon_meta,
1177
  $static_vals,
1178
- $format_number_fields
1179
  ) {
1180
  global $wpdb;
1181
  $coupons = array();
1182
  foreach ( $order->get_items( 'coupon' ) as $item ) {
1183
  $coupon_meta = array();
 
 
1184
  if ( $get_coupon_meta ) {
1185
  $recs = $wpdb->get_results( $wpdb->prepare( "SELECT meta_value,meta_key FROM {$wpdb->postmeta} AS meta
1186
  JOIN {$wpdb->posts} AS posts ON posts.ID = meta.post_id
@@ -1191,7 +1187,7 @@ class WC_Order_Export_Data_Extractor {
1191
  }
1192
 
1193
  $row = array();
1194
- foreach ( $labels as $field => $label ) {
1195
  if ( isset( $item[ $field ] ) ) {
1196
  $row[ $field ] = $item[ $field ];
1197
  } elseif ( $field == 'code' ) {
@@ -1205,20 +1201,14 @@ class WC_Order_Export_Data_Extractor {
1205
  } else {
1206
  $row[ $field ] = '';
1207
  }
1208
- if ( isset( $filters_active[ $field ] ) ) {
1209
- $row[ $field ] = apply_filters( "woe_get_order_coupon_value_{$field}", $row[ $field ], $order,
1210
- $item );
1211
- $row[ $field ] = apply_filters( "woe_get_order_coupon_{$format}_value_{$field}", $row[ $field ],
1212
- $order, $item );
1213
- }
1214
 
1215
  if ( $field == 'excerpt' ) {
1216
  $post = get_page_by_title( $item['name'], OBJECT, 'shop_' . $item['type'] );
1217
  $row[ $field ] = $post ? $post->post_excerpt : '';
1218
  }
1219
- if ( $format_number_fields ) {
1220
- $row[ $field ] = self::format_numbers( 'order_coupon', $row[ $field ], $field );
1221
- }
1222
  }
1223
  $row = apply_filters( 'woe_fetch_order_coupon', $row, $item, $coupon_meta );
1224
  if ( $row ) {
@@ -1226,39 +1216,31 @@ class WC_Order_Export_Data_Extractor {
1226
  }
1227
  }
1228
 
1229
- return apply_filters( "woe_fetch_order_coupons", $coupons, $order, $labels, $format, $static_vals );
1230
  }
1231
 
1232
 
1233
  /**
1234
  * @param WC_Order $order
1235
- * @param $labels
1236
- * @param $format
1237
- * @param $filters_active
1238
- * @param $static_vals
1239
- * @param $export_only_products
1240
- * @param $export_refunds
1241
  *
1242
  * @return array
1243
  */
1244
  public static function fetch_order_products(
1245
  $order,
1246
  $labels,
1247
- $format,
1248
- $filters_active,
1249
  $static_vals,
1250
- $export_only_products,
1251
- $export_refunds,
1252
- $skip_refunded_items,
1253
- $strip_tags_product_fields,
1254
- $format_number_fields
1255
  ) {
 
1256
  $product_fields_with_tags = array( 'product_variation', 'post_content', 'post_excerpt' );
1257
  $products = array();
1258
  $i = 0;
1259
  foreach ( $order->get_items( 'line_item' ) as $item_id => $item ) {
1260
  do_action( "woe_get_order_product_item", $item );
1261
- if ( $export_refunds AND $item['qty'] == 0 ) // skip zero items, when export refunds
1262
  {
1263
  continue;
1264
  }
@@ -1308,7 +1290,7 @@ class WC_Order_Export_Data_Extractor {
1308
  continue;
1309
  }
1310
 
1311
- if ( $skip_refunded_items ) {
1312
  $qty_minus_refund = $item_meta["_qty"][0] + $order->get_qty_refunded_for_item( $item_id ); // Yes we add negative! qty
1313
  if ( $qty_minus_refund <= 0 ) {
1314
  continue;
@@ -1317,18 +1299,19 @@ class WC_Order_Export_Data_Extractor {
1317
 
1318
  $i ++;
1319
  $row = array();
1320
- foreach ( $labels as $field => $label ) {
1321
  if ( strpos( $field, '__' ) !== false && $taxonomies = wc_get_product_terms( $item['product_id'],
1322
  substr( $field, 2 ), array( 'fields' => 'names' ) )
1323
  ) {
1324
  $row[ $field ] = implode( ', ', $taxonomies );
1325
  } else if ( $field == 'product_shipping_class' ) {
1326
- if ( $taxonomies = wc_get_product_terms( $item['product_id'], $field,
1327
- array( 'fields' => 'names' ) ) ) {
1328
- $row[ $field ] = implode( ', ', $taxonomies );
1329
- } else {
1330
- $row[ $field ] = "";
1331
- } // unknown class
 
1332
  } elseif ( $field == 'line_total_plus_tax' ) {
1333
  $row[ $field ] = $item_meta["_line_total"][0] + $item_meta["_line_tax"][0];
1334
  } elseif ( $field == 'line_subtotal_tax' ) {
@@ -1466,19 +1449,15 @@ class WC_Order_Export_Data_Extractor {
1466
  }
1467
  }
1468
 
1469
- if ( $strip_tags_product_fields AND in_array( $field, $product_fields_with_tags ) ) {
1470
  $row[ $field ] = strip_tags( $row[ $field ] );
1471
  }
1472
 
1473
- if ( $format_number_fields ) {
1474
- $row[ $field ] = self::format_numbers( 'order_product', $row[ $field ], $field );
1475
- }
1476
-
1477
  if ( isset( $row[ $field ] ) ) {
1478
  $row[ $field ] = apply_filters( "woe_get_order_product_value_{$field}", $row[ $field ], $order,
1479
  $item, $product, $item_meta );
1480
- $row[ $field ] = apply_filters( "woe_get_order_product_{$format}_value_{$field}", $row[ $field ],
1481
- $order, $item, $product, $item_meta );
1482
  }
1483
  }
1484
  $row = apply_filters( 'woe_fetch_order_product', $row, $order, $item, $product, $item_meta );
@@ -1486,10 +1465,16 @@ class WC_Order_Export_Data_Extractor {
1486
  $products[ $item_id ] = $row;
1487
  }
1488
  }
1489
-
1490
- return apply_filters( "woe_fetch_order_products", $products, $order, $labels, $format, $static_vals );
1491
  }
1492
 
 
 
 
 
 
 
1493
  public static function get_product_category_full( $product ) {
1494
  $full_names = array();
1495
  if ( ! $product ) {
@@ -1513,6 +1498,13 @@ class WC_Order_Export_Data_Extractor {
1513
  return join( self::$export_line_categories_separator, $full_names );
1514
  }
1515
 
 
 
 
 
 
 
 
1516
  public static function get_order_item_taxes_refund( $order, $item_id ) {
1517
  $tax_refund = 0;
1518
  $order_taxes = $order->get_taxes();
@@ -1527,34 +1519,26 @@ class WC_Order_Export_Data_Extractor {
1527
  public static function fetch_order_data(
1528
  $order_id,
1529
  $labels,
1530
- $format,
1531
- $filters_active,
1532
- $csv_max,
1533
  $export,
1534
- $get_coupon_meta,
1535
  $static_vals,
1536
  $options
1537
  ) {
1538
- global $wpdb;
1539
  global $wp_roles;
1540
 
1541
- $extra_rows = array();
1542
  $row = array();
1543
 
1544
- //$order_id = 390;
1545
-
1546
  // get order meta
1547
  $order_meta = array();
1548
- $recs = get_post_meta( $order_id );
1549
- foreach ( $recs as $meta_key=>$meta_values ) {
1550
- $order_meta[ $meta_key ] = join( self::$export_custom_fields_separator, $meta_values );
 
1551
  }
1552
 
1553
  // take order
1554
  self::$current_order = $order = new WC_Order( $order_id );
1555
 
1556
- self::$date_format = trim( $options['date_format'] . ' ' . $options['time_format'] );
1557
-
1558
  // add fields for WC 3.0
1559
  foreach ( array( "billing_country", "billing_state", "shipping_country", "shipping_state" ) as $field_30 ) {
1560
  $$field_30 = method_exists( $order,
@@ -1571,10 +1555,12 @@ class WC_Order_Export_Data_Extractor {
1571
  // overwrite child values for refunds
1572
  $is_refund = ( $post->post_type == 'shop_order_refund' );
1573
  $overwrite_child_order_meta = apply_filters( 'woe_overwrite_child_order_meta', $is_refund );
1574
- $recs = get_post_meta( $parent_order_id );
1575
- foreach ( $recs as $meta_key=>$meta_values ) {
1576
- if ( $overwrite_child_order_meta OR ! isset( $order_meta[ $meta_key ] ) ) {
1577
- $order_meta[ $meta_key ] = join( self::$export_custom_fields_separator, $meta_values );
 
 
1578
  }
1579
  }
1580
 
@@ -1599,25 +1585,38 @@ class WC_Order_Export_Data_Extractor {
1599
  }
1600
 
1601
  // we know parent!
1602
- if ( $export['products'] OR isset( $labels['order']['count_unique_products'] ) OR isset( $labels['order']['total_weight_items'] ) OR $options['include_products'] ) {
1603
- $temp = $labels['products'];
1604
- $temp['qty'] = '';
1605
- $temp['weight'] = '';
1606
- $data['products'] = self::fetch_order_products( $order, $temp, $format,
1607
- $filters_active['products'], $static_vals['products'], $options['include_products'],
1608
- $options['export_refunds'], $options['skip_refunded_items'], $options['strip_tags_product_fields'],
1609
- $options['format_number_fields'] );
 
 
 
 
 
 
 
1610
  if ( $options['include_products'] AND empty( $data['products'] ) AND apply_filters( "woe_skip_order_without_products",
1611
  false ) ) {
1612
  return array();
1613
  }
 
 
1614
  }
1615
- if ( $export['coupons'] OR isset( $labels['order']['coupons_used'] ) ) {
1616
  // get coupons from main order
1617
- $data['coupons'] = self::fetch_order_coupons( $parent_order ? $parent_order : $order, $labels['coupons'],
1618
- $format,
1619
- $filters_active['coupons'], $get_coupon_meta, $static_vals['coupons'],
1620
- $options['format_number_fields'] );
 
 
 
 
1621
  }
1622
 
1623
  // extra WP_User
@@ -1630,79 +1629,85 @@ class WC_Order_Export_Data_Extractor {
1630
  }
1631
 
1632
 
1633
- $order_fields = array();
1634
  // fill as it must
1635
- foreach ( $labels['order'] as $field => $label ) {
1636
  if ( substr( $field, 0, 5 ) == "USER_" ) { //user field
1637
  $key = substr( $field, 5 );
1638
  $row[ $field ] = $user ? $user->get( $key ) : '';
1639
  } elseif ( $field == 'order_id' ) {
1640
- $row['order_id'] = $order_id;
1641
  } elseif ( $field == 'order_date' ) {
1642
- $row['order_date'] = ! method_exists( $order,
1643
  "get_date_created" ) ? $order->order_date : ( $order->get_date_created() ? gmdate( 'Y-m-d H:i:s',
1644
  $order->get_date_created()->getOffsetTimestamp() ) : '' );
1645
  } elseif ( $field == 'modified_date' ) {
1646
- $row['modified_date'] = ! method_exists( $order,
1647
  "get_date_modified" ) ? $order->modified_date : ( $order->get_date_modified() ? gmdate( 'Y-m-d H:i:s',
1648
  $order->get_date_modified()->getOffsetTimestamp() ) : '' );
1649
  } elseif ( $field == 'completed_date' ) {
1650
- $row['completed_date'] = ! method_exists( $order,
1651
  "get_date_completed" ) ? $order->completed_date : ( $order->get_date_completed() ? gmdate( 'Y-m-d H:i:s',
1652
  $order->get_date_completed()->getOffsetTimestamp() ) : '' );
1653
  } elseif ( $field == 'paid_date' ) {
1654
- $row['paid_date'] = ! method_exists( $order,
1655
  "get_date_paid" ) ? $order->paid_date : ( $order->get_date_paid() ? gmdate( 'Y-m-d H:i:s',
1656
  $order->get_date_paid()->getOffsetTimestamp() ) : '' );
1657
  } elseif ( $field == 'order_number' ) {
1658
- $row['order_number'] = $parent_order ? $parent_order->get_order_number() : $order->get_order_number(); // use parent order number
1659
  } elseif ( $field == 'order_subtotal' ) {
1660
- $row['order_subtotal'] = wc_format_decimal( $order->get_subtotal(), 2 );
1661
  } elseif ( $field == 'order_subtotal_minus_discount' ) {
1662
  $row[ $field ] = $order->get_subtotal() - $order->get_total_discount();
1663
  } elseif ( $field == 'order_subtotal_refunded' ) {
1664
- $row['order_subtotal_refunded'] = wc_format_decimal( self::get_order_subtotal_refunded( $order ), 2 );
1665
  } elseif ( $field == 'order_subtotal_minus_refund' ) {
1666
- $row['order_subtotal_minus_refund'] = wc_format_decimal( $order->get_subtotal() - self::get_order_subtotal_refunded( $order ),
1667
  2 );
1668
  //order total
1669
  } elseif ( $field == 'order_total' ) {
1670
- $row['order_total'] = $order->get_total();
1671
  } elseif ( $field == 'order_total_no_tax' ) {
1672
- $row['order_total_no_tax'] = $order->get_total() - $order->get_total_tax();
1673
  } elseif ( $field == 'order_refund' ) {
1674
- $row['order_refund'] = $order->get_total_refunded();
1675
  } elseif ( $field == 'order_total_inc_refund' ) {
1676
- $row['order_total_inc_refund'] = $order->get_total() - $order->get_total_refunded();
1677
  //shipping
1678
  } elseif ( $field == 'order_shipping' ) {
1679
- $row['order_shipping'] = $order->get_total_shipping();
 
 
1680
  } elseif ( $field == 'order_shipping_refunded' ) {
1681
- $row['order_shipping_refunded'] = $order->get_total_shipping_refunded();
1682
  } elseif ( $field == 'order_shipping_minus_refund' ) {
1683
- $row['order_shipping_minus_refund'] = $order->get_total_shipping() - $order->get_total_shipping_refunded();
1684
  //shipping tax
1685
  } elseif ( $field == 'order_shipping_tax_refunded' ) {
1686
- $row['order_shipping_tax_refunded'] = self::get_order_shipping_tax_refunded( $order_id );
1687
  } elseif ( $field == 'order_shipping_tax_minus_refund' ) {
1688
- $row['order_shipping_tax_minus_refund'] = $order->get_shipping_tax() - self::get_order_shipping_tax_refunded( $order_id );
1689
  //order tax
1690
  } elseif ( $field == 'order_tax' ) {
1691
- $row['order_tax'] = wc_round_tax_total( $order->get_cart_tax() );
 
 
 
 
1692
  } elseif ( $field == 'order_total_tax' ) {
1693
- $row['order_total_tax'] = wc_round_tax_total( $order->get_total_tax() );
1694
  } elseif ( $field == 'order_total_tax_refunded' ) {
1695
- $row['order_total_tax_refunded'] = wc_round_tax_total( $order->get_total_tax_refunded() );
1696
  } elseif ( $field == 'order_total_tax_minus_refund' ) {
1697
- $row['order_total_tax_minus_refund'] = wc_round_tax_total( $order->get_total_tax() - $order->get_total_tax_refunded() );
1698
  } elseif ( $field == 'order_status' ) {
1699
  $status = empty( $order_status ) ? $order->get_status() : $order_status;
1700
  $status = 'wc-' === substr( $status, 0, 3 ) ? substr( $status, 3 ) : $status;
1701
- $row['order_status'] = isset( self::$statuses[ 'wc-' . $status ] ) ? self::$statuses[ 'wc-' . $status ] : $status;
1702
  } elseif ( $field == 'user_login' OR $field == 'user_email' OR $field == 'user_url') {
1703
  $row[ $field ] = $user ? $user->$field : "";
1704
  } elseif ( $field == 'user_role' ) {
1705
- $row[ $field ] = ( isset( $user->roles[0] ) && isset( $wp_roles->roles[ $user->roles[0] ] ) ) ? $wp_roles->roles[ $user->roles[0] ]['name'] : ""; // take first role Name
 
1706
  } elseif ( $field == 'customer_total_orders' ) {
1707
  $row[ $field ] = ( isset( $user->ID ) ) ? wc_get_customer_order_count( $user->ID ) : 0;
1708
  } elseif ( $field == 'billing_address' ) {
@@ -1730,20 +1735,7 @@ class WC_Order_Export_Data_Extractor {
1730
  } elseif ( $field == 'shipping_citystatezip' ) {
1731
  $row[ $field ] = self::get_city_state_postcode_field_value( $order, 'shipping' );
1732
  } elseif ( $field == 'products' OR $field == 'coupons' ) {
1733
- if ( $format == 'xls' OR $format == 'csv' OR $format == 'tsv' ) {
1734
- if ( $options[ $field . '_mode' ] == 'rows' ) {
1735
- //print_r(array_values($row));die();
1736
- //echo count($row)."-".(count($row)+count($labels[$field])-1)."|";
1737
- $items = apply_filters( 'woe_get_' . $field . '_items_for_' . $format . '_rows',
1738
- array_values( $data[ $field ] ), $order ); // remove keys for items in merge
1739
- self::csv_process_multi_rows( $field, $row, $extra_rows, $items, $labels[ $field ],
1740
- $options['item_rows_start_from_new_line'] );
1741
- } else {
1742
- $items = apply_filters( 'woe_get_' . $field . '_items_for_' . $format . '_cols',
1743
- array_values( $data[ $field ] ), $order );
1744
- self::csv_process_multi_cols( $field, $row, $items, $labels[ $field ], $csv_max[ $field ] );
1745
- }
1746
- } else {
1747
  $row[ $field ] = $data[ $field ];
1748
  }
1749
  } elseif ( $field == 'shipping_method_title' ) {
@@ -1839,55 +1831,12 @@ class WC_Order_Export_Data_Extractor {
1839
  }
1840
 
1841
  if ( isset( $row[ $field ] ) ) {
1842
- if ( $options['format_number_fields'] ) {
1843
- $row[ $field ] = self::format_numbers( 'order', $row[ $field ], $field );
1844
- }
1845
-
1846
  $row[ $field ] = apply_filters( "woe_get_order_value_{$field}", $row[ $field ], $order, $field );
1847
- $row[ $field ] = apply_filters( "woe_get_order_{$format}_value_{$field}", $row[ $field ], $order,
1848
- $field );
1849
-
1850
- // must add empty column to extra rows
1851
- if ( $field != 'products' AND $field != 'coupons' AND $extra_rows ) {
1852
- foreach ( $extra_rows as $idx => $extra_row ) {
1853
- $extra_rows[ $idx ][ $field ] = "";
1854
- }
1855
- }
1856
- $order_fields[] = $field;
1857
  } //if order field set
1858
  }
1859
 
1860
  $row = apply_filters( "woe_fetch_order", $row, $order );
1861
-
1862
- // Must fill child cells?
1863
- if ( empty( $options['item_rows_start_from_new_line'] ) AND ! empty( $options['populate_other_columns_product_rows'] ) AND $extra_rows ) {
1864
- foreach ( $extra_rows as $idx => $extra_row ) {
1865
- foreach ( $row as $key => $val ) {
1866
- if ( in_array( $key, $order_fields ) ) {
1867
- $extra_rows[ $idx ][ $key ] = $val;
1868
- }// copy main row values to new rows
1869
- }
1870
- }
1871
- }
1872
-
1873
-
1874
- if ( $extra_rows ) {
1875
- array_unshift( $extra_rows, $row );
1876
- } else {
1877
- $extra_rows = array( $row );
1878
- }
1879
-
1880
- //json for complex structures, don't encode nested products&coupons
1881
- foreach ( $extra_rows as $idx => $extra_row ) {
1882
- foreach( $extra_row as $key => $val ) {
1883
- if ( $key === 'products' OR $key === 'coupons' )
1884
- continue;
1885
- if ( is_array( $val ) )
1886
- $extra_rows[ $idx ][ $key ] = json_encode( $val );
1887
- }
1888
- }
1889
-
1890
- return apply_filters( "woe_fetch_order_data", $extra_rows );
1891
  }
1892
 
1893
  public static function get_city_state_postcode_field_value( $order, $type ) {
@@ -1908,85 +1857,6 @@ class WC_Order_Export_Data_Extractor {
1908
  return join( ", ", $citystatepostcode );
1909
  }
1910
 
1911
- public static function csv_process_multi_rows(
1912
- $type,
1913
- &$row,
1914
- &$extra_rows,
1915
- $items,
1916
- $labels,
1917
- $item_rows_start_from_new_line
1918
- ) {
1919
- // to support
1920
- // order row
1921
- // item1 row
1922
- // item1 row
1923
- if ( $item_rows_start_from_new_line ) {
1924
- foreach ( $items as $item ) {
1925
- $new_row = array();
1926
- foreach ( $labels as $field => $label ) {
1927
- $new_row[ $type . "_" . $field ] = $item[ $field ];
1928
- }
1929
- $extra_rows[] = $new_row;
1930
- }
1931
-
1932
- return;//done
1933
- }
1934
-
1935
- $row_size = count( $row );
1936
- // must add one record at least, if no coupons for example!
1937
- if ( empty( $items ) ) {
1938
- $item = array();
1939
- foreach ( $labels as $field => $label ) {
1940
- $item[ $field ] = "";
1941
- }
1942
- $items = array( $item );
1943
- }
1944
-
1945
- $pos = 0;
1946
- foreach ( $items as $data ) {
1947
- if ( $pos == 0 ) { //current row
1948
- foreach ( $labels as $field => $label ) {
1949
- $row[ $type . "_" . $field ] = $data[ $field ];
1950
- }
1951
- } else {
1952
- if ( ! isset( $extra_rows[ $pos - 1 ] ) ) {
1953
- $extra_rows[ $pos - 1 ] = array();
1954
- //add empty row with correct keys
1955
- foreach ( $row as $key => $value ) {
1956
- $extra_rows[ $pos - 1 ][ $key ] = "";
1957
- }
1958
- }
1959
- //set columns with values
1960
- foreach ( $labels as $field => $label ) {
1961
- $extra_rows[ $pos - 1 ][ $type . "_" . $field ] = $data[ $field ];
1962
- }
1963
- }
1964
- $pos ++;
1965
- }
1966
-
1967
- // Have we added new columns to ALL existing extra_rows ??
1968
- while ( $pos <= count( $extra_rows ) ) {
1969
- foreach ( $labels as $field => $label ) {
1970
- $extra_rows[ $pos - 1 ][ $type . "_" . $field ] = "";
1971
- }
1972
- $pos ++;
1973
- }
1974
- }
1975
-
1976
- public static function csv_process_multi_cols( $type, &$row, $data, $labels, $csv_max ) {
1977
- for ( $i = 0; $i < $csv_max; $i ++ ) {
1978
- if ( empty( $data[ $i ] ) ) {
1979
- foreach ( $labels as $field => $label ) {
1980
- $row[ $type . "_" . $field . "_" . $i ] = "";
1981
- }
1982
- } else {
1983
- foreach ( $labels as $field => $label ) {
1984
- $row[ $type . "_" . $field . "_" . $i ] = $data[ $i ][ $field ];
1985
- }
1986
- }
1987
- }
1988
- }
1989
-
1990
  public static function get_order_shipping_tax_refunded( $order_id ) {
1991
  global $wpdb;
1992
  $refund_ship_taxes = $wpdb->get_var( $wpdb->prepare( "
@@ -2048,11 +1918,10 @@ class WC_Order_Export_Data_Extractor {
2048
  if ( taxonomy_exists( wc_sanitize_taxonomy_name( $meta['meta_key'] ) ) ) {
2049
  $term = get_term_by( 'slug', $meta['meta_value'],
2050
  wc_sanitize_taxonomy_name( $meta['meta_key'] ) );
2051
- $meta['meta_key'] = wc_attribute_label( wc_sanitize_taxonomy_name( $meta['meta_key'] ) );
2052
  $meta['meta_value'] = isset( $term->name ) ? $term->name : $meta['meta_value'];
2053
  } else {
2054
- $meta['meta_key'] = apply_filters( 'woocommerce_attribute_label',
2055
- wc_attribute_label( $meta['meta_key'], $product ), $meta['meta_key'] );
2056
  }
2057
 
2058
  $value = wp_kses_post( $meta['meta_key'] ) . $value_delimiter . wp_kses_post( force_balance_tags( $meta['meta_value'] ) );
@@ -2105,15 +1974,4 @@ class WC_Order_Export_Data_Extractor {
2105
  return $shipping_methods;
2106
  }
2107
 
2108
- public static function format_numbers( $object, $value, $field ) {
2109
- $option = WC_Order_Export_Engine::$current_job_settings[ $object . '_fields' ][ $field ];
2110
- if ( isset( $option['format'] ) AND ( $option['format'] == 'money' OR $option['format'] == 'number' ) ) {
2111
- $new_value = number_format( floatval( $value ), self::$decimals, self::$decimal_separator,
2112
- self::$thousands_separator );
2113
- $value = apply_filters( 'woe_format_numbers', $new_value, $value );
2114
- }
2115
-
2116
- return $value;
2117
- }
2118
-
2119
  }
7
  static $statuses;
8
  static $countries;
9
  static $prices_include_tax;
 
 
 
10
  static $current_order;
 
11
  static $object_type = 'shop_order';
12
  static $export_subcategories_separator;
13
  static $export_line_categories_separator;
429
  $product_where = join( " AND ", $product_where );
430
  $sql = "SELECT DISTINCT ID FROM {$wpdb->posts} AS products $left_join_product_meta WHERE products.post_type in ('product','product_variation') AND products.post_status<>'trash' AND $product_where ";
431
  $settings['products'] = $wpdb->get_col( $sql );
432
+ if( empty($settings['products']) ) // failed condition!
433
+ $settings['products'] = array(0);
434
  }
435
 
436
  // we have to use variations , if user sets product attributes
438
  $values = self::sql_subset( $settings['products'] );
439
  $sql = "SELECT DISTINCT ID FROM {$wpdb->posts} AS products WHERE products.post_type in ('product','product_variation') AND products.post_status<>'trash' AND post_parent IN ($values)";
440
  $settings['products'] = $wpdb->get_col( $sql );
441
+ if( empty($settings['products']) ) // failed condition!
442
+ $settings['products'] = array(0);
443
  }
444
  if ( ! empty( $sql ) AND self::$track_sql_queries ) {
445
  self::$sql_queries[] = $sql;
741
  }
742
  }
743
  }
744
+ if ( ! empty($settings['user_custom_fields']) ) {
745
  $cf_names = self::get_user_custom_fields();
746
  $filters = self::parse_complex_pairs( $settings['user_custom_fields'], $cf_names );
747
  $pos = 1;
1125
  self::$statuses = wc_get_order_statuses();
1126
  self::$countries = WC()->countries->countries;
1127
  self::$prices_include_tax = get_option( 'woocommerce_prices_include_tax' ) == 'yes' ? true : false;
 
 
 
1128
  self::$export_subcategories_separator = apply_filters( 'woe_export_subcategories_separator', ">" );
1129
  self::$export_line_categories_separator = apply_filters( 'woe_export_line_categories_separator', ",\n" );
1130
  self::$export_itemmeta_values_separator = apply_filters( 'woe_export_itemmeta_values_separator', ", " );
1168
  public static function fetch_order_coupons(
1169
  $order,
1170
  $labels,
 
 
 
1171
  $static_vals,
1172
+ $options
1173
  ) {
1174
  global $wpdb;
1175
  $coupons = array();
1176
  foreach ( $order->get_items( 'coupon' ) as $item ) {
1177
  $coupon_meta = array();
1178
+ $get_coupon_meta = ( array_diff( $labels->get_keys(),
1179
+ array( 'code', 'discount_amount', 'discount_amount_tax', 'excerpt' ) ) );
1180
  if ( $get_coupon_meta ) {
1181
  $recs = $wpdb->get_results( $wpdb->prepare( "SELECT meta_value,meta_key FROM {$wpdb->postmeta} AS meta
1182
  JOIN {$wpdb->posts} AS posts ON posts.ID = meta.post_id
1187
  }
1188
 
1189
  $row = array();
1190
+ foreach ( $labels->unique_keys() as $field ) {
1191
  if ( isset( $item[ $field ] ) ) {
1192
  $row[ $field ] = $item[ $field ];
1193
  } elseif ( $field == 'code' ) {
1201
  } else {
1202
  $row[ $field ] = '';
1203
  }
1204
+
1205
+ $row[ $field ] = apply_filters( "woe_get_order_coupon_value_{$field}", $row[ $field ], $order,
1206
+ $item );
 
 
 
1207
 
1208
  if ( $field == 'excerpt' ) {
1209
  $post = get_page_by_title( $item['name'], OBJECT, 'shop_' . $item['type'] );
1210
  $row[ $field ] = $post ? $post->post_excerpt : '';
1211
  }
 
 
 
1212
  }
1213
  $row = apply_filters( 'woe_fetch_order_coupon', $row, $item, $coupon_meta );
1214
  if ( $row ) {
1216
  }
1217
  }
1218
 
1219
+ return apply_filters( "woe_fetch_order_coupons", $coupons, $order, $labels->get_legacy_labels(), $format="", $static_vals );
1220
  }
1221
 
1222
 
1223
  /**
1224
  * @param WC_Order $order
1225
+ * @param WC_Order_Export_Labels $labels
1226
+ * @param array $static_vals
1227
+ * @param array $options
 
 
 
1228
  *
1229
  * @return array
1230
  */
1231
  public static function fetch_order_products(
1232
  $order,
1233
  $labels,
 
 
1234
  $static_vals,
1235
+ $options
 
 
 
 
1236
  ) {
1237
+ $export_only_products = $options['include_products'];
1238
  $product_fields_with_tags = array( 'product_variation', 'post_content', 'post_excerpt' );
1239
  $products = array();
1240
  $i = 0;
1241
  foreach ( $order->get_items( 'line_item' ) as $item_id => $item ) {
1242
  do_action( "woe_get_order_product_item", $item );
1243
+ if ( $options['export_refunds'] AND $item['qty'] == 0 ) // skip zero items, when export refunds
1244
  {
1245
  continue;
1246
  }
1290
  continue;
1291
  }
1292
 
1293
+ if ( $options['skip_refunded_items'] ) {
1294
  $qty_minus_refund = $item_meta["_qty"][0] + $order->get_qty_refunded_for_item( $item_id ); // Yes we add negative! qty
1295
  if ( $qty_minus_refund <= 0 ) {
1296
  continue;
1299
 
1300
  $i ++;
1301
  $row = array();
1302
+ foreach ( $labels->unique_keys() as $field ) {
1303
  if ( strpos( $field, '__' ) !== false && $taxonomies = wc_get_product_terms( $item['product_id'],
1304
  substr( $field, 2 ), array( 'fields' => 'names' ) )
1305
  ) {
1306
  $row[ $field ] = implode( ', ', $taxonomies );
1307
  } else if ( $field == 'product_shipping_class' ) {
1308
+ $taxonomies = array();
1309
+ if( !empty($item['variation_id']) )// try get from variation at first!
1310
+ $taxonomies = wc_get_product_terms( $item['variation_id'], $field,array( 'fields' => 'names' ) );
1311
+ if( !$taxonomies )
1312
+ $taxonomies = wc_get_product_terms( $item['product_id'], $field,array( 'fields' => 'names' ) );
1313
+ //done
1314
+ $row[ $field ] = implode( ', ', $taxonomies );
1315
  } elseif ( $field == 'line_total_plus_tax' ) {
1316
  $row[ $field ] = $item_meta["_line_total"][0] + $item_meta["_line_tax"][0];
1317
  } elseif ( $field == 'line_subtotal_tax' ) {
1449
  }
1450
  }
1451
 
1452
+ if ( $options['strip_tags_product_fields'] AND in_array( $field, $product_fields_with_tags ) ) {
1453
  $row[ $field ] = strip_tags( $row[ $field ] );
1454
  }
1455
 
 
 
 
 
1456
  if ( isset( $row[ $field ] ) ) {
1457
  $row[ $field ] = apply_filters( "woe_get_order_product_value_{$field}", $row[ $field ], $order,
1458
  $item, $product, $item_meta );
1459
+ // $row[ $field ] = apply_filters( "woe_get_order_product_{$format}_value_{$field}", $row[ $field ],
1460
+ // $order, $item, $product, $item_meta );
1461
  }
1462
  }
1463
  $row = apply_filters( 'woe_fetch_order_product', $row, $order, $item, $product, $item_meta );
1465
  $products[ $item_id ] = $row;
1466
  }
1467
  }
1468
+
1469
+ return apply_filters( "woe_fetch_order_products", $products, $order, $labels->get_legacy_labels(), $format="", $static_vals );
1470
  }
1471
 
1472
+
1473
+ /**
1474
+ * @param $product WC_Product
1475
+ *
1476
+ * @return string
1477
+ */
1478
  public static function get_product_category_full( $product ) {
1479
  $full_names = array();
1480
  if ( ! $product ) {
1498
  return join( self::$export_line_categories_separator, $full_names );
1499
  }
1500
 
1501
+
1502
+ /**
1503
+ * @param $order WC_Order
1504
+ * @param $item_id
1505
+ *
1506
+ * @return int
1507
+ */
1508
  public static function get_order_item_taxes_refund( $order, $item_id ) {
1509
  $tax_refund = 0;
1510
  $order_taxes = $order->get_taxes();
1519
  public static function fetch_order_data(
1520
  $order_id,
1521
  $labels,
 
 
 
1522
  $export,
 
1523
  $static_vals,
1524
  $options
1525
  ) {
 
1526
  global $wp_roles;
1527
 
1528
+ // $extra_rows = array();
1529
  $row = array();
1530
 
 
 
1531
  // get order meta
1532
  $order_meta = array();
1533
+ if ( $order_post_meta = get_post_meta( $order_id )) {
1534
+ foreach ( $order_post_meta as $meta_key=>$meta_values ) {
1535
+ $order_meta[ $meta_key ] = join( self::$export_custom_fields_separator, $meta_values );
1536
+ }
1537
  }
1538
 
1539
  // take order
1540
  self::$current_order = $order = new WC_Order( $order_id );
1541
 
 
 
1542
  // add fields for WC 3.0
1543
  foreach ( array( "billing_country", "billing_state", "shipping_country", "shipping_state" ) as $field_30 ) {
1544
  $$field_30 = method_exists( $order,
1555
  // overwrite child values for refunds
1556
  $is_refund = ( $post->post_type == 'shop_order_refund' );
1557
  $overwrite_child_order_meta = apply_filters( 'woe_overwrite_child_order_meta', $is_refund );
1558
+
1559
+ if ( $parent_order_meta = get_post_meta( $parent_order_id ) ) {
1560
+ foreach ( $parent_order_meta as $meta_key=>$meta_values ) {
1561
+ if ( $overwrite_child_order_meta OR ! isset( $order_meta[ $meta_key ] ) ) {
1562
+ $order_meta[ $meta_key ] = join( self::$export_custom_fields_separator, $meta_values );
1563
+ }
1564
  }
1565
  }
1566
 
1585
  }
1586
 
1587
  // we know parent!
1588
+ if ( ( $export['products'] || isset( $labels['order']->count_unique_products ) || isset( $labels['order']->total_weight_items ) || $options['include_products'] ) && ! empty( $labels['products'] ) ) {
1589
+ $tmp_labels = clone $labels['products'];
1590
+ // need qty and weight?
1591
+ if( isset( $labels['order']->total_weight_items ) ) {
1592
+ if( !isset($tmp_labels->qty) )
1593
+ $tmp_labels->qty = "";
1594
+ if( !isset($tmp_labels->weight) )
1595
+ $tmp_labels->weight = "";
1596
+ }
1597
+ $data['products'] = self::fetch_order_products(
1598
+ $order,
1599
+ $tmp_labels,
1600
+ isset($static_vals['products']) ? $static_vals['products'] : array(),
1601
+ $options
1602
+ );
1603
  if ( $options['include_products'] AND empty( $data['products'] ) AND apply_filters( "woe_skip_order_without_products",
1604
  false ) ) {
1605
  return array();
1606
  }
1607
+ } else {
1608
+ $data['products'] = array();
1609
  }
1610
+ if ( ( $export['coupons'] OR isset( $labels['order']->coupons_used ) ) && ! empty( $labels['coupons'] ) ) {
1611
  // get coupons from main order
1612
+ $data['coupons'] = self::fetch_order_coupons(
1613
+ $parent_order ? $parent_order : $order,
1614
+ $labels['coupons'],
1615
+ isset($static_vals['coupons']) ? $static_vals['coupons'] : array(),
1616
+ $options
1617
+ );
1618
+ } else {
1619
+ $data['coupons'] = array();
1620
  }
1621
 
1622
  // extra WP_User
1629
  }
1630
 
1631
 
 
1632
  // fill as it must
1633
+ foreach ( $labels['order']->get_fetch_fields() as $field ) {
1634
  if ( substr( $field, 0, 5 ) == "USER_" ) { //user field
1635
  $key = substr( $field, 5 );
1636
  $row[ $field ] = $user ? $user->get( $key ) : '';
1637
  } elseif ( $field == 'order_id' ) {
1638
+ $row[ $field ] = $order_id;
1639
  } elseif ( $field == 'order_date' ) {
1640
+ $row[ $field ] = ! method_exists( $order,
1641
  "get_date_created" ) ? $order->order_date : ( $order->get_date_created() ? gmdate( 'Y-m-d H:i:s',
1642
  $order->get_date_created()->getOffsetTimestamp() ) : '' );
1643
  } elseif ( $field == 'modified_date' ) {
1644
+ $row[ $field ] = ! method_exists( $order,
1645
  "get_date_modified" ) ? $order->modified_date : ( $order->get_date_modified() ? gmdate( 'Y-m-d H:i:s',
1646
  $order->get_date_modified()->getOffsetTimestamp() ) : '' );
1647
  } elseif ( $field == 'completed_date' ) {
1648
+ $row[ $field ] = ! method_exists( $order,
1649
  "get_date_completed" ) ? $order->completed_date : ( $order->get_date_completed() ? gmdate( 'Y-m-d H:i:s',
1650
  $order->get_date_completed()->getOffsetTimestamp() ) : '' );
1651
  } elseif ( $field == 'paid_date' ) {
1652
+ $row[ $field ] = ! method_exists( $order,
1653
  "get_date_paid" ) ? $order->paid_date : ( $order->get_date_paid() ? gmdate( 'Y-m-d H:i:s',
1654
  $order->get_date_paid()->getOffsetTimestamp() ) : '' );
1655
  } elseif ( $field == 'order_number' ) {
1656
+ $row[ $field ] = $parent_order ? $parent_order->get_order_number() : $order->get_order_number(); // use parent order number
1657
  } elseif ( $field == 'order_subtotal' ) {
1658
+ $row[ $field ] = wc_format_decimal( $order->get_subtotal(), 2 );
1659
  } elseif ( $field == 'order_subtotal_minus_discount' ) {
1660
  $row[ $field ] = $order->get_subtotal() - $order->get_total_discount();
1661
  } elseif ( $field == 'order_subtotal_refunded' ) {
1662
+ $row[ $field ] = wc_format_decimal( self::get_order_subtotal_refunded( $order ), 2 );
1663
  } elseif ( $field == 'order_subtotal_minus_refund' ) {
1664
+ $row[ $field ] = wc_format_decimal( $order->get_subtotal() - self::get_order_subtotal_refunded( $order ),
1665
  2 );
1666
  //order total
1667
  } elseif ( $field == 'order_total' ) {
1668
+ $row[ $field ] = $order->get_total();
1669
  } elseif ( $field == 'order_total_no_tax' ) {
1670
+ $row[ $field ] = $order->get_total() - $order->get_total_tax();
1671
  } elseif ( $field == 'order_refund' ) {
1672
+ $row[ $field ] = $order->get_total_refunded();
1673
  } elseif ( $field == 'order_total_inc_refund' ) {
1674
+ $row[ $field ] = $order->get_total() - $order->get_total_refunded();
1675
  //shipping
1676
  } elseif ( $field == 'order_shipping' ) {
1677
+ $row[ $field ] = $order->get_shipping_total();
1678
+ } elseif ( $field == 'order_shipping_plus_tax' ) {
1679
+ $row[ $field ] = $order->get_shipping_total()+$order->get_shipping_tax();
1680
  } elseif ( $field == 'order_shipping_refunded' ) {
1681
+ $row[ $field ] = $order->get_total_shipping_refunded();
1682
  } elseif ( $field == 'order_shipping_minus_refund' ) {
1683
+ $row[ $field ] = $order->get_shipping_total() - $order->get_total_shipping_refunded();
1684
  //shipping tax
1685
  } elseif ( $field == 'order_shipping_tax_refunded' ) {
1686
+ $row[ $field ] = self::get_order_shipping_tax_refunded( $order_id );
1687
  } elseif ( $field == 'order_shipping_tax_minus_refund' ) {
1688
+ $row[ $field ] = $order->get_shipping_tax() - self::get_order_shipping_tax_refunded( $order_id );
1689
  //order tax
1690
  } elseif ( $field == 'order_tax' ) {
1691
+ $row[ $field ] = wc_round_tax_total( $order->get_cart_tax() );
1692
+ } elseif ( $field == 'order_total_fee' ) {
1693
+ $row[ $field ] = array_sum( array_map( function ( $item ) {
1694
+ return $item->get_total();
1695
+ }, $order->get_fees() ) );
1696
  } elseif ( $field == 'order_total_tax' ) {
1697
+ $row[ $field ] = wc_round_tax_total( $order->get_total_tax() );
1698
  } elseif ( $field == 'order_total_tax_refunded' ) {
1699
+ $row[ $field ] = wc_round_tax_total( $order->get_total_tax_refunded() );
1700
  } elseif ( $field == 'order_total_tax_minus_refund' ) {
1701
+ $row[ $field ] = wc_round_tax_total( $order->get_total_tax() - $order->get_total_tax_refunded() );
1702
  } elseif ( $field == 'order_status' ) {
1703
  $status = empty( $order_status ) ? $order->get_status() : $order_status;
1704
  $status = 'wc-' === substr( $status, 0, 3 ) ? substr( $status, 3 ) : $status;
1705
+ $row[ $field ] = isset( self::$statuses[ 'wc-' . $status ] ) ? self::$statuses[ 'wc-' . $status ] : $status;
1706
  } elseif ( $field == 'user_login' OR $field == 'user_email' OR $field == 'user_url') {
1707
  $row[ $field ] = $user ? $user->$field : "";
1708
  } elseif ( $field == 'user_role' ) {
1709
+ $roles = $wp_roles->roles;
1710
+ $row[ $field ] = ( isset( $user->roles[0] ) && isset( $roles[ $user->roles[0] ] ) ) ? $roles[ $user->roles[0] ]['name'] : ""; // take first role Name
1711
  } elseif ( $field == 'customer_total_orders' ) {
1712
  $row[ $field ] = ( isset( $user->ID ) ) ? wc_get_customer_order_count( $user->ID ) : 0;
1713
  } elseif ( $field == 'billing_address' ) {
1735
  } elseif ( $field == 'shipping_citystatezip' ) {
1736
  $row[ $field ] = self::get_city_state_postcode_field_value( $order, 'shipping' );
1737
  } elseif ( $field == 'products' OR $field == 'coupons' ) {
1738
+ if ( isset( $data[ $field ] ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
1739
  $row[ $field ] = $data[ $field ];
1740
  }
1741
  } elseif ( $field == 'shipping_method_title' ) {
1831
  }
1832
 
1833
  if ( isset( $row[ $field ] ) ) {
 
 
 
 
1834
  $row[ $field ] = apply_filters( "woe_get_order_value_{$field}", $row[ $field ], $order, $field );
 
 
 
 
 
 
 
 
 
 
1835
  } //if order field set
1836
  }
1837
 
1838
  $row = apply_filters( "woe_fetch_order", $row, $order );
1839
+ return $row;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1840
  }
1841
 
1842
  public static function get_city_state_postcode_field_value( $order, $type ) {
1857
  return join( ", ", $citystatepostcode );
1858
  }
1859
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1860
  public static function get_order_shipping_tax_refunded( $order_id ) {
1861
  global $wpdb;
1862
  $refund_ship_taxes = $wpdb->get_var( $wpdb->prepare( "
1918
  if ( taxonomy_exists( wc_sanitize_taxonomy_name( $meta['meta_key'] ) ) ) {
1919
  $term = get_term_by( 'slug', $meta['meta_value'],
1920
  wc_sanitize_taxonomy_name( $meta['meta_key'] ) );
1921
+ $meta['meta_key'] = wc_attribute_label( wc_sanitize_taxonomy_name( $meta['meta_key'] ), $product);
1922
  $meta['meta_value'] = isset( $term->name ) ? $term->name : $meta['meta_value'];
1923
  } else {
1924
+ $meta['meta_key'] = wc_attribute_label( $meta['meta_key'], $product );
 
1925
  }
1926
 
1927
  $value = wp_kses_post( $meta['meta_key'] ) . $value_delimiter . wp_kses_post( force_balance_tags( $meta['meta_value'] ) );
1974
  return $shipping_methods;
1975
  }
1976
 
 
 
 
 
 
 
 
 
 
 
 
1977
  }
classes/core/class-wc-order-export-engine.php CHANGED
@@ -47,6 +47,7 @@ class WC_Order_Export_Engine {
47
  break;
48
  }
49
  }
 
50
  } else {
51
  $results[] = $custom_export;
52
  }
@@ -55,6 +56,7 @@ class WC_Order_Export_Engine {
55
  return implode( "<br>\r\n", $results );
56
  }
57
 
 
58
  public static function prepare( $settings, $filepath ) {
59
  if ( empty( $settings['destination']['type'] ) ) {
60
  return __( "No destination selected", 'woo-order-export-lite' );
@@ -140,38 +142,96 @@ class WC_Order_Export_Engine {
140
  return $filename;
141
  }
142
 
 
 
143
 
144
- // labels for output columns
145
- private static function get_labels( $fields, $format, &$static_vals, &$field_formats ) {
146
- $labels = array();
147
- foreach ( $fields as $key => $field ) {
148
- if ( preg_match( '#^custom_field_#', $key ) ) { // for static fields
149
- $static_vals[ $key ] = isset( $field['value'] ) ? $field['value'] : $field['colname'];// FIX BUG here
 
 
 
 
 
 
 
 
 
150
  }
151
- if ( $field['checked'] ) {
152
- $labels[ $key ] = apply_filters( "woe_get_{$format}_label_{$key}", $field['colname'] );
153
 
154
- if ( isset( $field['format'] ) ) {
155
- $field_formats[ $field['format'] ][] = $key;
 
 
156
  }
157
  }
 
 
 
 
 
 
 
158
  }
159
 
160
- return $labels;
 
 
 
 
161
  }
162
 
163
- // gather columns having filters
164
- private static function check_filters( $fields, $format, $type ) {
165
- $filters = array();
166
- foreach ( $fields as $key => $field ) {
167
- if ( $field['checked'] AND has_filter( "woe_get_{$type}_{$format}_value_{$key}" ) ) {
168
- $filters[] = $key;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  }
 
 
 
170
  }
171
 
172
- return $filters;
 
 
 
 
173
  }
174
 
 
175
  /**
176
  * @param string $mode
177
  * @param array $settings
@@ -181,7 +241,7 @@ class WC_Order_Export_Engine {
181
  *
182
  * @return WOE_Formatter
183
  */
184
- private static function init_formater( $mode, $settings, $fname, &$labels, &$static_vals ) {
185
  $format = strtolower( $settings['format'] );
186
  include_once dirname( dirname( __FILE__ ) ) . "/formats/abstract-class-woe-formatter.php";
187
  if ( ! apply_filters( 'woe_load_custom_formatter_' . $format, false ) ) {
@@ -200,106 +260,69 @@ class WC_Order_Export_Engine {
200
  $class = 'WOE_Formatter_' . $format;
201
 
202
  do_action( 'woe_init_custom_formatter', $mode, $fname, $format_settings, $format, $labels, $field_formats,
203
- self::$date_format, $settings );
204
 
205
- return new $class( $mode, $fname, $format_settings, $format, $labels, $field_formats, self::$date_format );
206
  }
207
 
208
  private static function init_labels( $settings, &$labels, &$static_vals, &$field_formats ) {
209
  $format = strtolower( $settings['format'] );
210
 
211
- $static_vals = array( 'order' => array(), 'products' => array(), 'coupons' => array() );
212
- $field_formats = array( 'money' => array(), 'number' => array(), 'date' => array(), 'string' => array() );
213
- $labels = array(
214
- 'order' => self::get_labels( $settings['order_fields'], $format, $static_vals['order'], $field_formats ),
215
- 'products' => self::get_labels( $settings['order_product_fields'], $format, $static_vals['products'],
216
- $field_formats ),
217
- 'coupons' => self::get_labels( $settings['order_coupon_fields'], $format, $static_vals['coupons'],
218
- $field_formats ),
 
 
 
 
 
 
 
219
  );
220
- }
221
-
222
- private static function _prepare_xls_csv( $settings, $order_ids ) {
223
- $format = strtolower( $settings['format'] );
224
-
225
- $csv_max['coupons'] = $csv_max['products'] = 1;
226
- if ( $format == 'xls' OR $format == 'csv' OR $format == 'tsv' ) {
227
- if ( @$settings['order_fields']['products']['repeat'] == 'columns' ) {
228
- if ( @$settings['order_fields']['products']['max_cols'] ) {
229
- $csv_max['products'] = $settings['order_fields']['products']['max_cols'];
230
- } else {
231
- $csv_max['products'] = WC_Order_Export_Data_Extractor::get_max_order_items( "line_item",
232
- $order_ids );
233
- }
234
  }
235
- if ( @$settings['order_fields']['coupons']['repeat'] == 'columns' ) {
236
- if ( @$settings['order_fields']['coupons']['max_cols'] ) {
237
- $csv_max['coupons'] = $settings['order_fields']['coupons']['max_cols'];
238
- } else {
239
- $csv_max['coupons'] = WC_Order_Export_Data_Extractor::get_max_order_items( "coupon", $order_ids );
240
- }
241
  }
242
- }
243
-
244
- return $csv_max;
245
- }
246
 
247
- private static function _optimize_calls( $settings ) {
248
- $format = strtolower( $settings['format'] );
249
-
250
- $filters_active = array(
251
- 'order' => self::check_filters( $settings['order_fields'], $format, 'order' ),
252
- 'products' => self::check_filters( $settings['order_product_fields'], $format, 'order_product' ),
253
- 'coupons' => self::check_filters( $settings['order_coupon_fields'], $format, 'order_coupon' ),
254
- );
255
-
256
- return $filters_active;
257
- }
258
-
259
- private static function _check_products_and_coupons_fields( $settings, &$export, &$labels, &$get_coupon_meta ) {
260
- $export['products'] = $settings['order_fields']['products']['checked'];
261
- $export['coupons'] = $settings['order_fields']['coupons']['checked'];
262
- $get_coupon_meta = ( $export['coupons'] AND array_diff( array_keys( $labels['coupons'] ),
263
- array( 'code', 'discount_amount', 'discount_amount_tax', 'excerpt' ) ) );
264
- if ( empty( $labels['products'] ) ) {
265
- $export['products'] = 0;
266
- unset( $labels['order']['products'] );
267
- }
268
- if ( empty( $labels['coupons'] ) ) {
269
- $export['coupons'] = 0;
270
- unset( $labels['order']['coupons'] );
271
  }
 
272
  }
273
 
274
- private static function _make_header( $format, $labels, $csv_max ) {
275
- $header = ( $format == 'xls' OR $format == 'csv' OR $format == 'tsv' ) ? self::_make_header_csv( $labels,
276
- $csv_max ) : '';
277
- do_action( 'woe_make_header_custom_formatter', $format, $labels, $csv_max );
278
 
279
- return $header;
280
- }
281
-
282
- private static function _make_header_csv( $labels, $csv_max ) {
283
- $header = array();
284
- foreach ( $labels['order'] as $field => $label ) {
285
- $field_header = array();
286
- if ( $field == 'products' OR $field == 'coupons' ) {
287
- for ( $i = 1; $i <= $csv_max[ $field ]; $i ++ ) {
288
- foreach ( $labels[ $field ] as $field2 => $label2 ) {
289
- $field_header[] = $label2 . ( $csv_max[ $field ] > 1 ? ' #' . $i : '' );
290
- }
291
- }
292
  }
293
- if ( empty( $field_header ) ) {
294
- $field_header[] = $label;
295
  }
296
- $field_header = apply_filters( 'woe_add_csv_headers', $field_header, $field );
297
- $header = array_merge( $header, $field_header );
298
  }
299
 
300
- return $header;
301
  }
302
-
303
  private static function _install_options( $settings ) {
304
  global $wpdb;
305
 
@@ -307,14 +330,9 @@ class WC_Order_Export_Engine {
307
 
308
  $options = array();
309
 
310
- if ( $format == 'xls' AND @$settings['format_xls_populate_other_columns_product_rows']
311
- OR $format == 'csv' AND @$settings['format_csv_populate_other_columns_product_rows']
312
- OR $format == 'tsv' AND @$settings['format_tsv_populate_other_columns_product_rows'] ) {
313
- $options['populate_other_columns_product_rows'] = 1;
314
- }
315
  $options['item_rows_start_from_new_line'] = ( $format == 'csv' AND @$settings['format_csv_item_rows_start_from_new_line'] );
316
- $options['products_mode'] = isset( $settings['order_fields']['products']['repeat'] ) ? $settings['order_fields']['products']['repeat'] : "";
317
- $options['coupons_mode'] = isset( $settings['order_fields']['coupons']['repeat'] ) ? $settings['order_fields']['coupons']['repeat'] : "";
318
 
319
  if ( ! empty( $settings['all_products_from_order'] ) ) {
320
  $options['include_products'] = false;
@@ -445,12 +463,12 @@ class WC_Order_Export_Engine {
445
  }
446
 
447
  if ( $make_mode !== 'estimate' ) {
448
- $formater = self::init_formater( $make_mode, $settings, $filename, $labels, $static_vals );
449
  }
450
  $format = strtolower( $settings['format'] );
451
 
452
  if ( $make_mode == 'finish' ) {
453
- self::maybe_output_summary_report( $formater );
454
  $formater->finish();
455
 
456
  return $filename;
@@ -467,35 +485,28 @@ class WC_Order_Export_Engine {
467
  } elseif ( $make_mode == 'partial' ) {
468
  $sql .= apply_filters( "woe_sql_get_order_ids_order_by",
469
  " ORDER BY " . $settings['sort'] . " " . $settings['sort_direction'] );
470
- $offset = ($settings['mark_exported_orders'] && $settings['export_unmarked_orders']) ? 0 : intval( $offset );
471
  $limit = intval( $limit );
472
- $sql .= " LIMIT $offset,$limit";
473
  }
474
 
475
- $order_ids = $wpdb->get_col( $sql );
476
-
477
- // prepare for XLS/CSV
478
- $csv_max = self::_prepare_xls_csv( $settings, $order_ids );
479
 
480
- // try to optimize calls
481
- $filters_active = self::_optimize_calls( $settings );
482
 
483
  // check it once
484
- self::_check_products_and_coupons_fields( $settings, $export, $labels, $get_coupon_meta );
485
 
486
- // make header
487
- $header = self::_make_header( $format, $labels, $csv_max );
488
 
489
  if ( $make_mode != 'partial' ) { // Preview or start_estimate
490
- self::maybe_init_summary_report( $labels );
491
- $formater->start( $header );
492
  if ( $make_mode == 'start_estimate' ) { //Start return total count
493
  return $wpdb->get_var( str_replace( 'ID AS order_id', 'COUNT(ID) AS order_count', $sql ) );
494
  }
495
- } elseif ( $format == 'json' AND $offset > 0 ) { // json partial
496
- $formater->prev_added = true;
497
  }
498
- self::maybe_start_summary_report();
499
 
500
  WC_Order_Export_Data_Extractor::prepare_for_export();
501
  self::$orders_exported = 0;// incorrect value
@@ -505,16 +516,15 @@ class WC_Order_Export_Engine {
505
  continue;
506
  }
507
  self::$order_id = $order_id;
508
- $rows = WC_Order_Export_Data_Extractor::fetch_order_data( $order_id, $labels, $format,
509
- $filters_active,
510
- $csv_max, $export, $get_coupon_meta, $static_vals, self::$extractor_options );
511
- foreach ( $rows as $row ) {
512
- $row = apply_filters( "woe_fetch_order_row", $row, $order_id );
513
- if ( $row ) {
514
- $formater->output( $row );
515
- do_action( "woe_order_row_exported", $row, $order_id );
516
- }
517
  }
 
518
  if ( $make_mode != 'preview' ) {
519
  do_action( "woe_order_exported", $order_id );
520
  self::try_mark_order( $order_id, $settings );
@@ -527,9 +537,9 @@ class WC_Order_Export_Engine {
527
  if ( $make_mode == 'partial' ) {
528
  $formater->finish_partial();
529
  } elseif ( $make_mode == 'preview' ) {
530
- self::maybe_output_summary_report( $formater );
531
- $flat_formats = array( 'XLS', 'CSV', 'TSV' );//limit debug output
532
- if ( $settings['enable_debug'] AND in_array( $settings['format'], $flat_formats ) ) {
533
  echo "<b>" . __( 'Main SQL queries are listed below', 'woo-order-export-lite' ) . "</b>";
534
  echo '<textarea rows=5 style="width:100%">';
535
  $s = array();
@@ -558,11 +568,11 @@ class WC_Order_Export_Engine {
558
 
559
  $filename = ( ! empty( $filename ) ? $filename : self::tempnam( sys_get_temp_dir(), $settings['format'] ) );
560
 
561
- $formater = self::init_formater( '', $settings, $filename, $labels, $static_vals );
562
- $format = strtolower( $settings['format'] );
563
 
564
- self::maybe_init_summary_report( $labels );
565
- self::maybe_start_summary_report();
566
 
567
  //get IDs
568
  $sql = WC_Order_Export_Data_Extractor::sql_get_order_ids( $settings );
@@ -573,7 +583,7 @@ class WC_Order_Export_Engine {
573
  $sql .= " LIMIT " . intval( $limit );
574
  }
575
  if ( ! $order_ids ) {
576
- $order_ids = $wpdb->get_col( $sql );
577
  }
578
 
579
  if ( empty( $order_ids ) AND apply_filters( 'woe_schedule_job_skip_empty_file',
@@ -582,20 +592,15 @@ class WC_Order_Export_Engine {
582
  return false;
583
  }
584
 
585
- // prepare for XLS/CSV
586
- $csv_max = self::_prepare_xls_csv( $settings, $order_ids );
587
-
588
- // try to optimize calls
589
- $filters_active = self::_optimize_calls( $settings );
590
 
591
  // check it once
592
- self::_check_products_and_coupons_fields( $settings, $export, $labels, $get_coupon_meta );
593
 
594
- // make header
595
- $header = self::_make_header( $format, $labels, $csv_max );
596
 
597
- $formater->start( $header );
598
- do_action( 'woe_start_custom_formatter', $header );
599
 
600
  WC_Order_Export_Data_Extractor::prepare_for_export();
601
  self::$orders_exported = 0;
@@ -605,27 +610,24 @@ class WC_Order_Export_Engine {
605
  continue;
606
  }
607
  self::$order_id = $order_id;
608
- $rows = WC_Order_Export_Data_Extractor::fetch_order_data( $order_id, $labels, $format,
609
- $filters_active,
610
- $csv_max, $export, $get_coupon_meta, $static_vals, self::$extractor_options );
611
- foreach ( $rows as $row ) {
612
- $row = apply_filters( "woe_fetch_order_row", $row, $order_id );
613
- if ( $row ) {
614
- $formater->output( $row );
615
- do_action( "woe_order_row_exported", $row, $order_id );
616
- }
617
  }
618
  do_action( "woe_order_exported", $order_id );
619
 
620
- do_action( 'woe_formatter_output_custom_formatter', $order_id, $labels, $format, $filters_active,
621
- $csv_max, $export, $get_coupon_meta, $static_vals, self::$extractor_options );
622
 
623
  self::$orders_exported ++;
624
  self::try_modify_status( $order_id, $settings );
625
  self::try_mark_order( $order_id, $settings );
626
  }
627
 
628
- self::maybe_output_summary_report( $formater );
629
  $formater->finish();
630
  do_action( 'woe_finish_custom_formatter' );
631
 
@@ -651,8 +653,7 @@ class WC_Order_Export_Engine {
651
 
652
  $filename = ( ! empty( $filename ) ? $filename : self::tempnam( sys_get_temp_dir(), $settings['format'] ) );
653
 
654
- self::init_labels( $settings, $labels, $static_vals, $field_formats );
655
- $format = strtolower( $settings['format'] );
656
 
657
  //get IDs
658
  $sql = WC_Order_Export_Data_Extractor::sql_get_order_ids( $settings );
@@ -664,23 +665,18 @@ class WC_Order_Export_Engine {
664
  }
665
 
666
  if ( ! $order_ids ) {
667
- $order_ids = $wpdb->get_col( $sql );
668
  }
669
 
670
  if ( empty( $order_ids ) ) {
671
  return false;
672
  }
673
- // prepare for XLS/CSV
674
- $csv_max = self::_prepare_xls_csv( $settings, $order_ids );
675
-
676
- // try to optimize calls
677
- $filters_active = self::_optimize_calls( $settings );
678
 
679
  // check it once
680
- self::_check_products_and_coupons_fields( $settings, $export, $labels, $get_coupon_meta );
681
 
682
- // make header
683
- $header = self::_make_header( $format, $labels, $csv_max );
684
 
685
  $result = false;
686
 
@@ -692,18 +688,17 @@ class WC_Order_Export_Engine {
692
  continue;
693
  }
694
  self::$order_id = $order_id;
695
- $formater = self::init_formater( '', $settings, $filename, $_labels, $_static_vals );
696
 
697
  $formater->truncate();
698
- $formater->start( $header );
699
- $rows = WC_Order_Export_Data_Extractor::fetch_order_data( $order_id, $labels, $format, $filters_active,
700
- $csv_max, $export, $get_coupon_meta, $static_vals, self::$extractor_options );
701
- foreach ( $rows as $row ) {
702
- $row = apply_filters( "woe_fetch_order_row", $row, $order_id );
703
- if ( $row ) {
704
- $formater->output( $row );
705
- do_action( "woe_order_row_exported", $row, $order_id );
706
- }
707
  }
708
  do_action( "woe_order_exported", $order_id );
709
  self::$orders_exported = 1;
@@ -762,113 +757,8 @@ class WC_Order_Export_Engine {
762
  }
763
  }
764
 
765
-
766
- //SUMMARY report starts here
767
- private static function check_create_session() {
768
- if ( ! session_id() ) {
769
- @session_start();
770
- }
771
- }
772
-
773
- //reset data
774
- private static function maybe_init_summary_report( $labels ) {
775
- if ( ! self::$current_job_settings['summary_report_by_products'] ) {
776
- return;
777
- }
778
- self::check_create_session();
779
-
780
- //make new header
781
- add_filter( 'woe_' . strtolower( self::$current_job_settings['format'] ) . '_header_filter',
782
- function () use ( $labels ) {
783
- $header = array();
784
- foreach ( $labels['products'] as $k => $v ) {
785
- if ( ! preg_match( '#^(line_|qty)#', $k ) ) {
786
- $header[ $k ] = $v;
787
- }
788
- }
789
- $_SESSION['woe_summary_columns'] = $header;
790
-
791
- // prepare output
792
- $header = array_values( $header );
793
- // extra columns
794
- $summary_headers = array(
795
- __( "Total Quantity", 'woo-order-export-lite' ),
796
- __( "Total Amount", 'woo-order-export-lite' ),
797
- );
798
- $header = apply_filters( "woe_summary_headers", array_merge( $header, $summary_headers ) );
799
-
800
- return $header;
801
- } );
802
- $_SESSION['woe_summary_products'] = array();
803
- }
804
-
805
- //get ready to accept data
806
- private static function maybe_start_summary_report() {
807
- if ( ! self::$current_job_settings['summary_report_by_products'] ) {
808
- return;
809
- }
810
- self::check_create_session();
811
-
812
- //don't output orders
813
- add_filter( 'woe_fetch_order_row', '__return_false' );
814
- // gather details
815
- add_filter( "woe_fetch_order_products", array( 'WC_Order_Export_Engine', 'summary_report_add_order_products' ),
816
- 10, 5 );
817
- }
818
-
819
- public static function summary_report_add_order_products( $products, $order, $labels, $format, $static_vals ) {
820
- foreach ( $order->get_items() as $item_id => $item ) {
821
- if ( ! isset( $products[ $item_id ] ) ) {
822
- continue;
823
- }
824
- $prepared_product = $products[ $item_id ];
825
- $product = $order->get_product_from_item( $item );
826
-
827
- //ok can process this product
828
- $product_id = ! empty( $item['variation_id'] ) ? $item['variation_id'] : $item['product_id'];
829
- $key = ! empty( $product_id ) ? $product_id : $item['name'];
830
- $key = apply_filters( "woe_summary_products_adjust_key", $key, $product, $item, $order );
831
- if ( ! isset( $_SESSION['woe_summary_products'][ $key ] ) ) {
832
- //take only exported fields to match columns
833
- $summary_product = array_intersect_key( $prepared_product, $_SESSION['woe_summary_columns'] );
834
- //extra columns
835
- $summary_rows = apply_filters( "woe_summary_column_keys", array( 'qty' => 0, 'total' => 0 ) );
836
- foreach ( $summary_rows as $k => $default ) {
837
- $summary_product[ $k ] = $default;
838
- }
839
- $summary_product = apply_filters( "woe_summary_products_prepare_product",
840
- $summary_product, $key, $product, $item, $order );
841
- $_SESSION['woe_summary_products'][ $key ] = $summary_product;
842
- }
843
- //sum items
844
- $total = method_exists( $item,
845
- 'get_total' ) ? $item->get_total() : $item['line_total'];
846
- $_SESSION['woe_summary_products'][ $key ]['total'] += wc_round_tax_total( $total );
847
- $_SESSION['woe_summary_products'][ $key ]['qty'] += $item['qty'];
848
- do_action( 'woe_summary_products_add_item', $key, $item, $order );
849
- }
850
-
851
- return $products;
852
- }
853
-
854
- private static function maybe_output_summary_report( $formatter ) {
855
- if ( ! self::$current_job_settings['summary_report_by_products'] ) {
856
- return;
857
- }
858
- self::check_create_session();
859
-
860
- //possible formatting
861
- self::$current_job_settings['summary_fields']['total'] = array( 'format' => 'money' );
862
-
863
- ksort( $_SESSION['woe_summary_products'] );// by Name+Id
864
-
865
- do_action( 'woe_summary_before_output' );
866
-
867
- foreach ( $_SESSION['woe_summary_products'] as $data ) {
868
- if ( self::$extractor_options['format_number_fields'] and isset( $data['total'] ) ) {
869
- $data['total'] = WC_Order_Export_Data_Extractor::format_numbers( 'summary', $data['total'], 'total' );
870
- }
871
- $formatter->output( $data );
872
- }
873
  }
874
  }
47
  break;
48
  }
49
  }
50
+ do_action("woe_export_destination_finished", $exporter->finished_successfully, $export_type, $filename, $filepath, $settings, $exporter);
51
  } else {
52
  $results[] = $custom_export;
53
  }
56
  return implode( "<br>\r\n", $results );
57
  }
58
 
59
+ /* Zapier will pull files! */
60
  public static function prepare( $settings, $filepath ) {
61
  if ( empty( $settings['destination']['type'] ) ) {
62
  return __( "No destination selected", 'woo-order-export-lite' );
142
  return $filename;
143
  }
144
 
145
+ private static function get_order_labels( $settings, $format, $field_formats_list ) {
146
+ $fields = $settings['order_fields'];
147
 
148
+ $labels = new WC_Order_Export_Labels();
149
+ $static_fields = array();
150
+ $field_formats = array();
151
+
152
+ foreach ( $fields as $num_index => $field ) {
153
+ if ( empty ( $field['key'] ) ) {
154
+ continue;
155
+ }
156
+ $full_key = $field['key'];
157
+
158
+ $key = $full_key;
159
+ if ( preg_match( '/^plain_orders_(.+)/', $full_key, $matches ) ) {
160
+ if ( isset( $matches[1] ) && ! strpos( $matches[1], 'static_field' ) ) {
161
+ $key = $matches[1];
162
+ }
163
  }
 
 
164
 
165
+
166
+ if ( preg_match( '/^(static_field_.+)/', $full_key, $matches ) ) { // for static fields
167
+ if ( isset( $matches[1] ) ) {
168
+ $static_fields[ $matches[1] ] = isset( $field['value'] ) ? $field['value'] : $field['colname'];// FIX BUG here
169
  }
170
  }
171
+
172
+ if ( isset( $field['format'] ) && in_array( $field['format'], $field_formats_list ) ) {
173
+ $field_formats[ $field['format'] ][] = $key;
174
+ }
175
+
176
+ $field['colname'] = apply_filters( "woe_get_{$format}_label_{$key}", $field['colname'] );
177
+ $labels->$key = $field['colname'];
178
  }
179
 
180
+ return array(
181
+ 'labels' => $labels->is_not_empty() ? $labels : false,
182
+ 'static_fields' => $static_fields,
183
+ 'field_formats' => $field_formats,
184
+ );
185
  }
186
 
187
+ /* process product/coupon fields*/
188
+ private static function get_sub_segment_labels( $segment, $settings, $format, $field_formats_list ) {
189
+ $labels = new WC_Order_Export_Labels();
190
+ $static_fields = array();
191
+ $field_formats = array();
192
+
193
+ $is_flat = self::is_plain_format( $format );
194
+ $fields = $is_flat ? $settings['order_fields'] : $settings['order_' . $segment . '_fields'];
195
+
196
+ foreach ( $fields as $field ) {
197
+ if ( empty ( $field['key'] ) ) {
198
+ continue;
199
+ }
200
+ $full_key = $field['key'];
201
+
202
+ $key = $full_key;
203
+ if ( $is_flat ) {
204
+ if ( preg_match( '/^plain_'. $segment . 's_(.+)/', $full_key, $matches ) ) {
205
+ if ( isset( $matches[1] ) ) {
206
+ $key = $matches[1];
207
+ }
208
+ } else {
209
+ continue;
210
+ }
211
+ }
212
+
213
+ if ( preg_match( '/^(static_field_.+)/', $key, $matches ) ) { // for static fields
214
+ if ( isset( $matches[1] ) ) {
215
+ $static_fields[ $key ] = isset( $field['value'] ) ? $field['value'] : $field['colname'];// FIX BUG here
216
+ }
217
+ }
218
+
219
+ if ( isset( $field['format'] ) && in_array( $field['format'], $field_formats_list ) ) {
220
+ $field_formats[ $field['format'] ][] = $key;
221
  }
222
+
223
+ $field['colname'] = apply_filters( "woe_get_{$format}_label_{$key}", $field['colname'] );
224
+ $labels->$key = $field['colname'];
225
  }
226
 
227
+ return array(
228
+ 'labels' => $labels->is_not_empty() ? $labels : false,
229
+ 'static_fields' => $static_fields,
230
+ 'field_formats' => $field_formats,
231
+ );
232
  }
233
 
234
+
235
  /**
236
  * @param string $mode
237
  * @param array $settings
241
  *
242
  * @return WOE_Formatter
243
  */
244
+ private static function init_formater( $mode, $settings, $fname, &$labels, &$static_vals, $offset ) {
245
  $format = strtolower( $settings['format'] );
246
  include_once dirname( dirname( __FILE__ ) ) . "/formats/abstract-class-woe-formatter.php";
247
  if ( ! apply_filters( 'woe_load_custom_formatter_' . $format, false ) ) {
260
  $class = 'WOE_Formatter_' . $format;
261
 
262
  do_action( 'woe_init_custom_formatter', $mode, $fname, $format_settings, $format, $labels, $field_formats,
263
+ self::$date_format, $settings, $offset );
264
 
265
+ return new $class( $mode, $fname, $format_settings, $format, $labels, $field_formats, self::$date_format, $offset );
266
  }
267
 
268
  private static function init_labels( $settings, &$labels, &$static_vals, &$field_formats ) {
269
  $format = strtolower( $settings['format'] );
270
 
271
+ // $static_vals = array( 'order' => array(), 'products' => array(), 'coupons' => array() );
272
+ // $field_formats = array( 'money' => array(), 'number' => array(), 'date' => array(), 'string' => array() );
273
+ // $labels = array(
274
+ // 'order' => self::get_labels( $settings,'order_fields', $format, $static_vals['order'], $field_formats ),
275
+ // 'products' => self::get_labels( $settings,'order_product_fields', $format, $static_vals['products'],
276
+ // $field_formats ),
277
+ // 'coupons' => self::get_labels( $settings,'order_coupon_fields', $format, $static_vals['coupons'],
278
+ // $field_formats ),
279
+ // );
280
+
281
+ $field_formats_ar = array( 'money', 'number', 'date', 'string' );
282
+ $labels_data = array(
283
+ 'order' => self::get_order_labels( $settings, $format, $field_formats_ar ),
284
+ 'products' => self::get_sub_segment_labels( 'product', $settings, $format, $field_formats_ar ),
285
+ 'coupons' => self::get_sub_segment_labels( 'coupon', $settings, $format, $field_formats_ar ),
286
  );
287
+ $labels = array();
288
+ $static_vals = array();
289
+ $field_formats = array();
290
+ foreach ( $labels_data as $segment => $label_data ) {
291
+ $labels[$segment] = ! empty( $label_data['labels'] ) ? $label_data['labels'] : array();
292
+ if ( ! empty( $label_data['static_fields'] ) ) {
293
+ $static_vals[$segment] = $label_data['static_fields'];
 
 
 
 
 
 
 
294
  }
295
+ if ( ! empty( $label_data['field_formats'] ) ) {
296
+ $field_formats[$segment] = array_map( "array_unique", $label_data['field_formats'] );
297
+ //clean up possible duplicates
298
+ // $field_formats = array_merge_recursive( $field_formats, $label_data['field_formats'] );
 
 
299
  }
 
 
 
 
300
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
  }
302
+ // $field_formats = array_map( "array_unique", $field_formats );
303
  }
304
 
 
 
 
 
305
 
306
+ /**
307
+ * @param $settings
308
+ * @param $export
309
+ */
310
+ private static function _check_products_and_coupons_fields( $settings, &$export ) {
311
+ $export['products'] = false;
312
+ $export['coupons'] = false;
313
+ foreach ( $settings['order_fields'] as $field ) {
314
+ if ( 'products' == $field['key'] ) {
315
+ $export['products'] = true;
316
+ }
317
+ if ( 'coupons' == $field['key'] ) {
318
+ $export['coupons'] = true;
319
  }
320
+ if ( $export['coupons'] && $export['products'] ) {
321
+ break;
322
  }
 
 
323
  }
324
 
 
325
  }
 
326
  private static function _install_options( $settings ) {
327
  global $wpdb;
328
 
330
 
331
  $options = array();
332
 
 
 
 
 
 
333
  $options['item_rows_start_from_new_line'] = ( $format == 'csv' AND @$settings['format_csv_item_rows_start_from_new_line'] );
334
+ $options['products_mode'] = isset( $settings['duplicated_fields_settings']['products']['repeat'] ) ? $settings['duplicated_fields_settings']['products']['repeat'] : "";
335
+ $options['coupons_mode'] = isset( $settings['duplicated_fields_settings']['coupons']['repeat'] ) ? $settings['duplicated_fields_settings']['coupons']['repeat'] : "";
336
 
337
  if ( ! empty( $settings['all_products_from_order'] ) ) {
338
  $options['include_products'] = false;
463
  }
464
 
465
  if ( $make_mode !== 'estimate' ) {
466
+ $formater = self::init_formater( $make_mode, $settings, $filename, $labels, $static_vals, $offset );
467
  }
468
  $format = strtolower( $settings['format'] );
469
 
470
  if ( $make_mode == 'finish' ) {
471
+ // self::maybe_output_summary_report( $formater );
472
  $formater->finish();
473
 
474
  return $filename;
485
  } elseif ( $make_mode == 'partial' ) {
486
  $sql .= apply_filters( "woe_sql_get_order_ids_order_by",
487
  " ORDER BY " . $settings['sort'] . " " . $settings['sort_direction'] );
488
+ $startat = ($settings['mark_exported_orders'] && $settings['export_unmarked_orders']) ? 0 : intval( $offset );
489
  $limit = intval( $limit );
490
+ $sql .= " LIMIT $startat,$limit";
491
  }
492
 
493
+ $order_ids = apply_filters( "woe_get_order_ids", $wpdb->get_col( $sql ) );
 
 
 
494
 
495
+ // prepare for XLS/CSV moved to plain formatter
 
496
 
497
  // check it once
498
+ self::_check_products_and_coupons_fields( $settings, $export );
499
 
500
+ // make header moved to plain formatter
 
501
 
502
  if ( $make_mode != 'partial' ) { // Preview or start_estimate
503
+ // self::maybe_init_summary_report( $labels );
504
+ $formater->start();
505
  if ( $make_mode == 'start_estimate' ) { //Start return total count
506
  return $wpdb->get_var( str_replace( 'ID AS order_id', 'COUNT(ID) AS order_count', $sql ) );
507
  }
 
 
508
  }
509
+ // self::maybe_start_summary_report();
510
 
511
  WC_Order_Export_Data_Extractor::prepare_for_export();
512
  self::$orders_exported = 0;// incorrect value
516
  continue;
517
  }
518
  self::$order_id = $order_id;
519
+ $row = WC_Order_Export_Data_Extractor::fetch_order_data( $order_id, $labels,
520
+ $export, $static_vals, self::$extractor_options );
521
+
522
+ $row = apply_filters( "woe_fetch_order_row", $row, $order_id );
523
+ if ( $row ) {
524
+ $formater->output( $row );
525
+ do_action( "woe_order_row_exported", $row, $order_id );
 
 
526
  }
527
+
528
  if ( $make_mode != 'preview' ) {
529
  do_action( "woe_order_exported", $order_id );
530
  self::try_mark_order( $order_id, $settings );
537
  if ( $make_mode == 'partial' ) {
538
  $formater->finish_partial();
539
  } elseif ( $make_mode == 'preview' ) {
540
+ // self::maybe_output_summary_report( $formater );
541
+ //limit debug output
542
+ if ( $settings['enable_debug'] AND self::is_plain_format( $settings['format']) ) {
543
  echo "<b>" . __( 'Main SQL queries are listed below', 'woo-order-export-lite' ) . "</b>";
544
  echo '<textarea rows=5 style="width:100%">';
545
  $s = array();
568
 
569
  $filename = ( ! empty( $filename ) ? $filename : self::tempnam( sys_get_temp_dir(), $settings['format'] ) );
570
 
571
+ $formater = self::init_formater( '', $settings, $filename, $labels, $static_vals, 0 );
572
+ // $format = strtolower( $settings['format'] );
573
 
574
+ // self::maybe_init_summary_report( $labels );
575
+ // self::maybe_start_summary_report();
576
 
577
  //get IDs
578
  $sql = WC_Order_Export_Data_Extractor::sql_get_order_ids( $settings );
583
  $sql .= " LIMIT " . intval( $limit );
584
  }
585
  if ( ! $order_ids ) {
586
+ $order_ids = apply_filters( "woe_get_order_ids", $wpdb->get_col( $sql ) );
587
  }
588
 
589
  if ( empty( $order_ids ) AND apply_filters( 'woe_schedule_job_skip_empty_file',
592
  return false;
593
  }
594
 
595
+ // prepare for XLS/CSV moved to plain formatter
 
 
 
 
596
 
597
  // check it once
598
+ self::_check_products_and_coupons_fields( $settings, $export );
599
 
600
+ // make header moved to plain formatter
 
601
 
602
+ $formater->start();
603
+ do_action( 'woe_start_custom_formatter' );
604
 
605
  WC_Order_Export_Data_Extractor::prepare_for_export();
606
  self::$orders_exported = 0;
610
  continue;
611
  }
612
  self::$order_id = $order_id;
613
+ $row = WC_Order_Export_Data_Extractor::fetch_order_data( $order_id, $labels,
614
+ $export, $static_vals, self::$extractor_options );
615
+ $row = apply_filters( "woe_fetch_order_row", $row, $order_id );
616
+ if ( $row ) {
617
+ $formater->output( $row );
618
+ do_action( "woe_order_row_exported", $row, $order_id );
 
 
 
619
  }
620
  do_action( "woe_order_exported", $order_id );
621
 
622
+ do_action( 'woe_formatter_output_custom_formatter', $row, $order_id, $labels,
623
+ $export, $static_vals, self::$extractor_options );
624
 
625
  self::$orders_exported ++;
626
  self::try_modify_status( $order_id, $settings );
627
  self::try_mark_order( $order_id, $settings );
628
  }
629
 
630
+ // self::maybe_output_summary_report( $formater );
631
  $formater->finish();
632
  do_action( 'woe_finish_custom_formatter' );
633
 
653
 
654
  $filename = ( ! empty( $filename ) ? $filename : self::tempnam( sys_get_temp_dir(), $settings['format'] ) );
655
 
656
+ // $format = strtolower( $settings['format'] );
 
657
 
658
  //get IDs
659
  $sql = WC_Order_Export_Data_Extractor::sql_get_order_ids( $settings );
665
  }
666
 
667
  if ( ! $order_ids ) {
668
+ $order_ids = apply_filters( "woe_get_order_ids", $wpdb->get_col( $sql ) );
669
  }
670
 
671
  if ( empty( $order_ids ) ) {
672
  return false;
673
  }
674
+ // prepare for XLS/CSV moved to plain formatter
 
 
 
 
675
 
676
  // check it once
677
+ self::_check_products_and_coupons_fields( $settings, $export );
678
 
679
+ // make header moved to plain formatter
 
680
 
681
  $result = false;
682
 
688
  continue;
689
  }
690
  self::$order_id = $order_id;
691
+ $formater = self::init_formater( '', $settings, $filename, $labels, $static_vals, 0 );
692
 
693
  $formater->truncate();
694
+ $formater->start( );
695
+ $row = WC_Order_Export_Data_Extractor::fetch_order_data( $order_id, $labels,
696
+ $export, $static_vals, self::$extractor_options );
697
+ $row = apply_filters( "woe_fetch_order_row", $row, $order_id );
698
+
699
+ if ( $row ) {
700
+ $formater->output( $row );
701
+ do_action( "woe_order_row_exported", $row, $order_id );
 
702
  }
703
  do_action( "woe_order_exported", $order_id );
704
  self::$orders_exported = 1;
757
  }
758
  }
759
 
760
+ public static function is_plain_format( $format ) {
761
+ $flat_formats = array( 'xls', 'csv', 'tsv' );
762
+ return in_array( strtolower($format), $flat_formats);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
763
  }
764
  }
classes/formats/abstract-class-woe-formatter-plain-format.php ADDED
@@ -0,0 +1,273 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ exit; // Exit if accessed directly
4
+ }
5
+
6
+ require_once 'trait-woe-plain-format.php';
7
+
8
+ abstract class WOE_Formatter_Plain_Format extends WOE_Formatter {
9
+ use WOE_Order_Export_Plain_Format;
10
+ private $duplicate_settings = array();
11
+ private $summary_report;
12
+ protected $rows;
13
+
14
+ protected $summary_processing = false;
15
+
16
+ public function __construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format, $offset ) {
17
+ parent::__construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format, $offset );
18
+ $this->duplicate_settings = $this->settings['global_job_settings']['duplicated_fields_settings'];
19
+ $this->summary_report = $this->settings['global_job_settings']['summary_report_by_products'];
20
+ if( $this->summary_report ) {
21
+ self::check_create_session();
22
+ $this->field_formats["order"] = $this->field_formats["products"];// Products at top level!
23
+ }
24
+ $this->summary_processing = false; //true only when we finish order scan
25
+ }
26
+
27
+ public function output( $rec ) {
28
+ //don't output orders in summary mode!
29
+ if ( $this->summary_report AND !$this->summary_processing ) {
30
+ $this->try_fill_summary_report_fields( $rec );
31
+ return array();
32
+ }
33
+
34
+ $rec = parent::output( $rec );
35
+ if ( $this->summary_processing ) {
36
+ return array($rec); // need array for plain format iterators
37
+ }
38
+
39
+ return apply_filters( 'woe_fetch_order_data', $this->maybe_multiple_fields( $rec ) );
40
+ }
41
+
42
+ protected function maybe_multiple_fields( $rec ) {
43
+
44
+ //get modes
45
+ $products_repeat = $this->duplicate_settings['products']['repeat'];
46
+ $coupons_repeat = $this->duplicate_settings['coupons']['repeat'];
47
+
48
+ $tmp_rec = array();
49
+ foreach ( $this->labels['order']->get_labels() as $label_data ) {
50
+ $original_key = $label_data['key'];
51
+ $key = $label_data['parent_key'] ? $label_data['parent_key'] : $original_key;
52
+
53
+ $tmp_rec[ $key ] = isset( $rec[ $key ] ) ? $rec[ $key ] : "";
54
+ }
55
+ $rec = $tmp_rec;
56
+
57
+ //simpleast
58
+ if ( $products_repeat == 'inside_one_cell' )
59
+ $rec= $this->merge_nested_rows_to_one_record( $rec, 'products' );
60
+ if ( $coupons_repeat == 'inside_one_cell' )
61
+ $rec= $this->merge_nested_rows_to_one_record( $rec, 'coupons' );
62
+
63
+ //more complex
64
+ $repeat_as_cols = array();
65
+ if ( $products_repeat == 'columns')
66
+ $repeat_as_cols[] = 'products';
67
+ if ( $coupons_repeat == 'columns' )
68
+ $repeat_as_cols[] = 'coupons';
69
+ if( $repeat_as_cols)
70
+ $rec = $this->add_nested_rows_as_columns( $rec, $repeat_as_cols );
71
+
72
+ //we still have one records at this point!
73
+ if ( $products_repeat == 'rows' || $coupons_repeat == 'rows' ) {
74
+ $new_rows = $this->try_multi_rows( $rec);
75
+ //var_dump($new_rows ); die();
76
+ } else {
77
+ $new_rows = array( $rec );
78
+ }
79
+
80
+
81
+ foreach ( $new_rows as $index => &$row ) {
82
+ if ( isset( $row['products'] ) ) {
83
+ unset( $row['products'] );
84
+ }
85
+ if ( isset( $row['coupons'] ) ) {
86
+ unset( $row['coupons'] );
87
+ }
88
+ if ( isset( $row['line_number'] ) && $index > 0 ) {
89
+ $row['line_number'] = $this->counter_value;
90
+ $this->counter_value ++;
91
+ }
92
+
93
+ // json for complex structures, don't encode nested products&coupons
94
+ foreach ( $row as $key => &$val ) {
95
+ if ( is_array( $val ) ) {
96
+ $val = json_encode( $val );
97
+ }
98
+ }
99
+ }
100
+
101
+ return ( $new_rows );
102
+ }
103
+
104
+
105
+
106
+ protected function make_header( $data = '' ) {
107
+ $header = array();
108
+ $repeat['products'] = $this->duplicate_settings['products']['repeat'];
109
+ $repeat['coupons'] = $this->duplicate_settings['coupons']['repeat'];
110
+
111
+ if ( $this->summary_report ) {
112
+ return $this->make_summary_header( $data );
113
+ }
114
+
115
+ $group_fields = array(
116
+ 'products' => array(),
117
+ 'coupons' => array(),
118
+ );
119
+ $current_group_type = "";
120
+
121
+ foreach ( $this->labels['order']->to_Array() as $field => $label ) {
122
+ //should ignore start of 1st product/coupon section
123
+ if ( $field == 'products' OR $field == 'coupons' )
124
+ continue;
125
+
126
+ $prev_group_type = $current_group_type;
127
+ $added_to_group = false;
128
+
129
+ if ( preg_match( '/^plain_(products|coupons)_.+/', $field, $matches ) ) {
130
+ $type = $matches[1];
131
+ $current_group_type = $type;
132
+ if ( 'columns' == $repeat[$type] ) {
133
+ $group_fields[$type][] = $field;
134
+ $added_to_group = true;
135
+ }
136
+ } else {
137
+ $current_group_type = 'order';
138
+ }
139
+
140
+ // previously we get product/coupon fields?
141
+ if ( $prev_group_type !== $current_group_type AND !empty($group_fields[$prev_group_type]) ) {
142
+ $this->multiplicate_header( $header, $prev_group_type, $group_fields[$prev_group_type] );
143
+ $group_fields[$prev_group_type] = array();
144
+ }
145
+
146
+ if ( !$added_to_group ) {
147
+ // TODO create filter
148
+ $header[] = $label;
149
+
150
+ }
151
+ }
152
+
153
+ //have groups at the end ?
154
+ foreach( $group_fields as $group_type=>$fields) {
155
+ if ( ! empty($fields) ) {
156
+ $this->multiplicate_header( $header, $group_type, $fields );
157
+ }
158
+ }
159
+
160
+ do_action( 'woe_make_header_custom_formatter', $this->labels );// BUG: wrong hook
161
+
162
+ return $header;
163
+ }
164
+
165
+ private function multiplicate_header(&$header, $type, $grouped_headers) {
166
+ $multiply_fields = array();
167
+ $this->multiplicate_fields( $multiply_fields,$type, array(), $grouped_headers );
168
+ foreach ( array_keys($multiply_fields) as $multiply_field ) {
169
+ if ( preg_match( '/^plain_' . $type .'_(.+)_(\d+)/', $multiply_field, $matches ) ) {
170
+ $segment_field = $matches[1];
171
+ $index = $matches[2];
172
+ $header_tmp = $this->labels[ $type ]->$segment_field;
173
+
174
+ $header[] = apply_filters( 'woe_add_csv_headers', $header_tmp['label'] . ' #' . $index, $multiply_field);
175
+ }
176
+ }
177
+
178
+ }
179
+
180
+ //Summary report started here!
181
+
182
+ private static function check_create_session() {
183
+ if ( ! session_id() ) {
184
+ @session_start();
185
+ }
186
+ }
187
+
188
+ protected function make_summary_header( $data = '' ) {
189
+ $header = array();
190
+ self::check_create_session();
191
+ $_SESSION['woe_summary_products'] = array();
192
+
193
+ foreach ( $this->labels['products']->get_labels() as $label_data ) {
194
+ $field_header = $label_data['label'];
195
+ $key = $label_data['key'];
196
+
197
+ $field_header = apply_filters( 'woe_add_csv_headers', $field_header, $key );
198
+ if ( ! preg_match( '#^(line_|qty)#', $label_data['key'] ) ) {
199
+ $header[] = $field_header;
200
+ } else {
201
+ unset( $this->labels['products']->$key );
202
+ }
203
+ }
204
+ return apply_filters( 'woe_summary_headers', $header);
205
+ }
206
+
207
+ private function try_fill_summary_report_fields( $row ) {
208
+ $order = false;
209
+
210
+ foreach ( self::get_array_from_array( $row, 'products' ) as $item_id => $item ) {
211
+ $product_item = new WC_Order_Item_Product( $item_id );
212
+ $product = $product_item->get_product();
213
+ if ( ! $product ) {
214
+ continue;
215
+ }
216
+ if( !$order ) {
217
+ $order = new WC_Order( $product_item->get_order_id() );
218
+ }
219
+
220
+ $key = $product->get_id();
221
+ $key = apply_filters( "woe_summary_products_adjust_key", $key, $product, $product_item, $order );
222
+
223
+ //add new product
224
+ if ( ! isset( $_SESSION['woe_summary_products'][ $key ] ) ) {
225
+ $new_row = array();
226
+ foreach ( $this->labels['products']->get_labels() as $label_data ) {
227
+ $original_key = $label_data['key'];
228
+ $original_key = apply_filters( "woe_summary_products_adjust_key", $original_key, $product, $product_item );
229
+ if( preg_match( '#^(line_|qty)#', $original_key) )//skip item values!
230
+ continue;
231
+ $field_key = $label_data['parent_key'] ? $label_data['parent_key'] : $original_key;
232
+ if( preg_match('#^summary_report_total_#', $field_key ) )
233
+ $new_row[ $original_key ] = 0;//total fields
234
+ else
235
+ $new_row[ $original_key ] = $item[ $field_key ]; // already calculated
236
+ }
237
+ $new_row = apply_filters( 'woe_summary_column_keys', $new_row);// legacy hook
238
+ $new_row = apply_filters( "woe_summary_products_prepare_product", $new_row, $key, $product, $product_item, $order );
239
+ $_SESSION['woe_summary_products'][ $key ] = $new_row;
240
+ }
241
+
242
+ //increase totals
243
+ if ( isset( $_SESSION['woe_summary_products'][ $key ]['summary_report_total_qty'] ) ) {
244
+ $_SESSION['woe_summary_products'][ $key ]['summary_report_total_qty'] += $product_item->get_quantity();
245
+ }
246
+
247
+ if ( isset( $_SESSION['woe_summary_products'][ $key ]['summary_report_total_amount'] ) ) {
248
+ $total = method_exists( $product_item, 'get_total' ) ? $product_item->get_total() : $product_item['line_total'];
249
+ $_SESSION['woe_summary_products'][ $key ]['summary_report_total_amount'] += wc_round_tax_total( $total );
250
+ }
251
+ do_action("woe_summary_products_add_item", $key, $product_item, $order);
252
+ }
253
+ //no lines for order!
254
+ return array();
255
+ }
256
+
257
+ protected function try_apply_summary_report_fields() {
258
+ if ( $this->summary_report ) {
259
+ $this->summary_processing = true;
260
+ do_action( 'woe_summary_before_output' );
261
+ if ( $this->mode == 'preview' ) {
262
+ if( empty($this->rows ) ) // no headers!
263
+ $this->rows = array();
264
+ $this->rows += $_SESSION['woe_summary_products'];
265
+ } else {
266
+ foreach ( $_SESSION['woe_summary_products'] as $item ) {
267
+ $this->output( $item );
268
+ }
269
+ }
270
+ }
271
+ }
272
+
273
+ }
classes/formats/abstract-class-woe-formatter-sv.php CHANGED
@@ -6,16 +6,16 @@ if ( ! defined( 'ABSPATH' ) ) {
6
  if ( class_exists( 'WOE_Formatter_sv' ) ) {
7
  return;
8
  }
 
9
 
10
- abstract class WOE_Formatter_sv extends WOE_Formatter {
11
  var $enclosure;
12
  var $linebreak;
13
  var $delimiter;
14
  var $encoding;
15
- var $rows;
16
 
17
- public function __construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format ) {
18
- parent::__construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format );
19
 
20
  $this->enclosure = $this->convert_literals( isset( $this->settings['enclosure'] ) ? $this->settings['enclosure'] : '' );
21
  $this->linebreak = $this->convert_literals( isset( $this->settings['linebreak'] ) ? $this->settings['linebreak'] : '' );
@@ -30,6 +30,7 @@ abstract class WOE_Formatter_sv extends WOE_Formatter {
30
  }
31
 
32
  public function start( $data = '' ) {
 
33
  $data = apply_filters( "woe_{$this->format}_header_filter", $data );
34
  $this->prepare_array( $data );
35
  parent::start( $data );
@@ -57,42 +58,48 @@ abstract class WOE_Formatter_sv extends WOE_Formatter {
57
  }
58
 
59
  public function output( $rec ) {
60
- $this->prepare_array( $rec );
61
- $rec = parent::output( $rec );
62
-
63
- if ( $this->has_output_filter ) {
64
- $rec = apply_filters( "woe_{$this->format}_output_filter", $rec, $this );
65
- if ( ! $rec ) {
66
- return;
 
67
  }
68
- }
69
 
70
- if ( $this->mode == 'preview' ) {
71
- $this->rows[] = $rec;
72
- } else {
73
- if ( ! apply_filters( "woe_{$this->format}_custom_output_func", false, $this->handle, $rec,
74
- $this->delimiter, $this->linebreak, $this->enclosure, false ) ) {
75
- if ( $this->enclosure !== '' ) {
76
- fputcsv( $this->handle, $rec, $this->delimiter, $this->enclosure );
77
- } else {
78
- fwrite( $this->handle, implode( $this->delimiter, $rec ) . $this->linebreak );
 
79
  }
80
  }
81
  }
 
82
  }
83
 
84
  public function finish() {
 
 
85
  if ( $this->mode == 'preview' ) {
86
  $this->rows = apply_filters( "woe_{$this->format}_preview_rows", $this->rows );
87
  fwrite( $this->handle, '<table>' );
88
  if ( count( $this->rows ) < 2 ) {
89
  $this->rows[] = array( __( '<td colspan=10><b>No results</b></td>', 'woo-order-export-lite' ) );
90
  }
91
- foreach ( $this->rows as $rec ) {
92
- $rec = array_map( function ( $a ) {
93
- return '<td>' . $a . '';
94
- }, $rec );
95
- fwrite( $this->handle, '<tr><td>' . join( '</td><td>', $rec ) . "</td><tr>\n" );
 
 
96
  }
97
  fwrite( $this->handle, '</table>' );
98
  } else {
6
  if ( class_exists( 'WOE_Formatter_sv' ) ) {
7
  return;
8
  }
9
+ include_once 'abstract-class-woe-formatter-plain-format.php';
10
 
11
+ abstract class WOE_Formatter_sv extends WOE_Formatter_Plain_Format {
12
  var $enclosure;
13
  var $linebreak;
14
  var $delimiter;
15
  var $encoding;
 
16
 
17
+ public function __construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format, $offset ) {
18
+ parent::__construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format, $offset );
19
 
20
  $this->enclosure = $this->convert_literals( isset( $this->settings['enclosure'] ) ? $this->settings['enclosure'] : '' );
21
  $this->linebreak = $this->convert_literals( isset( $this->settings['linebreak'] ) ? $this->settings['linebreak'] : '' );
30
  }
31
 
32
  public function start( $data = '' ) {
33
+ $data = $this->make_header($data);
34
  $data = apply_filters( "woe_{$this->format}_header_filter", $data );
35
  $this->prepare_array( $data );
36
  parent::start( $data );
58
  }
59
 
60
  public function output( $rec ) {
61
+ $rows = parent::output( $rec );
62
+ foreach ( $rows as $row ) {
63
+ $this->prepare_array( $row );
64
+ if ( $this->has_output_filter ) {
65
+ $row = apply_filters( "woe_{$this->format}_output_filter", $row, $this );
66
+ if ( ! $row ) {
67
+ return;
68
+ }
69
  }
 
70
 
71
+ if ( $this->mode == 'preview' ) {
72
+ $this->rows[] = $row;
73
+ } else {
74
+ if ( ! apply_filters( "woe_{$this->format}_custom_output_func", false, $this->handle, $row,
75
+ $this->delimiter, $this->linebreak, $this->enclosure, false ) ) {
76
+ if ( $this->enclosure !== '' ) {
77
+ fputcsv( $this->handle, $row, $this->delimiter, $this->enclosure );
78
+ } else {
79
+ fwrite( $this->handle, implode( $this->delimiter, $row ) . $this->linebreak );
80
+ }
81
  }
82
  }
83
  }
84
+
85
  }
86
 
87
  public function finish() {
88
+ $this->try_apply_summary_report_fields();
89
+
90
  if ( $this->mode == 'preview' ) {
91
  $this->rows = apply_filters( "woe_{$this->format}_preview_rows", $this->rows );
92
  fwrite( $this->handle, '<table>' );
93
  if ( count( $this->rows ) < 2 ) {
94
  $this->rows[] = array( __( '<td colspan=10><b>No results</b></td>', 'woo-order-export-lite' ) );
95
  }
96
+ foreach ( $this->rows as $num=>$rec ) {
97
+ if ( $num == 0 AND $this->settings['display_column_names'] ) {
98
+ fwrite( $this->handle,
99
+ '<tr style="font-weight:bold"><td>' . join( '</td><td>', $rec ) . "</td><tr>\n" );
100
+ } else {
101
+ fwrite( $this->handle, '<tr><td>' . join( '</td><td>', $rec ) . "</td><tr>\n" );
102
+ }
103
  }
104
  fwrite( $this->handle, '</table>' );
105
  } else {
classes/formats/abstract-class-woe-formatter.php CHANGED
@@ -7,32 +7,49 @@ abstract class WOE_Formatter {
7
  var $has_output_filter;
8
  var $mode;
9
  var $settings;
 
 
 
 
 
10
  var $labels;
 
11
  var $handle;
12
  var $format;
13
  var $field_formats;
14
  var $date_format;
15
  var $auto_format_dates = true;
 
16
  var $counter_value;
17
 
18
- public function __construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format ) {
 
 
 
 
 
 
19
  $this->has_output_filter = has_filter( "woe_{$format}_output_filter" );
20
  $this->mode = $mode;
21
  $this->filename = $filename;
22
  $this->settings = $settings;
 
23
  $this->labels = $labels;
24
  $this->handle = fopen( $filename, 'a' );
25
  if ( ! $this->handle ) {
26
  throw new Exception( $filename . __( 'can not open for output', 'woo-order-export-lite' ) );
27
  }
28
- $this->format = $format;
 
29
 
30
  // format for cells
31
- $this->field_formats = $field_formats;
32
- $this->string_format_force = apply_filters( "woe_{$format}_string_format_force", false );
33
- $this->string_format_fields = apply_filters( "woe_{$format}_string_format_fields", $field_formats['string'] );
34
- $this->date_format_fields = apply_filters( "woe_{$format}_date_format_fields", $field_formats['date'] );
35
- $this->date_format = apply_filters( "woe_{$format}_date_format", $date_format );
 
 
36
 
37
  $this->counter_value = $this->get_counter();
38
  if ( ! $this->counter_value ) {
@@ -53,7 +70,11 @@ abstract class WOE_Formatter {
53
  public function output( $rec ) {
54
  $this->handle = apply_filters( "woe_formatter_set_handler_for_" . $this->format . "_row", $this->handle );
55
  if ( $this->auto_format_dates ) {
56
- $rec = $this->format_dates( $rec );
 
 
 
 
57
  }
58
  if ( isset( $rec['line_number'] ) ) {
59
  $rec['line_number'] = $this->counter_value;
@@ -89,12 +110,24 @@ abstract class WOE_Formatter {
89
  return $s;
90
  }
91
 
92
- protected function format_dates( $rec ) {
93
- foreach ( $rec as $field => $value ) {
94
- if ( in_array( $field, $this->field_formats['date'] ) ) {
95
- $ts = strtotime( $value );
96
- if ( $ts ) {
97
- $rec[ $field ] = date( $this->date_format, $ts );
 
 
 
 
 
 
 
 
 
 
 
 
98
  }
99
  }
100
  }
@@ -102,6 +135,40 @@ abstract class WOE_Formatter {
102
  return $rec;
103
  }
104
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
  protected function generate_key() {
107
  return $this->mode . '+' . $this->filename;
@@ -125,4 +192,14 @@ abstract class WOE_Formatter {
125
  return get_transient( $this->generate_key() );
126
  }
127
  }
 
 
 
 
 
 
 
 
 
 
128
  }
7
  var $has_output_filter;
8
  var $mode;
9
  var $settings;
10
+ var $offset;
11
+
12
+ /**
13
+ * @var WC_Order_Export_Labels[]
14
+ */
15
  var $labels;
16
+
17
  var $handle;
18
  var $format;
19
  var $field_formats;
20
  var $date_format;
21
  var $auto_format_dates = true;
22
+ var $format_number_fields;
23
  var $counter_value;
24
 
25
+ protected $filename;
26
+
27
+ protected $decimals;
28
+ protected $decimal_separator;
29
+ protected $thousands_separator;
30
+
31
+ public function __construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format, $offset ) {
32
  $this->has_output_filter = has_filter( "woe_{$format}_output_filter" );
33
  $this->mode = $mode;
34
  $this->filename = $filename;
35
  $this->settings = $settings;
36
+ $this->offset = $offset;
37
  $this->labels = $labels;
38
  $this->handle = fopen( $filename, 'a' );
39
  if ( ! $this->handle ) {
40
  throw new Exception( $filename . __( 'can not open for output', 'woo-order-export-lite' ) );
41
  }
42
+ $this->format = $format;
43
+ $this->format_number_fields = ! empty( $this->settings['global_job_settings']['format_number_fields'] ) ? $this->settings['global_job_settings']['format_number_fields'] : false;
44
 
45
  // format for cells
46
+ $this->field_formats = $field_formats;
47
+ $this->date_format = apply_filters( "woe_{$format}_date_format", $date_format );
48
+
49
+ // separators
50
+ $this->decimals = wc_get_price_decimals();
51
+ $this->decimal_separator = wc_get_price_decimal_separator();
52
+ $this->thousands_separator = apply_filters( 'woe_thousands_separator', '' );
53
 
54
  $this->counter_value = $this->get_counter();
55
  if ( ! $this->counter_value ) {
70
  public function output( $rec ) {
71
  $this->handle = apply_filters( "woe_formatter_set_handler_for_" . $this->format . "_row", $this->handle );
72
  if ( $this->auto_format_dates ) {
73
+ $rec = $this->format_fields( $rec, 'date' );
74
+ }
75
+ if ( $this->format_number_fields ) {
76
+ $rec = $this->format_fields( $rec, 'money' );
77
+ $rec = $this->format_fields( $rec, 'number' );
78
  }
79
  if ( isset( $rec['line_number'] ) ) {
80
  $rec['line_number'] = $this->counter_value;
110
  return $s;
111
  }
112
 
113
+ protected function format_fields( $rec, $format_type ) {
114
+ if ( isset( $this->field_formats['order'][ $format_type ] ) ) {
115
+ foreach ( $rec as $field => $value ) {
116
+ if ( $field == 'products' || $field == 'coupons' ) {
117
+ if ( isset( $this->field_formats[ $field ][ $format_type ] ) ) {
118
+ foreach ( $value as $item_id => $item_fields ) {
119
+ foreach ( $item_fields as $item_field => $item_field_value ) {
120
+ if ( in_array( $item_field, $this->field_formats[ $field ][ $format_type ] ) ) {
121
+ $rec[ $field ][ $item_id ][ $item_field ] = $this->format_field( $format_type,
122
+ $item_field_value );
123
+ }
124
+ }
125
+ }
126
+ }
127
+ } else {
128
+ if ( in_array( $field, $this->field_formats['order'][ $format_type ] ) ) {
129
+ $rec[ $field ] = $this->format_field( $format_type, $value );
130
+ }
131
  }
132
  }
133
  }
135
  return $rec;
136
  }
137
 
138
+ protected function format_field( $type, $field_value ) {
139
+ $func = array( $this, "format_{$type}_field" );
140
+
141
+ return is_callable( $func ) ? call_user_func( $func, $field_value ) : $field_value;
142
+ }
143
+
144
+ protected function format_date_field( $field_value ) {
145
+ $ts = strtotime( $field_value );
146
+ if ( $ts ) {
147
+ $field_value = date( $this->date_format, $ts );
148
+ }
149
+
150
+ return $field_value;
151
+ }
152
+
153
+ protected function format_money_field( $field_value ) {
154
+ $new_value = number_format(
155
+ floatval( $field_value ),
156
+ $this->decimals,
157
+ $this->decimal_separator,
158
+ $this->thousands_separator
159
+ );
160
+ $new_value = apply_filters( 'woe_format_money', $new_value, $field_value );
161
+
162
+ return $new_value;
163
+ }
164
+
165
+ protected function format_number_field( $field_value ) {
166
+ $new_value = $field_value ; //as is!
167
+ $new_value = apply_filters( 'woe_format_numbers', $new_value, $field_value );
168
+
169
+ return $new_value;
170
+ }
171
+
172
 
173
  protected function generate_key() {
174
  return $this->mode . '+' . $this->filename;
192
  return get_transient( $this->generate_key() );
193
  }
194
  }
195
+
196
+ protected function make_header() {
197
+ do_action( 'woe_make_header_custom_formatter', $this->labels );
198
+
199
+ return '';
200
+ }
201
+
202
+ protected static function get_array_from_array( $array, $key ) {
203
+ return isset( $array[ $key ] ) && is_array( $array[ $key ] ) ? $array[ $key ] : array();
204
+ }
205
  }
classes/formats/class-woe-formatter-json.php CHANGED
@@ -6,6 +6,11 @@ if ( ! defined( 'ABSPATH' ) ) {
6
  class WOE_Formatter_Json extends WOE_Formatter {
7
  var $prev_added = false;
8
 
 
 
 
 
 
9
  public function start( $data = '' ) {
10
  parent::start( $data );
11
 
@@ -26,29 +31,40 @@ class WOE_Formatter_Json extends WOE_Formatter {
26
  //rename fields in array
27
  $rec_out = array();
28
  $labels = $this->labels['order'];
29
- foreach ( $rec as $field => $value ) {
30
- if ( is_array( $value ) ) {
31
- if ( $field == "products" ) {
 
 
 
 
 
 
 
32
  $child_labels = $this->labels['products'];
33
- } elseif ( $field == "coupons" ) {
34
  $child_labels = $this->labels['coupons'];
35
  } else {
36
- $rec_out[ $labels[ $field ] ] = $value;
37
  continue;
38
  }
39
 
40
- $rec_out[ $labels[ $field ] ] = array();
41
- foreach ( $value as $child_elements ) {
42
  $child = array();
43
- foreach ( $child_elements as $field_child => $value_child ) {
44
- if ( isset( $child_labels[ $field_child ] ) ) {
45
- $child[ $child_labels[ $field_child ] ] = $value_child;
 
 
 
46
  }
47
  }
48
- $rec_out[ $labels[ $field ] ][] = $child;
49
  }
 
50
  } else {
51
- $rec_out[ $labels[ $field ] ] = $value;
52
  }
53
  }
54
 
6
  class WOE_Formatter_Json extends WOE_Formatter {
7
  var $prev_added = false;
8
 
9
+ public function __construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format, $offset ) {
10
+ parent::__construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format, $offset );
11
+ $this->prev_added = ($offset > 0);
12
+ }
13
+
14
  public function start( $data = '' ) {
15
  parent::start( $data );
16
 
31
  //rename fields in array
32
  $rec_out = array();
33
  $labels = $this->labels['order'];
34
+
35
+
36
+ foreach ( $labels->get_labels() as $label_data ) {
37
+ $original_key = $label_data['key'];
38
+ $label = $label_data['label'];
39
+ $key = $label_data['parent_key'] ? $label_data['parent_key'] : $original_key;
40
+
41
+ $field_value = $rec[$key];
42
+ if ( is_array( $field_value ) ) {
43
+ if ( $original_key == "products" ) {
44
  $child_labels = $this->labels['products'];
45
+ } elseif ( $original_key == "coupons" ) {
46
  $child_labels = $this->labels['coupons'];
47
  } else {
48
+ $rec_out[ $label ] = $field_value;
49
  continue;
50
  }
51
 
52
+ $rec_out[ $label ] = array();
53
+ foreach ( $field_value as $child_element ) {
54
  $child = array();
55
+ foreach ( $child_labels->get_labels() as $child_label_data ) {
56
+ $child_original_key = $child_label_data['key'];
57
+ $child_label = $child_label_data['label'];
58
+ $child_key = $child_label_data['parent_key'] ? $child_label_data['parent_key'] : $child_original_key;
59
+ if ( isset( $child_element[ $child_key ] ) ) {
60
+ $child[ $child_label ] = $child_element[ $child_key ];
61
  }
62
  }
63
+ $rec_out[ $label ][] = $child;
64
  }
65
+
66
  } else {
67
+ $rec_out[ $label ] = $field_value;
68
  }
69
  }
70
 
classes/formats/class-woe-formatter-tsv.php CHANGED
@@ -6,8 +6,8 @@ if ( ! defined( 'ABSPATH' ) ) {
6
  include_once 'abstract-class-woe-formatter-sv.php';
7
 
8
  class WOE_Formatter_Tsv extends WOE_Formatter_sv {
9
- public function __construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format ) {
10
- parent::__construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format );
11
 
12
  $this->enclosure = '';
13
  $this->delimiter = "\t";
6
  include_once 'abstract-class-woe-formatter-sv.php';
7
 
8
  class WOE_Formatter_Tsv extends WOE_Formatter_sv {
9
+ public function __construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format, $offset ) {
10
+ parent::__construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format, $offset );
11
 
12
  $this->enclosure = '';
13
  $this->delimiter = "\t";
classes/formats/class-woe-formatter-xls.php CHANGED
@@ -3,19 +3,33 @@ if ( ! defined( 'ABSPATH' ) ) {
3
  exit; // Exit if accessed directly
4
  }
5
 
 
6
 
7
  if ( ! class_exists( 'PHPExcel' ) ) {
8
  include_once dirname( __FILE__ ) . '/../PHPExcel.php';
9
  }
10
 
11
- class WOE_Formatter_Xls extends WOE_Formatter {
12
- var $rows;
13
- var $auto_format_dates = false;
 
14
 
15
- public function __construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format ) {
16
- parent::__construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format );
17
 
 
 
 
18
 
 
 
 
 
 
 
 
 
 
19
  if ( $mode != 'preview' ) {
20
  //more memory for XLS?
21
  ini_set( 'memory_limit', '512M' );
@@ -43,10 +57,18 @@ class WOE_Formatter_Xls extends WOE_Formatter {
43
 
44
  // Excel uses another format!
45
  $this->date_format = apply_filters( 'woe_xls_date_format', $this->convert_php_date_format( $date_format ) );
 
 
 
 
 
 
 
46
  }
47
  }
48
 
49
  public function start( $data = '' ) {
 
50
  $data = apply_filters( "woe_xls_header_filter", $data );
51
  parent::start( $data );
52
 
@@ -91,45 +113,51 @@ class WOE_Formatter_Xls extends WOE_Formatter {
91
  }
92
 
93
  public function output( $rec ) {
94
- $rec = parent::output( $rec );
95
- if ( $this->has_output_filter ) {
96
- $rec = apply_filters( "woe_xls_output_filter", $rec, $this );
97
- if ( ! $rec ) {
98
- return;
 
 
 
99
  }
100
- }
101
 
102
- if ( $this->mode == 'preview' ) {
103
- $rec = $this->format_dates( $rec );
104
- $this->rows[] = $rec;
105
- } else {
106
- $this->last_row ++;
107
- $pos = 0;
108
- foreach ( $rec as $field => $text ) {
109
- if ( $this->string_format_force OR in_array( $field, $this->string_format_fields ) ) {
110
- $this->objPHPExcel->getActiveSheet()->setCellValueExplicitByColumnAndRow( $pos, $this->last_row,
111
- $text );
112
- } elseif ( in_array( $field, $this->date_format_fields ) ) {// DATE!
113
- if ( $text ) {
114
- if ( empty( $this->settings['global_job_settings']['time_format'] ) ) { // must remove time!
115
- $text = date( "Y-m-d", strtotime( $text ) );
 
 
 
 
 
 
 
116
  }
117
- $text = PHPExcel_Shared_Date::PHPToExcel( new DateTime( $text ) );
118
- $this->objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow( $pos, $this->last_row,
119
- $text );
120
  }
121
- $this->objPHPExcel->getActiveSheet()->getStyleByColumnAndRow( $pos,
122
- $this->last_row )->getNumberFormat()->setFormatCode( $this->date_format );
123
- } else {
124
- $this->objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow( $pos, $this->last_row, $text );
125
  }
126
- do_action( "woe_xls_format_cell", $this, $field, $text, $rec, $pos );
127
- $pos ++;
128
  }
129
  }
 
130
  }
131
 
132
  public function finish() {
 
133
  if ( $this->mode == 'preview' ) {
134
  $max_columns = 0;
135
  fwrite( $this->handle, '<table>' );
@@ -217,4 +245,12 @@ class WOE_Formatter_Xls extends WOE_Formatter {
217
  return strtr( $date_format, $replacements );
218
  }
219
 
 
 
 
 
 
 
 
 
220
  }
3
  exit; // Exit if accessed directly
4
  }
5
 
6
+ include_once 'abstract-class-woe-formatter-plain-format.php';
7
 
8
  if ( ! class_exists( 'PHPExcel' ) ) {
9
  include_once dirname( __FILE__ ) . '/../PHPExcel.php';
10
  }
11
 
12
+ class WOE_Formatter_Xls extends WOE_Formatter_Plain_Format {
13
+ private $string_format_force = false;
14
+ private $string_format_fields;
15
+ private $date_format_fields;
16
 
17
+ public function __construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format, $offset ) {
18
+ parent::__construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format, $offset );
19
 
20
+ $this->string_format_force = apply_filters( "woe_{$format}_string_format_force", false );
21
+
22
+ $field_formats = $this->field_formats['order']; // overwrite! probably modified by parent
23
 
24
+ $this->string_format_fields = isset( $field_formats['string'] ) ? $field_formats['string'] : array();
25
+ $this->string_format_fields = apply_filters( "woe_{$format}_string_format_fields", $this->string_format_fields );
26
+
27
+ $this->date_format_fields = isset( $field_formats['date'] ) ? $field_formats['date'] : array();
28
+ $this->date_format_fields = apply_filters( "woe_{$format}_date_format_fields", $this->date_format_fields );
29
+
30
+ $this->money_format_fields = isset( $field_formats['money'] ) ? $field_formats['money'] : array();
31
+ $this->money_format_fields = apply_filters( "woe_{$format}_date_money_fields", $this->money_format_fields );
32
+
33
  if ( $mode != 'preview' ) {
34
  //more memory for XLS?
35
  ini_set( 'memory_limit', '512M' );
57
 
58
  // Excel uses another format!
59
  $this->date_format = apply_filters( 'woe_xls_date_format', $this->convert_php_date_format( $date_format ) );
60
+ $this->money_format = apply_filters( 'woe_xls_money_format', PHPExcel_Style_NumberFormat::FORMAT_NUMBER_00);
61
+ // Excel will format!
62
+ $this->auto_format_dates = false;
63
+ $this->format_number_fields_original = $this->format_number_fields ;
64
+ $this->format_number_fields = false;
65
+ } else {
66
+ $this->auto_format_dates = true;
67
  }
68
  }
69
 
70
  public function start( $data = '' ) {
71
+ $data = $this->make_header();
72
  $data = apply_filters( "woe_xls_header_filter", $data );
73
  parent::start( $data );
74
 
113
  }
114
 
115
  public function output( $rec ) {
116
+ $rows = parent::output( $rec );
117
+
118
+ foreach ( $rows as $row ) {
119
+ if ( $this->has_output_filter ) {
120
+ $row = apply_filters( "woe_xls_output_filter", $row, $this );
121
+ if ( ! $row ) {
122
+ return;
123
+ }
124
  }
 
125
 
126
+ if ( $this->mode == 'preview' ) {
127
+ $row = array_map( "nl2br", $row );
128
+ $this->rows[] = $row;
129
+ } else {
130
+ $this->last_row ++;
131
+ $pos = 0;
132
+ foreach ( $row as $field => $text ) {
133
+ if ( $this->string_format_force OR $this->field_format_is( $field, $this->string_format_fields ) ) {// STRING
134
+ $this->objPHPExcel->getActiveSheet()->getStyleByColumnAndRow( $pos,$this->last_row )->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_TEXT );
135
+ $this->objPHPExcel->getActiveSheet()->setCellValueExplicitByColumnAndRow( $pos, $this->last_row, $text );
136
+ } elseif ( $this->format_number_fields_original AND $this->field_format_is( $field, $this->money_format_fields ) ) { // MONEY
137
+ $this->objPHPExcel->getActiveSheet()->getStyleByColumnAndRow( $pos,$this->last_row )->getNumberFormat()->setFormatCode( $this->money_format );
138
+ $this->objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow( $pos, $this->last_row, $text );
139
+ } elseif ( $this->field_format_is( $field, $this->date_format_fields ) ) {// DATE!
140
+ $this->objPHPExcel->getActiveSheet()->getStyleByColumnAndRow( $pos,$this->last_row )->getNumberFormat()->setFormatCode( $this->date_format );
141
+ if ( $text ) {
142
+ if ( empty( $this->settings['global_job_settings']['time_format'] ) ) { // must remove time!
143
+ $text = date( "Y-m-d", strtotime( $text ) );
144
+ }
145
+ $text = PHPExcel_Shared_Date::PHPToExcel( new DateTime( $text ) );
146
+ $this->objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow( $pos, $this->last_row, $text );
147
  }
148
+ } else {
149
+ $this->objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow( $pos, $this->last_row, $text );
 
150
  }
151
+ do_action( "woe_xls_format_cell", $this, $field, $text, $row, $pos );
152
+ $pos ++;
 
 
153
  }
 
 
154
  }
155
  }
156
+
157
  }
158
 
159
  public function finish() {
160
+ $this->try_apply_summary_report_fields();
161
  if ( $this->mode == 'preview' ) {
162
  $max_columns = 0;
163
  fwrite( $this->handle, '<table>' );
245
  return strtr( $date_format, $replacements );
246
  }
247
 
248
+ protected function field_format_is($field, $format_fields) {
249
+ if ( in_array($field, $format_fields) )
250
+ return true;
251
+ if( preg_match('#^(.+?)_\d+$#', $field, $duplicated_field) ) {
252
+ return in_array($duplicated_field[1], $format_fields);
253
+ }
254
+ return false;
255
+ }
256
  }
classes/formats/class-woe-formatter-xml.php CHANGED
@@ -5,8 +5,8 @@ if ( ! defined( 'ABSPATH' ) ) {
5
 
6
  class WOE_Formatter_Xml extends WOE_Formatter {
7
 
8
- public function __construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format ) {
9
- parent::__construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format );
10
 
11
  $this->linebreak = apply_filters( "woe_xml_output_linebreak", "\n" );
12
  }
@@ -37,14 +37,20 @@ class WOE_Formatter_Xml extends WOE_Formatter {
37
 
38
  $labels = $this->labels['order'];
39
  $rec = apply_filters( 'woe_xml_prepare_record', $rec );
40
- foreach ( $rec as $field => $value ) {
41
- $value = apply_filters( 'woe_xml_prepare_field_' . $field, $value, $rec );
42
- if ( is_array( $value ) ) {
43
- $childs = $xml->addChild( $labels[ $field ] ); // add Products
44
- if ( $field == "products" ) {
 
 
 
 
 
 
45
  $child_tag = $this->settings['product_tag'];
46
  $child_labels = $this->labels['products'];
47
- } elseif ( $field == "coupons" ) {
48
  $child_tag = $this->settings['coupon_tag'];
49
  $child_labels = $this->labels['coupons'];
50
  } else {
@@ -53,26 +59,28 @@ class WOE_Formatter_Xml extends WOE_Formatter {
53
  $child_labels = array();
54
  }
55
  // modify children using filters
56
- $child_tag = apply_filters( 'woe_xml_child_tagname_' . $field, $child_tag, $value, $rec );
57
- $child_labels = apply_filters( 'woe_xml_child_labels_' . $field, $child_labels, $value, $rec );
58
 
59
- foreach ( $value as $child_key => $child_elements ) {
60
  $tag_name = $child_tag ? $child_tag : $child_key;
61
  // add nested Product if array!
62
  $child = $childs->addChild( $tag_name,
63
- is_array( $child_elements ) ? null : $this->prepare_string( $child_elements ) );
64
- // products/coupons
65
- if ( is_array( $child_elements ) ) {
66
- foreach ( $child_elements as $field_child => $value_child ) {
67
- if ( isset( $child_labels[ $field_child ] ) ) {
68
- $child->addChild( $child_labels[ $field_child ],
69
- $this->prepare_string( $value_child ) );
 
 
70
  }
71
  }
72
  }
73
  }
74
  } else {
75
- $xml->addChild( $labels[ $field ], $this->prepare_string( $value ) );
76
  }
77
  }
78
 
5
 
6
  class WOE_Formatter_Xml extends WOE_Formatter {
7
 
8
+ public function __construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format, $offset ) {
9
+ parent::__construct( $mode, $filename, $settings, $format, $labels, $field_formats, $date_format, $offset );
10
 
11
  $this->linebreak = apply_filters( "woe_xml_output_linebreak", "\n" );
12
  }
37
 
38
  $labels = $this->labels['order'];
39
  $rec = apply_filters( 'woe_xml_prepare_record', $rec );
40
+
41
+ foreach ( $labels->get_labels() as $label_data ) {
42
+ $original_key = $label_data['key'];
43
+ $label = $label_data['label'];
44
+ $key = $label_data['parent_key'] ? $label_data['parent_key'] : $original_key;
45
+
46
+ $field_value = apply_filters( 'woe_xml_prepare_field_' . $original_key, $rec[$key], $rec );
47
+
48
+ if ( is_array( $field_value ) ) {
49
+ $childs = $xml->addChild( $label ); // add Products
50
+ if ( $original_key == "products" ) {
51
  $child_tag = $this->settings['product_tag'];
52
  $child_labels = $this->labels['products'];
53
+ } elseif ( $original_key == "coupons" ) {
54
  $child_tag = $this->settings['coupon_tag'];
55
  $child_labels = $this->labels['coupons'];
56
  } else {
59
  $child_labels = array();
60
  }
61
  // modify children using filters
62
+ $child_tag = apply_filters( 'woe_xml_child_tagname_' . $original_key, $child_tag, $field_value, $rec );
63
+ $child_labels = apply_filters( 'woe_xml_child_labels_' . $original_key, $child_labels, $field_value, $rec );
64
 
65
+ foreach ( $field_value as $child_key => $child_element ) {
66
  $tag_name = $child_tag ? $child_tag : $child_key;
67
  // add nested Product if array!
68
  $child = $childs->addChild( $tag_name,
69
+ is_array( $child_element ) ? null : $this->prepare_string( $child_element ) );
70
+ // products/coupons
71
+ if ( is_array( $child_element ) ) {
72
+ foreach ( $child_labels->get_labels() as $child_label_data ) {
73
+ $child_original_key = $child_label_data['key'];
74
+ $child_label = $child_label_data['label'];
75
+ $child_key = $child_label_data['parent_key'] ? $child_label_data['parent_key'] : $child_original_key;
76
+ if ( isset( $child_element[ $child_key ] ) ) {
77
+ $child->addChild( $child_label, $this->prepare_string( $child_element[ $child_key ] ) );
78
  }
79
  }
80
  }
81
  }
82
  } else {
83
+ $xml->addChild( $label, $this->prepare_string( $field_value ) );
84
  }
85
  }
86
 
classes/formats/trait-woe-plain-format.php ADDED
@@ -0,0 +1,242 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ trait WOE_Order_Export_Plain_Format {
5
+
6
+
7
+ private function multiplicate_fields(&$row, $type, $field_values, $fields) {
8
+ $multiplied_fields = array();
9
+
10
+ $group_by_item = $this->duplicate_settings[$type]['group_by'];
11
+ // $multiply_count = $repeat ? $this->duplicate_settings[$type]['max_cols'] : 1;
12
+ $multiply_count = $this->duplicate_settings[$type]['max_cols'];
13
+
14
+ if ( $group_by_item == 'product' ) {
15
+ $index = 1;
16
+
17
+ foreach ( $field_values as $item ) {
18
+ if ( $multiply_count < $index ) {
19
+ break;
20
+ }
21
+ foreach ( $fields as $original_key ) {
22
+ $label_data = $this->labels['order']->$original_key;
23
+ $key = $label_data['parent_key'] ? $label_data['parent_key'] : $original_key;
24
+
25
+ if ( isset( $item[ str_replace( 'plain_' . $type . '_', '', $key ) ] ) ) {
26
+ $multiplied_fields[ $original_key . '_' . $index ] = $item[ str_replace( 'plain_' . $type . '_', '',
27
+ $key ) ];
28
+ } else {
29
+ $multiplied_fields[ $original_key . '_' . $index ] = '';
30
+ }
31
+
32
+ }
33
+
34
+ $index ++;
35
+ }
36
+ for ( $i = $index; $i <= $multiply_count; $i ++ ) {
37
+ foreach ( $fields as $original_key ) {
38
+ $multiplied_fields[ $original_key . '_' . $i ] = '';
39
+ }
40
+ }
41
+
42
+ } elseif ( $group_by_item == 'as_independent_columns' ) {
43
+ foreach ( $fields as $original_key ) {
44
+
45
+ $label_data = $this->labels['order']->$original_key;
46
+ $key = $label_data['parent_key'] ? $label_data['parent_key'] : $original_key;
47
+
48
+ $index = 1;
49
+ foreach ( $field_values as $item ) {
50
+ if ( $multiply_count < $index ) {
51
+ break;
52
+ }
53
+
54
+ if ( isset( $item[ str_replace( 'plain_' . $type .'_', '', $key ) ] ) ) {
55
+ $multiplied_fields[ $original_key . '_' . $index ] = $item[ str_replace( 'plain_' . $type . '_', '',
56
+ $key ) ];
57
+ } else {
58
+ $multiplied_fields[ $original_key . '_' . $index ] = '';
59
+ }
60
+ $index ++;
61
+ }
62
+ for ( $i = $index; $i <= $multiply_count; $i ++ ) {
63
+ $multiplied_fields[ $original_key . '_' . $i ] = '';
64
+ }
65
+ }
66
+ }
67
+
68
+ $row = array_merge( $row, $multiplied_fields );
69
+ }
70
+
71
+
72
+ /**
73
+ * @param $row
74
+ * @param $repeat_as_cols
75
+ *
76
+ * @return array
77
+ */
78
+ protected function add_nested_rows_as_columns( $row, $repeat_as_cols ) {
79
+ $new_row = array();
80
+
81
+ foreach( $repeat_as_cols as $type) {
82
+ $nested_rows[$type] = self::get_array_from_array( $row, $type );
83
+ $field_group[$type] = array();
84
+ }
85
+ $mask = "#^plain_(products|coupons)_#";
86
+ $current_field_segment = "";
87
+
88
+ foreach ( $this->labels['order']->get_labels() as $label_data ) {
89
+ $original_key = $label_data['key'];
90
+ $key = $label_data['parent_key'] ? $label_data['parent_key'] : $original_key;
91
+ if ( !isset( $row[ $key ] ) ) {
92
+ continue;
93
+ }
94
+
95
+ $previous_field_segment = $current_field_segment;
96
+
97
+ if ( preg_match($mask,$key, $m) AND in_array($m[1], $repeat_as_cols) ) {
98
+ $type = $m[1];
99
+ $field_group[$type][] = $original_key;
100
+ $current_field_segment = $type;
101
+ } else {
102
+ $current_field_segment = 'order';
103
+ }
104
+
105
+ if ( $previous_field_segment!= $current_field_segment AND in_array($previous_field_segment,$repeat_as_cols) ) {
106
+ $type = $previous_field_segment;
107
+ if( $field_group[$type] ) {
108
+ $this->multiplicate_fields( $new_row, $type, $nested_rows[$type], $field_group[$type] );
109
+ $field_group[$type] = array();
110
+ }
111
+ }
112
+
113
+ //just copy as is
114
+ if ( $current_field_segment == 'order' ) {
115
+ $new_row[ $original_key ] = $row[ $key ];
116
+ }
117
+ }
118
+
119
+ //final clean up
120
+ foreach($repeat_as_cols as $type) {
121
+ if ( ! empty($field_group[$type]) ) {
122
+ $this->multiplicate_fields( $new_row, $type, $nested_rows[$type], $field_group[$type] );
123
+ }
124
+ unset($new_row[$type]);
125
+ }
126
+ return $new_row;
127
+ }
128
+
129
+ protected function try_multi_rows( $row ) {
130
+ $repeat_products = $this->duplicate_settings['products']['repeat'] == 'rows';
131
+ $repeat_coupons = $this->duplicate_settings['coupons']['repeat'] == 'rows';
132
+
133
+ $populate_non_products = isset( $this->duplicate_settings['products']['populate_other_columns'] ) && $this->duplicate_settings['products']['populate_other_columns'] == '1';
134
+
135
+ $item_rows_start_from_new_line = ( $this->format == 'csv' && $this->settings['global_job_settings']['format_csv_item_rows_start_from_new_line'] );
136
+
137
+ $combinations = array();
138
+
139
+ $p_combinations = array();
140
+ if ( $repeat_products ) {
141
+ foreach ( self::get_array_from_array( $row, 'products' ) as $products_fields_item ) {
142
+ $result_tmp = array();
143
+ foreach ( $products_fields_item as $field_name => $products_field_value ) {
144
+ if ( isset($this->labels['products']->$field_name ) ) // label must be assigned!
145
+ $result_tmp[ 'plain_products_' . $field_name ] = $products_field_value;
146
+ }
147
+
148
+ $p_combinations[] = $result_tmp;
149
+ }
150
+ }
151
+
152
+ $c_combinations = array();
153
+ if ( $repeat_coupons ) {
154
+ foreach ( self::get_array_from_array( $row, 'coupons' ) as $coupons_fields_item ) {
155
+ $result_tmp = array();
156
+ foreach ( $coupons_fields_item as $field_name => $coupons_field_value ) {
157
+ if ( isset($this->labels['coupons']->$field_name ) ) // label must be assigned!
158
+ $result_tmp[ 'plain_coupons_' . $field_name ] = $coupons_field_value;
159
+ }
160
+
161
+ $c_combinations[] = $result_tmp;
162
+ }
163
+ }
164
+
165
+ if ( empty( $p_combinations ) ) {
166
+ $combinations = $c_combinations;
167
+ } elseif ( empty( $c_combinations ) ) {
168
+ $combinations = $p_combinations;
169
+ } else {
170
+ // $item_rows_start_from_new_line has higher priority
171
+ if ( $item_rows_start_from_new_line ) {
172
+ foreach ( $p_combinations as $p_combination ) {
173
+ $combinations[] = $p_combination;
174
+ }
175
+ foreach ( $c_combinations as $c_combination ) {
176
+ $combinations[] = $c_combination;
177
+ }
178
+ } else {
179
+ $max_len = max( count( $c_combinations ), count( $p_combinations ) );
180
+ for ( $i = 0; $i < $max_len; $i ++ ) {
181
+ // output product and coupon fields one to one if its exits
182
+ // row 1 -> product 1 - coupon 1 (+ order fields)
183
+ // row 2 -> product 2 - coupon 2
184
+ // row 3 -> product 3 - coupon 3
185
+ // and so on
186
+ $p_combination = isset( $p_combinations[ $i ] ) ? $p_combinations[ $i ] : array();
187
+ $c_combination = isset( $c_combinations[ $i ] ) ? $c_combinations[ $i ] : array();
188
+ $combinations[] = array_merge( $p_combination, $c_combination );
189
+ }
190
+ }
191
+ }
192
+ // add blank combination because we need only order fields in first row for this option
193
+ if ( $item_rows_start_from_new_line ) {
194
+ array_unshift( $combinations, array() );
195
+ }
196
+
197
+ if ( empty( $combinations ) ) {
198
+ return array($row);
199
+ }
200
+
201
+ $new_rows = array();
202
+ foreach ( $combinations as $num_index => $combination ) {
203
+ if($item_rows_start_from_new_line) {
204
+ $new_row = ( $num_index == 0 ) ? $row : array();
205
+ } elseif ( $num_index == 0 OR $populate_non_products ) {
206
+ $new_row = $row; // 1st -- as is
207
+ } else { //must adjust positions for 2nd , 3rd,... rows
208
+ foreach($row as $k=>$v)
209
+ $new_row[$k] = "";
210
+ }
211
+
212
+ foreach ( $combination as $field_name => $field_value ) {
213
+ $new_row[ $field_name ] = $field_value;
214
+ foreach ( $this->labels['order']->get_childs( $field_name ) as $label_order_data_1 ) {
215
+ $new_row[ $label_order_data_1['key'] ] = $field_value;
216
+ }
217
+ }
218
+ $new_rows[] = $new_row;
219
+ }
220
+
221
+ return $new_rows;
222
+ }
223
+
224
+ private function merge_nested_rows_to_one_record( $row, $type ) {
225
+ $line_delimiter = $this->convert_literals( $this->duplicate_settings[$type]['line_delimiter'] );
226
+
227
+ $merged_values = array();
228
+ foreach($row[$type] as $line) {
229
+ foreach($line as $k=>$v) {
230
+ $plain_key = "plain_{$type}_{$k}";
231
+ if( !isset($merged_values[$plain_key]) ) {
232
+ $merged_values[$plain_key] = true;
233
+ $row[$plain_key] = $v;
234
+ }
235
+ else
236
+ $row[$plain_key] .= $line_delimiter . $v;
237
+ }
238
+ }
239
+ unset($row[$type]);
240
+ return $row;
241
+ }
242
+ }
i18n/languages/woo-order-export-lite.pot CHANGED
@@ -3,7 +3,7 @@ msgid ""
3
  msgstr ""
4
  "Project-Id-Version: PACKAGE VERSION\n"
5
  "Report-Msgid-Bugs-To: \n"
6
- "POT-Creation-Date: 2018-08-30 10:27+0000\n"
7
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
8
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
9
  "Language-Team: \n"
@@ -14,465 +14,478 @@ msgstr ""
14
  "Content-Transfer-Encoding: 8bit\n"
15
  "X-Generator: Loco https://localise.biz/"
16
 
17
- #: woo-order-export-lite.php:59
18
  msgid ""
19
  "Please, <a href=\"plugins.php\">deactivate</a> Free version of Advanced "
20
  "Order Export For WooCommerce!"
21
  msgstr ""
22
 
23
- #: view/settings-form.php:55
 
 
 
 
 
 
 
 
 
24
  msgid "Filter orders by"
25
  msgstr ""
26
 
27
- #: view/settings-form.php:59 view/settings-form.php:228
28
- #: classes/core/class-wc-order-export-data-extractor-ui.php:585
29
  msgid "Order Date"
30
  msgstr ""
31
 
32
- #: view/settings-form.php:64 view/settings-form.php:229
33
- #: classes/core/class-wc-order-export-data-extractor-ui.php:590
34
  msgid "Modification Date"
35
  msgstr ""
36
 
37
- #: view/settings-form.php:69
38
- #: classes/core/class-wc-order-export-data-extractor-ui.php:604
39
  msgid "Paid Date"
40
  msgstr ""
41
 
42
- #: view/settings-form.php:74
43
- #: classes/core/class-wc-order-export-data-extractor-ui.php:599
44
  msgid "Completed Date"
45
  msgstr ""
46
 
47
- #: view/settings-form.php:78
48
  msgid "This date range should not be saved in the scheduled task"
49
  msgstr ""
50
 
51
- #: view/settings-form.php:80
52
  msgid "Date range"
53
  msgstr ""
54
 
55
- #: view/settings-form.php:82
56
  msgid "to"
57
  msgstr ""
58
 
59
- #: view/settings-form.php:86
60
  msgid "Express export"
61
  msgstr ""
62
 
63
- #: view/settings-form.php:87
64
  msgid "Summary Report By Products"
65
  msgstr ""
66
 
67
- #: view/settings-form.php:88
68
- msgid "Set up fields"
69
- msgstr ""
70
-
71
- #: view/settings-form.php:96
72
  msgid "Export filename"
73
  msgstr ""
74
 
75
- #: view/settings-form.php:106
76
  msgid "Format"
77
  msgstr ""
78
 
79
- #: view/settings-form.php:117
80
  msgid "XLS options"
81
  msgstr ""
82
 
83
- #: view/settings-form.php:123
84
  msgid "Export as .xls (Binary File Format)"
85
  msgstr ""
86
 
87
- #: view/settings-form.php:124
88
  msgid "Use sheet name"
89
  msgstr ""
90
 
91
- #: view/settings-form.php:125 view/settings-form.php:137
92
- #: view/settings-form.php:167
93
  msgid "Output column titles as first line"
94
  msgstr ""
95
 
96
- #: view/settings-form.php:126
97
  msgid "Auto column width"
98
  msgstr ""
99
 
100
- #: view/settings-form.php:127 view/settings-form.php:138
101
- #: view/settings-form.php:168
102
- msgid "Populate other columns if products exported as rows"
103
- msgstr ""
104
-
105
- #: view/settings-form.php:128
106
  msgid "Right-to-Left direction"
107
  msgstr ""
108
 
109
- #: view/settings-form.php:130
110
  msgid "CSV options"
111
  msgstr ""
112
 
113
- #: view/settings-form.php:136 view/settings-form.php:166
114
  msgid "Output UTF-8 BOM"
115
  msgstr ""
116
 
117
- #: view/settings-form.php:139
118
  msgid "Convert line breaks to literals"
119
  msgstr ""
120
 
121
- #: view/settings-form.php:140
122
  msgid "Item rows start from new line"
123
  msgstr ""
124
 
125
- #: view/settings-form.php:141
126
  msgid "Enclosure"
127
  msgstr ""
128
 
129
- #: view/settings-form.php:142
130
  msgid "Field Delimiter"
131
  msgstr ""
132
 
133
- #: view/settings-form.php:143 view/settings-form.php:169
134
  msgid "Line Break"
135
  msgstr ""
136
 
137
- #: view/settings-form.php:145 view/settings-form.php:171
138
  msgid "Character encoding"
139
  msgstr ""
140
 
141
- #: view/settings-form.php:148
142
  msgid "XML options"
143
  msgstr ""
144
 
145
- #: view/settings-form.php:150
146
  msgid "Prepend XML"
147
  msgstr ""
148
 
149
- #: view/settings-form.php:151
150
  msgid "Root tag"
151
  msgstr ""
152
 
153
- #: view/settings-form.php:152
154
  msgid "Order tag"
155
  msgstr ""
156
 
157
- #: view/settings-form.php:153
158
  msgid "Product tag"
159
  msgstr ""
160
 
161
- #: view/settings-form.php:154
162
  msgid "Coupon tag"
163
  msgstr ""
164
 
165
- #: view/settings-form.php:155
166
  msgid "Append XML"
167
  msgstr ""
168
 
169
- #: view/settings-form.php:156
170
  msgid "Self closing tags"
171
  msgstr ""
172
 
173
- #: view/settings-form.php:158
174
  msgid "JSON options"
175
  msgstr ""
176
 
177
- #: view/settings-form.php:159
178
  msgid "Start tag"
179
  msgstr ""
180
 
181
- #: view/settings-form.php:160
182
  msgid "End tag"
183
  msgstr ""
184
 
185
- #: view/settings-form.php:162
186
  msgid "TSV options"
187
  msgstr ""
188
 
189
- #: view/settings-form.php:178
 
190
  msgid "Date"
191
  msgstr ""
192
 
193
- #: view/settings-form.php:191 view/settings-form.php:213
194
- msgid "-"
195
- msgstr ""
196
-
197
- #: view/settings-form.php:193 view/settings-form.php:215
198
  msgid "custom"
199
  msgstr ""
200
 
201
- #: view/settings-form.php:201
202
  msgid "Time"
203
  msgstr ""
204
 
205
- #: view/settings-form.php:227
206
- #: classes/core/class-wc-order-export-data-extractor-ui.php:581
207
  msgid "Order ID"
208
  msgstr ""
209
 
210
- #: view/settings-form.php:244
211
  msgid "Descending"
212
  msgstr ""
213
 
214
- #: view/settings-form.php:245
215
  msgid "Ascending"
216
  msgstr ""
217
 
218
- #: view/settings-form.php:250
219
  #, php-format
220
  msgid "Sort orders by %s in %s order"
221
  msgstr ""
222
 
223
- #: view/settings-form.php:255
224
  msgid "Change order status to"
225
  msgstr ""
226
 
227
- #: view/settings-form.php:257
228
  msgid "- don't modify -"
229
  msgstr ""
230
 
231
- #: view/settings-form.php:267
232
  msgid "Misc settings"
233
  msgstr ""
234
 
235
- #: view/settings-form.php:272
236
  msgid "Format numbers (use WC decimal separator)"
237
  msgstr ""
238
 
239
- #: view/settings-form.php:276
240
  msgid "Export all order notes"
241
  msgstr ""
242
 
243
- #: view/settings-form.php:280
244
  msgid "Export refund notes as Customer Note"
245
  msgstr ""
246
 
247
- #: view/settings-form.php:284
248
  msgid "Strip tags from Product Description/Variation"
249
  msgstr ""
250
 
251
- #: view/settings-form.php:288
252
  msgid "Cleanup phone (export only digits)"
253
  msgstr ""
254
 
255
- #: view/settings-form.php:292
256
  msgid "Enable debug output"
257
  msgstr ""
258
 
259
- #: view/settings-form.php:296
260
  msgid "Custom PHP code to modify output"
261
  msgstr ""
262
 
263
- #: view/settings-form.php:300
264
  msgid ""
265
  "Please check permissions for your role. You must have capability "
266
  "“edit_themes” to use this box."
267
  msgstr ""
268
 
269
- #: view/settings-form.php:303
270
  msgid "Use only unnamed functions!"
271
  msgstr ""
272
 
273
- #: view/settings-form.php:317
274
  msgid "Filter by order"
275
  msgstr ""
276
 
277
- #: view/settings-form.php:320
278
  msgid "Don't export child orders"
279
  msgstr ""
280
 
281
- #: view/settings-form.php:321
282
  msgid "Export refunds"
283
  msgstr ""
284
 
285
- #: view/settings-form.php:322
286
  msgid "Mark exported orders"
287
  msgstr ""
288
 
289
- #: view/settings-form.php:323
290
  msgid "Export unmarked orders only"
291
  msgstr ""
292
 
293
- #: view/settings-form.php:324
294
  msgid "Order statuses"
295
  msgstr ""
296
 
297
- #: view/settings-form.php:331 view/settings-form.php:556
298
  msgid "Custom fields"
299
  msgstr ""
300
 
301
- #: view/settings-form.php:370
302
  msgid ""
303
  "The filters won't work correctly.<br>Another plugin(or theme) has loaded "
304
  "outdated Select2.js"
305
  msgstr ""
306
 
307
- #: view/settings-form.php:371
308
  msgid "Filter by product"
309
  msgstr ""
310
 
311
- #: view/settings-form.php:374
312
  msgid "Export all products from the order"
313
  msgstr ""
314
 
315
- #: view/settings-form.php:375
316
  msgid "Skip fully refunded items"
317
  msgstr ""
318
 
319
- #: view/settings-form.php:376
320
  msgid "Product categories"
321
  msgstr ""
322
 
323
- #: view/settings-form.php:386
324
  msgid "Vendor/creator"
325
  msgstr ""
326
 
327
- #: view/settings-form.php:399
328
  msgid "Product"
329
  msgstr ""
330
 
331
- #: view/settings-form.php:411
332
  msgid "Product taxonomies"
333
  msgstr ""
334
 
335
- #: view/settings-form.php:437
336
  msgid "Product custom fields"
337
  msgstr ""
338
 
339
- #: view/settings-form.php:468
340
  msgid "Variable product attributes"
341
  msgstr ""
342
 
343
- #: view/settings-form.php:495
344
  msgid "Item meta data"
345
  msgstr ""
346
 
347
- #: view/settings-form.php:532
348
  msgid "Filter by customers"
349
  msgstr ""
350
 
351
- #: view/settings-form.php:536
352
  msgid "Usernames"
353
  msgstr ""
354
 
355
- #: view/settings-form.php:547
356
  msgid "User roles"
357
  msgstr ""
358
 
359
- #: view/settings-form.php:593
360
  msgid "Filter by coupons"
361
  msgstr ""
362
 
363
- #: view/settings-form.php:598
364
  msgid "Any coupon used"
365
  msgstr ""
366
 
367
- #: view/settings-form.php:600
368
- #: classes/core/class-wc-order-export-data-extractor-ui.php:835
369
- #: classes/core/class-wc-order-export-data-extractor-ui.php:1019
 
370
  msgid "Coupons"
371
  msgstr ""
372
 
373
- #: view/settings-form.php:615
374
  msgid "Filter by billing"
375
  msgstr ""
376
 
377
- #: view/settings-form.php:618
378
  msgid "Billing locations"
379
  msgstr ""
380
 
381
- #: view/settings-form.php:642
382
  msgid "Payment methods"
383
  msgstr ""
384
 
385
- #: view/settings-form.php:654
386
  msgid "Filter by shipping"
387
  msgstr ""
388
 
389
- #: view/settings-form.php:657
390
  msgid "Shipping locations"
391
  msgstr ""
392
 
393
- #: view/settings-form.php:681
394
  msgid "Shipping methods"
395
  msgstr ""
396
 
397
- #: view/settings-form.php:693
398
  msgid "Filter by item and metadata"
399
  msgstr ""
400
 
401
- #: view/settings-form.php:696
402
  msgid "Item names"
403
  msgstr ""
404
 
405
- #: view/settings-form.php:720
406
  msgid "Item metadata"
407
  msgstr ""
408
 
409
- #: view/settings-form.php:754 classes/class-wc-order-export-admin.php:572
410
  msgid "Set up fields to export"
411
  msgstr ""
412
 
413
- #: view/settings-form.php:760 view/modal-controls.php:36
414
- msgid "Meta key"
415
  msgstr ""
416
 
417
- #: view/settings-form.php:768 view/settings-form.php:780
418
- #: view/modal-controls.php:20 view/modal-controls.php:26
419
- #: view/modal-controls.php:43 view/modal-controls.php:49
420
- msgid "Column name"
421
  msgstr ""
422
 
423
- #: view/settings-form.php:771
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
424
  msgid "or type meta key here"
425
  msgstr ""
426
 
427
- #: view/settings-form.php:772 view/settings-form.php:800
428
- #: view/modal-controls.php:4 view/modal-controls.php:39
429
  msgid "Hide unused fields"
430
  msgstr ""
431
 
432
- #: view/settings-form.php:775 view/settings-form.php:783
 
 
 
 
 
 
 
 
433
  msgid "Confirm"
434
  msgstr ""
435
 
436
- #: view/settings-form.php:776 view/settings-form.php:784
 
 
437
  msgid "Cancel"
438
  msgstr ""
439
 
440
- #: view/settings-form.php:781 view/modal-controls.php:27
441
- #: view/modal-controls.php:50
442
  msgid "Value"
443
  msgstr ""
444
 
445
- #: view/settings-form.php:787
446
- msgid "Use sections"
447
- msgstr ""
448
-
449
- #: view/settings-form.php:794
450
- msgid "Actions"
451
- msgstr ""
452
-
453
- #: view/settings-form.php:795 view/modal-controls.php:22
454
- #: view/modal-controls.php:45
455
- msgid "Add field"
456
  msgstr ""
457
 
458
- #: view/settings-form.php:797 view/modal-controls.php:29
459
- #: view/modal-controls.php:52
460
- msgid "Add static field"
461
  msgstr ""
462
 
463
- #: view/settings-form.php:801
464
- msgid "Show unused fields"
465
  msgstr ""
466
 
467
- #: view/settings-form.php:809
468
- msgid "Select all"
469
  msgstr ""
470
 
471
- #: view/settings-form.php:812
472
- msgid "Drag rows to reorder exported fields"
473
  msgstr ""
474
 
475
- #: view/settings-form.php:823
476
  #, php-format
477
  msgid ""
478
  "If you see this message after page load, user interface won't work correctly!"
@@ -480,48 +493,56 @@ msgid ""
480
  "it). Probably, it's a conflict with another plugin or active theme."
481
  msgstr ""
482
 
483
- #: view/settings-form.php:825
484
  msgid "Preview"
485
  msgstr ""
486
 
487
- #: view/settings-form.php:825
488
  msgid "Might be different from actual export!"
489
  msgstr ""
490
 
491
- #: view/settings-form.php:826
492
  msgid "Save settings"
493
  msgstr ""
494
 
495
- #: view/settings-form.php:828
 
 
 
 
496
  msgid "Export"
497
  msgstr ""
498
 
499
- #: view/settings-form.php:831
500
  msgid "Export [w/o progressbar]"
501
  msgstr ""
502
 
503
- #: view/settings-form.php:831
504
  msgid "It might not work for huge datasets!"
505
  msgstr ""
506
 
507
- #: view/settings-form.php:834
508
  msgid "Save as a profile"
509
  msgstr ""
510
 
511
- #: view/settings-form.php:837
512
  #, php-format
513
  msgid "Export total: %s orders"
514
  msgstr ""
515
 
516
- #: view/settings-form.php:838
517
  msgid "Preview size"
518
  msgstr ""
519
 
520
- #: view/settings-form.php:846
 
 
 
 
521
  msgid "Press 'Esc' to cancel the export"
522
  msgstr ""
523
 
524
- #: view/settings-form.php:847
525
  msgid "Click here to download"
526
  msgstr ""
527
 
@@ -553,26 +574,6 @@ msgstr ""
553
  msgid "Help"
554
  msgstr ""
555
 
556
- #: view/modal-controls.php:6
557
- msgid "Product fields"
558
- msgstr ""
559
-
560
- #: view/modal-controls.php:9
561
- msgid "Order item fields"
562
- msgstr ""
563
-
564
- #: view/modal-controls.php:11
565
- msgid "OR"
566
- msgstr ""
567
-
568
- #: view/modal-controls.php:12
569
- msgid "Taxonomy"
570
- msgstr ""
571
-
572
- #: view/modal-controls.php:38
573
- msgid "All meta"
574
- msgstr ""
575
-
576
  #: classes/class-wc-order-export-admin.php:91
577
  msgid "Export Status"
578
  msgstr ""
@@ -608,80 +609,144 @@ msgstr ""
608
 
609
  #: classes/class-wc-order-export-admin.php:573
610
  #, php-format
611
- msgid "Add %s as %s columns %s as rows"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
612
  msgstr ""
613
 
614
- #: classes/class-wc-order-export-admin.php:614
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
615
  msgid "empty column name"
616
  msgstr ""
617
 
618
- #: classes/class-wc-order-export-admin.php:615
619
  msgid "empty meta key"
620
  msgstr ""
621
 
622
- #: classes/class-wc-order-export-admin.php:616
623
  msgid "select product field or item field or taxonomy"
624
  msgstr ""
625
 
626
- #: classes/class-wc-order-export-admin.php:618
627
  msgid "empty value"
628
  msgstr ""
629
 
630
- #: classes/class-wc-order-export-admin.php:619
631
  msgid "title is empty"
632
  msgstr ""
633
 
634
- #: classes/class-wc-order-export-admin.php:620
635
  msgid "Date From is greater than Date To"
636
  msgstr ""
637
 
638
- #: classes/class-wc-order-export-admin.php:621
639
  msgid "Please, set up fields to export"
640
  msgstr ""
641
 
642
- #: classes/class-wc-order-export-admin.php:622
643
  #: classes/admin/class-wc-order-export-ajax.php:356
644
- #: classes/core/class-wc-order-export-engine.php:748
645
- #: classes/core/class-wc-order-export-engine.php:761
646
  msgid "Nothing to export. Please, adjust your filters"
647
  msgstr ""
648
 
649
- #: classes/class-wc-order-export-admin.php:624
650
- #: classes/core/class-wc-order-export-data-extractor.php:229
651
  msgid "empty"
652
  msgstr ""
653
 
654
- #: classes/class-wc-order-export-admin.php:719
655
  #, php-format
656
  msgid "Status change job #%s for order #%s. Result: %s"
657
  msgstr ""
658
 
659
- #: classes/class-wc-order-export-admin.php:782
660
  #, php-format
661
  msgid "Export as %s"
662
  msgstr ""
663
 
664
- #: classes/class-wc-order-export-admin.php:788
665
  msgid "Mark exported"
666
  msgstr ""
667
 
668
- #: classes/class-wc-order-export-admin.php:789
669
  msgid "Unmark exported"
670
  msgstr ""
671
 
672
- #: classes/class-wc-order-export-admin.php:795
673
  #, php-format
674
  msgid "Export as profile '%s'"
675
  msgstr ""
676
 
677
- #: classes/class-wc-order-export-admin.php:866
678
  #, php-format
679
  msgid "%s order marked."
680
  msgid_plural "%s orders marked."
681
  msgstr[0] ""
682
  msgstr[1] ""
683
 
684
- #: classes/class-wc-order-export-admin.php:875
685
  #, php-format
686
  msgid "%s order unmarked."
687
  msgid_plural "%s orders unmarked."
@@ -783,17 +848,17 @@ msgstr ""
783
  msgid "Buy %s to get access to Scheduled jobs"
784
  msgstr ""
785
 
786
- #: classes/formats/abstract-class-woe-formatter-sv.php:89
787
- #: classes/formats/class-woe-formatter-xls.php:137
788
  msgid "<td colspan=10><b>No results</b></td>"
789
  msgstr ""
790
 
791
- #: classes/formats/abstract-class-woe-formatter.php:26
792
  msgid "can not open for output"
793
  msgstr ""
794
 
795
- #: classes/formats/class-woe-formatter-xls.php:75
796
- #: classes/admin/class-wc-order-export-manage.php:214
797
  msgid "Orders"
798
  msgstr ""
799
 
@@ -825,6 +890,12 @@ msgstr ""
825
  msgid "Sat"
826
  msgstr ""
827
 
 
 
 
 
 
 
828
  #: classes/admin/class-wc-order-export-ajax.php:20
829
  msgid "Wrong key for cron url!"
830
  msgstr ""
@@ -841,513 +912,548 @@ msgstr ""
841
  msgid "Item ID"
842
  msgstr ""
843
 
844
- #: classes/core/class-wc-order-export-data-extractor-ui.php:347
845
  msgid "Item #"
846
  msgstr ""
847
 
848
- #: classes/core/class-wc-order-export-data-extractor-ui.php:348
849
  msgid "SKU"
850
  msgstr ""
851
 
852
- #: classes/core/class-wc-order-export-data-extractor-ui.php:350
853
  msgid "Item Name"
854
  msgstr ""
855
 
856
- #: classes/core/class-wc-order-export-data-extractor-ui.php:354
857
  msgid "Product Id"
858
  msgstr ""
859
 
860
- #: classes/core/class-wc-order-export-data-extractor-ui.php:358
861
  msgid "Product Name"
862
  msgstr ""
863
 
864
- #: classes/core/class-wc-order-export-data-extractor-ui.php:362
865
  msgid "Variation Id"
866
  msgstr ""
867
 
868
- #: classes/core/class-wc-order-export-data-extractor-ui.php:366
869
  msgid "Product Variation"
870
  msgstr ""
871
 
872
- #: classes/core/class-wc-order-export-data-extractor-ui.php:370
873
  msgid "Item Seller"
874
  msgstr ""
875
 
876
- #: classes/core/class-wc-order-export-data-extractor-ui.php:374
877
  msgid "Quantity"
878
  msgstr ""
879
 
880
- #: classes/core/class-wc-order-export-data-extractor-ui.php:378
881
  msgid "Quantity (- Refund)"
882
  msgstr ""
883
 
884
- #: classes/core/class-wc-order-export-data-extractor-ui.php:382
885
  msgid "Item Cost"
886
  msgstr ""
887
 
888
- #: classes/core/class-wc-order-export-data-extractor-ui.php:387
889
  msgid "Product Current Price"
890
  msgstr ""
891
 
892
- #: classes/core/class-wc-order-export-data-extractor-ui.php:392
893
  msgid "Order Line (w/o tax)"
894
  msgstr ""
895
 
896
- #: classes/core/class-wc-order-export-data-extractor-ui.php:397
897
  msgid "Order Line Tax"
898
  msgstr ""
899
 
900
- #: classes/core/class-wc-order-export-data-extractor-ui.php:402
901
  msgid "Order Line Tax Refunded"
902
  msgstr ""
903
 
904
- #: classes/core/class-wc-order-export-data-extractor-ui.php:407
905
  msgid "Order Line Tax (- Refund)"
906
  msgstr ""
907
 
908
- #: classes/core/class-wc-order-export-data-extractor-ui.php:412
909
  msgid "Order Line Subtotal"
910
  msgstr ""
911
 
912
- #: classes/core/class-wc-order-export-data-extractor-ui.php:417
913
  msgid "Order Line Subtotal Tax"
914
  msgstr ""
915
 
916
- #: classes/core/class-wc-order-export-data-extractor-ui.php:422
917
  msgid "Order Line Total"
918
  msgstr ""
919
 
920
- #: classes/core/class-wc-order-export-data-extractor-ui.php:427
921
  msgid "Order Line Total (include tax)"
922
  msgstr ""
923
 
924
- #: classes/core/class-wc-order-export-data-extractor-ui.php:432
925
  msgid "Order Line Total Refunded"
926
  msgstr ""
927
 
928
- #: classes/core/class-wc-order-export-data-extractor-ui.php:437
929
  msgid "Order Line Total (- Refund)"
930
  msgstr ""
931
 
932
- #: classes/core/class-wc-order-export-data-extractor-ui.php:442
933
  msgid "Item Discount Amount"
934
  msgstr ""
935
 
936
- #: classes/core/class-wc-order-export-data-extractor-ui.php:447
937
  msgid "Item Tax Rate"
938
  msgstr ""
939
 
940
- #: classes/core/class-wc-order-export-data-extractor-ui.php:451
941
  msgid "Type"
942
  msgstr ""
943
 
944
- #: classes/core/class-wc-order-export-data-extractor-ui.php:453
945
  msgid "Category"
946
  msgstr ""
947
 
948
- #: classes/core/class-wc-order-export-data-extractor-ui.php:456
949
  msgid "Tags"
950
  msgstr ""
951
 
952
- #: classes/core/class-wc-order-export-data-extractor-ui.php:458
953
  msgid "Width"
954
  msgstr ""
955
 
956
- #: classes/core/class-wc-order-export-data-extractor-ui.php:463
957
  msgid "Length"
958
  msgstr ""
959
 
960
- #: classes/core/class-wc-order-export-data-extractor-ui.php:468
961
  msgid "Height"
962
  msgstr ""
963
 
964
- #: classes/core/class-wc-order-export-data-extractor-ui.php:473
965
  msgid "Weight"
966
  msgstr ""
967
 
968
- #: classes/core/class-wc-order-export-data-extractor-ui.php:478
969
  msgid "Product URL"
970
  msgstr ""
971
 
972
- #: classes/core/class-wc-order-export-data-extractor-ui.php:482
973
  msgid "Download URL"
974
  msgstr ""
975
 
976
- #: classes/core/class-wc-order-export-data-extractor-ui.php:486
977
  msgid "Image URL"
978
  msgstr ""
979
 
980
- #: classes/core/class-wc-order-export-data-extractor-ui.php:490
981
  msgid "Product Shipping Class"
982
  msgstr ""
983
 
984
- #: classes/core/class-wc-order-export-data-extractor-ui.php:494
985
  msgid "Description"
986
  msgstr ""
987
 
988
- #: classes/core/class-wc-order-export-data-extractor-ui.php:498
989
  msgid "Short Description"
990
  msgstr ""
991
 
992
- #: classes/core/class-wc-order-export-data-extractor-ui.php:502
993
  msgid "Full names for categories"
994
  msgstr ""
995
 
996
- #: classes/core/class-wc-order-export-data-extractor-ui.php:518
 
 
 
 
 
 
 
 
997
  msgid "Coupon Code"
998
  msgstr ""
999
 
1000
- #: classes/core/class-wc-order-export-data-extractor-ui.php:522
1001
  msgid "Discount Amount"
1002
  msgstr ""
1003
 
1004
- #: classes/core/class-wc-order-export-data-extractor-ui.php:527
1005
  msgid "Discount Amount Tax"
1006
  msgstr ""
1007
 
1008
- #: classes/core/class-wc-order-export-data-extractor-ui.php:532
1009
  msgid "Discount Amount + Tax"
1010
  msgstr ""
1011
 
1012
- #: classes/core/class-wc-order-export-data-extractor-ui.php:536
1013
  msgid "Coupon Description"
1014
  msgstr ""
1015
 
1016
- #: classes/core/class-wc-order-export-data-extractor-ui.php:540
1017
  msgid "Coupon Type"
1018
  msgstr ""
1019
 
1020
- #: classes/core/class-wc-order-export-data-extractor-ui.php:544
1021
  msgid "Coupon Amount"
1022
  msgstr ""
1023
 
1024
- #: classes/core/class-wc-order-export-data-extractor-ui.php:580
1025
  msgid "Line number"
1026
  msgstr ""
1027
 
1028
- #: classes/core/class-wc-order-export-data-extractor-ui.php:582
1029
  msgid "Order Number"
1030
  msgstr ""
1031
 
1032
- #: classes/core/class-wc-order-export-data-extractor-ui.php:583
1033
  msgid "Order Status"
1034
  msgstr ""
1035
 
1036
- #: classes/core/class-wc-order-export-data-extractor-ui.php:595
1037
  msgid "Transaction ID"
1038
  msgstr ""
1039
 
1040
- #: classes/core/class-wc-order-export-data-extractor-ui.php:609
 
 
 
 
1041
  msgid "Date of first refund"
1042
  msgstr ""
1043
 
1044
- #: classes/core/class-wc-order-export-data-extractor-ui.php:614
1045
  msgid "Customer Note"
1046
  msgstr ""
1047
 
1048
- #: classes/core/class-wc-order-export-data-extractor-ui.php:619
1049
  msgid "Order Notes"
1050
  msgstr ""
1051
 
1052
- #: classes/core/class-wc-order-export-data-extractor-ui.php:629
1053
  msgid "Customer IP address"
1054
  msgstr ""
1055
 
1056
- #: classes/core/class-wc-order-export-data-extractor-ui.php:633
1057
  msgid "Customer User ID"
1058
  msgstr ""
1059
 
1060
- #: classes/core/class-wc-order-export-data-extractor-ui.php:637
1061
  msgid "Customer Username"
1062
  msgstr ""
1063
 
1064
- #: classes/core/class-wc-order-export-data-extractor-ui.php:641
1065
  msgid "User Website"
1066
  msgstr ""
1067
 
1068
- #: classes/core/class-wc-order-export-data-extractor-ui.php:645
1069
  msgid "Customer User Email"
1070
  msgstr ""
1071
 
1072
- #: classes/core/class-wc-order-export-data-extractor-ui.php:649
1073
  msgid "Customer Role"
1074
  msgstr ""
1075
 
1076
- #: classes/core/class-wc-order-export-data-extractor-ui.php:653
1077
  msgid "Customer Total Orders"
1078
  msgstr ""
1079
 
1080
- #: classes/core/class-wc-order-export-data-extractor-ui.php:662
1081
  msgid "First Name (Billing)"
1082
  msgstr ""
1083
 
1084
- #: classes/core/class-wc-order-export-data-extractor-ui.php:667
1085
  msgid "Last Name (Billing)"
1086
  msgstr ""
1087
 
1088
- #: classes/core/class-wc-order-export-data-extractor-ui.php:672
1089
  msgid "Full Name (Billing)"
1090
  msgstr ""
1091
 
1092
- #: classes/core/class-wc-order-export-data-extractor-ui.php:677
1093
  msgid "Company (Billing)"
1094
  msgstr ""
1095
 
1096
- #: classes/core/class-wc-order-export-data-extractor-ui.php:682
1097
  msgid "Address 1&2 (Billing)"
1098
  msgstr ""
1099
 
1100
- #: classes/core/class-wc-order-export-data-extractor-ui.php:687
1101
  msgid "Address 1 (Billing)"
1102
  msgstr ""
1103
 
1104
- #: classes/core/class-wc-order-export-data-extractor-ui.php:692
1105
  msgid "Address 2 (Billing)"
1106
  msgstr ""
1107
 
1108
- #: classes/core/class-wc-order-export-data-extractor-ui.php:697
1109
  msgid "City (Billing)"
1110
  msgstr ""
1111
 
1112
- #: classes/core/class-wc-order-export-data-extractor-ui.php:702
1113
  msgid "State Code (Billing)"
1114
  msgstr ""
1115
 
1116
- #: classes/core/class-wc-order-export-data-extractor-ui.php:707
1117
  msgid "City, State, Zip (Billing)"
1118
  msgstr ""
1119
 
1120
- #: classes/core/class-wc-order-export-data-extractor-ui.php:712
1121
  msgid "State Name (Billing)"
1122
  msgstr ""
1123
 
1124
- #: classes/core/class-wc-order-export-data-extractor-ui.php:717
1125
  msgid "Postcode (Billing)"
1126
  msgstr ""
1127
 
1128
- #: classes/core/class-wc-order-export-data-extractor-ui.php:722
1129
  msgid "Country Code (Billing)"
1130
  msgstr ""
1131
 
1132
- #: classes/core/class-wc-order-export-data-extractor-ui.php:727
1133
  msgid "Country Name (Billing)"
1134
  msgstr ""
1135
 
1136
- #: classes/core/class-wc-order-export-data-extractor-ui.php:732
1137
  msgid "Email (Billing)"
1138
  msgstr ""
1139
 
1140
- #: classes/core/class-wc-order-export-data-extractor-ui.php:737
1141
  msgid "Phone (Billing)"
1142
  msgstr ""
1143
 
1144
- #: classes/core/class-wc-order-export-data-extractor-ui.php:747
1145
  msgid "First Name (Shipping)"
1146
  msgstr ""
1147
 
1148
- #: classes/core/class-wc-order-export-data-extractor-ui.php:752
1149
  msgid "Last Name (Shipping)"
1150
  msgstr ""
1151
 
1152
- #: classes/core/class-wc-order-export-data-extractor-ui.php:757
1153
  msgid "Full Name (Shipping)"
1154
  msgstr ""
1155
 
1156
- #: classes/core/class-wc-order-export-data-extractor-ui.php:762
1157
  msgid "Company (Shipping)"
1158
  msgstr ""
1159
 
1160
- #: classes/core/class-wc-order-export-data-extractor-ui.php:767
1161
  msgid "Address 1&2 (Shipping)"
1162
  msgstr ""
1163
 
1164
- #: classes/core/class-wc-order-export-data-extractor-ui.php:772
1165
  msgid "Address 1 (Shipping)"
1166
  msgstr ""
1167
 
1168
- #: classes/core/class-wc-order-export-data-extractor-ui.php:777
1169
  msgid "Address 2 (Shipping)"
1170
  msgstr ""
1171
 
1172
- #: classes/core/class-wc-order-export-data-extractor-ui.php:782
1173
  msgid "City (Shipping)"
1174
  msgstr ""
1175
 
1176
- #: classes/core/class-wc-order-export-data-extractor-ui.php:787
1177
  msgid "State Code (Shipping)"
1178
  msgstr ""
1179
 
1180
- #: classes/core/class-wc-order-export-data-extractor-ui.php:792
1181
  msgid "City, State, Zip (Shipping)"
1182
  msgstr ""
1183
 
1184
- #: classes/core/class-wc-order-export-data-extractor-ui.php:797
1185
  msgid "State Name (Shipping)"
1186
  msgstr ""
1187
 
1188
- #: classes/core/class-wc-order-export-data-extractor-ui.php:802
1189
  msgid "Postcode (Shipping)"
1190
  msgstr ""
1191
 
1192
- #: classes/core/class-wc-order-export-data-extractor-ui.php:807
1193
  msgid "Country Code (Shipping)"
1194
  msgstr ""
1195
 
1196
- #: classes/core/class-wc-order-export-data-extractor-ui.php:812
1197
  msgid "Country Name (Shipping)"
1198
  msgstr ""
1199
 
1200
- #: classes/core/class-wc-order-export-data-extractor-ui.php:823
1201
- #: classes/core/class-wc-order-export-data-extractor-ui.php:1018
1202
- msgid "Products"
1203
- msgstr ""
1204
-
1205
- #: classes/core/class-wc-order-export-data-extractor-ui.php:846
1206
  msgid "Shipping Method Title"
1207
  msgstr ""
1208
 
1209
- #: classes/core/class-wc-order-export-data-extractor-ui.php:851
1210
  msgid "Shipping Method"
1211
  msgstr ""
1212
 
1213
- #: classes/core/class-wc-order-export-data-extractor-ui.php:856
1214
  msgid "Payment Method Title"
1215
  msgstr ""
1216
 
1217
- #: classes/core/class-wc-order-export-data-extractor-ui.php:861
1218
  msgid "Payment Method"
1219
  msgstr ""
1220
 
1221
- #: classes/core/class-wc-order-export-data-extractor-ui.php:866
1222
  msgid "Coupons Used"
1223
  msgstr ""
1224
 
1225
- #: classes/core/class-wc-order-export-data-extractor-ui.php:871
1226
  msgid "Cart Discount Amount"
1227
  msgstr ""
1228
 
1229
- #: classes/core/class-wc-order-export-data-extractor-ui.php:876
1230
  msgid "Cart Discount Amount Tax"
1231
  msgstr ""
1232
 
1233
- #: classes/core/class-wc-order-export-data-extractor-ui.php:881
1234
  msgid "Order Subtotal Amount"
1235
  msgstr ""
1236
 
1237
- #: classes/core/class-wc-order-export-data-extractor-ui.php:891
 
 
 
 
1238
  msgid "Order Subtotal Amount Refunded"
1239
  msgstr ""
1240
 
1241
- #: classes/core/class-wc-order-export-data-extractor-ui.php:896
1242
  msgid "Order Subtotal Amount (- Refund)"
1243
  msgstr ""
1244
 
1245
- #: classes/core/class-wc-order-export-data-extractor-ui.php:901
1246
  msgid "Order Tax Amount"
1247
  msgstr ""
1248
 
1249
- #: classes/core/class-wc-order-export-data-extractor-ui.php:906
1250
  msgid "Order Shipping Amount"
1251
  msgstr ""
1252
 
1253
- #: classes/core/class-wc-order-export-data-extractor-ui.php:911
 
 
 
 
1254
  msgid "Order Shipping Amount Refunded"
1255
  msgstr ""
1256
 
1257
- #: classes/core/class-wc-order-export-data-extractor-ui.php:916
1258
  msgid "Order Shipping Amount (- Refund)"
1259
  msgstr ""
1260
 
1261
- #: classes/core/class-wc-order-export-data-extractor-ui.php:921
1262
  msgid "Order Shipping Tax Amount"
1263
  msgstr ""
1264
 
1265
- #: classes/core/class-wc-order-export-data-extractor-ui.php:926
1266
  msgid "Order Shipping Tax Refunded"
1267
  msgstr ""
1268
 
1269
- #: classes/core/class-wc-order-export-data-extractor-ui.php:931
1270
  msgid "Order Shipping Tax Amount (- Refund)"
1271
  msgstr ""
1272
 
1273
- #: classes/core/class-wc-order-export-data-extractor-ui.php:936
 
 
 
 
1274
  msgid "Order Refund Amount"
1275
  msgstr ""
1276
 
1277
- #: classes/core/class-wc-order-export-data-extractor-ui.php:941
1278
  msgid "Order Total Amount (- Refund)"
1279
  msgstr ""
1280
 
1281
- #: classes/core/class-wc-order-export-data-extractor-ui.php:946
1282
  msgid "Order Total Amount"
1283
  msgstr ""
1284
 
1285
- #: classes/core/class-wc-order-export-data-extractor-ui.php:951
1286
  msgid "Order Total Amount without Tax"
1287
  msgstr ""
1288
 
1289
- #: classes/core/class-wc-order-export-data-extractor-ui.php:956
1290
  msgid "Order Total Tax Amount"
1291
  msgstr ""
1292
 
1293
- #: classes/core/class-wc-order-export-data-extractor-ui.php:961
1294
  msgid "Order Total Tax Amount Refunded"
1295
  msgstr ""
1296
 
1297
- #: classes/core/class-wc-order-export-data-extractor-ui.php:966
1298
  msgid "Order Total Tax Amount (- Refund)"
1299
  msgstr ""
1300
 
1301
- #: classes/core/class-wc-order-export-data-extractor-ui.php:971
1302
- msgid "Currency"
1303
- msgstr ""
1304
-
1305
- #: classes/core/class-wc-order-export-data-extractor-ui.php:981
1306
  msgid "Total weight"
1307
  msgstr ""
1308
 
1309
- #: classes/core/class-wc-order-export-data-extractor-ui.php:986
1310
  msgid "Total items"
1311
  msgstr ""
1312
 
1313
- #: classes/core/class-wc-order-export-data-extractor-ui.php:990
1314
  msgid "Exported items"
1315
  msgstr ""
1316
 
1317
- #: classes/core/class-wc-order-export-data-extractor-ui.php:994
1318
  msgid "Total products"
1319
  msgstr ""
1320
 
1321
- #: classes/core/class-wc-order-export-data-extractor-ui.php:1014
1322
  msgid "Common"
1323
  msgstr ""
1324
 
1325
- #: classes/core/class-wc-order-export-data-extractor-ui.php:1015
1326
  msgid "User"
1327
  msgstr ""
1328
 
1329
- #: classes/core/class-wc-order-export-data-extractor-ui.php:1016
1330
- msgid "Billing"
1331
  msgstr ""
1332
 
1333
- #: classes/core/class-wc-order-export-data-extractor-ui.php:1017
1334
- msgid "Shipping"
1335
  msgstr ""
1336
 
1337
- #: classes/core/class-wc-order-export-data-extractor-ui.php:1020
1338
  msgid "Cart"
1339
  msgstr ""
1340
 
1341
- #: classes/core/class-wc-order-export-data-extractor-ui.php:1021
 
 
 
 
 
 
 
 
1342
  msgid "Others"
1343
  msgstr ""
1344
 
1345
- #: classes/core/class-wc-order-export-data-extractor.php:2101
 
 
 
 
 
 
 
 
 
 
 
 
1346
  msgid "[Rest of the World]"
1347
  msgstr ""
1348
 
1349
  #: classes/core/class-wc-order-export-engine.php:19
1350
- #: classes/core/class-wc-order-export-engine.php:60
1351
  msgid "No destination selected"
1352
  msgstr ""
1353
 
@@ -1355,31 +1461,23 @@ msgstr ""
1355
  msgid "Wrong format"
1356
  msgstr ""
1357
 
1358
- #: classes/core/class-wc-order-export-engine.php:70
1359
  msgid "Wrong export type"
1360
  msgstr ""
1361
 
1362
- #: classes/core/class-wc-order-export-engine.php:398
1363
  msgid "Don't Panic"
1364
  msgstr ""
1365
 
1366
- #: classes/core/class-wc-order-export-engine.php:399
1367
  #, php-format
1368
  msgid "The code you are trying to save produced a fatal error on line %d:"
1369
  msgstr ""
1370
 
1371
- #: classes/core/class-wc-order-export-engine.php:533
1372
  msgid "Main SQL queries are listed below"
1373
  msgstr ""
1374
 
1375
- #: classes/core/class-wc-order-export-engine.php:795
1376
- msgid "Total Quantity"
1377
- msgstr ""
1378
-
1379
- #: classes/core/class-wc-order-export-engine.php:796
1380
- msgid "Total Amount"
1381
- msgstr ""
1382
-
1383
  #. Name of the plugin
1384
  msgid "Advanced Order Export For WooCommerce"
1385
  msgstr ""
3
  msgstr ""
4
  "Project-Id-Version: PACKAGE VERSION\n"
5
  "Report-Msgid-Bugs-To: \n"
6
+ "POT-Creation-Date: 2018-10-23 10:45+0000\n"
7
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
8
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
9
  "Language-Team: \n"
14
  "Content-Transfer-Encoding: 8bit\n"
15
  "X-Generator: Loco https://localise.biz/"
16
 
17
+ #: woo-order-export-lite.php:65
18
  msgid ""
19
  "Please, <a href=\"plugins.php\">deactivate</a> Free version of Advanced "
20
  "Order Export For WooCommerce!"
21
  msgstr ""
22
 
23
+ #: view/settings-form.php:28
24
+ msgid "Field format"
25
+ msgstr ""
26
+
27
+ #: view/settings-form.php:31 view/settings-form.php:214
28
+ #: view/settings-form.php:236
29
+ msgid "-"
30
+ msgstr ""
31
+
32
+ #: view/settings-form.php:85
33
  msgid "Filter orders by"
34
  msgstr ""
35
 
36
+ #: view/settings-form.php:89 view/settings-form.php:251
37
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:638
38
  msgid "Order Date"
39
  msgstr ""
40
 
41
+ #: view/settings-form.php:94 view/settings-form.php:252
42
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:643
43
  msgid "Modification Date"
44
  msgstr ""
45
 
46
+ #: view/settings-form.php:99
47
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:663
48
  msgid "Paid Date"
49
  msgstr ""
50
 
51
+ #: view/settings-form.php:104
52
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:658
53
  msgid "Completed Date"
54
  msgstr ""
55
 
56
+ #: view/settings-form.php:108
57
  msgid "This date range should not be saved in the scheduled task"
58
  msgstr ""
59
 
60
+ #: view/settings-form.php:110
61
  msgid "Date range"
62
  msgstr ""
63
 
64
+ #: view/settings-form.php:112
65
  msgid "to"
66
  msgstr ""
67
 
68
+ #: view/settings-form.php:116
69
  msgid "Express export"
70
  msgstr ""
71
 
72
+ #: view/settings-form.php:117
73
  msgid "Summary Report By Products"
74
  msgstr ""
75
 
76
+ #: view/settings-form.php:125
 
 
 
 
77
  msgid "Export filename"
78
  msgstr ""
79
 
80
+ #: view/settings-form.php:135
81
  msgid "Format"
82
  msgstr ""
83
 
84
+ #: view/settings-form.php:146
85
  msgid "XLS options"
86
  msgstr ""
87
 
88
+ #: view/settings-form.php:151
89
  msgid "Export as .xls (Binary File Format)"
90
  msgstr ""
91
 
92
+ #: view/settings-form.php:152
93
  msgid "Use sheet name"
94
  msgstr ""
95
 
96
+ #: view/settings-form.php:153 view/settings-form.php:163
97
+ #: view/settings-form.php:191
98
  msgid "Output column titles as first line"
99
  msgstr ""
100
 
101
+ #: view/settings-form.php:154
102
  msgid "Auto column width"
103
  msgstr ""
104
 
105
+ #: view/settings-form.php:155
 
 
 
 
 
106
  msgid "Right-to-Left direction"
107
  msgstr ""
108
 
109
+ #: view/settings-form.php:157
110
  msgid "CSV options"
111
  msgstr ""
112
 
113
+ #: view/settings-form.php:162 view/settings-form.php:190
114
  msgid "Output UTF-8 BOM"
115
  msgstr ""
116
 
117
+ #: view/settings-form.php:164
118
  msgid "Convert line breaks to literals"
119
  msgstr ""
120
 
121
+ #: view/settings-form.php:165
122
  msgid "Item rows start from new line"
123
  msgstr ""
124
 
125
+ #: view/settings-form.php:166
126
  msgid "Enclosure"
127
  msgstr ""
128
 
129
+ #: view/settings-form.php:167
130
  msgid "Field Delimiter"
131
  msgstr ""
132
 
133
+ #: view/settings-form.php:168 view/settings-form.php:192
134
  msgid "Line Break"
135
  msgstr ""
136
 
137
+ #: view/settings-form.php:170 view/settings-form.php:194
138
  msgid "Character encoding"
139
  msgstr ""
140
 
141
+ #: view/settings-form.php:173
142
  msgid "XML options"
143
  msgstr ""
144
 
145
+ #: view/settings-form.php:175
146
  msgid "Prepend XML"
147
  msgstr ""
148
 
149
+ #: view/settings-form.php:176
150
  msgid "Root tag"
151
  msgstr ""
152
 
153
+ #: view/settings-form.php:177
154
  msgid "Order tag"
155
  msgstr ""
156
 
157
+ #: view/settings-form.php:178
158
  msgid "Product tag"
159
  msgstr ""
160
 
161
+ #: view/settings-form.php:179
162
  msgid "Coupon tag"
163
  msgstr ""
164
 
165
+ #: view/settings-form.php:180
166
  msgid "Append XML"
167
  msgstr ""
168
 
169
+ #: view/settings-form.php:181
170
  msgid "Self closing tags"
171
  msgstr ""
172
 
173
+ #: view/settings-form.php:183
174
  msgid "JSON options"
175
  msgstr ""
176
 
177
+ #: view/settings-form.php:184
178
  msgid "Start tag"
179
  msgstr ""
180
 
181
+ #: view/settings-form.php:185
182
  msgid "End tag"
183
  msgstr ""
184
 
185
+ #: view/settings-form.php:187
186
  msgid "TSV options"
187
  msgstr ""
188
 
189
+ #: view/settings-form.php:201
190
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1116
191
  msgid "Date"
192
  msgstr ""
193
 
194
+ #: view/settings-form.php:216 view/settings-form.php:238
 
 
 
 
195
  msgid "custom"
196
  msgstr ""
197
 
198
+ #: view/settings-form.php:224
199
  msgid "Time"
200
  msgstr ""
201
 
202
+ #: view/settings-form.php:250
203
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:623
204
  msgid "Order ID"
205
  msgstr ""
206
 
207
+ #: view/settings-form.php:267
208
  msgid "Descending"
209
  msgstr ""
210
 
211
+ #: view/settings-form.php:268
212
  msgid "Ascending"
213
  msgstr ""
214
 
215
+ #: view/settings-form.php:273
216
  #, php-format
217
  msgid "Sort orders by %s in %s order"
218
  msgstr ""
219
 
220
+ #: view/settings-form.php:278
221
  msgid "Change order status to"
222
  msgstr ""
223
 
224
+ #: view/settings-form.php:280
225
  msgid "- don't modify -"
226
  msgstr ""
227
 
228
+ #: view/settings-form.php:290
229
  msgid "Misc settings"
230
  msgstr ""
231
 
232
+ #: view/settings-form.php:295
233
  msgid "Format numbers (use WC decimal separator)"
234
  msgstr ""
235
 
236
+ #: view/settings-form.php:299
237
  msgid "Export all order notes"
238
  msgstr ""
239
 
240
+ #: view/settings-form.php:303
241
  msgid "Export refund notes as Customer Note"
242
  msgstr ""
243
 
244
+ #: view/settings-form.php:307
245
  msgid "Strip tags from Product Description/Variation"
246
  msgstr ""
247
 
248
+ #: view/settings-form.php:311
249
  msgid "Cleanup phone (export only digits)"
250
  msgstr ""
251
 
252
+ #: view/settings-form.php:315
253
  msgid "Enable debug output"
254
  msgstr ""
255
 
256
+ #: view/settings-form.php:319
257
  msgid "Custom PHP code to modify output"
258
  msgstr ""
259
 
260
+ #: view/settings-form.php:323
261
  msgid ""
262
  "Please check permissions for your role. You must have capability "
263
  "“edit_themes” to use this box."
264
  msgstr ""
265
 
266
+ #: view/settings-form.php:326
267
  msgid "Use only unnamed functions!"
268
  msgstr ""
269
 
270
+ #: view/settings-form.php:340
271
  msgid "Filter by order"
272
  msgstr ""
273
 
274
+ #: view/settings-form.php:343
275
  msgid "Don't export child orders"
276
  msgstr ""
277
 
278
+ #: view/settings-form.php:344
279
  msgid "Export refunds"
280
  msgstr ""
281
 
282
+ #: view/settings-form.php:345
283
  msgid "Mark exported orders"
284
  msgstr ""
285
 
286
+ #: view/settings-form.php:346
287
  msgid "Export unmarked orders only"
288
  msgstr ""
289
 
290
+ #: view/settings-form.php:347
291
  msgid "Order statuses"
292
  msgstr ""
293
 
294
+ #: view/settings-form.php:354 view/settings-form.php:583
295
  msgid "Custom fields"
296
  msgstr ""
297
 
298
+ #: view/settings-form.php:393
299
  msgid ""
300
  "The filters won't work correctly.<br>Another plugin(or theme) has loaded "
301
  "outdated Select2.js"
302
  msgstr ""
303
 
304
+ #: view/settings-form.php:394
305
  msgid "Filter by product"
306
  msgstr ""
307
 
308
+ #: view/settings-form.php:397
309
  msgid "Export all products from the order"
310
  msgstr ""
311
 
312
+ #: view/settings-form.php:398
313
  msgid "Skip fully refunded items"
314
  msgstr ""
315
 
316
+ #: view/settings-form.php:399
317
  msgid "Product categories"
318
  msgstr ""
319
 
320
+ #: view/settings-form.php:413
321
  msgid "Vendor/creator"
322
  msgstr ""
323
 
324
+ #: view/settings-form.php:426
325
  msgid "Product"
326
  msgstr ""
327
 
328
+ #: view/settings-form.php:438
329
  msgid "Product taxonomies"
330
  msgstr ""
331
 
332
+ #: view/settings-form.php:464
333
  msgid "Product custom fields"
334
  msgstr ""
335
 
336
+ #: view/settings-form.php:495
337
  msgid "Variable product attributes"
338
  msgstr ""
339
 
340
+ #: view/settings-form.php:522
341
  msgid "Item meta data"
342
  msgstr ""
343
 
344
+ #: view/settings-form.php:559
345
  msgid "Filter by customers"
346
  msgstr ""
347
 
348
+ #: view/settings-form.php:563
349
  msgid "Usernames"
350
  msgstr ""
351
 
352
+ #: view/settings-form.php:574
353
  msgid "User roles"
354
  msgstr ""
355
 
356
+ #: view/settings-form.php:620
357
  msgid "Filter by coupons"
358
  msgstr ""
359
 
360
+ #: view/settings-form.php:625
361
  msgid "Any coupon used"
362
  msgstr ""
363
 
364
+ #: view/settings-form.php:627
365
+ #: classes/admin/class-wc-order-export-manage.php:700
366
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:901
367
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1103
368
  msgid "Coupons"
369
  msgstr ""
370
 
371
+ #: view/settings-form.php:642
372
  msgid "Filter by billing"
373
  msgstr ""
374
 
375
+ #: view/settings-form.php:645
376
  msgid "Billing locations"
377
  msgstr ""
378
 
379
+ #: view/settings-form.php:669
380
  msgid "Payment methods"
381
  msgstr ""
382
 
383
+ #: view/settings-form.php:681
384
  msgid "Filter by shipping"
385
  msgstr ""
386
 
387
+ #: view/settings-form.php:684
388
  msgid "Shipping locations"
389
  msgstr ""
390
 
391
+ #: view/settings-form.php:708
392
  msgid "Shipping methods"
393
  msgstr ""
394
 
395
+ #: view/settings-form.php:720
396
  msgid "Filter by item and metadata"
397
  msgstr ""
398
 
399
+ #: view/settings-form.php:723
400
  msgid "Item names"
401
  msgstr ""
402
 
403
+ #: view/settings-form.php:747
404
  msgid "Item metadata"
405
  msgstr ""
406
 
407
+ #: view/settings-form.php:781
408
  msgid "Set up fields to export"
409
  msgstr ""
410
 
411
+ #: view/settings-form.php:796
412
+ msgid "Drag rows to reorder exported fields"
413
  msgstr ""
414
 
415
+ #: view/settings-form.php:801
416
+ msgid "Remove all fields"
 
 
417
  msgstr ""
418
 
419
+ #: view/settings-form.php:828
420
+ msgid "Actions"
421
+ msgstr ""
422
+
423
+ #: view/settings-form.php:831
424
+ msgid "Add field"
425
+ msgstr ""
426
+
427
+ #: view/settings-form.php:834
428
+ msgid "Add static field"
429
+ msgstr ""
430
+
431
+ #: view/settings-form.php:840 view/settings-form.php:928
432
+ msgid "Meta key"
433
+ msgstr ""
434
+
435
+ #: view/settings-form.php:850 view/settings-form.php:890
436
+ #: view/settings-form.php:934
437
  msgid "or type meta key here"
438
  msgstr ""
439
 
440
+ #: view/settings-form.php:853 view/settings-form.php:885
441
+ #: view/settings-form.php:930
442
  msgid "Hide unused fields"
443
  msgstr ""
444
 
445
+ #: view/settings-form.php:856 view/settings-form.php:868
446
+ #: view/settings-form.php:902 view/settings-form.php:912
447
+ #: view/settings-form.php:936 view/settings-form.php:947
448
+ msgid "Column name"
449
+ msgstr ""
450
+
451
+ #: view/settings-form.php:862 view/settings-form.php:879
452
+ #: view/settings-form.php:906 view/settings-form.php:923
453
+ #: view/settings-form.php:941 view/settings-form.php:959
454
  msgid "Confirm"
455
  msgstr ""
456
 
457
+ #: view/settings-form.php:863 view/settings-form.php:880
458
+ #: view/settings-form.php:907 view/settings-form.php:924
459
+ #: view/settings-form.php:942 view/settings-form.php:962
460
  msgid "Cancel"
461
  msgstr ""
462
 
463
+ #: view/settings-form.php:872 view/settings-form.php:916
464
+ #: view/settings-form.php:951
465
  msgid "Value"
466
  msgstr ""
467
 
468
+ #: view/settings-form.php:887
469
+ msgid "Product fields"
 
 
 
 
 
 
 
 
 
470
  msgstr ""
471
 
472
+ #: view/settings-form.php:889
473
+ msgid "Order item fields"
 
474
  msgstr ""
475
 
476
+ #: view/settings-form.php:891
477
+ msgid "OR"
478
  msgstr ""
479
 
480
+ #: view/settings-form.php:892
481
+ msgid "Taxonomy"
482
  msgstr ""
483
 
484
+ #: view/settings-form.php:929
485
+ msgid "All meta"
486
  msgstr ""
487
 
488
+ #: view/settings-form.php:989
489
  #, php-format
490
  msgid ""
491
  "If you see this message after page load, user interface won't work correctly!"
493
  "it). Probably, it's a conflict with another plugin or active theme."
494
  msgstr ""
495
 
496
+ #: view/settings-form.php:991
497
  msgid "Preview"
498
  msgstr ""
499
 
500
+ #: view/settings-form.php:991
501
  msgid "Might be different from actual export!"
502
  msgstr ""
503
 
504
+ #: view/settings-form.php:993 view/settings-form.php:996
505
  msgid "Save settings"
506
  msgstr ""
507
 
508
+ #: view/settings-form.php:995
509
+ msgid "Save & Exit"
510
+ msgstr ""
511
+
512
+ #: view/settings-form.php:1000
513
  msgid "Export"
514
  msgstr ""
515
 
516
+ #: view/settings-form.php:1003
517
  msgid "Export [w/o progressbar]"
518
  msgstr ""
519
 
520
+ #: view/settings-form.php:1003
521
  msgid "It might not work for huge datasets!"
522
  msgstr ""
523
 
524
+ #: view/settings-form.php:1006
525
  msgid "Save as a profile"
526
  msgstr ""
527
 
528
+ #: view/settings-form.php:1009
529
  #, php-format
530
  msgid "Export total: %s orders"
531
  msgstr ""
532
 
533
+ #: view/settings-form.php:1010
534
  msgid "Preview size"
535
  msgstr ""
536
 
537
+ #: view/settings-form.php:1016
538
+ msgid "Settings were successfully updated!"
539
+ msgstr ""
540
+
541
+ #: view/settings-form.php:1020
542
  msgid "Press 'Esc' to cancel the export"
543
  msgstr ""
544
 
545
+ #: view/settings-form.php:1021
546
  msgid "Click here to download"
547
  msgstr ""
548
 
574
  msgid "Help"
575
  msgstr ""
576
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
577
  #: classes/class-wc-order-export-admin.php:91
578
  msgid "Export Status"
579
  msgstr ""
609
 
610
  #: classes/class-wc-order-export-admin.php:573
611
  #, php-format
612
+ msgid "Add %s fields"
613
+ msgstr ""
614
+
615
+ #: classes/class-wc-order-export-admin.php:575
616
+ msgid "rows"
617
+ msgstr ""
618
+
619
+ #: classes/class-wc-order-export-admin.php:576
620
+ msgid "columns"
621
+ msgstr ""
622
+
623
+ #: classes/class-wc-order-export-admin.php:577
624
+ msgid "one row"
625
+ msgstr ""
626
+
627
+ #: classes/class-wc-order-export-admin.php:580
628
+ msgid "Add"
629
+ msgstr ""
630
+
631
+ #: classes/class-wc-order-export-admin.php:581
632
+ msgid "as"
633
+ msgstr ""
634
+
635
+ #: classes/class-wc-order-export-admin.php:582
636
+ msgid "Split values by"
637
+ msgstr ""
638
+
639
+ #: classes/class-wc-order-export-admin.php:583
640
+ msgid "Fill order columns for"
641
+ msgstr ""
642
+
643
+ #: classes/class-wc-order-export-admin.php:584
644
+ msgid "all rows"
645
  msgstr ""
646
 
647
+ #: classes/class-wc-order-export-admin.php:585
648
+ msgid "1st row only"
649
+ msgstr ""
650
+
651
+ #: classes/class-wc-order-export-admin.php:587
652
+ msgid "Grouping by product"
653
+ msgstr ""
654
+
655
+ #: classes/class-wc-order-export-admin.php:588
656
+ msgid "Grouping by coupon"
657
+ msgstr ""
658
+
659
+ #: classes/class-wc-order-export-admin.php:592
660
+ msgid "Set up product fields"
661
+ msgstr ""
662
+
663
+ #: classes/class-wc-order-export-admin.php:593
664
+ msgid "Set up coupon fields"
665
+ msgstr ""
666
+
667
+ #: classes/class-wc-order-export-admin.php:594
668
+ msgid "products"
669
+ msgstr ""
670
+
671
+ #: classes/class-wc-order-export-admin.php:595
672
+ msgid "coupons"
673
+ msgstr ""
674
+
675
+ #: classes/class-wc-order-export-admin.php:597
676
+ msgid "Remove all fields?"
677
+ msgstr ""
678
+
679
+ #: classes/class-wc-order-export-admin.php:639
680
  msgid "empty column name"
681
  msgstr ""
682
 
683
+ #: classes/class-wc-order-export-admin.php:640
684
  msgid "empty meta key"
685
  msgstr ""
686
 
687
+ #: classes/class-wc-order-export-admin.php:641
688
  msgid "select product field or item field or taxonomy"
689
  msgstr ""
690
 
691
+ #: classes/class-wc-order-export-admin.php:643
692
  msgid "empty value"
693
  msgstr ""
694
 
695
+ #: classes/class-wc-order-export-admin.php:644
696
  msgid "title is empty"
697
  msgstr ""
698
 
699
+ #: classes/class-wc-order-export-admin.php:645
700
  msgid "Date From is greater than Date To"
701
  msgstr ""
702
 
703
+ #: classes/class-wc-order-export-admin.php:646
704
  msgid "Please, set up fields to export"
705
  msgstr ""
706
 
707
+ #: classes/class-wc-order-export-admin.php:647
708
  #: classes/admin/class-wc-order-export-ajax.php:356
709
+ #: classes/core/class-wc-order-export-engine.php:743
710
+ #: classes/core/class-wc-order-export-engine.php:756
711
  msgid "Nothing to export. Please, adjust your filters"
712
  msgstr ""
713
 
714
+ #: classes/class-wc-order-export-admin.php:649
715
+ #: classes/core/class-wc-order-export-data-extractor.php:225
716
  msgid "empty"
717
  msgstr ""
718
 
719
+ #: classes/class-wc-order-export-admin.php:761
720
  #, php-format
721
  msgid "Status change job #%s for order #%s. Result: %s"
722
  msgstr ""
723
 
724
+ #: classes/class-wc-order-export-admin.php:824
725
  #, php-format
726
  msgid "Export as %s"
727
  msgstr ""
728
 
729
+ #: classes/class-wc-order-export-admin.php:830
730
  msgid "Mark exported"
731
  msgstr ""
732
 
733
+ #: classes/class-wc-order-export-admin.php:831
734
  msgid "Unmark exported"
735
  msgstr ""
736
 
737
+ #: classes/class-wc-order-export-admin.php:837
738
  #, php-format
739
  msgid "Export as profile '%s'"
740
  msgstr ""
741
 
742
+ #: classes/class-wc-order-export-admin.php:908
743
  #, php-format
744
  msgid "%s order marked."
745
  msgid_plural "%s orders marked."
746
  msgstr[0] ""
747
  msgstr[1] ""
748
 
749
+ #: classes/class-wc-order-export-admin.php:917
750
  #, php-format
751
  msgid "%s order unmarked."
752
  msgid_plural "%s orders unmarked."
848
  msgid "Buy %s to get access to Scheduled jobs"
849
  msgstr ""
850
 
851
+ #: classes/formats/abstract-class-woe-formatter-sv.php:94
852
+ #: classes/formats/class-woe-formatter-xls.php:165
853
  msgid "<td colspan=10><b>No results</b></td>"
854
  msgstr ""
855
 
856
+ #: classes/formats/abstract-class-woe-formatter.php:40
857
  msgid "can not open for output"
858
  msgstr ""
859
 
860
+ #: classes/formats/class-woe-formatter-xls.php:97
861
+ #: classes/admin/class-wc-order-export-manage.php:203
862
  msgid "Orders"
863
  msgstr ""
864
 
890
  msgid "Sat"
891
  msgstr ""
892
 
893
+ #: classes/admin/class-wc-order-export-manage.php:657
894
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:889
895
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1102
896
+ msgid "Products"
897
+ msgstr ""
898
+
899
  #: classes/admin/class-wc-order-export-ajax.php:20
900
  msgid "Wrong key for cron url!"
901
  msgstr ""
912
  msgid "Item ID"
913
  msgstr ""
914
 
915
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:349
916
  msgid "Item #"
917
  msgstr ""
918
 
919
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:354
920
  msgid "SKU"
921
  msgstr ""
922
 
923
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:359
924
  msgid "Item Name"
925
  msgstr ""
926
 
927
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:364
928
  msgid "Product Id"
929
  msgstr ""
930
 
931
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:369
932
  msgid "Product Name"
933
  msgstr ""
934
 
935
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:374
936
  msgid "Variation Id"
937
  msgstr ""
938
 
939
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:379
940
  msgid "Product Variation"
941
  msgstr ""
942
 
943
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:384
944
  msgid "Item Seller"
945
  msgstr ""
946
 
947
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:389
948
  msgid "Quantity"
949
  msgstr ""
950
 
951
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:394
952
  msgid "Quantity (- Refund)"
953
  msgstr ""
954
 
955
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:399
956
  msgid "Item Cost"
957
  msgstr ""
958
 
959
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:404
960
  msgid "Product Current Price"
961
  msgstr ""
962
 
963
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:409
964
  msgid "Order Line (w/o tax)"
965
  msgstr ""
966
 
967
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:414
968
  msgid "Order Line Tax"
969
  msgstr ""
970
 
971
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:419
972
  msgid "Order Line Tax Refunded"
973
  msgstr ""
974
 
975
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:424
976
  msgid "Order Line Tax (- Refund)"
977
  msgstr ""
978
 
979
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:429
980
  msgid "Order Line Subtotal"
981
  msgstr ""
982
 
983
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:434
984
  msgid "Order Line Subtotal Tax"
985
  msgstr ""
986
 
987
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:439
988
  msgid "Order Line Total"
989
  msgstr ""
990
 
991
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:444
992
  msgid "Order Line Total (include tax)"
993
  msgstr ""
994
 
995
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:449
996
  msgid "Order Line Total Refunded"
997
  msgstr ""
998
 
999
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:454
1000
  msgid "Order Line Total (- Refund)"
1001
  msgstr ""
1002
 
1003
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:459
1004
  msgid "Item Discount Amount"
1005
  msgstr ""
1006
 
1007
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:464
1008
  msgid "Item Tax Rate"
1009
  msgstr ""
1010
 
1011
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:468
1012
  msgid "Type"
1013
  msgstr ""
1014
 
1015
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:470
1016
  msgid "Category"
1017
  msgstr ""
1018
 
1019
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:473
1020
  msgid "Tags"
1021
  msgstr ""
1022
 
1023
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:475
1024
  msgid "Width"
1025
  msgstr ""
1026
 
1027
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:480
1028
  msgid "Length"
1029
  msgstr ""
1030
 
1031
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:485
1032
  msgid "Height"
1033
  msgstr ""
1034
 
1035
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:490
1036
  msgid "Weight"
1037
  msgstr ""
1038
 
1039
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:495
1040
  msgid "Product URL"
1041
  msgstr ""
1042
 
1043
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:500
1044
  msgid "Download URL"
1045
  msgstr ""
1046
 
1047
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:505
1048
  msgid "Image URL"
1049
  msgstr ""
1050
 
1051
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:510
1052
  msgid "Product Shipping Class"
1053
  msgstr ""
1054
 
1055
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:515
1056
  msgid "Description"
1057
  msgstr ""
1058
 
1059
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:520
1060
  msgid "Short Description"
1061
  msgstr ""
1062
 
1063
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:525
1064
  msgid "Full names for categories"
1065
  msgstr ""
1066
 
1067
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:530
1068
+ msgid "Summary Report Total Quantity"
1069
+ msgstr ""
1070
+
1071
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:535
1072
+ msgid "Summary Report Total Amount"
1073
+ msgstr ""
1074
+
1075
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:552
1076
  msgid "Coupon Code"
1077
  msgstr ""
1078
 
1079
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:557
1080
  msgid "Discount Amount"
1081
  msgstr ""
1082
 
1083
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:562
1084
  msgid "Discount Amount Tax"
1085
  msgstr ""
1086
 
1087
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:567
1088
  msgid "Discount Amount + Tax"
1089
  msgstr ""
1090
 
1091
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:572
1092
  msgid "Coupon Description"
1093
  msgstr ""
1094
 
1095
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:576
1096
  msgid "Coupon Type"
1097
  msgstr ""
1098
 
1099
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:581
1100
  msgid "Coupon Amount"
1101
  msgstr ""
1102
 
1103
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:618
1104
  msgid "Line number"
1105
  msgstr ""
1106
 
1107
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:628
1108
  msgid "Order Number"
1109
  msgstr ""
1110
 
1111
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:633
1112
  msgid "Order Status"
1113
  msgstr ""
1114
 
1115
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:648
1116
  msgid "Transaction ID"
1117
  msgstr ""
1118
 
1119
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:653
1120
+ msgid "Currency"
1121
+ msgstr ""
1122
+
1123
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:668
1124
  msgid "Date of first refund"
1125
  msgstr ""
1126
 
1127
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:673
1128
  msgid "Customer Note"
1129
  msgstr ""
1130
 
1131
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:678
1132
  msgid "Order Notes"
1133
  msgstr ""
1134
 
1135
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:688
1136
  msgid "Customer IP address"
1137
  msgstr ""
1138
 
1139
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:693
1140
  msgid "Customer User ID"
1141
  msgstr ""
1142
 
1143
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:698
1144
  msgid "Customer Username"
1145
  msgstr ""
1146
 
1147
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:703
1148
  msgid "User Website"
1149
  msgstr ""
1150
 
1151
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:708
1152
  msgid "Customer User Email"
1153
  msgstr ""
1154
 
1155
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:713
1156
  msgid "Customer Role"
1157
  msgstr ""
1158
 
1159
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:718
1160
  msgid "Customer Total Orders"
1161
  msgstr ""
1162
 
1163
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:728
1164
  msgid "First Name (Billing)"
1165
  msgstr ""
1166
 
1167
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:733
1168
  msgid "Last Name (Billing)"
1169
  msgstr ""
1170
 
1171
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:738
1172
  msgid "Full Name (Billing)"
1173
  msgstr ""
1174
 
1175
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:743
1176
  msgid "Company (Billing)"
1177
  msgstr ""
1178
 
1179
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:748
1180
  msgid "Address 1&2 (Billing)"
1181
  msgstr ""
1182
 
1183
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:753
1184
  msgid "Address 1 (Billing)"
1185
  msgstr ""
1186
 
1187
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:758
1188
  msgid "Address 2 (Billing)"
1189
  msgstr ""
1190
 
1191
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:763
1192
  msgid "City (Billing)"
1193
  msgstr ""
1194
 
1195
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:768
1196
  msgid "State Code (Billing)"
1197
  msgstr ""
1198
 
1199
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:773
1200
  msgid "City, State, Zip (Billing)"
1201
  msgstr ""
1202
 
1203
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:778
1204
  msgid "State Name (Billing)"
1205
  msgstr ""
1206
 
1207
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:783
1208
  msgid "Postcode (Billing)"
1209
  msgstr ""
1210
 
1211
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:788
1212
  msgid "Country Code (Billing)"
1213
  msgstr ""
1214
 
1215
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:793
1216
  msgid "Country Name (Billing)"
1217
  msgstr ""
1218
 
1219
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:798
1220
  msgid "Email (Billing)"
1221
  msgstr ""
1222
 
1223
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:803
1224
  msgid "Phone (Billing)"
1225
  msgstr ""
1226
 
1227
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:813
1228
  msgid "First Name (Shipping)"
1229
  msgstr ""
1230
 
1231
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:818
1232
  msgid "Last Name (Shipping)"
1233
  msgstr ""
1234
 
1235
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:823
1236
  msgid "Full Name (Shipping)"
1237
  msgstr ""
1238
 
1239
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:828
1240
  msgid "Company (Shipping)"
1241
  msgstr ""
1242
 
1243
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:833
1244
  msgid "Address 1&2 (Shipping)"
1245
  msgstr ""
1246
 
1247
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:838
1248
  msgid "Address 1 (Shipping)"
1249
  msgstr ""
1250
 
1251
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:843
1252
  msgid "Address 2 (Shipping)"
1253
  msgstr ""
1254
 
1255
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:848
1256
  msgid "City (Shipping)"
1257
  msgstr ""
1258
 
1259
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:853
1260
  msgid "State Code (Shipping)"
1261
  msgstr ""
1262
 
1263
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:858
1264
  msgid "City, State, Zip (Shipping)"
1265
  msgstr ""
1266
 
1267
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:863
1268
  msgid "State Name (Shipping)"
1269
  msgstr ""
1270
 
1271
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:868
1272
  msgid "Postcode (Shipping)"
1273
  msgstr ""
1274
 
1275
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:873
1276
  msgid "Country Code (Shipping)"
1277
  msgstr ""
1278
 
1279
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:878
1280
  msgid "Country Name (Shipping)"
1281
  msgstr ""
1282
 
1283
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:912
 
 
 
 
 
1284
  msgid "Shipping Method Title"
1285
  msgstr ""
1286
 
1287
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:917
1288
  msgid "Shipping Method"
1289
  msgstr ""
1290
 
1291
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:922
1292
  msgid "Payment Method Title"
1293
  msgstr ""
1294
 
1295
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:927
1296
  msgid "Payment Method"
1297
  msgstr ""
1298
 
1299
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:932
1300
  msgid "Coupons Used"
1301
  msgstr ""
1302
 
1303
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:937
1304
  msgid "Cart Discount Amount"
1305
  msgstr ""
1306
 
1307
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:942
1308
  msgid "Cart Discount Amount Tax"
1309
  msgstr ""
1310
 
1311
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:947
1312
  msgid "Order Subtotal Amount"
1313
  msgstr ""
1314
 
1315
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:952
1316
+ msgid "Order Subtotal - Cart Discount"
1317
+ msgstr ""
1318
+
1319
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:957
1320
  msgid "Order Subtotal Amount Refunded"
1321
  msgstr ""
1322
 
1323
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:962
1324
  msgid "Order Subtotal Amount (- Refund)"
1325
  msgstr ""
1326
 
1327
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:967
1328
  msgid "Order Tax Amount"
1329
  msgstr ""
1330
 
1331
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:977
1332
  msgid "Order Shipping Amount"
1333
  msgstr ""
1334
 
1335
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:982
1336
+ msgid "Order Shipping + Tax Amount"
1337
+ msgstr ""
1338
+
1339
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:987
1340
  msgid "Order Shipping Amount Refunded"
1341
  msgstr ""
1342
 
1343
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:992
1344
  msgid "Order Shipping Amount (- Refund)"
1345
  msgstr ""
1346
 
1347
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:997
1348
  msgid "Order Shipping Tax Amount"
1349
  msgstr ""
1350
 
1351
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1002
1352
  msgid "Order Shipping Tax Refunded"
1353
  msgstr ""
1354
 
1355
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1007
1356
  msgid "Order Shipping Tax Amount (- Refund)"
1357
  msgstr ""
1358
 
1359
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1017
1360
+ msgid "Order Total Fee"
1361
+ msgstr ""
1362
+
1363
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1022
1364
  msgid "Order Refund Amount"
1365
  msgstr ""
1366
 
1367
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1027
1368
  msgid "Order Total Amount (- Refund)"
1369
  msgstr ""
1370
 
1371
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1032
1372
  msgid "Order Total Amount"
1373
  msgstr ""
1374
 
1375
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1037
1376
  msgid "Order Total Amount without Tax"
1377
  msgstr ""
1378
 
1379
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1042
1380
  msgid "Order Total Tax Amount"
1381
  msgstr ""
1382
 
1383
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1047
1384
  msgid "Order Total Tax Amount Refunded"
1385
  msgstr ""
1386
 
1387
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1052
1388
  msgid "Order Total Tax Amount (- Refund)"
1389
  msgstr ""
1390
 
1391
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1062
 
 
 
 
1392
  msgid "Total weight"
1393
  msgstr ""
1394
 
1395
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1067
1396
  msgid "Total items"
1397
  msgstr ""
1398
 
1399
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1072
1400
  msgid "Exported items"
1401
  msgstr ""
1402
 
1403
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1077
1404
  msgid "Total products"
1405
  msgstr ""
1406
 
1407
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1098
1408
  msgid "Common"
1409
  msgstr ""
1410
 
1411
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1099
1412
  msgid "User"
1413
  msgstr ""
1414
 
1415
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1100
1416
+ msgid "Billing Address"
1417
  msgstr ""
1418
 
1419
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1101
1420
+ msgid "Shipping Address"
1421
  msgstr ""
1422
 
1423
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1104
1424
  msgid "Cart"
1425
  msgstr ""
1426
 
1427
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1105
1428
+ msgid "Shipping"
1429
+ msgstr ""
1430
+
1431
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1106
1432
+ msgid "Totals"
1433
+ msgstr ""
1434
+
1435
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1107
1436
  msgid "Others"
1437
  msgstr ""
1438
 
1439
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1113
1440
+ msgid "String"
1441
+ msgstr ""
1442
+
1443
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1114
1444
+ msgid "Money"
1445
+ msgstr ""
1446
+
1447
+ #: classes/core/class-wc-order-export-data-extractor-ui.php:1115
1448
+ msgid "Number"
1449
+ msgstr ""
1450
+
1451
+ #: classes/core/class-wc-order-export-data-extractor.php:1970
1452
  msgid "[Rest of the World]"
1453
  msgstr ""
1454
 
1455
  #: classes/core/class-wc-order-export-engine.php:19
1456
+ #: classes/core/class-wc-order-export-engine.php:62
1457
  msgid "No destination selected"
1458
  msgstr ""
1459
 
1461
  msgid "Wrong format"
1462
  msgstr ""
1463
 
1464
+ #: classes/core/class-wc-order-export-engine.php:72
1465
  msgid "Wrong export type"
1466
  msgstr ""
1467
 
1468
+ #: classes/core/class-wc-order-export-engine.php:416
1469
  msgid "Don't Panic"
1470
  msgstr ""
1471
 
1472
+ #: classes/core/class-wc-order-export-engine.php:417
1473
  #, php-format
1474
  msgid "The code you are trying to save produced a fatal error on line %d:"
1475
  msgstr ""
1476
 
1477
+ #: classes/core/class-wc-order-export-engine.php:543
1478
  msgid "Main SQL queries are listed below"
1479
  msgstr ""
1480
 
 
 
 
 
 
 
 
 
1481
  #. Name of the plugin
1482
  msgid "Advanced Order Export For WooCommerce"
1483
  msgstr ""
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: woocommerce,export,order,xls,csv,xml,woo export lite,export orders,orders
5
  Requires PHP: 5.3.0
6
  Requires at least: 4.7
7
  Tested up to: 4.9
8
- Stable tag: 1.5.6
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -46,7 +46,7 @@ Please create a topic in the "Support" section with any ideas or suggestions for
46
 
47
  > Pro Version
48
 
49
- > Are you looking to have your WooCommerce products drop shipped from a third party? Our plugin can help you export your orders to CSV/XML/etc and send them to your drop shipper. You can even automate this process with [Pro version](https://algolplus.com/plugins/downloads/woocommerce-order-export/) .
50
 
51
 
52
 
@@ -66,7 +66,7 @@ Need help? Create ticket in [helpdesk system](https://algolplus.freshdesk.com).
66
  Check [some snippets](https://algolplus.com/plugins/snippets-plugins/) for popular plugins or review [this page](https://algolplus.com/plugins/code-samples/) to study how to extend the plugin.
67
 
68
  = I want to add a product attribute to the export =
69
- Check screenshot #5! You should open section "Set up fields", scroll down to field "Products", click button "Set up fields", select field in the dropdown, type column title and press button "Add field".
70
 
71
  = I can't filter/export custom attribute for Simple Product =
72
  I'm sorry, but it's impossible. You should add this attribute to Products>Attributes at first and use "Filter by Product Taxonomies".
@@ -103,6 +103,11 @@ Yes, you can email a request to aprokaev@gmail.com. We intensively develop this
103
 
104
  == Changelog ==
105
 
 
 
 
 
 
106
  = 1.5.6 - 2018-08-30 =
107
  * Added filter by user custom fields
108
  * Added order fields "Count of exported items", "User Website"
5
  Requires PHP: 5.3.0
6
  Requires at least: 4.7
7
  Tested up to: 4.9
8
+ Stable tag: 2.0.0
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
46
 
47
  > Pro Version
48
 
49
+ > Are you looking to have your WooCommerce products drop shipped from a third party? Our plugin can help you export your orders to CSV/XML/etc and send them to your drop shipper. You can even automate this process with [Pro version](https://algolplus.com/plugins/downloads/advanced-order-export-for-woocommerce-pro/) .
50
 
51
 
52
 
66
  Check [some snippets](https://algolplus.com/plugins/snippets-plugins/) for popular plugins or review [this page](https://algolplus.com/plugins/code-samples/) to study how to extend the plugin.
67
 
68
  = I want to add a product attribute to the export =
69
+ Check screenshot #5! You should open section "Set up fields", open section "Products"(right column), click button "Add field", select field in 2nd dropdown, type column title and press button "Confirm".
70
 
71
  = I can't filter/export custom attribute for Simple Product =
72
  I'm sorry, but it's impossible. You should add this attribute to Products>Attributes at first and use "Filter by Product Taxonomies".
103
 
104
  == Changelog ==
105
 
106
+ = 2.0.0 - 2018-10-24 =
107
+ * It's a **major update**. Backup settings (tab "Tools") before upgrading
108
+ * New section "Set up fields to export" - simplify UI, format fields, allow duplicates
109
+ * Compatible with Woocommerce 3.5
110
+
111
  = 1.5.6 - 2018-08-30 =
112
  * Added filter by user custom fields
113
  * Added order fields "Count of exported items", "User Website"
view/modal-controls.php DELETED
@@ -1,55 +0,0 @@
1
- <div id='fields_control_products' class='fields_control_style' style="display: none;">
2
- <div class='div_meta' >
3
- <div id="custom_meta_products_mode">
4
- <label><input id="custom_meta_products_mode_used" type="checkbox" name="custom_meta_products_mode" value="used"> <?php _e('Hide unused fields', 'woo-order-export-lite') ?></label>
5
- </div>
6
- <label for="select_custom_meta_products"><?php _e('Product fields', 'woo-order-export-lite')?>:</label>
7
- <select id='select_custom_meta_products'></select>
8
-
9
- <label for="select_custom_meta_order_items"><?php _e('Order item fields', 'woo-order-export-lite')?>:</label>
10
- <select id='select_custom_meta_order_items'></select>
11
- <div style="width: 80%; text-align: center;"><?php _e('OR', 'woo-order-export-lite') ?></div>
12
- <label><?php _e('Taxonomy', 'woo-order-export-lite')?>:</label><select id='select_custom_taxonomies_products'>
13
- <option></option>
14
- <?php
15
- foreach (WC_Order_Export_Data_Extractor_UI::get_product_taxonomies() as $tax_id => $tax_name) {
16
- echo "<option value='__$tax_name' >__$tax_name</option>";
17
- };
18
- ?>
19
- </select>
20
- <label><?php _e('Column name', 'woo-order-export-lite')?>:</label><input type='text' id='colname_custom_meta_products'/>
21
- <div style="text-align: right;">
22
- <button id='button_custom_meta_products' class='button-secondary'><?php _e('Add field', 'woo-order-export-lite')?></button>
23
- </div>
24
- </div>
25
- <div class='div_custom'>
26
- <label><?php _e('Column name', 'woo-order-export-lite')?>:</label><input type='text' id='colname_custom_field_products'/>
27
- <label><?php _e('Value', 'woo-order-export-lite')?>:</label><input type='text' id='value_custom_field_products'/>
28
- <div style="text-align: right;">
29
- <button id='button_custom_field_products' class='button-secondary'><?php _e('Add static field', 'woo-order-export-lite')?></button>
30
- </div>
31
- </div>
32
- </div>
33
-
34
- <div id='fields_control_coupons' class='fields_control_style' style="display: none;">
35
- <div class='div_meta' >
36
- <label><?php _e('Meta key', 'woo-order-export-lite')?>:</label>
37
- <div id="custom_meta_coupons_mode" style="display: none;">
38
- <label><input id="custom_meta_coupons_mode_all" type="radio" name="custom_meta_coupons_mode" value="all"> <?php _e('All meta', 'woo-order-export-lite') ?></label>
39
- <label><input id="custom_meta_coupons_mode_used" type="radio" name="custom_meta_coupons_mode" value="used"> <?php _e('Hide unused fields', 'woo-order-export-lite') ?></label>
40
- </div>
41
- <select id='select_custom_meta_coupons'>
42
- </select>
43
- <label><?php _e('Column name', 'woo-order-export-lite')?>:</label><input type='text' id='colname_custom_meta_coupons'/></label>
44
- <div style="text-align: right;">
45
- <button id='button_custom_meta_coupons' class='button-secondary'><?php _e('Add field', 'woo-order-export-lite')?></button>
46
- </div>
47
- </div>
48
- <div class='div_custom'>
49
- <label><?php _e('Column name', 'woo-order-export-lite')?>:</label><input type='text' id='colname_custom_field_coupons'/></label>
50
- <label><?php _e('Value', 'woo-order-export-lite')?>:</label><input type='text' id='value_custom_field_coupons'/></label>
51
- <div style="text-align: right;">
52
- <button id='button_custom_field_coupons' class='button-secondary'><?php _e('Add static field', 'woo-order-export-lite')?></button>
53
- </div>
54
- </div>
55
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
view/settings-form.php CHANGED
@@ -2,7 +2,6 @@
2
  if ( !defined( 'ABSPATH' ) ) {
3
  exit; // Exit if accessed directly
4
  }
5
- add_thickbox();
6
  /**
7
  * @var WC_Order_Export_Admin $WC_Order_Export WC_Order_Export_Admin instance
8
  * @var string $mode ( now | profiles | cron | order-action )
@@ -15,40 +14,71 @@ $settings = WC_Order_Export_Manage::get( $mode, $id );
15
  $settings = apply_filters('woe_settings_page_prepare', $settings );
16
  $order_custom_meta_fields = WC_Order_Export_Data_Extractor_UI::get_all_order_custom_meta_fields();
17
  $readonly_php = WC_Order_Export_Admin::user_can_add_custom_php() ? '' : 'readonly';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  ?>
19
 
20
  <script>
21
  var mode = '<?php echo $mode ?>';
22
  var job_id = '<?php echo $id ?>';
23
  var output_format = '<?php echo $settings[ 'format' ] ?>';
24
- var order_fields = <?php echo json_encode( $settings[ 'order_fields' ] ) ?>;
25
- var order_products_fields = <?php echo json_encode( $settings[ 'order_product_fields' ] ) ?>;
26
- var order_coupons_fields = <?php echo json_encode( $settings[ 'order_coupon_fields' ] ) ?>;
 
 
27
  var order_custom_meta_fields = <?php echo json_encode( $order_custom_meta_fields ) ?>;
28
  var order_products_custom_meta_fields = <?php echo json_encode( WC_Order_Export_Data_Extractor_UI::get_product_custom_fields() ) ?>;
29
  var order_order_item_custom_meta_fields = <?php echo json_encode( WC_Order_Export_Data_Extractor_UI::get_product_itemmeta() ) ?>;
30
  var order_coupons_custom_meta_fields = <?php echo json_encode( WC_Order_Export_Data_Extractor_UI::get_all_coupon_custom_meta_fields() ) ?>;
 
 
31
  var summary_mode = <?php echo $settings['summary_report_by_products'] ?>;
32
  </script>
33
 
34
 
35
- <?php include 'modal-controls.php'; ?>
36
  <form method="post" id="export_job_settings">
37
  <?php if ( $mode !== WC_Order_Export_Manage::EXPORT_NOW ): ?>
38
  <div style="width: 100%;">&nbsp;</div>
39
  <?php endif; ?>
40
 
41
  <div id="my-left" style="float: left; width: 49%; max-width: 500px;">
42
- <?php
43
- if ( $mode === WC_Order_Export_Manage::EXPORT_PROFILE ):
44
  include 'pro-version/top-profile.php';
45
- elseif ( $mode === WC_Order_Export_Manage::EXPORT_ORDER_ACTION ):
46
  include 'pro-version/top-order-actions.php';
47
- elseif ( $mode === WC_Order_Export_Manage::EXPORT_SCHEDULE ):
48
  include 'pro-version/top-scheduled-jobs.php';
49
- endif;
50
  ?>
51
 
 
 
52
  <?php if ( $show[ 'date_filter' ] ) : ?>
53
  <div id="my-export-date-field" class="my-block">
54
  <div class="wc-oe-header">
@@ -85,7 +115,6 @@ $readonly_php = WC_Order_Export_Admin::user_can_add_custom_php() ? '' : 'readonl
85
 
86
  <button id="my-quick-export-btn" class="button-primary"><?php _e( 'Express export', 'woo-order-export-lite' ) ?></button>
87
  <div id="summary_report_by_products" style="display:inline-block"><input type="hidden" name="settings[summary_report_by_products]" value="0"/><label><input type="checkbox" id=summary_report_by_products_checkbox name="settings[summary_report_by_products]" value="1" <?php checked($settings[ 'summary_report_by_products' ]) ?> /> <?php _e( "Summary Report By Products", 'woo-order-export-lite' ) ?></label>
88
- &nbsp;&nbsp;<label id="summary_setup_fields"><a href="#TB_inline?width=600&height=550&inlineId=modal-manage-products" class="thickbox " id="link_modal_manage_products_summary"><?php _e( 'Set up fields', 'woo-order-export-lite' ) ?></a></label>
89
  </div>
90
  </div>
91
  <br>
@@ -118,24 +147,20 @@ $readonly_php = WC_Order_Export_Admin::user_can_add_custom_php() ? '' : 'readonl
118
  <input type=hidden name="settings[format_xls_use_xls_format]" value=0>
119
  <input type=hidden name="settings[format_xls_display_column_names]" value=0>
120
  <input type=hidden name="settings[format_xls_auto_width]" value=0>
121
- <input type=hidden name="settings[format_xls_populate_other_columns_product_rows]" value=0>
122
  <input type=hidden name="settings[format_xls_direction_rtl]" value=0>
123
  <input type=checkbox name="settings[format_xls_use_xls_format]" value=1 <?php if ( @$settings[ 'format_xls_use_xls_format' ] ) echo 'checked'; ?> id="format_xls_use_xls_format"> <?php _e( 'Export as .xls (Binary File Format)', 'woo-order-export-lite' ) ?><br>
124
  <input type=checkbox checked disabled><?php _e( 'Use sheet name', 'woo-order-export-lite' ) ?></b><input type=text name="settings[format_xls_sheet_name]" value='<?php echo $settings[ 'format_xls_sheet_name' ] ?>' size=10><br>
125
  <input type=checkbox name="settings[format_xls_display_column_names]" value=1 <?php if ( @$settings[ 'format_xls_display_column_names' ] ) echo 'checked'; ?> > <?php _e( 'Output column titles as first line', 'woo-order-export-lite' ) ?><br>
126
  <input type=checkbox name="settings[format_xls_auto_width]" value=1 <?php if ( @$settings[ 'format_xls_auto_width' ] ) echo 'checked'; ?> > <?php _e( 'Auto column width', 'woo-order-export-lite' ) ?><br>
127
- <input type=checkbox name="settings[format_xls_populate_other_columns_product_rows]" value=1 <?php if ( @$settings[ 'format_xls_populate_other_columns_product_rows' ] ) echo 'checked'; ?> > <?php _e( 'Populate other columns if products exported as rows', 'woo-order-export-lite' ) ?><br>
128
  <input type=checkbox name="settings[format_xls_direction_rtl]" value=1 <?php if ( @$settings[ 'format_xls_direction_rtl' ] ) echo 'checked'; ?> > <?php _e( 'Right-to-Left direction', 'woo-order-export-lite' ) ?><br>
129
  </div>
130
  <div id='CSV_options' style='display:none'><strong><?php _e( 'CSV options', 'woo-order-export-lite' ) ?></strong><br>
131
  <input type=hidden name="settings[format_csv_add_utf8_bom]" value=0>
132
  <input type=hidden name="settings[format_csv_display_column_names]" value=0>
133
- <input type=hidden name="settings[format_csv_populate_other_columns_product_rows]" value=0>
134
  <input type=hidden name="settings[format_csv_delete_linebreaks]" value=0>
135
  <input type=hidden name="settings[format_csv_item_rows_start_from_new_line]" value=0>
136
  <input type=checkbox name="settings[format_csv_add_utf8_bom]" value=1 <?php if ( @$settings[ 'format_csv_add_utf8_bom' ] ) echo 'checked'; ?> > <?php _e( 'Output UTF-8 BOM', 'woo-order-export-lite' ) ?><br>
137
  <input type=checkbox name="settings[format_csv_display_column_names]" value=1 <?php if ( @$settings[ 'format_csv_display_column_names' ] ) echo 'checked'; ?> > <?php _e( 'Output column titles as first line', 'woo-order-export-lite' ) ?><br>
138
- <input type=checkbox name="settings[format_csv_populate_other_columns_product_rows]" value=1 <?php if ( @$settings[ 'format_csv_populate_other_columns_product_rows' ] ) echo 'checked'; ?> > <?php _e( 'Populate other columns if products exported as rows', 'woo-order-export-lite' ) ?><br>
139
  <input type=checkbox name="settings[format_csv_delete_linebreaks]" value=1 <?php if ( @$settings[ 'format_csv_delete_linebreaks' ] ) echo 'checked'; ?> > <?php _e( 'Convert line breaks to literals', 'woo-order-export-lite' ) ?><br>
140
  <input type=checkbox name="settings[format_csv_item_rows_start_from_new_line]" value=1 <?php if ( @$settings[ 'format_csv_item_rows_start_from_new_line' ] ) echo 'checked'; ?> > <?php _e( 'Item rows start from new line', 'woo-order-export-lite' ) ?><br>
141
  <?php _e( 'Enclosure', 'woo-order-export-lite' ) ?> <input type=text name="settings[format_csv_enclosure]" value='<?php echo $settings[ 'format_csv_enclosure' ] ?>' size=1>
@@ -162,10 +187,8 @@ $readonly_php = WC_Order_Export_Admin::user_can_add_custom_php() ? '' : 'readonl
162
  <div id='TSV_options' style='display:none'><strong><?php _e( 'TSV options', 'woo-order-export-lite' ) ?></strong><br>
163
  <input type=hidden name="settings[format_tsv_add_utf8_bom]" value=0>
164
  <input type=hidden name="settings[format_tsv_display_column_names]" value=0>
165
- <input type=hidden name="settings[format_tsv_populate_other_columns_product_rows]" value=0>
166
  <input type=checkbox name="settings[format_tsv_add_utf8_bom]" value=1 <?php if ( @$settings[ 'format_tsv_add_utf8_bom' ] ) echo 'checked'; ?> > <?php _e( 'Output UTF-8 BOM', 'woo-order-export-lite' ) ?><br>
167
  <input type=checkbox name="settings[format_tsv_display_column_names]" value=1 <?php if ( @$settings[ 'format_tsv_display_column_names' ] ) echo 'checked'; ?> > <?php _e( 'Output column titles as first line', 'woo-order-export-lite' ) ?><br>
168
- <input type=checkbox name="settings[format_tsv_populate_other_columns_product_rows]" value=1 <?php if ( @$settings[ 'format_tsv_populate_other_columns_product_rows' ] ) echo 'checked'; ?> > <?php _e( 'Populate other columns if products exported as rows', 'woo-order-export-lite' ) ?><br>
169
  <?php _e( 'Line Break', 'woo-order-export-lite' ) ?><input type=text name="settings[format_tsv_linebreak]" value='<?php echo $settings[ 'format_tsv_linebreak' ] ?>' size=4><br>
170
  <?php if ( function_exists( 'iconv' ) ): ?>
171
  <?php _e( 'Character encoding', 'woo-order-export-lite' ) ?><input type=text name="settings[format_tsv_encoding]" value="<?php echo $settings[ 'format_tsv_encoding' ] ?>"><br>
@@ -217,7 +240,7 @@ $readonly_php = WC_Order_Export_Admin::user_can_add_custom_php() ? '' : 'readonl
217
  <div id="custom_time_format_block" style="<?php echo in_array( @$settings[ 'time_format' ], $time_format ) ? 'display: none' : '' ?>">
218
  <input type="text" name="settings[time_format]" value="<?php echo $settings[ 'time_format' ] ?>">
219
  </div>
220
- </div>
221
  </div>
222
  </div>
223
  <br/>
@@ -308,7 +331,7 @@ $readonly_php = WC_Order_Export_Admin::user_can_add_custom_php() ? '' : 'readonl
308
  </div>
309
 
310
  <div id="my-right" style="float: left; width: 48%; margin: 0px 10px; max-width: 500px;">
311
- <?php
312
  if ( in_array( $mode, array( WC_Order_Export_Manage::EXPORT_SCHEDULE, WC_Order_Export_Manage::EXPORT_ORDER_ACTION ) ) ):
313
  include "pro-version/destinations.php";
314
  endif; ?>
@@ -379,8 +402,12 @@ $readonly_php = WC_Order_Export_Admin::user_can_add_custom_php() ? '' : 'readonl
379
  if ( $settings[ 'product_categories' ] )
380
  foreach ( $settings[ 'product_categories' ] as $cat ) {
381
  $cat_term = get_term( $cat, 'product_cat' );
 
 
 
 
 
382
  ?>
383
- <option selected value="<?php echo $cat_term->term_id ?>"> <?php echo $cat_term->name; ?></option>
384
  <?php } ?>
385
  </select>
386
  <span class="wc-oe-header"><?php _e( 'Vendor/creator', 'woo-order-export-lite' ) ?></span>
@@ -543,7 +570,7 @@ $readonly_php = WC_Order_Export_Admin::user_can_add_custom_php() ? '' : 'readonl
543
  <option selected value="<?php echo $user_id ?>"> <?php echo $user->display_name; ?></option>
544
  <?php } ?>
545
  </select>
546
-
547
  <span class="wc-oe-header"><?php _e( 'User roles', 'woo-order-export-lite' ) ?></span>
548
  <select id="user_roles" name="settings[user_roles][]" multiple="multiple" style="width: 100%; max-width: 25%;">
549
  <?php
@@ -578,7 +605,7 @@ $readonly_php = WC_Order_Export_Admin::user_can_add_custom_php() ? '' : 'readonl
578
  <br>
579
  <select id="user_custom_fields_check" multiple name="settings[user_custom_fields][]" style="width: 100%; max-width: 25%;">
580
  <?php
581
- if ( $settings[ 'user_custom_fields' ] )
582
  foreach ( $settings[ 'user_custom_fields' ] as $value ) {
583
  ?>
584
  <option selected value="<?php echo $value; ?>"> <?php echo $value; ?></option>
@@ -688,7 +715,7 @@ $readonly_php = WC_Order_Export_Admin::user_can_add_custom_php() ? '' : 'readonl
688
  </div>
689
 
690
  <br>
691
-
692
  <div class="my-block">
693
  <span class="my-hide-next "><?php _e( 'Filter by item and metadata', 'woo-order-export-lite' ) ?>
694
  <span class="ui-icon ui-icon-triangle-1-s my-icon-triangle"></span></span>
@@ -716,7 +743,7 @@ $readonly_php = WC_Order_Export_Admin::user_can_add_custom_php() ? '' : 'readonl
716
  <option selected value="<?php echo $name; ?>"> <?php echo $name; ?></option>
717
  <?php } ?>
718
  </select>
719
-
720
  <span class="wc-oe-header"><?php _e( 'Item metadata', 'woo-order-export-lite' ) ?></span>
721
  <br>
722
  <select id="item_metadata">
@@ -724,9 +751,9 @@ $readonly_php = WC_Order_Export_Admin::user_can_add_custom_php() ? '' : 'readonl
724
  <optgroup label="<?php echo ucwords($type); ?>">
725
  <?php foreach ( $meta_keys as $item_meta_key ) { ?>
726
  <option value="<?php echo $type.":".$item_meta_key; ?>" ><?php echo $item_meta_key; ?></option>
727
- <?php } ?>
728
  </optgroup>
729
- <?php } ?>
730
  </select>
731
  <select id="item_metadata_compare" class="select_compare">
732
  <option>=</option>
@@ -742,10 +769,10 @@ $readonly_php = WC_Order_Export_Admin::user_can_add_custom_php() ? '' : 'readonl
742
  <option selected value="<?php echo $meta; ?>"> <?php echo $meta; ?></option>
743
  <?php } ?>
744
  </select>
745
-
746
  </div>
747
  </div>
748
-
749
  </div>
750
 
751
  <div class="clearfix"></div>
@@ -754,67 +781,205 @@ $readonly_php = WC_Order_Export_Admin::user_can_add_custom_php() ? '' : 'readonl
754
  <span id='adjust-fields-btn' class="my-hide-next "><?php _e( 'Set up fields to export', 'woo-order-export-lite' ) ?>
755
  <span class="ui-icon ui-icon-triangle-1-s my-icon-triangle"></span></span>
756
  <div id="manage_fields" style="display: none;">
757
- <br>
758
- <div id='fields_control' style='display:none'>
759
- <div class='div_meta' style='display:none'>
760
- <label style="width: 40%;"><?php _e( 'Meta key', 'woo-order-export-lite' ) ?>:
761
- <select id='select_custom_meta_order'>
762
- <?php
763
- foreach ( $order_custom_meta_fields as $meta_id => $meta_name ) {
764
- echo "<option value='$meta_name' >$meta_name</option>";
765
- };
766
- ?>
767
- </select></label>
768
- <label style="width: 40%;"><?php _e( 'Column name', 'woo-order-export-lite' ) ?>:<input type='text' id='colname_custom_meta'/></label>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
769
 
770
- <div id="custom_meta_order_mode">
771
- <label style="width: 40%;"><input style="width: 80%;" type='text' id='text_custom_meta_order' placeholder="<?php _e('or type meta key here', 'woo-order-export-lite') ?>"/><br></label>
772
- <label><input id="custom_meta_order_mode_used" type="checkbox" name="custom_meta_order_mode" value="used"> <?php _e('Hide unused fields', 'woo-order-export-lite') ?></label>
773
- </div>
774
- <div style="text-align: right;">
775
- <button id='button_custom_meta' class='button-secondary'><?php _e( 'Confirm', 'woo-order-export-lite' ) ?></button>
776
- <button class='button-secondary button_cancel'><?php _e( 'Cancel', 'woo-order-export-lite' ) ?></button>
777
- </div>
778
- </div>
779
- <div class='div_custom' style='display:none;'>
780
- <label style="width: 40%;"><?php _e( 'Column name', 'woo-order-export-lite' ) ?>:<input type='text' id='colname_custom_field'/></label>
781
- <label style="width: 40%;"><?php _e( 'Value', 'woo-order-export-lite' ) ?>:<input type='text' id='value_custom_field'/></label>
782
- <div style="text-align: right;">
783
- <button id='button_custom_field' class='button-secondary'><?php _e( 'Confirm', 'woo-order-export-lite' ) ?></button>
784
- <button class='button-secondary button_cancel'><?php _e( 'Cancel', 'woo-order-export-lite' ) ?></button>
785
- </div>
786
- </div>
787
- <div class='div1'><span><strong><?php _e( 'Use sections', 'woo-order-export-lite' ) ?>:</strong></span> <?php
788
- foreach ( WC_Order_Export_Data_Extractor_UI::get_order_segments() as $section_id => $section_name ) {
789
- echo "<label ><input type=checkbox value=$section_id checked class='field_section'>$section_name &nbsp;</label>";
790
- }
791
- ?>
792
- </div>
793
- <div class='div2'>
794
- <span><strong><?php _e( 'Actions', 'woo-order-export-lite' ) ?>:</strong></span>
795
- <button id='orders_add_custom_meta' class='button-secondary'><?php _e( 'Add field', 'woo-order-export-lite' ) ?></button>
796
- <br><br>
797
- <button id='orders_add_custom_field' class='button-secondary'><?php _e( 'Add static field', 'woo-order-export-lite' ) ?></button>
798
- <br><br>
799
- <button id='hide_unchecked' class='button button-secondary'>
800
- <div style="padding:0px;"><?php _e( 'Hide unused fields', 'woo-order-export-lite' ) ?></div>
801
- <div style="padding:0px;display:none"><?php _e( 'Show unused fields', 'woo-order-export-lite' ) ?></div>
802
- </button>
803
- </div>
804
- </div>
805
- <div id='fields' style='display:none;'>
806
- <br>
807
- <div class="mapping_col_2">
808
- <label style="margin-left: 3px;">
809
- <input type="checkbox" name="orders_all"> <?php _e( 'Select all', 'woo-order-export-lite' ) ?></label>
810
- </div>
811
- <label class="mapping_col_3" style="color: red; font-size: medium;">
812
- <?php _e( 'Drag rows to reorder exported fields', 'woo-order-export-lite' ) ?>
813
- </label>
814
- <br>
815
- <ul id="order_fields"></ul>
816
 
817
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
818
  <div id="modal_content" style="display: none;"></div>
819
  </div>
820
 
@@ -823,7 +988,13 @@ $readonly_php = WC_Order_Export_Admin::user_can_add_custom_php() ? '' : 'readonl
823
  <div id=JS_error_onload style='color:red;font-size: 120%;'><?php echo sprintf(__( "If you see this message after page load, user interface won't work correctly!<br>There is a JS error (<a target=blank href='%s'>read here</a> how to view it). Probably, it's a conflict with another plugin or active theme.", 'woo-order-export-lite' ) , "https://codex.wordpress.org/Using_Your_Browser_to_Diagnose_JavaScript_Errors#Step_3:_Diagnosis"); ?></div>
824
  <p class="submit">
825
  <input type="submit" id='preview-btn' class="button-secondary preview-btn" data-limit="<?php echo ($mode === WC_Order_Export_Manage::EXPORT_ORDER_ACTION ? 1 : 5); ?>" value="<?php _e( 'Preview', 'woo-order-export-lite' ) ?>" title="<?php _e( 'Might be different from actual export!', 'woo-order-export-lite' ) ?>" />
826
- <input type="submit" id='save-btn' class="button-primary" value="<?php _e( 'Save settings', 'woo-order-export-lite' ) ?>" />
 
 
 
 
 
 
827
  <?php if ( $show[ 'export_button' ] ) { ?>
828
  <input type="submit" id='export-btn' class="button-secondary" value="<?php _e( 'Export', 'woo-order-export-lite' ) ?>" />
829
  <?php } ?>
@@ -841,6 +1012,8 @@ $readonly_php = WC_Order_Export_Admin::user_can_add_custom_php() ? '' : 'readonl
841
  <?php endforeach ?>
842
  </span>
843
  </p>
 
 
844
  <?php if ( $show[ 'export_button' ] OR $show[ 'export_button_plain' ] ) { ?>
845
  <div id="progress_div" style="display: none;">
846
  <h1 class="title-cancel"><?php _e( "Press 'Esc' to cancel the export", 'woo-order-export-lite' ) ?></h1>
2
  if ( !defined( 'ABSPATH' ) ) {
3
  exit; // Exit if accessed directly
4
  }
 
5
  /**
6
  * @var WC_Order_Export_Admin $WC_Order_Export WC_Order_Export_Admin instance
7
  * @var string $mode ( now | profiles | cron | order-action )
14
  $settings = apply_filters('woe_settings_page_prepare', $settings );
15
  $order_custom_meta_fields = WC_Order_Export_Data_Extractor_UI::get_all_order_custom_meta_fields();
16
  $readonly_php = WC_Order_Export_Admin::user_can_add_custom_php() ? '' : 'readonly';
17
+
18
+ function print_formats_field( $type, $segment = "" ) {
19
+ if ( ! $type && $type !== 'meta' && $type !== 'field' ) {
20
+ return '';
21
+ }
22
+ $margin_left = 'meta' == $type ? '1px' : '4px';
23
+ // colname_custom_field
24
+ $id = $segment ? 'format_custom_' . $type . '_' . $segment : 'format_custom_' . $type;
25
+
26
+ $formats_fields_html =
27
+ '<label for="' . $id . '">' .
28
+ __( 'Field format', 'woo-order-export-lite' ) . ':' .
29
+ '</label>' .
30
+ '<select type="text" id="' . $id . '" style="max-width: 215px; margin-left: ' . $margin_left . '">' .
31
+ '<option value="" >' . __('-', 'woo-order-export-lite') . '</option>';
32
+
33
+ foreach ( WC_Order_Export_Data_Extractor_UI::get_format_fields() as $format_id => $format_label ) {
34
+ $formats_fields_html .= "<option value='$format_id' >$format_label</option>";
35
+ };
36
+ $formats_fields_html .= '</select>';
37
+
38
+ return $formats_fields_html;
39
+ }
40
+
41
+
42
+
43
  ?>
44
 
45
  <script>
46
  var mode = '<?php echo $mode ?>';
47
  var job_id = '<?php echo $id ?>';
48
  var output_format = '<?php echo $settings[ 'format' ] ?>';
49
+ var selected_order_fields = <?php echo json_encode( $settings[ 'order_fields' ] ) ?>;
50
+ var selected_order_products_fields = <?php echo json_encode( $settings[ 'order_product_fields' ] ) ?>;
51
+ var selected_order_coupons_fields = <?php echo json_encode( $settings[ 'order_coupon_fields' ] ) ?>;
52
+ var duplicated_fields_settings = <?php echo json_encode( $settings[ 'duplicated_fields_settings' ] ) ?>;
53
+ var all_fields = <?php echo json_encode( WC_Order_Export_Manage::make_all_fields( $settings[ 'format' ] ) ); ?>;
54
  var order_custom_meta_fields = <?php echo json_encode( $order_custom_meta_fields ) ?>;
55
  var order_products_custom_meta_fields = <?php echo json_encode( WC_Order_Export_Data_Extractor_UI::get_product_custom_fields() ) ?>;
56
  var order_order_item_custom_meta_fields = <?php echo json_encode( WC_Order_Export_Data_Extractor_UI::get_product_itemmeta() ) ?>;
57
  var order_coupons_custom_meta_fields = <?php echo json_encode( WC_Order_Export_Data_Extractor_UI::get_all_coupon_custom_meta_fields() ) ?>;
58
+ var order_segments = <?php echo json_encode( WC_Order_Export_Data_Extractor_UI::get_order_segments() ) ?>;
59
+ var field_formats = <?php echo json_encode( WC_Order_Export_Data_Extractor_UI::get_format_fields() ) ?>;
60
  var summary_mode = <?php echo $settings['summary_report_by_products'] ?>;
61
  </script>
62
 
63
 
 
64
  <form method="post" id="export_job_settings">
65
  <?php if ( $mode !== WC_Order_Export_Manage::EXPORT_NOW ): ?>
66
  <div style="width: 100%;">&nbsp;</div>
67
  <?php endif; ?>
68
 
69
  <div id="my-left" style="float: left; width: 49%; max-width: 500px;">
70
+ <?php
71
+ if ( $mode === WC_Order_Export_Manage::EXPORT_PROFILE ):
72
  include 'pro-version/top-profile.php';
73
+ elseif ( $mode === WC_Order_Export_Manage::EXPORT_ORDER_ACTION ):
74
  include 'pro-version/top-order-actions.php';
75
+ elseif ( $mode === WC_Order_Export_Manage::EXPORT_SCHEDULE ):
76
  include 'pro-version/top-scheduled-jobs.php';
77
+ endif;
78
  ?>
79
 
80
+ <input type="hidden" name="settings[version]" value="<?php echo isset($settings[ 'version' ]) ? $settings[ 'version' ] : '2.0' ?>">
81
+
82
  <?php if ( $show[ 'date_filter' ] ) : ?>
83
  <div id="my-export-date-field" class="my-block">
84
  <div class="wc-oe-header">
115
 
116
  <button id="my-quick-export-btn" class="button-primary"><?php _e( 'Express export', 'woo-order-export-lite' ) ?></button>
117
  <div id="summary_report_by_products" style="display:inline-block"><input type="hidden" name="settings[summary_report_by_products]" value="0"/><label><input type="checkbox" id=summary_report_by_products_checkbox name="settings[summary_report_by_products]" value="1" <?php checked($settings[ 'summary_report_by_products' ]) ?> /> <?php _e( "Summary Report By Products", 'woo-order-export-lite' ) ?></label>
 
118
  </div>
119
  </div>
120
  <br>
147
  <input type=hidden name="settings[format_xls_use_xls_format]" value=0>
148
  <input type=hidden name="settings[format_xls_display_column_names]" value=0>
149
  <input type=hidden name="settings[format_xls_auto_width]" value=0>
 
150
  <input type=hidden name="settings[format_xls_direction_rtl]" value=0>
151
  <input type=checkbox name="settings[format_xls_use_xls_format]" value=1 <?php if ( @$settings[ 'format_xls_use_xls_format' ] ) echo 'checked'; ?> id="format_xls_use_xls_format"> <?php _e( 'Export as .xls (Binary File Format)', 'woo-order-export-lite' ) ?><br>
152
  <input type=checkbox checked disabled><?php _e( 'Use sheet name', 'woo-order-export-lite' ) ?></b><input type=text name="settings[format_xls_sheet_name]" value='<?php echo $settings[ 'format_xls_sheet_name' ] ?>' size=10><br>
153
  <input type=checkbox name="settings[format_xls_display_column_names]" value=1 <?php if ( @$settings[ 'format_xls_display_column_names' ] ) echo 'checked'; ?> > <?php _e( 'Output column titles as first line', 'woo-order-export-lite' ) ?><br>
154
  <input type=checkbox name="settings[format_xls_auto_width]" value=1 <?php if ( @$settings[ 'format_xls_auto_width' ] ) echo 'checked'; ?> > <?php _e( 'Auto column width', 'woo-order-export-lite' ) ?><br>
 
155
  <input type=checkbox name="settings[format_xls_direction_rtl]" value=1 <?php if ( @$settings[ 'format_xls_direction_rtl' ] ) echo 'checked'; ?> > <?php _e( 'Right-to-Left direction', 'woo-order-export-lite' ) ?><br>
156
  </div>
157
  <div id='CSV_options' style='display:none'><strong><?php _e( 'CSV options', 'woo-order-export-lite' ) ?></strong><br>
158
  <input type=hidden name="settings[format_csv_add_utf8_bom]" value=0>
159
  <input type=hidden name="settings[format_csv_display_column_names]" value=0>
 
160
  <input type=hidden name="settings[format_csv_delete_linebreaks]" value=0>
161
  <input type=hidden name="settings[format_csv_item_rows_start_from_new_line]" value=0>
162
  <input type=checkbox name="settings[format_csv_add_utf8_bom]" value=1 <?php if ( @$settings[ 'format_csv_add_utf8_bom' ] ) echo 'checked'; ?> > <?php _e( 'Output UTF-8 BOM', 'woo-order-export-lite' ) ?><br>
163
  <input type=checkbox name="settings[format_csv_display_column_names]" value=1 <?php if ( @$settings[ 'format_csv_display_column_names' ] ) echo 'checked'; ?> > <?php _e( 'Output column titles as first line', 'woo-order-export-lite' ) ?><br>
 
164
  <input type=checkbox name="settings[format_csv_delete_linebreaks]" value=1 <?php if ( @$settings[ 'format_csv_delete_linebreaks' ] ) echo 'checked'; ?> > <?php _e( 'Convert line breaks to literals', 'woo-order-export-lite' ) ?><br>
165
  <input type=checkbox name="settings[format_csv_item_rows_start_from_new_line]" value=1 <?php if ( @$settings[ 'format_csv_item_rows_start_from_new_line' ] ) echo 'checked'; ?> > <?php _e( 'Item rows start from new line', 'woo-order-export-lite' ) ?><br>
166
  <?php _e( 'Enclosure', 'woo-order-export-lite' ) ?> <input type=text name="settings[format_csv_enclosure]" value='<?php echo $settings[ 'format_csv_enclosure' ] ?>' size=1>
187
  <div id='TSV_options' style='display:none'><strong><?php _e( 'TSV options', 'woo-order-export-lite' ) ?></strong><br>
188
  <input type=hidden name="settings[format_tsv_add_utf8_bom]" value=0>
189
  <input type=hidden name="settings[format_tsv_display_column_names]" value=0>
 
190
  <input type=checkbox name="settings[format_tsv_add_utf8_bom]" value=1 <?php if ( @$settings[ 'format_tsv_add_utf8_bom' ] ) echo 'checked'; ?> > <?php _e( 'Output UTF-8 BOM', 'woo-order-export-lite' ) ?><br>
191
  <input type=checkbox name="settings[format_tsv_display_column_names]" value=1 <?php if ( @$settings[ 'format_tsv_display_column_names' ] ) echo 'checked'; ?> > <?php _e( 'Output column titles as first line', 'woo-order-export-lite' ) ?><br>
 
192
  <?php _e( 'Line Break', 'woo-order-export-lite' ) ?><input type=text name="settings[format_tsv_linebreak]" value='<?php echo $settings[ 'format_tsv_linebreak' ] ?>' size=4><br>
193
  <?php if ( function_exists( 'iconv' ) ): ?>
194
  <?php _e( 'Character encoding', 'woo-order-export-lite' ) ?><input type=text name="settings[format_tsv_encoding]" value="<?php echo $settings[ 'format_tsv_encoding' ] ?>"><br>
240
  <div id="custom_time_format_block" style="<?php echo in_array( @$settings[ 'time_format' ], $time_format ) ? 'display: none' : '' ?>">
241
  <input type="text" name="settings[time_format]" value="<?php echo $settings[ 'time_format' ] ?>">
242
  </div>
243
+ </div>
244
  </div>
245
  </div>
246
  <br/>
331
  </div>
332
 
333
  <div id="my-right" style="float: left; width: 48%; margin: 0px 10px; max-width: 500px;">
334
+ <?php
335
  if ( in_array( $mode, array( WC_Order_Export_Manage::EXPORT_SCHEDULE, WC_Order_Export_Manage::EXPORT_ORDER_ACTION ) ) ):
336
  include "pro-version/destinations.php";
337
  endif; ?>
402
  if ( $settings[ 'product_categories' ] )
403
  foreach ( $settings[ 'product_categories' ] as $cat ) {
404
  $cat_term = get_term( $cat, 'product_cat' );
405
+ if ($cat_term) {
406
+ ?>
407
+ <option selected value="<?php echo $cat_term->term_id ?>"> <?php echo $cat_term->name; ?></option>
408
+ <?php
409
+ }
410
  ?>
 
411
  <?php } ?>
412
  </select>
413
  <span class="wc-oe-header"><?php _e( 'Vendor/creator', 'woo-order-export-lite' ) ?></span>
570
  <option selected value="<?php echo $user_id ?>"> <?php echo $user->display_name; ?></option>
571
  <?php } ?>
572
  </select>
573
+
574
  <span class="wc-oe-header"><?php _e( 'User roles', 'woo-order-export-lite' ) ?></span>
575
  <select id="user_roles" name="settings[user_roles][]" multiple="multiple" style="width: 100%; max-width: 25%;">
576
  <?php
605
  <br>
606
  <select id="user_custom_fields_check" multiple name="settings[user_custom_fields][]" style="width: 100%; max-width: 25%;">
607
  <?php
608
+ if ( ! empty($settings[ 'user_custom_fields' ]) )
609
  foreach ( $settings[ 'user_custom_fields' ] as $value ) {
610
  ?>
611
  <option selected value="<?php echo $value; ?>"> <?php echo $value; ?></option>
715
  </div>
716
 
717
  <br>
718
+
719
  <div class="my-block">
720
  <span class="my-hide-next "><?php _e( 'Filter by item and metadata', 'woo-order-export-lite' ) ?>
721
  <span class="ui-icon ui-icon-triangle-1-s my-icon-triangle"></span></span>
743
  <option selected value="<?php echo $name; ?>"> <?php echo $name; ?></option>
744
  <?php } ?>
745
  </select>
746
+
747
  <span class="wc-oe-header"><?php _e( 'Item metadata', 'woo-order-export-lite' ) ?></span>
748
  <br>
749
  <select id="item_metadata">
751
  <optgroup label="<?php echo ucwords($type); ?>">
752
  <?php foreach ( $meta_keys as $item_meta_key ) { ?>
753
  <option value="<?php echo $type.":".$item_meta_key; ?>" ><?php echo $item_meta_key; ?></option>
754
+ <?php } ?>
755
  </optgroup>
756
+ <?php } ?>
757
  </select>
758
  <select id="item_metadata_compare" class="select_compare">
759
  <option>=</option>
769
  <option selected value="<?php echo $meta; ?>"> <?php echo $meta; ?></option>
770
  <?php } ?>
771
  </select>
772
+
773
  </div>
774
  </div>
775
+
776
  </div>
777
 
778
  <div class="clearfix"></div>
781
  <span id='adjust-fields-btn' class="my-hide-next "><?php _e( 'Set up fields to export', 'woo-order-export-lite' ) ?>
782
  <span class="ui-icon ui-icon-triangle-1-s my-icon-triangle"></span></span>
783
  <div id="manage_fields" style="display: none;">
784
+ <div style="display: grid; grid-template-columns: 10fr 1fr 10fr;">
785
+ <div class="clear"></div>
786
+ <div></div>
787
+ <div >
788
+ <br class="clear"/>
789
+ </div>
790
+ <div id='fields' style='display:none;'>
791
+ <div class="fields-control-block"></div>
792
+ <br>
793
+ <div class="fields-control">
794
+ <div style="display: inline-block; float: left">
795
+ <label style="font-size: medium;">
796
+ <?php _e( 'Drag rows to reorder exported fields', 'woo-order-export-lite' ) ?>
797
+ </label>
798
+ </div>
799
+ <div style="display: inline-block; float: right; margin-bottom: 15px">
800
+ <a id="clear_selected_fields" class="button" style="background-color: #bb77ae; color: white;: ">
801
+ <?php _e( 'Remove all fields', 'woo-order-export-lite' ) ?>
802
+ </a>
803
+ </div>
804
+ </div>
805
+ <div >
806
+ <br class="clear"/>
807
+ </div>
808
+ <ul id="order_fields"></ul>
809
+ </div>
810
+ <div></div>
811
+ <div id='unselected_fields'>
812
+ <ul class="subsubsub">
813
+ <?php $segments = WC_Order_Export_Data_Extractor_UI::get_order_segments(); ?>
814
+ <?php foreach ( $segments as $id => $segment_title ): ?>
815
+ <li>
816
+ <a class="segment_choice"
817
+ data-segment="<?php echo $id; ?>" href="#segment=<?php echo $id; ?>">
818
+ <?php echo $segment_title; ?>
819
+ </a>
820
+ <?php echo( end( $segments ) == $segment_title ? '' : ' | ' ); ?>
821
+ </li>
822
+ <?php endforeach; ?>
823
+ </ul>
824
+ <br class="clear">
825
+ <div class="tab-controls">
826
+ <div class="tab-actions-buttons">
827
+ <span class="tab-actions-buttons__title">
828
+ <strong><?php _e( 'Actions', 'woo-order-export-lite' ) ?>:</strong>
829
+ </span>
830
+ <button class='button-secondary add-meta'>
831
+ <?php _e( 'Add field', 'woo-order-export-lite' ) ?>
832
+ </button>
833
+ <button class='button-secondary add-custom'>
834
+ <?php _e( 'Add static field', 'woo-order-export-lite' ) ?>
835
+ </button>
836
+ </div>
837
+ <div class="tab-actions-forms">
838
+ <div class='div_meta segment-form all-segments'>
839
+ <label for="select_custom_meta_order">
840
+ <?php _e( 'Meta key', 'woo-order-export-lite' ) ?>:
841
+ </label><br/>
842
+ <select id='select_custom_meta_order'>
843
+ <?php
844
+ foreach ( $order_custom_meta_fields as $meta_id => $meta_name ) {
845
+ echo "<option value='$meta_name' >$meta_name</option>";
846
+ };
847
+ ?>
848
+ </select>
849
+ <div id="custom_meta_order_mode" style="margin-bottom: 10px;">
850
+ <input style="width: 80%;" type='text' id='text_custom_meta_order' placeholder="<?php _e('or type meta key here', 'woo-order-export-lite') ?>"/><br>
851
+ </div>
852
+ <div style="margin-bottom: 8px;">
853
+ <input id="custom_meta_order_mode_used" type="checkbox" name="custom_meta_order_mode" value="used"> <?php _e('Hide unused fields', 'woo-order-export-lite') ?>
854
+ </div>
855
+ <hr>
856
+ <div style="margin-top: 20px;"><label for="colname_custom_meta"><?php _e( 'Column name', 'woo-order-export-lite' ) ?>:</label><input type='text' id='colname_custom_meta'/>
857
+ </div>
858
+ <div style="margin-top: 20px;">
859
+ <?php echo print_formats_field('meta'); ?>
860
+ </div>
861
+ <div style="text-align: right;">
862
+ <button id='button_custom_meta' class='button-secondary'><?php _e( 'Confirm', 'woo-order-export-lite' ) ?></button>
863
+ <button class='button-secondary button-cancel'><?php _e( 'Cancel', 'woo-order-export-lite' ) ?></button>
864
+ </div>
865
+ </div>
866
+ <div class='div_custom segment-form all-segments'>
867
+ <div>
868
+ <label for="colname_custom_field"><?php _e( 'Column name', 'woo-order-export-lite' ) ?>:</label>
869
+ <input type='text' id='colname_custom_field'/>
870
+ </div>
871
+ <div>
872
+ <label for="value_custom_field"><?php _e( 'Value', 'woo-order-export-lite' ) ?>:</label>
873
+ <input type='text' id='value_custom_field'/>
874
+ </div>
875
+ <div>
876
+ <?php echo print_formats_field('field'); ?>
877
+ </div>
878
+ <div style="text-align: right;">
879
+ <button id='button_custom_field' class='button-secondary'><?php _e( 'Confirm', 'woo-order-export-lite' ) ?></button>
880
+ <button class='button-secondary button-cancel'><?php _e( 'Cancel', 'woo-order-export-lite' ) ?></button>
881
+ </div>
882
+ </div>
883
+ <div class='div_meta products-segment segment-form products-add-field' >
884
+ <div id="custom_meta_products_mode" class="hide">
885
+ <label><input id="custom_meta_products_mode_used" type="checkbox" name="custom_meta_products_mode" value="used"> <?php _e('Hide unused fields', 'woo-order-export-lite') ?></label>
886
+ </div>
887
+ <label for="select_custom_meta_products"><?php _e('Product fields', 'woo-order-export-lite')?>:</label><select id='select_custom_meta_products'></select>
888
+
889
+ <label for="select_custom_meta_order_items"><?php _e('Order item fields', 'woo-order-export-lite')?>:</label><select id='select_custom_meta_order_items'></select>
890
+ <label>&nbsp;</label><input style="width: 80%;" type='text' id='text_custom_meta_order_items' placeholder="<?php _e('or type meta key here', 'woo-order-export-lite') ?>"/><br>
891
+ <div style="width: 80%; text-align: center;"><?php _e('OR', 'woo-order-export-lite') ?></div>
892
+ <label><?php _e('Taxonomy', 'woo-order-export-lite')?>:</label><select id='select_custom_taxonomies_products'>
893
+ <option></option>
894
+ <?php
895
+ foreach (WC_Order_Export_Data_Extractor_UI::get_product_taxonomies() as $tax_id => $tax_name) {
896
+ echo "<option value='__$tax_name' >__$tax_name</option>";
897
+ };
898
+ ?>
899
+ </select>
900
+ <hr>
901
+ <div style="margin-top: 15px;"></div>
902
+ <label><?php _e('Column name', 'woo-order-export-lite')?>:</label><input type='text' id='colname_custom_meta_products'/>
903
+ <div style="margin-top: 15px;"></div>
904
+ <?php echo print_formats_field('meta', 'products'); ?>
905
+ <div style="text-align: right;">
906
+ <button id='button_custom_meta_products' class='button-secondary'><?php _e('Confirm', 'woo-order-export-lite')?></button>
907
+ <button class='button-secondary button-cancel'><?php _e( 'Cancel', 'woo-order-export-lite' ) ?></button>
908
+ </div>
909
+ </div>
910
+ <div class='div_custom products-segment segment-form products-add-static-field'>
911
+ <div>
912
+ <label for="colname_custom_field_products"><?php _e('Column name', 'woo-order-export-lite')?>:</label>
913
+ <input type='text' id='colname_custom_field_products'/>
914
+ </div>
915
+ <div>
916
+ <label for="value_custom_field_products"><?php _e('Value', 'woo-order-export-lite')?>:</label>
917
+ <input type='text' id='value_custom_field_products'/>
918
+ </div>
919
+ <div>
920
+ <?php echo print_formats_field('field', 'products'); ?>
921
+ </div>
922
+ <div style="text-align: right;">
923
+ <button id='button_custom_field_products' class='button-secondary'><?php _e('Confirm', 'woo-order-export-lite')?></button>
924
+ <button class='button-secondary button-cancel'><?php _e( 'Cancel', 'woo-order-export-lite' ) ?></button>
925
+ </div>
926
+ </div>
927
+ <div class='div_meta coupons-segment segment-form coupons-add-field' >
928
+ <label><?php _e('Meta key', 'woo-order-export-lite')?>:</label><div id="custom_meta_coupons_mode" style="display: none;">
929
+ <label><input id="custom_meta_coupons_mode_used" type="checkbox" name="custom_meta_coupons_mode" value="used"> <?php _e('Hide unused fields', 'woo-order-export-lite') ?></label>
930
+ </div>
931
+ <br>
932
+ <select id='select_custom_meta_coupons'></select>
933
+ <input style="width: 80%;margin-bottom: 10px;" type='text' id='text_custom_meta_coupons' placeholder="<?php _e('or type meta key here', 'woo-order-export-lite') ?>"/><br/>
934
+ <hr>
935
+ <label><?php _e('Column name', 'woo-order-export-lite')?>:</label><input type='text' id='colname_custom_meta_coupons'/></label>
936
+ <div style="margin-top: 20px;">
937
+ <?php echo print_formats_field('meta', 'coupons'); ?>
938
+ </div>
939
+ <div style="text-align: right;">
940
+ <button id='button_custom_meta_coupons' class='button-secondary'><?php _e('Confirm', 'woo-order-export-lite')?></button>
941
+ <button class='button-secondary button-cancel'><?php _e( 'Cancel', 'woo-order-export-lite' ) ?></button>
942
+ </div>
943
+ </div>
944
+ <div class='div_custom coupons-segment segment-form coupons-add-static-field'>
945
+ <div>
946
+ <label for="colname_custom_field_coupons"><?php _e('Column name', 'woo-order-export-lite')?>:</label>
947
+ <input type='text' id='colname_custom_field_coupons'/>
948
+ </div>
949
+ <div>
950
+ <label for="value_custom_field_coupons"><?php _e('Value', 'woo-order-export-lite')?>:</label>
951
+ <input type='text' id='value_custom_field_coupons'/>
952
+ </div>
953
+ <div>
954
+ <?php echo print_formats_field('field', 'coupons'); ?>
955
+ </div>
956
+ <div style="text-align: right;">
957
+ <button id='button_custom_field_coupons' class='button-secondary'>
958
+ <?php _e('Confirm', 'woo-order-export-lite')?>
959
+ </button>
960
+ <button class='button-secondary button-cancel'>
961
+ <?php _e( 'Cancel', 'woo-order-export-lite' ) ?>
962
+ </button>
963
+ </div>
964
+ </div>
965
+ </div>
966
+ </div>
967
 
968
+ <div id="unselected_fields_list"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
969
 
970
+
971
+ <!-- <div class="section settings-segment" id="order_segment">-->
972
+ <!-- <h1>ORDER</h1>-->
973
+ <!-- </div>-->
974
+ <!-- <div class="section settings-segment" id="products_segment">-->
975
+ <!-- <h1>PRODUCT</h1>-->
976
+ <!-- </div>-->
977
+ <!-- <div class="section settings-segment" id="coupons_segment">-->
978
+ <!-- <h1>COUPON</h1>-->
979
+ <!-- </div>-->
980
+
981
+ </div>
982
+ </div>
983
  <div id="modal_content" style="display: none;"></div>
984
  </div>
985
 
988
  <div id=JS_error_onload style='color:red;font-size: 120%;'><?php echo sprintf(__( "If you see this message after page load, user interface won't work correctly!<br>There is a JS error (<a target=blank href='%s'>read here</a> how to view it). Probably, it's a conflict with another plugin or active theme.", 'woo-order-export-lite' ) , "https://codex.wordpress.org/Using_Your_Browser_to_Diagnose_JavaScript_Errors#Step_3:_Diagnosis"); ?></div>
989
  <p class="submit">
990
  <input type="submit" id='preview-btn' class="button-secondary preview-btn" data-limit="<?php echo ($mode === WC_Order_Export_Manage::EXPORT_ORDER_ACTION ? 1 : 5); ?>" value="<?php _e( 'Preview', 'woo-order-export-lite' ) ?>" title="<?php _e( 'Might be different from actual export!', 'woo-order-export-lite' ) ?>" />
991
+ <?php if($mode == 'now'): ?>
992
+ <input type="submit" id='save-only-btn' class="button-primary" value="<?php _e( 'Save settings', 'woo-order-export-lite' ) ?>" />
993
+ <?php else: ?>
994
+ <input type="submit" id='save-btn' class="button-primary" value="<?php _e( 'Save & Exit', 'woo-order-export-lite' ) ?>" />
995
+ <input type="submit" id='save-only-btn' class="button-secondary" value="<?php _e( 'Save settings', 'woo-order-export-lite' ) ?>" />
996
+ <?php endif; ?>
997
+
998
  <?php if ( $show[ 'export_button' ] ) { ?>
999
  <input type="submit" id='export-btn' class="button-secondary" value="<?php _e( 'Export', 'woo-order-export-lite' ) ?>" />
1000
  <?php } ?>
1012
  <?php endforeach ?>
1013
  </span>
1014
  </p>
1015
+ <div id=Settings_updated style='display:none;color:green;font-size: 120%;'><?php _e( "Settings were successfully updated!", 'woo-order-export-lite' )?></div>
1016
+
1017
  <?php if ( $show[ 'export_button' ] OR $show[ 'export_button_plain' ] ) { ?>
1018
  <div id="progress_div" style="display: none;">
1019
  <h1 class="title-cancel"><?php _e( "Press 'Esc' to cancel the export", 'woo-order-export-lite' ) ?></h1>
view/tab/order-actions.php CHANGED
@@ -2,6 +2,6 @@
2
  if ( !defined( 'ABSPATH' ) ) {
3
  exit; // Exit if accessed directly
4
  }
5
- $pro_link = '<a href="https://algolplus.com/plugins/downloads/woocommerce-order-export/" target=_blank>' . __( 'Pro version', 'woo-order-export-lite' ) . '</a>';
6
  ?>
7
  <div class="tabs-content"><?php echo sprintf ( __( 'Buy %s to get access to Status change jobs', 'woo-order-export-lite' ), $pro_link ) ?></div>
2
  if ( !defined( 'ABSPATH' ) ) {
3
  exit; // Exit if accessed directly
4
  }
5
+ $pro_link = '<a href="https://algolplus.com/plugins/downloads/advanced-order-export-for-woocommerce-pro/" target=_blank>' . __( 'Pro version', 'woo-order-export-lite' ) . '</a>';
6
  ?>
7
  <div class="tabs-content"><?php echo sprintf ( __( 'Buy %s to get access to Status change jobs', 'woo-order-export-lite' ), $pro_link ) ?></div>
view/tab/profiles.php CHANGED
@@ -2,6 +2,6 @@
2
  if ( !defined( 'ABSPATH' ) ) {
3
  exit; // Exit if accessed directly
4
  }
5
- $pro_link = '<a href="https://algolplus.com/plugins/downloads/woocommerce-order-export/" target=_blank>' . __( 'Pro version', 'woo-order-export-lite' ) . '</a>';
6
  ?>
7
  <div class="tabs-content"><?php echo sprintf ( __( 'Buy %s to get access to profiles', 'woo-order-export-lite' ), $pro_link ) ?></div>
2
  if ( !defined( 'ABSPATH' ) ) {
3
  exit; // Exit if accessed directly
4
  }
5
+ $pro_link = '<a href="https://algolplus.com/plugins/downloads/advanced-order-export-for-woocommerce-pro/" target=_blank>' . __( 'Pro version', 'woo-order-export-lite' ) . '</a>';
6
  ?>
7
  <div class="tabs-content"><?php echo sprintf ( __( 'Buy %s to get access to profiles', 'woo-order-export-lite' ), $pro_link ) ?></div>
view/tab/schedules.php CHANGED
@@ -2,6 +2,6 @@
2
  if ( !defined( 'ABSPATH' ) ) {
3
  exit; // Exit if accessed directly
4
  }
5
- $pro_link = '<a href="https://algolplus.com/plugins/downloads/woocommerce-order-export/" target=_blank>' . __( 'Pro version', 'woo-order-export-lite' ) . '</a>';
6
  ?>
7
  <div class="tabs-content"><?php echo sprintf ( __( 'Buy %s to get access to Scheduled jobs', 'woo-order-export-lite' ), $pro_link ) ?></div>
2
  if ( !defined( 'ABSPATH' ) ) {
3
  exit; // Exit if accessed directly
4
  }
5
+ $pro_link = '<a href="https://algolplus.com/plugins/downloads/advanced-order-export-for-woocommerce-pro/" target=_blank>' . __( 'Pro version', 'woo-order-export-lite' ) . '</a>';
6
  ?>
7
  <div class="tabs-content"><?php echo sprintf ( __( 'Buy %s to get access to Scheduled jobs', 'woo-order-export-lite' ), $pro_link ) ?></div>
woo-order-export-lite.php CHANGED
@@ -5,11 +5,11 @@
5
  * Description: Export orders from WooCommerce with ease (Excel/CSV/XML/JSON supported)
6
  * Author: AlgolPlus
7
  * Author URI: https://algolplus.com/
8
- * Version: 1.5.6
9
  * Text Domain: woo-order-export-lite
10
  * Domain Path: /i18n/languages/
11
  * WC requires at least: 2.6.0
12
- * WC tested up to: 3.4.0
13
  *
14
  * Copyright: (c) 2015 AlgolPlus LLC. (algol.plus@gmail.com)
15
  *
@@ -25,26 +25,14 @@
25
  if ( !defined( 'ABSPATH' ) )
26
  exit; // Exit if accessed directly
27
 
28
- if ( !defined( 'WOE_IPN_URL_OPTION_KEY') )
29
- define( 'WOE_IPN_URL_OPTION_KEY', 'woe_ipn_url_key' );
30
-
31
  // a small function to check startup conditions
32
  if( ! function_exists("woe_check_running_options") ) {
33
  function woe_check_running_options() {
34
 
35
  $is_backend = is_admin();
36
- $is_cron = defined( 'DOING_CRON' );
37
- $is_frontend_checkout = isset( $_REQUEST['wc-ajax'] ) && $_REQUEST['wc-ajax'] === 'checkout'
38
- || isset( $_POST['woocommerce_checkout_place_order'] )
39
- || preg_match( '/\bwc\-api\b/', filter_input( INPUT_SERVER, 'REQUEST_URI' )) // WC_API
40
- || preg_match( '/\bwc\/v\d+\b/', filter_input( INPUT_SERVER, 'REQUEST_URI' )); // Rest API
41
-
42
- $ipn_url = get_option( WOE_IPN_URL_OPTION_KEY );
43
- $is_ipn = ( $ipn_url AND stripos( $_SERVER['REQUEST_URI'], $ipn_url ) );
44
-
45
- return $is_backend || $is_cron || $is_frontend_checkout || $is_ipn;
46
  }
47
- }
48
 
49
  if ( ! woe_check_running_options() ) {
50
  return;
@@ -65,15 +53,15 @@ if( class_exists( 'WC_Order_Export_Admin' ) ) {
65
  return;
66
  }
67
 
68
-
69
  include 'classes/class-wc-order-export-admin.php';
70
  include 'classes/admin/class-wc-order-export-ajax.php';
71
  include 'classes/admin/class-wc-order-export-manage.php';
 
72
  include 'classes/core/class-wc-order-export-engine.php';
73
  include 'classes/core/class-wc-order-export-data-extractor.php';
74
  include 'classes/core/class-wc-order-export-data-extractor-ui.php';
75
 
76
- define( 'WOE_VERSION', '1.5.6' );
77
  define( 'WOE_PLUGIN_BASENAME', plugin_basename(__FILE__) );
78
  define( 'WOE_PLUGIN_BASEPATH', dirname(__FILE__) );
79
  $wc_order_export = new WC_Order_Export_Admin();
5
  * Description: Export orders from WooCommerce with ease (Excel/CSV/XML/JSON supported)
6
  * Author: AlgolPlus
7
  * Author URI: https://algolplus.com/
8
+ * Version: 2.0.0
9
  * Text Domain: woo-order-export-lite
10
  * Domain Path: /i18n/languages/
11
  * WC requires at least: 2.6.0
12
+ * WC tested up to: 3.5.0
13
  *
14
  * Copyright: (c) 2015 AlgolPlus LLC. (algol.plus@gmail.com)
15
  *
25
  if ( !defined( 'ABSPATH' ) )
26
  exit; // Exit if accessed directly
27
 
 
 
 
28
  // a small function to check startup conditions
29
  if( ! function_exists("woe_check_running_options") ) {
30
  function woe_check_running_options() {
31
 
32
  $is_backend = is_admin();
33
+ return $is_backend;
 
 
 
 
 
 
 
 
 
34
  }
35
+ }
36
 
37
  if ( ! woe_check_running_options() ) {
38
  return;
53
  return;
54
  }
55
 
 
56
  include 'classes/class-wc-order-export-admin.php';
57
  include 'classes/admin/class-wc-order-export-ajax.php';
58
  include 'classes/admin/class-wc-order-export-manage.php';
59
+ include 'classes/admin/class-wc-order-export-labels.php';
60
  include 'classes/core/class-wc-order-export-engine.php';
61
  include 'classes/core/class-wc-order-export-data-extractor.php';
62
  include 'classes/core/class-wc-order-export-data-extractor-ui.php';
63
 
64
+ define( 'WOE_VERSION', '2.0.0' );
65
  define( 'WOE_PLUGIN_BASENAME', plugin_basename(__FILE__) );
66
  define( 'WOE_PLUGIN_BASEPATH', dirname(__FILE__) );
67
  $wc_order_export = new WC_Order_Export_Admin();