WooCommerce Multilingual – run WooCommerce with WPML - Version 3.8.0

Version Description

Download this release

Release Info

Developer mihaimihai
Plugin Icon 128x128 WooCommerce Multilingual – run WooCommerce with WPML
Version 3.8.0
Comparing to
See all releases

Code changes from version 3.7.16 to 3.8.0

Files changed (106) hide show
  1. assets/css/currency-switcher.css +0 -41
  2. assets/css/font-awesome.min.css +0 -403
  3. assets/css/jquery.cleditor.css +0 -24
  4. assets/css/management.css +0 -983
  5. assets/css/tooltip.css +0 -22
  6. assets/css/wcml-prices.css +0 -134
  7. assets/font/FontAwesome.otf +0 -0
  8. assets/font/fontawesome-webfont.eot +0 -0
  9. assets/font/fontawesome-webfont.svg +0 -399
  10. assets/font/fontawesome-webfont.ttf +0 -0
  11. assets/font/fontawesome-webfont.woff +0 -0
  12. assets/images/icon-woo-downloadable.png +0 -0
  13. assets/images/icon-woo-external.png +0 -0
  14. assets/images/icon-woo-grouped.png +0 -0
  15. assets/images/icon-woo-simple.png +0 -0
  16. assets/images/icon-woo-variable.png +0 -0
  17. assets/images/icon-woo-virtual.png +0 -0
  18. assets/images/image_10.png +0 -0
  19. assets/js/jquery.cleditor.min.js +0 -8
  20. assets/js/scripts.js +0 -1466
  21. assets/js/tooltip_init.js +0 -11
  22. compatibility/assets/js/wcml-bookings.js +0 -96
  23. compatibility/class-wcml-accommodation-bookings.php +170 -170
  24. compatibility/class-wcml-adventure-tours.php +365 -0
  25. compatibility/class-wcml-ajax-layered-nav-widget.php +38 -38
  26. compatibility/class-wcml-bookings.php +1911 -1881
  27. compatibility/class-wcml-bulk-stock-management.php +45 -45
  28. compatibility/class-wcml-checkout-addons.php +20 -20
  29. compatibility/class-wcml-checkout-field-editor.php +125 -125
  30. compatibility/class-wcml-compatibility-helper.php +18 -18
  31. compatibility/class-wcml-composite-products.php +342 -319
  32. compatibility/class-wcml-dynamic-pricing.php +81 -95
  33. compatibility/class-wcml-extra-product-options.php +107 -122
  34. compatibility/class-wcml-flatsome.php +16 -16
  35. compatibility/class-wcml-gravityforms.php +47 -47
  36. compatibility/class-wcml-mix-and-match-products.php +67 -78
  37. compatibility/class-wcml-per-product-shipping.php +30 -30
  38. compatibility/class-wcml-product-addons.php +175 -76
  39. compatibility/class-wcml-product-bundles.php +364 -345
  40. compatibility/class-wcml-sensei.php +231 -231
  41. compatibility/class-wcml-tab-manager.php +535 -516
  42. compatibility/class-wcml-table-rate-shipping.php +65 -66
  43. compatibility/class-wcml-variation-swatches-and-photos.php +62 -62
  44. compatibility/class-wcml-wc-name-your-price.php +24 -24
  45. compatibility/class-wcml-wc-subscriptions.php +185 -65
  46. compatibility/class-wcml-wcexporter.php +70 -70
  47. compatibility/class-wcml-wpseo.php +41 -0
  48. compatibility/{assets → res}/css/wcml-bookings.css +59 -52
  49. compatibility/res/js/wcml-adventure-tours.js +31 -0
  50. compatibility/res/js/wcml-bookings.js +85 -0
  51. compatibility/templates/bundles_box.php +0 -61
  52. compatibility/templates/wc_bookings_custom_box_html.php +0 -30
  53. compatibility/templates/wc_tab_manager_custom_box_html.php +0 -60
  54. compatibility/templates/woocommerce-composite-products.php +0 -35
  55. embedded/installer/changelog.txt +133 -0
  56. embedded/installer/composer.json +31 -0
  57. embedded/installer/includes/class-installer-dependencies.php +278 -0
  58. embedded/installer/includes/class-installer-theme.php +979 -0
  59. embedded/installer/includes/installer-api.php +81 -0
  60. embedded/installer/includes/installer-upgrader-skins.php +37 -0
  61. embedded/installer/includes/installer.class.php +2559 -0
  62. embedded/installer/includes/translation-service-info.class.php +35 -0
  63. embedded/installer/installer.php +22 -0
  64. embedded/installer/loader.php +151 -0
  65. embedded/installer/locale/installer-ar.mo +0 -0
  66. embedded/installer/locale/installer-de_DE.mo +0 -0
  67. embedded/installer/locale/installer-el.mo +0 -0
  68. embedded/installer/locale/installer-es_ES.mo +0 -0
  69. embedded/installer/locale/installer-fr_FR.mo +0 -0
  70. embedded/installer/locale/installer-he_IL.mo +0 -0
  71. embedded/installer/locale/installer-it_IT.mo +0 -0
  72. embedded/installer/locale/installer-ja.mo +0 -0
  73. embedded/installer/locale/installer-ko_KR.mo +0 -0
  74. embedded/installer/locale/installer-nl_NL.mo +0 -0
  75. embedded/installer/locale/installer-pl_PL.mo +0 -0
  76. embedded/installer/locale/installer-pt_BR.mo +0 -0
  77. embedded/installer/locale/installer-pt_PT.mo +0 -0
  78. embedded/installer/locale/installer-ru_RU.mo +0 -0
  79. embedded/installer/locale/installer-sv_SE.mo +0 -0
  80. embedded/installer/locale/installer-uk_UA.mo +0 -0
  81. embedded/installer/locale/installer-vi.mo +0 -0
  82. embedded/installer/locale/installer-zh_CN.mo +0 -0
  83. embedded/installer/locale/installer-zh_TW.mo +0 -0
  84. embedded/installer/locale/orig/installer.po +230 -0
  85. embedded/installer/repositories.xml +13 -0
  86. embedded/installer/res/css/admin.css +186 -0
  87. embedded/installer/res/img/complete.png +0 -0
  88. embedded/installer/res/img/computer.png +0 -0
  89. embedded/installer/res/img/dn.gif +0 -0
  90. embedded/installer/res/img/dn2.gif +0 -0
  91. embedded/installer/res/img/globe.png +0 -0
  92. embedded/installer/res/img/icon_error.gif +0 -0
  93. embedded/installer/res/img/on.png +0 -0
  94. embedded/installer/res/img/spinner.gif +0 -0
  95. embedded/installer/res/js/admin.js +403 -0
  96. embedded/installer/res/js/iframeResizer.min.js +10 -0
  97. embedded/installer/res/js/installer_theme_install.js +97 -0
  98. embedded/installer/templates/downloads-list-compact.php +80 -0
  99. embedded/installer/templates/downloads-list.php +85 -0
  100. embedded/installer/templates/products-compact.php +129 -0
  101. embedded/installer/templates/repository-listing.php +179 -0
  102. inc/admin-menus/class-wcml-admin-menus.php +244 -0
  103. inc/admin-menus/class-wcml-links.php +25 -0
  104. inc/admin-menus/class-wcml-setup.php +332 -0
  105. inc/{ajax-setup.class.php → class-wcml-ajax-setup.php} +119 -119
  106. inc/class-wcml-attributes.php +358 -0
assets/css/currency-switcher.css DELETED
@@ -1,41 +0,0 @@
1
- ul.wcml_currency_switcher{
2
- padding: 0 !important;
3
- margin: 0 !important;
4
- list-style-type: none !important;
5
- position: relative;
6
- }
7
-
8
- ul.wcml_currency_switcher li{
9
- cursor: pointer;
10
- border: 1px solid #cdcdcd;
11
- }
12
-
13
- .wcml-active-currency{
14
- background-color: #E5E5E5;
15
- }
16
-
17
- ul.wcml_currency_switcher.curr_list_vertical{
18
- border-top: 1px solid #cdcdcd;
19
- display: inline-block;
20
- }
21
-
22
- ul.wcml_currency_switcher.curr_list_horizontal li{
23
- float: left;
24
- position: relative;
25
- padding: 2px 5px;
26
- margin-left: 1px;
27
- }
28
- ul.wcml_currency_switcher.curr_list_horizontal li:first-child{
29
- margin-left: 0;
30
- }
31
-
32
- ul.wcml_currency_switcher.curr_list_vertical li{
33
- border-top-width: 0;
34
- padding-left: 10px;
35
- cursor: pointer;
36
- }
37
-
38
- ul.wcml_currency_switcher.curr_list_vertical li{
39
- padding: 3px 10px;
40
- margin: 0;
41
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/css/font-awesome.min.css DELETED
@@ -1,403 +0,0 @@
1
- @font-face{font-family:'FontAwesome';src:url('../font/fontawesome-webfont.eot?v=3.2.1');src:url('../font/fontawesome-webfont.eot?#iefix&v=3.2.1') format('embedded-opentype'),url('../font/fontawesome-webfont.woff?v=3.2.1') format('woff'),url('../font/fontawesome-webfont.ttf?v=3.2.1') format('truetype'),url('../font/fontawesome-webfont.svg#fontawesomeregular?v=3.2.1') format('svg');font-weight:normal;font-style:normal;}[class^="icon-"],[class*=" icon-"]{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;*margin-right:.3em;}
2
- [class^="icon-"]:before,[class*=" icon-"]:before{text-decoration:inherit;display:inline-block;speak:none;}
3
- .icon-large:before{vertical-align:-10%;font-size:1.3333333333333333em;}
4
- a [class^="icon-"],a [class*=" icon-"]{display:inline;}
5
- [class^="icon-"].icon-fixed-width,[class*=" icon-"].icon-fixed-width{display:inline-block;width:1.1428571428571428em;text-align:right;padding-right:0.2857142857142857em;}[class^="icon-"].icon-fixed-width.icon-large,[class*=" icon-"].icon-fixed-width.icon-large{width:1.4285714285714286em;}
6
- .icons-ul{margin-left:2.142857142857143em;list-style-type:none;}.icons-ul>li{position:relative;}
7
- .icons-ul .icon-li{position:absolute;left:-2.142857142857143em;width:2.142857142857143em;text-align:center;line-height:inherit;}
8
- [class^="icon-"].hide,[class*=" icon-"].hide{display:none;}
9
- .icon-muted{color:#eeeeee;}
10
- .icon-light{color:#ffffff;}
11
- .icon-dark{color:#333333;}
12
- .icon-border{border:solid 1px #eeeeee;padding:.2em .25em .15em;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
13
- .icon-2x{font-size:2em;}.icon-2x.icon-border{border-width:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
14
- .icon-3x{font-size:3em;}.icon-3x.icon-border{border-width:3px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;}
15
- .icon-4x{font-size:4em;}.icon-4x.icon-border{border-width:4px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}
16
- .icon-5x{font-size:5em;}.icon-5x.icon-border{border-width:5px;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px;}
17
- .pull-right{float:right;}
18
- .pull-left{float:left;}
19
- [class^="icon-"].pull-left,[class*=" icon-"].pull-left{margin-right:.3em;}
20
- [class^="icon-"].pull-right,[class*=" icon-"].pull-right{margin-left:.3em;}
21
- [class^="icon-"],[class*=" icon-"]{display:inline;width:auto;height:auto;line-height:normal;vertical-align:baseline;background-image:none;background-position:0% 0%;background-repeat:repeat;margin-top:0;}
22
- .icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"]{background-image:none;}
23
- .btn [class^="icon-"].icon-large,.nav [class^="icon-"].icon-large,.btn [class*=" icon-"].icon-large,.nav [class*=" icon-"].icon-large{line-height:.9em;}
24
- .btn [class^="icon-"].icon-spin,.nav [class^="icon-"].icon-spin,.btn [class*=" icon-"].icon-spin,.nav [class*=" icon-"].icon-spin{display:inline-block;}
25
- .nav-tabs [class^="icon-"],.nav-pills [class^="icon-"],.nav-tabs [class*=" icon-"],.nav-pills [class*=" icon-"],.nav-tabs [class^="icon-"].icon-large,.nav-pills [class^="icon-"].icon-large,.nav-tabs [class*=" icon-"].icon-large,.nav-pills [class*=" icon-"].icon-large{line-height:.9em;}
26
- .btn [class^="icon-"].pull-left.icon-2x,.btn [class*=" icon-"].pull-left.icon-2x,.btn [class^="icon-"].pull-right.icon-2x,.btn [class*=" icon-"].pull-right.icon-2x{margin-top:.18em;}
27
- .btn [class^="icon-"].icon-spin.icon-large,.btn [class*=" icon-"].icon-spin.icon-large{line-height:.8em;}
28
- .btn.btn-small [class^="icon-"].pull-left.icon-2x,.btn.btn-small [class*=" icon-"].pull-left.icon-2x,.btn.btn-small [class^="icon-"].pull-right.icon-2x,.btn.btn-small [class*=" icon-"].pull-right.icon-2x{margin-top:.25em;}
29
- .btn.btn-large [class^="icon-"],.btn.btn-large [class*=" icon-"]{margin-top:0;}.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x,.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-top:.05em;}
30
- .btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x{margin-right:.2em;}
31
- .btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-left:.2em;}
32
- .nav-list [class^="icon-"],.nav-list [class*=" icon-"]{line-height:inherit;}
33
- .icon-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:-35%;}.icon-stack [class^="icon-"],.icon-stack [class*=" icon-"]{display:block;text-align:center;position:absolute;width:100%;height:100%;font-size:1em;line-height:inherit;*line-height:2em;}
34
- .icon-stack .icon-stack-base{font-size:2em;*line-height:1em;}
35
- .icon-spin{display:inline-block;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear;}
36
- a .icon-stack,a .icon-spin{display:inline-block;text-decoration:none;}
37
- @-moz-keyframes spin{0%{-moz-transform:rotate(0deg);} 100%{-moz-transform:rotate(359deg);}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg);} 100%{-webkit-transform:rotate(359deg);}}@-o-keyframes spin{0%{-o-transform:rotate(0deg);} 100%{-o-transform:rotate(359deg);}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg);} 100%{-ms-transform:rotate(359deg);}}@keyframes spin{0%{transform:rotate(0deg);} 100%{transform:rotate(359deg);}}.icon-rotate-90:before{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);}
38
- .icon-rotate-180:before{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);}
39
- .icon-rotate-270:before{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);}
40
- .icon-flip-horizontal:before{-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1);}
41
- .icon-flip-vertical:before{-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1);}
42
- a .icon-rotate-90:before,a .icon-rotate-180:before,a .icon-rotate-270:before,a .icon-flip-horizontal:before,a .icon-flip-vertical:before{display:inline-block;}
43
- .icon-glass:before{content:"\f000";}
44
- .icon-music:before{content:"\f001";}
45
- .icon-search:before{content:"\f002";}
46
- .icon-envelope-alt:before{content:"\f003";}
47
- .icon-heart:before{content:"\f004";}
48
- .icon-star:before{content:"\f005";}
49
- .icon-star-empty:before{content:"\f006";}
50
- .icon-user:before{content:"\f007";}
51
- .icon-film:before{content:"\f008";}
52
- .icon-th-large:before{content:"\f009";}
53
- .icon-th:before{content:"\f00a";}
54
- .icon-th-list:before{content:"\f00b";}
55
- .icon-ok:before{content:"\f00c";}
56
- .icon-remove:before{content:"\f00d";}
57
- .icon-zoom-in:before{content:"\f00e";}
58
- .icon-zoom-out:before{content:"\f010";}
59
- .icon-power-off:before,.icon-off:before{content:"\f011";}
60
- .icon-signal:before{content:"\f012";}
61
- .icon-gear:before,.icon-cog:before{content:"\f013";}
62
- .icon-trash:before{content:"\f014";}
63
- .icon-home:before{content:"\f015";}
64
- .icon-file-alt:before{content:"\f016";}
65
- .icon-time:before{content:"\f017";}
66
- .icon-road:before{content:"\f018";}
67
- .icon-download-alt:before{content:"\f019";}
68
- .icon-download:before{content:"\f01a";}
69
- .icon-upload:before{content:"\f01b";}
70
- .icon-inbox:before{content:"\f01c";}
71
- .icon-play-circle:before{content:"\f01d";}
72
- .icon-rotate-right:before,.icon-repeat:before{content:"\f01e";}
73
- .icon-refresh:before{content:"\f021";}
74
- .icon-list-alt:before{content:"\f022";}
75
- .icon-lock:before{content:"\f023";}
76
- .icon-flag:before{content:"\f024";}
77
- .icon-headphones:before{content:"\f025";}
78
- .icon-volume-off:before{content:"\f026";}
79
- .icon-volume-down:before{content:"\f027";}
80
- .icon-volume-up:before{content:"\f028";}
81
- .icon-qrcode:before{content:"\f029";}
82
- .icon-barcode:before{content:"\f02a";}
83
- .icon-tag:before{content:"\f02b";}
84
- .icon-tags:before{content:"\f02c";}
85
- .icon-book:before{content:"\f02d";}
86
- .icon-bookmark:before{content:"\f02e";}
87
- .icon-print:before{content:"\f02f";}
88
- .icon-camera:before{content:"\f030";}
89
- .icon-font:before{content:"\f031";}
90
- .icon-bold:before{content:"\f032";}
91
- .icon-italic:before{content:"\f033";}
92
- .icon-text-height:before{content:"\f034";}
93
- .icon-text-width:before{content:"\f035";}
94
- .icon-align-left:before{content:"\f036";}
95
- .icon-align-center:before{content:"\f037";}
96
- .icon-align-right:before{content:"\f038";}
97
- .icon-align-justify:before{content:"\f039";}
98
- .icon-list:before{content:"\f03a";}
99
- .icon-indent-left:before{content:"\f03b";}
100
- .icon-indent-right:before{content:"\f03c";}
101
- .icon-facetime-video:before{content:"\f03d";}
102
- .icon-picture:before{content:"\f03e";}
103
- .icon-pencil:before{content:"\f040";}
104
- .icon-map-marker:before{content:"\f041";}
105
- .icon-adjust:before{content:"\f042";}
106
- .icon-tint:before{content:"\f043";}
107
- .icon-edit:before{content:"\f044";}
108
- .icon-share:before{content:"\f045";}
109
- .icon-check:before{content:"\f046";}
110
- .icon-move:before{content:"\f047";}
111
- .icon-step-backward:before{content:"\f048";}
112
- .icon-fast-backward:before{content:"\f049";}
113
- .icon-backward:before{content:"\f04a";}
114
- .icon-play:before{content:"\f04b";}
115
- .icon-pause:before{content:"\f04c";}
116
- .icon-stop:before{content:"\f04d";}
117
- .icon-forward:before{content:"\f04e";}
118
- .icon-fast-forward:before{content:"\f050";}
119
- .icon-step-forward:before{content:"\f051";}
120
- .icon-eject:before{content:"\f052";}
121
- .icon-chevron-left:before{content:"\f053";}
122
- .icon-chevron-right:before{content:"\f054";}
123
- .icon-plus-sign:before{content:"\f055";}
124
- .icon-minus-sign:before{content:"\f056";}
125
- .icon-remove-sign:before{content:"\f057";}
126
- .icon-ok-sign:before{content:"\f058";}
127
- .icon-question-sign:before{content:"\f059";}
128
- .icon-info-sign:before{content:"\f05a";}
129
- .icon-screenshot:before{content:"\f05b";}
130
- .icon-remove-circle:before{content:"\f05c";}
131
- .icon-ok-circle:before{content:"\f05d";}
132
- .icon-ban-circle:before{content:"\f05e";}
133
- .icon-arrow-left:before{content:"\f060";}
134
- .icon-arrow-right:before{content:"\f061";}
135
- .icon-arrow-up:before{content:"\f062";}
136
- .icon-arrow-down:before{content:"\f063";}
137
- .icon-mail-forward:before,.icon-share-alt:before{content:"\f064";}
138
- .icon-resize-full:before{content:"\f065";}
139
- .icon-resize-small:before{content:"\f066";}
140
- .icon-plus:before{content:"\f067";}
141
- .icon-minus:before{content:"\f068";}
142
- .icon-asterisk:before{content:"\f069";}
143
- .icon-exclamation-sign:before{content:"\f06a";}
144
- .icon-gift:before{content:"\f06b";}
145
- .icon-leaf:before{content:"\f06c";}
146
- .icon-fire:before{content:"\f06d";}
147
- .icon-eye-open:before{content:"\f06e";}
148
- .icon-eye-close:before{content:"\f070";}
149
- .icon-warning-sign:before{content:"\f071";}
150
- .icon-plane:before{content:"\f072";}
151
- .icon-calendar:before{content:"\f073";}
152
- .icon-random:before{content:"\f074";}
153
- .icon-comment:before{content:"\f075";}
154
- .icon-magnet:before{content:"\f076";}
155
- .icon-chevron-up:before{content:"\f077";}
156
- .icon-chevron-down:before{content:"\f078";}
157
- .icon-retweet:before{content:"\f079";}
158
- .icon-shopping-cart:before{content:"\f07a";}
159
- .icon-folder-close:before{content:"\f07b";}
160
- .icon-folder-open:before{content:"\f07c";}
161
- .icon-resize-vertical:before{content:"\f07d";}
162
- .icon-resize-horizontal:before{content:"\f07e";}
163
- .icon-bar-chart:before{content:"\f080";}
164
- .icon-twitter-sign:before{content:"\f081";}
165
- .icon-facebook-sign:before{content:"\f082";}
166
- .icon-camera-retro:before{content:"\f083";}
167
- .icon-key:before{content:"\f084";}
168
- .icon-gears:before,.icon-cogs:before{content:"\f085";}
169
- .icon-comments:before{content:"\f086";}
170
- .icon-thumbs-up-alt:before{content:"\f087";}
171
- .icon-thumbs-down-alt:before{content:"\f088";}
172
- .icon-star-half:before{content:"\f089";}
173
- .icon-heart-empty:before{content:"\f08a";}
174
- .icon-signout:before{content:"\f08b";}
175
- .icon-linkedin-sign:before{content:"\f08c";}
176
- .icon-pushpin:before{content:"\f08d";}
177
- .icon-external-link:before{content:"\f08e";}
178
- .icon-signin:before{content:"\f090";}
179
- .icon-trophy:before{content:"\f091";}
180
- .icon-github-sign:before{content:"\f092";}
181
- .icon-upload-alt:before{content:"\f093";}
182
- .icon-lemon:before{content:"\f094";}
183
- .icon-phone:before{content:"\f095";}
184
- .icon-unchecked:before,.icon-check-empty:before{content:"\f096";}
185
- .icon-bookmark-empty:before{content:"\f097";}
186
- .icon-phone-sign:before{content:"\f098";}
187
- .icon-twitter:before{content:"\f099";}
188
- .icon-facebook:before{content:"\f09a";}
189
- .icon-github:before{content:"\f09b";}
190
- .icon-unlock:before{content:"\f09c";}
191
- .icon-credit-card:before{content:"\f09d";}
192
- .icon-rss:before{content:"\f09e";}
193
- .icon-hdd:before{content:"\f0a0";}
194
- .icon-bullhorn:before{content:"\f0a1";}
195
- .icon-bell:before{content:"\f0a2";}
196
- .icon-certificate:before{content:"\f0a3";}
197
- .icon-hand-right:before{content:"\f0a4";}
198
- .icon-hand-left:before{content:"\f0a5";}
199
- .icon-hand-up:before{content:"\f0a6";}
200
- .icon-hand-down:before{content:"\f0a7";}
201
- .icon-circle-arrow-left:before{content:"\f0a8";}
202
- .icon-circle-arrow-right:before{content:"\f0a9";}
203
- .icon-circle-arrow-up:before{content:"\f0aa";}
204
- .icon-circle-arrow-down:before{content:"\f0ab";}
205
- .icon-globe:before{content:"\f0ac";}
206
- .icon-wrench:before{content:"\f0ad";}
207
- .icon-tasks:before{content:"\f0ae";}
208
- .icon-filter:before{content:"\f0b0";}
209
- .icon-briefcase:before{content:"\f0b1";}
210
- .icon-fullscreen:before{content:"\f0b2";}
211
- .icon-group:before{content:"\f0c0";}
212
- .icon-link:before{content:"\f0c1";}
213
- .icon-cloud:before{content:"\f0c2";}
214
- .icon-beaker:before{content:"\f0c3";}
215
- .icon-cut:before{content:"\f0c4";}
216
- .icon-copy:before{content:"\f0c5";}
217
- .icon-paperclip:before,.icon-paper-clip:before{content:"\f0c6";}
218
- .icon-save:before{content:"\f0c7";}
219
- .icon-sign-blank:before{content:"\f0c8";}
220
- .icon-reorder:before{content:"\f0c9";}
221
- .icon-list-ul:before{content:"\f0ca";}
222
- .icon-list-ol:before{content:"\f0cb";}
223
- .icon-strikethrough:before{content:"\f0cc";}
224
- .icon-underline:before{content:"\f0cd";}
225
- .icon-table:before{content:"\f0ce";}
226
- .icon-magic:before{content:"\f0d0";}
227
- .icon-truck:before{content:"\f0d1";}
228
- .icon-pinterest:before{content:"\f0d2";}
229
- .icon-pinterest-sign:before{content:"\f0d3";}
230
- .icon-google-plus-sign:before{content:"\f0d4";}
231
- .icon-google-plus:before{content:"\f0d5";}
232
- .icon-money:before{content:"\f0d6";}
233
- .icon-caret-down:before{content:"\f0d7";}
234
- .icon-caret-up:before{content:"\f0d8";}
235
- .icon-caret-left:before{content:"\f0d9";}
236
- .icon-caret-right:before{content:"\f0da";}
237
- .icon-columns:before{content:"\f0db";}
238
- .icon-sort:before{content:"\f0dc";}
239
- .icon-sort-down:before{content:"\f0dd";}
240
- .icon-sort-up:before{content:"\f0de";}
241
- .icon-envelope:before{content:"\f0e0";}
242
- .icon-linkedin:before{content:"\f0e1";}
243
- .icon-rotate-left:before,.icon-undo:before{content:"\f0e2";}
244
- .icon-legal:before{content:"\f0e3";}
245
- .icon-dashboard:before{content:"\f0e4";}
246
- .icon-comment-alt:before{content:"\f0e5";}
247
- .icon-comments-alt:before{content:"\f0e6";}
248
- .icon-bolt:before{content:"\f0e7";}
249
- .icon-sitemap:before{content:"\f0e8";}
250
- .icon-umbrella:before{content:"\f0e9";}
251
- .icon-paste:before{content:"\f0ea";}
252
- .icon-lightbulb:before{content:"\f0eb";}
253
- .icon-exchange:before{content:"\f0ec";}
254
- .icon-cloud-download:before{content:"\f0ed";}
255
- .icon-cloud-upload:before{content:"\f0ee";}
256
- .icon-user-md:before{content:"\f0f0";}
257
- .icon-stethoscope:before{content:"\f0f1";}
258
- .icon-suitcase:before{content:"\f0f2";}
259
- .icon-bell-alt:before{content:"\f0f3";}
260
- .icon-coffee:before{content:"\f0f4";}
261
- .icon-food:before{content:"\f0f5";}
262
- .icon-file-text-alt:before{content:"\f0f6";}
263
- .icon-building:before{content:"\f0f7";}
264
- .icon-hospital:before{content:"\f0f8";}
265
- .icon-ambulance:before{content:"\f0f9";}
266
- .icon-medkit:before{content:"\f0fa";}
267
- .icon-fighter-jet:before{content:"\f0fb";}
268
- .icon-beer:before{content:"\f0fc";}
269
- .icon-h-sign:before{content:"\f0fd";}
270
- .icon-plus-sign-alt:before{content:"\f0fe";}
271
- .icon-double-angle-left:before{content:"\f100";}
272
- .icon-double-angle-right:before{content:"\f101";}
273
- .icon-double-angle-up:before{content:"\f102";}
274
- .icon-double-angle-down:before{content:"\f103";}
275
- .icon-angle-left:before{content:"\f104";}
276
- .icon-angle-right:before{content:"\f105";}
277
- .icon-angle-up:before{content:"\f106";}
278
- .icon-angle-down:before{content:"\f107";}
279
- .icon-desktop:before{content:"\f108";}
280
- .icon-laptop:before{content:"\f109";}
281
- .icon-tablet:before{content:"\f10a";}
282
- .icon-mobile-phone:before{content:"\f10b";}
283
- .icon-circle-blank:before{content:"\f10c";}
284
- .icon-quote-left:before{content:"\f10d";}
285
- .icon-quote-right:before{content:"\f10e";}
286
- .icon-spinner:before{content:"\f110";}
287
- .icon-circle:before{content:"\f111";}
288
- .icon-mail-reply:before,.icon-reply:before{content:"\f112";}
289
- .icon-github-alt:before{content:"\f113";}
290
- .icon-folder-close-alt:before{content:"\f114";}
291
- .icon-folder-open-alt:before{content:"\f115";}
292
- .icon-expand-alt:before{content:"\f116";}
293
- .icon-collapse-alt:before{content:"\f117";}
294
- .icon-smile:before{content:"\f118";}
295
- .icon-frown:before{content:"\f119";}
296
- .icon-meh:before{content:"\f11a";}
297
- .icon-gamepad:before{content:"\f11b";}
298
- .icon-keyboard:before{content:"\f11c";}
299
- .icon-flag-alt:before{content:"\f11d";}
300
- .icon-flag-checkered:before{content:"\f11e";}
301
- .icon-terminal:before{content:"\f120";}
302
- .icon-code:before{content:"\f121";}
303
- .icon-reply-all:before{content:"\f122";}
304
- .icon-mail-reply-all:before{content:"\f122";}
305
- .icon-star-half-full:before,.icon-star-half-empty:before{content:"\f123";}
306
- .icon-location-arrow:before{content:"\f124";}
307
- .icon-crop:before{content:"\f125";}
308
- .icon-code-fork:before{content:"\f126";}
309
- .icon-unlink:before{content:"\f127";}
310
- .icon-question:before{content:"\f128";}
311
- .icon-info:before{content:"\f129";}
312
- .icon-exclamation:before{content:"\f12a";}
313
- .icon-superscript:before{content:"\f12b";}
314
- .icon-subscript:before{content:"\f12c";}
315
- .icon-eraser:before{content:"\f12d";}
316
- .icon-puzzle-piece:before{content:"\f12e";}
317
- .icon-microphone:before{content:"\f130";}
318
- .icon-microphone-off:before{content:"\f131";}
319
- .icon-shield:before{content:"\f132";}
320
- .icon-calendar-empty:before{content:"\f133";}
321
- .icon-fire-extinguisher:before{content:"\f134";}
322
- .icon-rocket:before{content:"\f135";}
323
- .icon-maxcdn:before{content:"\f136";}
324
- .icon-chevron-sign-left:before{content:"\f137";}
325
- .icon-chevron-sign-right:before{content:"\f138";}
326
- .icon-chevron-sign-up:before{content:"\f139";}
327
- .icon-chevron-sign-down:before{content:"\f13a";}
328
- .icon-html5:before{content:"\f13b";}
329
- .icon-css3:before{content:"\f13c";}
330
- .icon-anchor:before{content:"\f13d";}
331
- .icon-unlock-alt:before{content:"\f13e";}
332
- .icon-bullseye:before{content:"\f140";}
333
- .icon-ellipsis-horizontal:before{content:"\f141";}
334
- .icon-ellipsis-vertical:before{content:"\f142";}
335
- .icon-rss-sign:before{content:"\f143";}
336
- .icon-play-sign:before{content:"\f144";}
337
- .icon-ticket:before{content:"\f145";}
338
- .icon-minus-sign-alt:before{content:"\f146";}
339
- .icon-check-minus:before{content:"\f147";}
340
- .icon-level-up:before{content:"\f148";}
341
- .icon-level-down:before{content:"\f149";}
342
- .icon-check-sign:before{content:"\f14a";}
343
- .icon-edit-sign:before{content:"\f14b";}
344
- .icon-external-link-sign:before{content:"\f14c";}
345
- .icon-share-sign:before{content:"\f14d";}
346
- .icon-compass:before{content:"\f14e";}
347
- .icon-collapse:before{content:"\f150";}
348
- .icon-collapse-top:before{content:"\f151";}
349
- .icon-expand:before{content:"\f152";}
350
- .icon-euro:before,.icon-eur:before{content:"\f153";}
351
- .icon-gbp:before{content:"\f154";}
352
- .icon-dollar:before,.icon-usd:before{content:"\f155";}
353
- .icon-rupee:before,.icon-inr:before{content:"\f156";}
354
- .icon-yen:before,.icon-jpy:before{content:"\f157";}
355
- .icon-renminbi:before,.icon-cny:before{content:"\f158";}
356
- .icon-won:before,.icon-krw:before{content:"\f159";}
357
- .icon-bitcoin:before,.icon-btc:before{content:"\f15a";}
358
- .icon-file:before{content:"\f15b";}
359
- .icon-file-text:before{content:"\f15c";}
360
- .icon-sort-by-alphabet:before{content:"\f15d";}
361
- .icon-sort-by-alphabet-alt:before{content:"\f15e";}
362
- .icon-sort-by-attributes:before{content:"\f160";}
363
- .icon-sort-by-attributes-alt:before{content:"\f161";}
364
- .icon-sort-by-order:before{content:"\f162";}
365
- .icon-sort-by-order-alt:before{content:"\f163";}
366
- .icon-thumbs-up:before{content:"\f164";}
367
- .icon-thumbs-down:before{content:"\f165";}
368
- .icon-youtube-sign:before{content:"\f166";}
369
- .icon-youtube:before{content:"\f167";}
370
- .icon-xing:before{content:"\f168";}
371
- .icon-xing-sign:before{content:"\f169";}
372
- .icon-youtube-play:before{content:"\f16a";}
373
- .icon-dropbox:before{content:"\f16b";}
374
- .icon-stackexchange:before{content:"\f16c";}
375
- .icon-instagram:before{content:"\f16d";}
376
- .icon-flickr:before{content:"\f16e";}
377
- .icon-adn:before{content:"\f170";}
378
- .icon-bitbucket:before{content:"\f171";}
379
- .icon-bitbucket-sign:before{content:"\f172";}
380
- .icon-tumblr:before{content:"\f173";}
381
- .icon-tumblr-sign:before{content:"\f174";}
382
- .icon-long-arrow-down:before{content:"\f175";}
383
- .icon-long-arrow-up:before{content:"\f176";}
384
- .icon-long-arrow-left:before{content:"\f177";}
385
- .icon-long-arrow-right:before{content:"\f178";}
386
- .icon-apple:before{content:"\f179";}
387
- .icon-windows:before{content:"\f17a";}
388
- .icon-android:before{content:"\f17b";}
389
- .icon-linux:before{content:"\f17c";}
390
- .icon-dribbble:before{content:"\f17d";}
391
- .icon-skype:before{content:"\f17e";}
392
- .icon-foursquare:before{content:"\f180";}
393
- .icon-trello:before{content:"\f181";}
394
- .icon-female:before{content:"\f182";}
395
- .icon-male:before{content:"\f183";}
396
- .icon-gittip:before{content:"\f184";}
397
- .icon-sun:before{content:"\f185";}
398
- .icon-moon:before{content:"\f186";}
399
- .icon-archive:before{content:"\f187";}
400
- .icon-bug:before{content:"\f188";}
401
- .icon-vk:before{content:"\f189";}
402
- .icon-weibo:before{content:"\f18a";}
403
- .icon-renren:before{content:"\f18b";}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/css/jquery.cleditor.css DELETED
@@ -1,24 +0,0 @@
1
- .cleditorMain {border:1px solid #999; padding:0 1px 1px; background-color:white; width:auto; height:auto}
2
- .cleditorMain iframe {border:none; margin:0; padding:0}
3
- .cleditorMain textarea {border:none; margin:0; padding:0; overflow-y:scroll; font:10pt Arial,Verdana; resize:none; outline:none /* webkit grip focus */}
4
- .cleditorToolbar {background: url('../images/toolbar.gif') repeat}
5
- .cleditorGroup {float:left; height:26px}
6
- .cleditorButton {float:left; width:24px; height:24px; margin:1px 0 1px 0; background: url('../images/buttons.gif')}
7
- .cleditorDisabled {opacity:0.3; filter:alpha(opacity=30)}
8
- .cleditorDivider {float:left; width:1px; height:23px; margin:1px 0 1px 0; background:#CCC}
9
- .cleditorPopup {border:solid 1px #999; background-color:white; color:#333333; position:absolute; font:10pt Arial,Verdana; cursor:default; z-index:10000}
10
- .cleditorList div {padding:2px 4px 2px 4px}
11
- .cleditorList p,
12
- .cleditorList h1,
13
- .cleditorList h2,
14
- .cleditorList h3,
15
- .cleditorList h4,
16
- .cleditorList h5,
17
- .cleditorList h6,
18
- .cleditorList font {padding:0; margin:0; background-color:Transparent}
19
- .cleditorColor {width:150px; padding:1px 0 0 1px}
20
- .cleditorColor div {float:left; width:14px; height:14px; margin:0 1px 1px 0}
21
- .cleditorPrompt {background-color:#F6F7F9; padding:4px; font-size:8.5pt}
22
- .cleditorPrompt input,
23
- .cleditorPrompt textarea {font:8.5pt Arial,Verdana;}
24
- .cleditorMsg {background-color:#FDFCEE; width:150px; padding:4px; font-size:8.5pt}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/css/management.css DELETED
@@ -1,983 +0,0 @@
1
- .wrap h2{
2
- margin-bottom: 20px;
3
- }
4
- #add_currency label {
5
- width: 170px;
6
- float: left;
7
- }
8
-
9
- .manage_table_th_width {
10
- width: 250px;
11
- }
12
-
13
- .lang_selector_width {
14
- width: 195px;
15
- }
16
-
17
- .flag_img {
18
- margin-right: 5px;
19
- }
20
-
21
- #add_currency label.wcml-error {
22
- display: block;
23
- background: #ffd2d2;
24
- padding: 0 10px;
25
- margin-top: 2px;
26
- margin-right: 43.5%;
27
- float: right;
28
- }
29
-
30
- .none{
31
- display: none;
32
- }
33
- .wcml_wrap .icon-ok{
34
- color: #51a351;
35
- }
36
- .wcml_wrap .icon-refresh {
37
- color: #3a87ad;
38
- }
39
-
40
- .wcml_wrap .icon-warning-sign,
41
- .wcml_trblsh .icon-warning-sign{
42
- color:#9d261d;
43
- }
44
-
45
- .wcml_wrap .icon-ok,
46
- .wcml_wrap .icon-warning-sign,
47
- .wcml_trblsh .icon-warning-sign {
48
- position: relative;
49
- top: 2px;
50
- margin: 0 4px;
51
- font-size: 16px;
52
- vertical-align: baseline;
53
- }
54
-
55
- .wcml_wrap {
56
- border: 1px solid #CCCCCC;
57
- padding:10px;
58
- background-color:#ffffff;
59
- margin-bottom: 20px;
60
- min-width: 900px;
61
- }
62
-
63
- .wcml_miss_lang{
64
- border: 1px solid #CCCCCC;
65
- padding:10px;
66
- background-color:#efefef;
67
- width: 350px;
68
- margin-left: 20px;
69
- margin-bottom: 20px;
70
- display: inline-block;
71
- }
72
- .wcml_miss_lang span,.wcml_miss_lang i{
73
- display: inline-block;
74
- }
75
- .wp-core-ui .wcml_miss_lang .button{
76
- margin-left: 25px;
77
- margin-top: 10px;
78
- }
79
- .wcml_miss_lang i{
80
- vertical-align: top;
81
- }
82
- .wcmp_lang_hide{
83
- cursor: pointer;
84
- float: right;
85
- width: 100%;
86
- text-align: right;
87
- text-decoration: underline;
88
- }
89
-
90
- .wcml-section {
91
- clear: both;
92
- padding: 0 0 10px 0;
93
- margin: 0 0 30px 0;
94
- border-bottom: 1px solid #ededed;
95
- width: 900px;
96
- overflow: hidden;
97
- }
98
- .wcml-section-content .wcml-section-content-inner{
99
- margin: 0 0 20px 0;
100
- padding: 0 0 10px 0;
101
- border-bottom: 1px solid #ededed;
102
- float: left;
103
- width: 100%;
104
- }
105
- .wcml-section:last-child {
106
- border: none;
107
- margin: 0;
108
- }
109
-
110
- .wcml-section-header {
111
- width: 300px;
112
- float: left;
113
- }
114
-
115
- .wcml-section-header h3 {
116
- color: #333;
117
- font-weight: normal;
118
- font-size: 20px;
119
- }
120
-
121
-
122
- .wcml-section-content {
123
- float: left;
124
- width: 570px;
125
- margin-left: 30px;
126
- }
127
-
128
- .wcml_products {
129
- margin: 20px 0;
130
- position: relative;
131
- }
132
-
133
- .clr{
134
- clear: both;
135
- }
136
- .wcml_product_actions{}
137
- .wcml_send_to_trnsl{
138
- float: right;
139
- border: none;
140
- background-color: #FFF;
141
- padding: 0;
142
- text-decoration: underline;
143
- color: #21759b;
144
- cursor: pointer;
145
- }
146
- .wcml_send_to_trnsl:hover{
147
- color: #d54e21;
148
- }
149
- .widefat th .wcml_check_all{
150
- margin: 0;
151
- margin-right: 5px;
152
- }
153
- .wcml_products_translation{
154
- table-layout: fixed;
155
- width: auto;
156
- border: 1px solid #ededed;
157
- border-collapse: collapse;
158
- }
159
-
160
- .wcml_products_translation th {
161
- background: #f9f9f9;
162
- }
163
-
164
- .wcml_products_translation>thead>tr>th:first-child,
165
- .wcml_products_translation>tbody>tr>td:first-child {
166
- border-bottom: 0;
167
- position: absolute;
168
- left: 0;
169
- width: 217px;
170
- }
171
- .wcml_products_translation>tbody>tr{
172
- border-bottom: 1px solid #e1e1e1;
173
- }
174
-
175
- .wcml_products_translation .prod_images,
176
- .wcml_products_translation .prod_variations {
177
- margin: 10px 0;
178
- }
179
-
180
- .wcml_products_translation .missing-translation {
181
- margin: 10px 0 0 0;
182
- }
183
-
184
- .wcml_products_translation .edit-translation-link,
185
- .wcml_products_translation .wcml_update {
186
- margin-left: 5px;
187
- }
188
-
189
- .wcml_products_translation .wcml_update {
190
-
191
- }
192
-
193
- .wcml_products_translation .edit-translation-link i {
194
- display: inline-block;
195
- font-size: 14px;
196
- vertical-align: middle;
197
- }
198
-
199
- .wcml_products_translation textarea {
200
- min-width: 135px;
201
- }
202
-
203
- .wcml_products_translation>tbody>tr>td:first-child{
204
- min-height: 25px;
205
- white-space: nowrap;
206
- vertical-align: middle;
207
- }
208
- .wcml_products_translation>tbody>tr>td span,.wcml_products_translation>tbody>tr>td a{
209
- white-space: nowrap;
210
- }
211
- .wcml_products_translation>tbody>tr>td input[type="checkbox"]{
212
- margin-right: 2px;
213
- }
214
- .wcml_products .outer {
215
- position:relative;
216
- }
217
-
218
- .wcml_product_row .inner {
219
- overflow-x: auto;
220
- overflow-y: visible;
221
- margin-left: 227px;
222
- border: 1px solid #ccc;
223
- }
224
-
225
- .translations_statuses{
226
- float: left;
227
- }
228
- .wcml_wrap .translations_statuses i {
229
- font-size: 16px;
230
- vertical-align: middle;
231
- position: static;
232
- margin: 0;
233
- cursor: default;
234
- width: 20px;
235
- display: inline-block;
236
- }
237
-
238
- .wcml_details{
239
- vertical-align: middle;
240
- line-height: 20px;
241
- }
242
- .trbl_variables_products .spinner,
243
- .wcml_spinner{
244
- margin: 0;
245
- float: none;
246
- }
247
- .wcml_products .spinner{
248
- display: block;
249
- float: left;
250
- margin: 0 5px;
251
- display: none;
252
- visibility: visible;
253
- }
254
- .wcml_cat_block{
255
- display: none;
256
- }
257
- .wcml_tag_remove{
258
- vertical-align: middle;
259
- position: relative;
260
- margin-right: 2px;
261
- display: inline-block;
262
- width: 10px;
263
- height: 10px;
264
- background: transparent url("../images/xit.gif") no-repeat 0 0;
265
- cursor: pointer;
266
- }
267
- .wcml_tag_remove:hover{
268
- background-position:-10px 0;
269
- }
270
- .wcml_tag_search{
271
- float: left;
272
- width: 90px;
273
- }
274
- .wcml_tags{
275
- clear: both;
276
- }
277
- .outer button.button-secondary.wcml_add_new_tag,.outer button.button-secondary.wcml_edit_content{
278
- margin-top: 0px;
279
- }
280
- .wcml_price{
281
- width: 100px;
282
- }
283
- .wcml_single_price{
284
- white-space: nowrap;
285
- }
286
-
287
- .wcml_editor{
288
- display: none;
289
- position: fixed;
290
- top: 30px;
291
- left: 30px;
292
- right: 30px;
293
- bottom: 30px;
294
- z-index: 10000;
295
- background-color: #f1f1f1;
296
- padding: 10px;
297
- padding-top: 35px;
298
- -webkit-border-radius: 3px;
299
- border-radius: 3px;
300
- overflow-y: scroll;
301
- }
302
- .wcml_fade{
303
- display: none;
304
- position: fixed;
305
- top: 0;
306
- left: 0;
307
- right: 0;
308
- bottom: 0;
309
- min-height: 360px;
310
- background: #000;
311
- opacity: .7;
312
- z-index: 9999;
313
- }
314
- .wp-editor-container{
315
- background-color: #fff;
316
- }
317
- .wcml_editor_buttons{
318
- float: left;
319
- width: 100%;
320
- }
321
- .wcml_editor_buttons h3{
322
- float: left;
323
- }
324
- .wcml_editor_buttons .button-secondary{
325
- margin-top: 15px;
326
- }
327
- /* Woocommerce styles*/
328
- .inside {
329
- margin: 0;
330
- padding: 0
331
- }
332
-
333
- .single_product_galery {
334
- padding: 0 0 0 9px;
335
- }
336
-
337
- .product_images_container ul {
338
- overflow: hidden;
339
- margin: 0;
340
- padding: 0
341
- }
342
-
343
- .product_images_container ul li.image,.product_images_container ul li.add, .product_images_container ul li.wc-metabox-sortable-placeholder {
344
- width: 80px;
345
- height: 80px;
346
- overflow: hidden;
347
- float: left;
348
- cursor: move;
349
- border: 1px solid #d5d5d5;
350
- margin: 9px 9px 0 0;
351
- background: #f7f7f7;
352
- -webkit-border-radius: 2px;
353
- -moz-border-radius: 2px;
354
- border-radius: 2px;
355
- position: relative;
356
- -webkit-box-sizing: border-box;
357
- -moz-box-sizing: border-box;
358
- box-sizing: border-box
359
- }
360
-
361
- .product_variations_images ul{
362
- width: 300px;
363
- height: 200px;
364
- overflow-y: auto;
365
- }
366
- .product_variations_images ul li.var_image{
367
- width: 90px;
368
- height: auto;
369
- float: left;
370
- }
371
- .product_variations_images .variation_placeholder{
372
- display: none;
373
- }
374
-
375
- .product_variations_images ul li .upload_image_button{
376
- width: 75px;
377
- height: 75px;
378
- overflow: hidden;
379
- float: left;
380
- border: 1px solid #d5d5d5;
381
- background: #f7f7f7;
382
- -webkit-border-radius: 2px;
383
- -moz-border-radius: 2px;
384
- border-radius: 2px;
385
- position: relative;
386
- -webkit-box-sizing: border-box;
387
- -moz-box-sizing: border-box;
388
- box-sizing: border-box
389
- }
390
-
391
- .product_variations_images .upload_image_button .overlay {
392
- display: none;
393
- width: 75px;
394
- height: 75px;
395
- position: absolute;
396
- top: 0;
397
- left: 0;
398
- margin: 0;
399
- padding: 0;
400
- opacity: .5;
401
- background: #eee url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAXklEQVQYGW2OUQrAMAhDFy8+dnKnwiuh2I+aJulDZebDkfSie1b28Q7EXWrfvSm60RQnkQUC8ja7owpmL6d4GdDZ0cNNHyIhZEj4QYCxze6orsluAh8AnR0xKPR07weXJi8JGd3qqwAAAABJRU5ErkJggg==) no-repeat center center
402
- }
403
-
404
- .product_variations_images .upload_image_button:hover .overlay {
405
- display: block
406
- }
407
- .product_variations_images .upload_image_button.remove .overlay {
408
- background: #eee url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAWElEQVQYGY2OUQ6AMAxCZdm9jSev65K3YKNm+6EFBlVEHDxJJ3Pi0C72xlBNyTs3jU7wEUTTIB51GCp2CL8HLpHEdaOLb/N2dfuq9NT0zOo/M9q6EaImsd/uViMLVuD4KAAAAABJRU5ErkJggg==) no-repeat center center
409
- }
410
-
411
-
412
- .product_images_container ul li.image img,.product_variations_images ul li.var_image img,.product_images_container ul li.add img,.product_images_container ul li.wc-metabox-sortable-placeholder img {
413
- width: 100%;
414
- height: auto;
415
- display: block
416
- }
417
-
418
- .product_images_container ul li.wc-metabox-sortable-placeholder {
419
- border: 4px dashed #ddd;
420
- background: #f7f7f7 url(../images/image_watermark.png) no-repeat center
421
- }
422
-
423
- .product_images_container ul ul.actions {
424
- position: absolute;
425
- top: 0;
426
- right: 0;
427
- padding: 2px;
428
- display: none
429
- }
430
-
431
- .product_images_container ul ul.actions li {
432
- background: #eee;
433
- border: 1px solid #ddd;
434
- -webkit-border-radius: 2px;
435
- -moz-border-radius: 2px;
436
- border-radius: 2px;
437
- padding: 1px;
438
- float: right;
439
- margin: 0 0 0 2px
440
- }
441
-
442
- .product_images_container ul ul.actions li a {
443
- width: 10px;
444
- padding: 10px 0 0 0;
445
- margin: 0;
446
- height: 0;
447
- display: block;
448
- overflow: hidden;
449
- }
450
-
451
- .product_images_container ul ul.actions li a.view {
452
- background: url(../images/image_10.png) no-repeat top left
453
- }
454
-
455
- .product_images_container ul ul.actions li a.delete {
456
- background: url(../images/delete_10.png) no-repeat top left
457
- }
458
-
459
- .product_images_container ul li:hover ul.actions {
460
- display: block
461
- }
462
-
463
- .wcml_popup_ok,.wcml_popup_close,.wcml_popup_cancel{
464
- float: right;
465
- }
466
- .wp-core-ui .button-secondary.wcml_popup_ok{
467
- margin-right: 5px;
468
- }
469
- .wcml_editor_original{
470
- overflow: hidden;
471
- padding-bottom: 10px;
472
- }
473
- .wcml_editor_translation{
474
- overflow: hidden;
475
- margin-top: 15px;
476
- }
477
- .wcml_line{
478
- border-bottom: 1px solid #555;
479
- -moz-box-shadow: 1px 1px 3px #555;
480
- box-shadow: 1px 1px 3px #555;
481
- }
482
- .cleditorButton.cleditorDisabled{
483
- opacity: 1;
484
- }
485
- .stat_img{
486
- margin-right: 5px;
487
- padding: 1px;
488
- text-align: center;
489
- }
490
- .product_thumbnail_block .image img{
491
- cursor: pointer;
492
- }
493
-
494
- /*pagination block*/
495
- .wcml_product_pagination{
496
- float: right;
497
- }
498
- .displaying-num{
499
- margin-right: 10px;
500
- font-size: 12px;
501
- font-style: italic;
502
- color: #777;
503
- font-family: Georgia,"Times New Roman","Bitstream Charter",Times,serif;
504
- }
505
- .wcml_product_pagination a,
506
- .wcml_product_title_block a{
507
- border-color: #e3e3e3;
508
- background: #eee;
509
- -moz-box-shadow: inset 0 1px 0 #fff;
510
- -webkit-box-shadow: inset 0 1px 0 #fff;
511
- box-shadow: inset 0 1px 0 #fff;
512
- text-decoration: none;
513
- padding: 3px 6px;
514
- -webkit-border-radius: 3px;
515
- border-radius: 3px;
516
- border-width: 1px;
517
- border-style: solid;
518
- }
519
- .wcml_product_pagination a.disabled,
520
- .wcml_product_title_block a.disabled{
521
- color: #aaa;
522
- cursor: default;
523
- }
524
-
525
- .wcml_product_title_block h3{
526
- display: inline-block;
527
- margin-right: 20px;
528
- }
529
-
530
- .wcml_product_pagination input{
531
- text-align: center;
532
- border-color: #dfdfdf;
533
- background-color: #fff;
534
- color: #333;
535
- -webkit-border-radius: 3px;
536
- border-radius: 3px;
537
- border-width: 1px;
538
- border-style: solid;
539
- }
540
-
541
- textarea[disabled] {
542
- background-color: #eee;
543
- }
544
-
545
- .wcml_variation_file_paths{
546
- white-space: nowrap;
547
- float: left;
548
- }
549
- .wcml_file_paths_textarea,.wcml_variation_file_paths label,.wcml_file_paths,.custom_attr_label{
550
- float: left;
551
- }
552
- .wcml_file_paths{
553
- clear: both;
554
- }
555
- .wcml_variation_file_paths .wcml_file_paths{
556
- clear: none;
557
- }
558
- .wcml_variation_file_paths textarea{
559
- margin-bottom: 5px;
560
- }
561
- .wcml_variation_file_paths label,.custom_attr_label{
562
- clear: both;
563
- line-height: 24px;
564
- margin-right: 5px;
565
- }
566
-
567
- .button-wrap,
568
- .widefat td .button-wrap {
569
- text-align: right;
570
- margin: 10px 0;
571
- }
572
-
573
- .button-wrap [class^="icon-"] {
574
- margin: 0 5px 0 0;
575
- }
576
-
577
- .wcml_languages_currency{
578
- width: auto;
579
- }
580
- .languages_currencies_table input[type="submit"]{
581
- margin-top: 10px;
582
- }
583
- .wp-core-ui .save_currency,.wp-core-ui .cancel_currency,.currency_code select,.currency_value input{
584
- display: none;
585
- }
586
- .wp-core-ui .save_currency{
587
- color: #51a351;
588
- font-size: 18px;
589
- cursor: pointer;
590
- }
591
- .wp-core-ui .cancel_currency{
592
- color: #9d261d;
593
- font-size: 18px;
594
- cursor: pointer;
595
- }
596
- .wp-core-ui .button-secondary.save_currency{
597
- background: #1e8cbe;
598
- border-color: #0074a2;
599
- -webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,.6);
600
- box-shadow: inset 0 1px 0 rgba(120,200,230,.6);
601
- color: #fff;
602
- }
603
- .currency_value{
604
- float: left;
605
- margin-right: 3px;
606
-
607
- }
608
- .currency_value input[type=text]{
609
- width: 45px;
610
- }
611
- .currency-actions {
612
- text-align: right;
613
- }
614
- .currency_action_update,
615
- .currency_action_delete {
616
- display: inline-block;
617
- }
618
-
619
- .edit-mode .currency_action_update,
620
- .edit-mode .currency_action_delete {
621
- display: block;
622
- margin: 2px 1px;
623
- float: left;
624
- }
625
- .currency_changed,
626
- .currency_value span,
627
- .currency_position span{
628
- font-size: 10px;
629
- font-style: italic;
630
- color: #9A9A9A;
631
- }
632
-
633
- .currency_position{
634
- margin-top:0px;
635
- }
636
-
637
- .wcml_currency_options_popup{
638
- position: absolute;
639
- background: #fff;
640
- background-color: rgba(255, 255, 255, 0.9);
641
- box-shadow: 10px 10px 5px #888888;
642
- border: 1px solid #777;
643
- border-radius: 5px;
644
- z-index: 999;
645
- min-width:400px;
646
- display:none;
647
- margin-left:230px;
648
- }
649
- .currency_code .wcml_currency_options_popup tr{height:auto;}
650
- .currency_code .wcml_currency_options_popup select{display: inline;}
651
-
652
-
653
- .currency_code .code_val{
654
- display: block;
655
- }
656
- .currency-actions button {
657
- margin: 0 0 4px 0;
658
- }
659
-
660
- .currency-actions .spinner {
661
- float: none;
662
- display: inline-block;
663
- vertical-align: middle;
664
- margin: 0 5px 0 0;
665
- }
666
- table.widefat.currency_table{
667
- float: left;
668
- width: 250px;
669
- border-right: none;
670
- }
671
- .currency_table .icon-trash,
672
- .currency_table .icon-edit {
673
- font-size: 16px;
674
- vertical-align: middle;
675
- }
676
-
677
- .currency_table .icon-trash {
678
- color: #d54e21;
679
- }
680
- .currency_table .icon-edit {
681
- color: #333;
682
- }
683
- .prod_images,.prod_variations,.custom_fields_block{
684
- display: none;
685
- }
686
- .prod_images img{
687
- width: 75px;
688
- height: 75px;
689
- }
690
- .prod_images th,.prod_variations th{
691
- text-align: center;
692
- }
693
- .prod_image_show,.prod_image_hide,.prod_variations_show,.prod_variations_hide{
694
- cursor: pointer;
695
- }
696
- .currency_value .wcml-error,
697
- .wcml-error{
698
- font-size: 10px;
699
- color: red;
700
- display: inline-block;
701
- }
702
- .troubleshoot_link_block{
703
- float: right;
704
- }
705
-
706
- .trbl_variables_products{
707
- padding: 10px;
708
- border: 1px solid #8cceea;
709
- background-color: #eff8fc;
710
- -moz-border-radius-bottomleft: 5px;
711
- -moz-border-radius-bottomright: 5px;
712
- -moz-border-radius-topleft: 5px;
713
- -moz-border-radius-topright: 5px;
714
- border-bottom-left-radius: 5px 5px;
715
- border-bottom-right-radius: 5px 5px;
716
- border-top-left-radius: 5px 5px;
717
- border-top-right-radius: 5px 5px;
718
- }
719
- .trbl_variables_products label span{
720
- font-weight: bold;
721
-
722
- }
723
- .wcml_trbl_warning{
724
- padding: 10px;
725
- margin-bottom: 10px;
726
- border: 1px solid #f00;
727
- background-color: #ffb7b7;
728
- -moz-border-radius-bottomleft: 5px;
729
- -moz-border-radius-bottomright: 5px;
730
- -moz-border-radius-topleft: 5px;
731
- -moz-border-radius-topright: 5px;
732
- border-bottom-left-radius: 5px 5px;
733
- border-bottom-right-radius: 5px 5px;
734
- border-top-left-radius: 5px 5px;
735
- border-top-right-radius: 5px 5px;
736
- }
737
- #wcml_sync_variations{
738
- background-color: #21759b;
739
- background-image: -webkit-gradient(linear,left top,left bottom,from(#2a95c5),to(#21759b));
740
- background-image: -webkit-linear-gradient(top,#2a95c5,#21759b);
741
- background-image: -moz-linear-gradient(top,#2a95c5,#21759b);
742
- background-image: -ms-linear-gradient(top,#2a95c5,#21759b);
743
- background-image: -o-linear-gradient(top,#2a95c5,#21759b);
744
- background-image: linear-gradient(to bottom,#2a95c5,#21759b);
745
- border-color: #21759b;
746
- border-bottom-color: #1e6a8d;
747
- -webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,0.5);
748
- box-shadow: inset 0 1px 0 rgba(120,200,230,0.5);
749
- color: #fff;
750
- text-decoration: none;
751
- text-shadow: 0 1px 0 rgba(0,0,0,0.1);
752
- }
753
-
754
- .js-tax-translation li .actions{margin:3px 0 0 27px;}
755
-
756
- .wcml_duplicate_product_notice td{border-bottom: none !important;}
757
-
758
- /* Icons */
759
- .wcml_products [class^="icon-woo"] {
760
- width: 24px;
761
- height: 24px;
762
- background-position: center center;
763
- display: inline-block;
764
- }
765
- .wcml_products .icon-woo-simple { background-image: url('../images/icon-woo-simple.png'); }
766
- .wcml_products .icon-woo-downloadable { background-image: url('../images/icon-woo-downloadable.png'); }
767
- .wcml_products .icon-woo-external { background-image: url('../images/icon-woo-external.png'); }
768
- .wcml_products .icon-woo-grouped { background-image: url('../images/icon-woo-grouped.png'); }
769
- .wcml_products .icon-woo-variable { background-image: url('../images/icon-woo-variable.png'); }
770
- .wcml_products .icon-woo-virtual { background-image: url('../images/icon-woo-virtual.png'); }
771
- .wcml_products .children_icon{ margin-left: 20px }
772
- /* Icons END */
773
-
774
- .wcml_product_status_text,.prod_parent_text {
775
- font-style: italic;
776
- color: #9A9A9A;
777
- }
778
- .wcml_no_found_text{
779
- text-align: center;
780
- }
781
- #multi-currency-per-language-details{
782
- float: left;
783
- width: 100%;
784
- }
785
- /* on/off buttons */
786
- .currency_languages{
787
- position: relative;
788
- text-align: center;
789
- }
790
- .currency_languages ul{
791
- list-style:none;
792
- width:43px;
793
- height:20px;
794
- float: left;
795
- display: block;
796
- margin: 0;
797
- }
798
- .currency_languages .wcml_onof_buttons{
799
- display: inline-block;
800
- }
801
- .currency_languages ul li{
802
- float: left;
803
- line-height: 16px;
804
- font-size: 8px;
805
- padding: 1px 3px 0;
806
- background: #E5E5E5;
807
- background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#F3F3F3), to(#E5E5E5));
808
- text-shadow: 0 1px 0 #FFF;
809
- border-left: 1px solid #D5D5D5;
810
- border-top: 1px solid #D5D5D5;
811
- border-bottom: 1px solid #D5D5D5;
812
- -webkit-box-shadow: 0 1px 0 #FFF inset, 0 0 5px rgba(0, 0, 0, .1) inset, 0 1px 1px rgba(0, 0, 0, .3);
813
- margin: 0;
814
- }
815
-
816
- .currency_languages ul li:first-child{
817
- -webkit-border-radius:5px 0 0 5px;
818
- }
819
- .currency_languages ul li:last-child{
820
- -webkit-border-radius:0 5px 5px 0;
821
- }
822
-
823
- .currency_languages ul li a{
824
- text-decoration: none;
825
- font-family:Helvetica, Arial;
826
- text-transform:uppercase;
827
- color:#a1a1a1;
828
- }
829
-
830
- .currency_languages .on{
831
- background: #21759b;
832
- background-image:-webkit-gradient(linear, 0% 0%, 0% 100%, from(#21759b), to(#21759b));
833
- text-shadow:0 -1px 0 #21759b, 0 0 7px #FFF;
834
- border-right:1px solid #21759b;
835
- border-top:1px solid #21759b;
836
- border-bottom:1px solid #21759b;
837
- -webkit-box-shadow:0 1px 2px rgba(0, 0, 0, .7) inset, 0 1px 0 #21759b;
838
- }
839
-
840
- .currency_languages ul li:not(.on):active{
841
- background-image:-webkit-gradient(linear, 0% 0%, 0% 100%, from(#ddd), to(#f1f1f1));
842
- }
843
-
844
- table.widefat.currency_lang_table{
845
- border-left: none;
846
- }
847
- .currency_languages ul li.on a{
848
- color:#FFF;
849
- cursor: default;
850
- }
851
- .currency_lang_table th{
852
- text-align: center;
853
- }
854
- .currency_wrap{
855
- width: 320px;
856
- float: left;
857
- margin-bottom: 10px;
858
- }
859
- .currency_inner{
860
- overflow-x: auto;
861
- overflow-y: visible;
862
- }
863
- .currency_table tr,
864
- .currency_lang_table tr,
865
- .currency_lang_table tr.default_currency{
866
- height: 64px;
867
- }
868
-
869
- .currency_table tr td{
870
- padding-top: 0;
871
- padding-bottom: 0;
872
- }
873
-
874
- .currency_table td,.currency_lang_table td{
875
- vertical-align: middle;
876
- }
877
- .currency_lang_table.widefat td{
878
- padding-right: 0;
879
- padding-left: 0;
880
- }
881
-
882
- .default_currency select{
883
- font-size: 10px;
884
- height: 24px;
885
- margin: 0;
886
- margin-right: 3px;
887
- }
888
- .default_currency td{
889
- border-top: 1px solid #e5e5e5;
890
- }
891
- .default_currency .cur_label{
892
- display: block;
893
- }
894
- .default_currency .inf_message{
895
- font-size: 10px;
896
- font-style: italic;
897
- color: #9A9A9A;
898
- }
899
- .wcml_add_currency.button-wrap{
900
- margin-top: 0;
901
- float: left;
902
- }
903
-
904
- .currency_table select, .currency_table input{
905
- font-size:10px !important;
906
- padding: 0px;
907
- height: 20px;
908
- line-height:20px;
909
- }
910
-
911
- .ext_rate,
912
- .decimals_number,
913
- .abstract_amount,
914
- .currency_option_input{
915
- width:50px;
916
- }
917
-
918
- /* Currency switcher*/
919
- #wcml_currencies_order{
920
- display: block;
921
- overflow: hidden;
922
- width: 100%;
923
- }
924
-
925
- #wcml_currencies_order li {
926
- float: left;
927
- margin: 0 8px 8px 0;
928
- padding: 2px 8px;
929
- border: 1px solid #DFDFDF;
930
- border-radius: 2px;
931
- background: linear-gradient(to top, #ECECEC, #F9F9F9) repeat scroll 0 0 #F1F1F1;
932
- cursor: move;
933
- }
934
- .wcml_currencies_order_ajx_resp{
935
- padding-top: 5px;
936
- color: #E68A00;
937
- }
938
- .explanation-text {
939
- color: #999;
940
- }
941
- input[name="wcml_curr_template"]{
942
- width: 100%;
943
- }
944
- .wcml_curr_style label{
945
- line-height: 30px;
946
- }
947
-
948
- #wcml_curr_sel_preview_wrap{
949
- clear: both;
950
- float: right;
951
- padding: 15px 15px;
952
- border: 1px solid #ccc;
953
- margin-top: 20px;
954
- }
955
- #wcml_curr_sel_preview_wrap p{
956
- margin-top: 0;
957
- }
958
- .wcml_product_name{
959
- line-height: 20px;
960
- }
961
- .wcml_prod_filters{
962
- float: left;
963
- }
964
- .wcml_content_tr{
965
- width: 100%;
966
- }
967
- .wcml_miss_lang p:first-child{
968
- float:left;
969
- }
970
- #display_custom_prices_select{
971
- display: inline-block;
972
- width: 100%;
973
- }
974
- .edit_slug_input,
975
- .edit_slug_hide_link {
976
- display: none;
977
- }
978
-
979
- .wcml-wrap .nav-tab{
980
- float: none;
981
- font-size: 12px;
982
- line-height: 26px;
983
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/css/tooltip.css DELETED
@@ -1,22 +0,0 @@
1
- .wcml-section-header .icon-question-sign,
2
- .wcml-section-content .icon-question-sign,
3
- .wcml_tootlip_icon.icon-question-sign,
4
- th .icon-question-sign{
5
- color: #ccc;
6
- cursor: pointer;
7
- vertical-align: middle;
8
- font-size: 12px;
9
- }
10
-
11
- .wcml-section-header .icon-question-sign:hover,
12
- .wcml_tootlip_icon.icon-question-sign:hover,
13
- .wcml-section-content .icon-question-sign:hover,
14
- th .icon-question-sign:hover{
15
- color: #007cbd;
16
- -webkit-transition: all 0.15s linear;
17
- -moz-transition: all 0.15s linear;
18
- -ms-transition: all 0.15s linear;
19
- -o-transition: all 0.15s linear;
20
- transition: all 0.15s linear;
21
- cursor: help;
22
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/css/wcml-prices.css DELETED
@@ -1,134 +0,0 @@
1
- .wcml_custom_prices_block{
2
- float: left;
3
- margin-top: 10px;
4
- width: 100%;
5
- }
6
- #general_product_data .wcml_custom_prices_block{
7
- padding-left: 10px;
8
- }
9
- .wcml_custom_prices_options_block,
10
- .custom_prices_message_block{
11
- display: inline-block;
12
- width: 100%;
13
- }
14
-
15
- .wcml_custom_prices_manually_block_control{
16
- padding-left:10px;
17
- }
18
-
19
- .wcml_custom_prices_options_block input.wcml_custom_prices_input,
20
- .wc-metaboxes-wrapper .wcml_custom_prices_options_block input.wcml_custom_prices_input,
21
- .wcml_custom_prices_manually_block input.wcml_schedule_input,
22
- .wc-metaboxes-wrapper .wcml_custom_prices_manually_block input.wcml_schedule_input{
23
- width: 16px;
24
- clear: both;
25
- margin: 2px 5px 2px 0;
26
- float: left;
27
- }
28
- .wcml_custom_prices_options_block label,
29
- .wcml_schedule_options label,
30
- .custom_prices_message_block label{
31
- width: auto;
32
- margin: 0;
33
- float: left;
34
- }
35
- .custom_prices_message_block label{
36
- color: #9d261d;
37
- }
38
-
39
- .wc-metaboxes-wrapper .wcml_custom_prices_manually_block .currency_blck>label,
40
- .wc-metaboxes-wrapper .wcml_automaticaly_prices_block label,
41
- .currency_blck,
42
- .wcml_schedule_dates{
43
- clear: both;
44
- }
45
- .wcml_custom_prices_manually_block,
46
- .wcml_automaticaly_prices_block,
47
- .wcml_schedule_dates{
48
- clear: both;
49
- display: none;
50
- padding-left:10px;
51
- }
52
- .wcml_custom_prices_manually_block p,
53
- .wcml_automaticaly_prices_block p{
54
- clear: both;
55
- margin-top: 0;
56
- }
57
- .currency_blck{
58
- float: left;
59
- width: 100%;
60
- margin-bottom: 5px;
61
- border-bottom: 1px solid #dfdfdf;
62
- padding: 5px 0;
63
- }
64
- .currency_blck>label,
65
- .wcml_automaticaly_prices_block>label{
66
- font-weight: bold;
67
- margin-left: 0;
68
- }
69
-
70
- .wcml_schedule_manually_block_hide,
71
- .wcml_custom_prices_auto_block_hide{
72
- display: none;
73
- }
74
-
75
- .wcml_custom_prices_manually_block_show,
76
- .wcml_custom_prices_manually_block_hide{
77
- clear: both;
78
- float: left;
79
- }
80
- .wcml_no_price_message{
81
- font-style: italic;
82
- font-size: 12px;
83
- }
84
- .wcml_schedule{
85
- padding-left: 12px;
86
- clear: both;
87
- float: left;
88
- }
89
- .wcml_schedule_options{
90
- float: left;
91
- }
92
- .wcml_schedule .wcml_schedule_options label,
93
- .woocommerce_variation .wcml_schedule .wcml_schedule_options label{
94
- width: 200px;
95
- }
96
- .woocommerce_options_panel .wcml_schedule_dates input.short{
97
- width: 100px;
98
- }
99
- .wcml_schedule label{
100
- margin: 0;
101
- }
102
- .woocommerce_variation .currency_blck label{
103
- float: left;
104
- display: inline-block;
105
- width: 150px;
106
- }
107
-
108
- .woocommerce_variation .currency_blck p{
109
- padding: 5px 20px 5px 12px;
110
- }
111
-
112
- .woocommerce_variation .currency_blck p input{
113
- width: 50%;
114
- float: left;
115
- display: inline-block;
116
- }
117
-
118
- .woocommerce_variation .wcml_schedule_dates input{
119
- float: left;
120
- }
121
-
122
- .options_group.show_if_downloadable{
123
- clear: both;
124
- }
125
- .wcml_price_error{
126
- display: none;
127
- background: #aa0000;
128
- color: #fff;
129
- font-size: 12px;
130
- font-weight: bold;
131
- margin-left: 5px;
132
- float: left;
133
- padding: 1px 6px;
134
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/font/FontAwesome.otf DELETED
Binary file
assets/font/fontawesome-webfont.eot DELETED
Binary file
assets/font/fontawesome-webfont.svg DELETED
@@ -1,399 +0,0 @@
1
- <?xml version="1.0" standalone="no"?>
2
- <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
3
- <svg xmlns="http://www.w3.org/2000/svg">
4
- <metadata></metadata>
5
- <defs>
6
- <font id="fontawesomeregular" horiz-adv-x="1536" >
7
- <font-face units-per-em="1792" ascent="1536" descent="-256" />
8
- <missing-glyph horiz-adv-x="448" />
9
- <glyph unicode=" " horiz-adv-x="448" />
10
- <glyph unicode="&#x09;" horiz-adv-x="448" />
11
- <glyph unicode="&#xa0;" horiz-adv-x="448" />
12
- <glyph unicode="&#xa8;" horiz-adv-x="1792" />
13
- <glyph unicode="&#xa9;" horiz-adv-x="1792" />
14
- <glyph unicode="&#xae;" horiz-adv-x="1792" />
15
- <glyph unicode="&#xb4;" horiz-adv-x="1792" />
16
- <glyph unicode="&#xc6;" horiz-adv-x="1792" />
17
- <glyph unicode="&#x2000;" horiz-adv-x="768" />
18
- <glyph unicode="&#x2001;" />
19
- <glyph unicode="&#x2002;" horiz-adv-x="768" />
20
- <glyph unicode="&#x2003;" />
21
- <glyph unicode="&#x2004;" horiz-adv-x="512" />
22
- <glyph unicode="&#x2005;" horiz-adv-x="384" />
23
- <glyph unicode="&#x2006;" horiz-adv-x="256" />
24
- <glyph unicode="&#x2007;" horiz-adv-x="256" />
25
- <glyph unicode="&#x2008;" horiz-adv-x="192" />
26
- <glyph unicode="&#x2009;" horiz-adv-x="307" />
27
- <glyph unicode="&#x200a;" horiz-adv-x="85" />
28
- <glyph unicode="&#x202f;" horiz-adv-x="307" />
29
- <glyph unicode="&#x205f;" horiz-adv-x="384" />
30
- <glyph unicode="&#x2122;" horiz-adv-x="1792" />
31
- <glyph unicode="&#x221e;" horiz-adv-x="1792" />
32
- <glyph unicode="&#x2260;" horiz-adv-x="1792" />
33
- <glyph unicode="&#xe000;" horiz-adv-x="500" d="M0 0z" />
34
- <glyph unicode="&#xf000;" horiz-adv-x="1792" d="M1699 1350q0 -35 -43 -78l-632 -632v-768h320q26 0 45 -19t19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45t45 19h320v768l-632 632q-43 43 -43 78q0 23 18 36.5t38 17.5t43 4h1408q23 0 43 -4t38 -17.5t18 -36.5z" />
35
- <glyph unicode="&#xf001;" d="M1536 1312v-1120q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v537l-768 -237v-709q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89 t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v967q0 31 19 56.5t49 35.5l832 256q12 4 28 4q40 0 68 -28t28 -68z" />
36
- <glyph unicode="&#xf002;" horiz-adv-x="1664" d="M1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -52 -38 -90t-90 -38q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5 t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
37
- <glyph unicode="&#xf003;" horiz-adv-x="1792" d="M1664 32v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5t-102.5 -24.5h-1h-1q-48 0 -102.5 24.5t-86.5 48.5t-83 67q-158 132 -426 338q-37 30 -69 66v-768q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1664 1083v11v13.5t-0.5 13 t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5q0 -168 147 -284q193 -152 401 -317q6 -5 35 -29.5t46 -37.5t44.5 -31.5t50.5 -27.5t43 -9h1h1q20 0 43 9t50.5 27.5t44.5 31.5t46 37.5t35 29.5q208 165 401 317q54 43 100.5 115.5t46.5 131.5z M1792 1120v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
38
- <glyph unicode="&#xf004;" horiz-adv-x="1792" d="M896 -128q-26 0 -44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600 q-18 -18 -44 -18z" />
39
- <glyph unicode="&#xf005;" horiz-adv-x="1664" d="M1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -21 -10.5 -35.5t-30.5 -14.5q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455 l502 -73q56 -9 56 -46z" />
40
- <glyph unicode="&#xf006;" horiz-adv-x="1664" d="M1137 532l306 297l-422 62l-189 382l-189 -382l-422 -62l306 -297l-73 -421l378 199l377 -199zM1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -50 -41 -50q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500 l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46z" />
41
- <glyph unicode="&#xf007;" horiz-adv-x="1408" d="M1408 131q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q9 0 42 -21.5t74.5 -48t108 -48t133.5 -21.5t133.5 21.5t108 48t74.5 48t42 21.5q61 0 111.5 -20t85.5 -53.5t62 -81 t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" />
42
- <glyph unicode="&#xf008;" horiz-adv-x="1920" d="M384 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 320v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 704v128q0 26 -19 45t-45 19h-128 q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 -64v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM384 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45 t45 -19h128q26 0 45 19t19 45zM1792 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 704v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1792 320v128 q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 704v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19 t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1920 1248v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
43
- <glyph unicode="&#xf009;" horiz-adv-x="1664" d="M768 512v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM768 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 512v-384q0 -52 -38 -90t-90 -38 h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" />
44
- <glyph unicode="&#xf00a;" horiz-adv-x="1792" d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 288v-192q0 -40 -28 -68t-68 -28h-320 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192 q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68z" />
45
- <glyph unicode="&#xf00b;" horiz-adv-x="1792" d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-960 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 h960q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68z" />
46
- <glyph unicode="&#xf00c;" horiz-adv-x="1792" d="M1671 970q0 -40 -28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68z" />
47
- <glyph unicode="&#xf00d;" horiz-adv-x="1408" d="M1298 214q0 -40 -28 -68l-136 -136q-28 -28 -68 -28t-68 28l-294 294l-294 -294q-28 -28 -68 -28t-68 28l-136 136q-28 28 -28 68t28 68l294 294l-294 294q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -294l294 294q28 28 68 28t68 -28l136 -136q28 -28 28 -68 t-28 -68l-294 -294l294 -294q28 -28 28 -68z" />
48
- <glyph unicode="&#xf00e;" horiz-adv-x="1664" d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-224q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v224h-224q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h224v224q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-224h224 q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5 t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
49
- <glyph unicode="&#xf010;" horiz-adv-x="1664" d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-576q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h576q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5z M1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z " />
50
- <glyph unicode="&#xf011;" d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61t-298 61t-245 164t-164 245t-61 298q0 182 80.5 343t226.5 270q43 32 95.5 25t83.5 -50q32 -42 24.5 -94.5t-49.5 -84.5q-98 -74 -151.5 -181t-53.5 -228q0 -104 40.5 -198.5t109.5 -163.5t163.5 -109.5 t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5q0 121 -53.5 228t-151.5 181q-42 32 -49.5 84.5t24.5 94.5q31 43 84 50t95 -25q146 -109 226.5 -270t80.5 -343zM896 1408v-640q0 -52 -38 -90t-90 -38t-90 38t-38 90v640q0 52 38 90t90 38t90 -38t38 -90z" />
51
- <glyph unicode="&#xf012;" horiz-adv-x="1792" d="M256 96v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 224v-320q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 480v-576q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23 v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1408 864v-960q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1376v-1472q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1472q0 14 9 23t23 9h192q14 0 23 -9t9 -23z" />
52
- <glyph unicode="&#xf013;" d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1536 749v-222q0 -12 -8 -23t-20 -13l-185 -28q-19 -54 -39 -91q35 -50 107 -138q10 -12 10 -25t-9 -23q-27 -37 -99 -108t-94 -71q-12 0 -26 9l-138 108q-44 -23 -91 -38 q-16 -136 -29 -186q-7 -28 -36 -28h-222q-14 0 -24.5 8.5t-11.5 21.5l-28 184q-49 16 -90 37l-141 -107q-10 -9 -25 -9q-14 0 -25 11q-126 114 -165 168q-7 10 -7 23q0 12 8 23q15 21 51 66.5t54 70.5q-27 50 -41 99l-183 27q-13 2 -21 12.5t-8 23.5v222q0 12 8 23t19 13 l186 28q14 46 39 92q-40 57 -107 138q-10 12 -10 24q0 10 9 23q26 36 98.5 107.5t94.5 71.5q13 0 26 -10l138 -107q44 23 91 38q16 136 29 186q7 28 36 28h222q14 0 24.5 -8.5t11.5 -21.5l28 -184q49 -16 90 -37l142 107q9 9 24 9q13 0 25 -10q129 -119 165 -170q7 -8 7 -22 q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5z" />
53
- <glyph unicode="&#xf014;" horiz-adv-x="1408" d="M512 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM768 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1024 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1152 76v948h-896v-948q0 -22 7 -40.5t14.5 -27t10.5 -8.5h832q3 0 10.5 8.5t14.5 27t7 40.5zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832 q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" />
54
- <glyph unicode="&#xf015;" horiz-adv-x="1664" d="M1408 544v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6zM1631 613l-62 -74q-8 -9 -21 -11h-3q-13 0 -21 7l-692 577l-692 -577q-12 -8 -24 -7q-13 2 -21 11l-62 74q-8 10 -7 23.5t11 21.5 l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5z" />
55
- <glyph unicode="&#xf016;" horiz-adv-x="1280" d="M128 0h1024v768h-416q-40 0 -68 28t-28 68v416h-512v-1280zM768 896h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376zM1280 864v-896q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h640q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88z " />
56
- <glyph unicode="&#xf017;" d="M896 992v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
57
- <glyph unicode="&#xf018;" horiz-adv-x="1920" d="M1111 540v4l-24 320q-1 13 -11 22.5t-23 9.5h-186q-13 0 -23 -9.5t-11 -22.5l-24 -320v-4q-1 -12 8 -20t21 -8h244q12 0 21 8t8 20zM1870 73q0 -73 -46 -73h-704q13 0 22 9.5t8 22.5l-20 256q-1 13 -11 22.5t-23 9.5h-272q-13 0 -23 -9.5t-11 -22.5l-20 -256 q-1 -13 8 -22.5t22 -9.5h-704q-46 0 -46 73q0 54 26 116l417 1044q8 19 26 33t38 14h339q-13 0 -23 -9.5t-11 -22.5l-15 -192q-1 -14 8 -23t22 -9h166q13 0 22 9t8 23l-15 192q-1 13 -11 22.5t-23 9.5h339q20 0 38 -14t26 -33l417 -1044q26 -62 26 -116z" />
58
- <glyph unicode="&#xf019;" horiz-adv-x="1664" d="M1280 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 416v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h465l135 -136 q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68zM1339 985q17 -41 -14 -70l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39z" />
59
- <glyph unicode="&#xf01a;" d="M1120 608q0 -12 -10 -24l-319 -319q-11 -9 -23 -9t-23 9l-320 320q-15 16 -7 35q8 20 30 20h192v352q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-352h192q14 0 23 -9t9 -23zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273 t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
60
- <glyph unicode="&#xf01b;" d="M1118 660q-8 -20 -30 -20h-192v-352q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v352h-192q-14 0 -23 9t-9 23q0 12 10 24l319 319q11 9 23 9t23 -9l320 -320q15 -16 7 -35zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198 t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
61
- <glyph unicode="&#xf01c;" d="M1023 576h316q-1 3 -2.5 8t-2.5 8l-212 496h-708l-212 -496q-1 -2 -2.5 -8t-2.5 -8h316l95 -192h320zM1536 546v-482q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v482q0 62 25 123l238 552q10 25 36.5 42t52.5 17h832q26 0 52.5 -17t36.5 -42l238 -552 q25 -61 25 -123z" />
62
- <glyph unicode="&#xf01d;" d="M1184 640q0 -37 -32 -55l-544 -320q-15 -9 -32 -9q-16 0 -32 8q-32 19 -32 56v640q0 37 32 56q33 18 64 -1l544 -320q32 -18 32 -55zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
63
- <glyph unicode="&#xf01e;" d="M1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l138 138q-148 137 -349 137q-104 0 -198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5q119 0 225 52t179 147q7 10 23 12q14 0 25 -9 l137 -138q9 -8 9.5 -20.5t-7.5 -22.5q-109 -132 -264 -204.5t-327 -72.5q-156 0 -298 61t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q147 0 284.5 -55.5t244.5 -156.5l130 129q29 31 70 14q39 -17 39 -59z" />
64
- <glyph unicode="&#xf021;" d="M1511 480q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129q-19 -19 -45 -19t-45 19t-19 45v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117 q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5zM1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5v7q65 268 270 434.5t480 166.5 q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45z" />
65
- <glyph unicode="&#xf022;" horiz-adv-x="1792" d="M384 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M384 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1536 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5z M1536 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5zM1536 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5 t9.5 -22.5zM1664 160v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 1248v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47 t47 -113z" />
66
- <glyph unicode="&#xf023;" horiz-adv-x="1152" d="M320 768h512v192q0 106 -75 181t-181 75t-181 -75t-75 -181v-192zM1152 672v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v192q0 184 132 316t316 132t316 -132t132 -316v-192h32q40 0 68 -28t28 -68z" />
67
- <glyph unicode="&#xf024;" horiz-adv-x="1792" d="M320 1280q0 -72 -64 -110v-1266q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v1266q-64 38 -64 110q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48 t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45z" />
68
- <glyph unicode="&#xf025;" horiz-adv-x="1664" d="M1664 650q0 -166 -60 -314l-20 -49l-185 -33q-22 -83 -90.5 -136.5t-156.5 -53.5v-32q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-32q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78 t-315.5 -78t-236.5 -209t-88 -279q0 -98 29 -193l68 -12q34 60 93 95.5t130 35.5v32q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v32q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314q0 151 67 291t179 242.5 t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291z" />
69
- <glyph unicode="&#xf026;" horiz-adv-x="768" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45z" />
70
- <glyph unicode="&#xf027;" horiz-adv-x="1152" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 35.5 t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142z" />
71
- <glyph unicode="&#xf028;" horiz-adv-x="1664" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 35.5 t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142zM1408 640q0 -153 -85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5 t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5q140 -59 225 -188.5t85 -282.5zM1664 640q0 -230 -127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289 t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19q13 0 26 -5q211 -91 338 -283.5t127 -422.5z" />
72
- <glyph unicode="&#xf029;" horiz-adv-x="1408" d="M384 384v-128h-128v128h128zM384 1152v-128h-128v128h128zM1152 1152v-128h-128v128h128zM128 129h384v383h-384v-383zM128 896h384v384h-384v-384zM896 896h384v384h-384v-384zM640 640v-640h-640v640h640zM1152 128v-128h-128v128h128zM1408 128v-128h-128v128h128z M1408 640v-384h-384v128h-128v-384h-128v640h384v-128h128v128h128zM640 1408v-640h-640v640h640zM1408 1408v-640h-640v640h640z" />
73
- <glyph unicode="&#xf02a;" horiz-adv-x="1792" d="M63 0h-63v1408h63v-1408zM126 1h-32v1407h32v-1407zM220 1h-31v1407h31v-1407zM377 1h-31v1407h31v-1407zM534 1h-62v1407h62v-1407zM660 1h-31v1407h31v-1407zM723 1h-31v1407h31v-1407zM786 1h-31v1407h31v-1407zM943 1h-63v1407h63v-1407zM1100 1h-63v1407h63v-1407z M1226 1h-63v1407h63v-1407zM1352 1h-63v1407h63v-1407zM1446 1h-63v1407h63v-1407zM1635 1h-94v1407h94v-1407zM1698 1h-32v1407h32v-1407zM1792 0h-63v1408h63v-1408z" />
74
- <glyph unicode="&#xf02b;" d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 l715 -714q37 -39 37 -91z" />
75
- <glyph unicode="&#xf02c;" horiz-adv-x="1920" d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 l715 -714q37 -39 37 -91zM1899 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-36 0 -59 14t-53 45l470 470q37 37 37 90q0 52 -37 91l-715 714q-38 38 -102 64.5t-117 26.5h224q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91z" />
76
- <glyph unicode="&#xf02d;" horiz-adv-x="1664" d="M1639 1058q40 -57 18 -129l-275 -906q-19 -64 -76.5 -107.5t-122.5 -43.5h-923q-77 0 -148.5 53.5t-99.5 131.5q-24 67 -2 127q0 4 3 27t4 37q1 8 -3 21.5t-3 19.5q2 11 8 21t16.5 23.5t16.5 23.5q23 38 45 91.5t30 91.5q3 10 0.5 30t-0.5 28q3 11 17 28t17 23 q21 36 42 92t25 90q1 9 -2.5 32t0.5 28q4 13 22 30.5t22 22.5q19 26 42.5 84.5t27.5 96.5q1 8 -3 25.5t-2 26.5q2 8 9 18t18 23t17 21q8 12 16.5 30.5t15 35t16 36t19.5 32t26.5 23.5t36 11.5t47.5 -5.5l-1 -3q38 9 51 9h761q74 0 114 -56t18 -130l-274 -906 q-36 -119 -71.5 -153.5t-128.5 -34.5h-869q-27 0 -38 -15q-11 -16 -1 -43q24 -70 144 -70h923q29 0 56 15.5t35 41.5l300 987q7 22 5 57q38 -15 59 -43zM575 1056q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5 t-16.5 -22.5zM492 800q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5z" />
77
- <glyph unicode="&#xf02e;" horiz-adv-x="1280" d="M1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
78
- <glyph unicode="&#xf02f;" horiz-adv-x="1664" d="M384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1536 576q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 576v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68 v160h-224q-13 0 -22.5 9.5t-9.5 22.5v416q0 79 56.5 135.5t135.5 56.5h64v544q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-256h64q79 0 135.5 -56.5t56.5 -135.5z" />
79
- <glyph unicode="&#xf030;" horiz-adv-x="1920" d="M960 864q119 0 203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5t84.5 203.5t203.5 84.5zM1664 1280q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181v896q0 106 75 181t181 75h224l51 136 q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224zM960 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
80
- <glyph unicode="&#xf031;" horiz-adv-x="1664" d="M725 977l-170 -450q73 -1 153.5 -2t119 -1.5t52.5 -0.5l29 2q-32 95 -92 241q-53 132 -92 211zM21 -128h-21l2 79q22 7 80 18q89 16 110 31q20 16 48 68l237 616l280 724h75h53l11 -21l205 -480q103 -242 124 -297q39 -102 96 -235q26 -58 65 -164q24 -67 65 -149 q22 -49 35 -57q22 -19 69 -23q47 -6 103 -27q6 -39 6 -57q0 -14 -1 -26q-80 0 -192 8q-93 8 -189 8q-79 0 -135 -2l-200 -11l-58 -2q0 45 4 78l131 28q56 13 68 23q12 12 12 27t-6 32l-47 114l-92 228l-450 2q-29 -65 -104 -274q-23 -64 -23 -84q0 -31 17 -43 q26 -21 103 -32q3 0 13.5 -2t30 -5t40.5 -6q1 -28 1 -58q0 -17 -2 -27q-66 0 -349 20l-48 -8q-81 -14 -167 -14z" />
81
- <glyph unicode="&#xf032;" horiz-adv-x="1408" d="M555 15q76 -32 140 -32q131 0 216 41t122 113q38 70 38 181q0 114 -41 180q-58 94 -141 126q-80 32 -247 32q-74 0 -101 -10v-144l-1 -173l3 -270q0 -15 12 -44zM541 761q43 -7 109 -7q175 0 264 65t89 224q0 112 -85 187q-84 75 -255 75q-52 0 -130 -13q0 -44 2 -77 q7 -122 6 -279l-1 -98q0 -43 1 -77zM0 -128l2 94q45 9 68 12q77 12 123 31q17 27 21 51q9 66 9 194l-2 497q-5 256 -9 404q-1 87 -11 109q-1 4 -12 12q-18 12 -69 15q-30 2 -114 13l-4 83l260 6l380 13l45 1q5 0 14 0.5t14 0.5q1 0 21.5 -0.5t40.5 -0.5h74q88 0 191 -27 q43 -13 96 -39q57 -29 102 -76q44 -47 65 -104t21 -122q0 -70 -32 -128t-95 -105q-26 -20 -150 -77q177 -41 267 -146q92 -106 92 -236q0 -76 -29 -161q-21 -62 -71 -117q-66 -72 -140 -108q-73 -36 -203 -60q-82 -15 -198 -11l-197 4q-84 2 -298 -11q-33 -3 -272 -11z" />
82
- <glyph unicode="&#xf033;" horiz-adv-x="1024" d="M0 -126l17 85q4 1 77 20q76 19 116 39q29 37 41 101l27 139l56 268l12 64q8 44 17 84.5t16 67t12.5 46.5t9 30.5t3.5 11.5l29 157l16 63l22 135l8 50v38q-41 22 -144 28q-28 2 -38 4l19 103l317 -14q39 -2 73 -2q66 0 214 9q33 2 68 4.5t36 2.5q-2 -19 -6 -38 q-7 -29 -13 -51q-55 -19 -109 -31q-64 -16 -101 -31q-12 -31 -24 -88q-9 -44 -13 -82q-44 -199 -66 -306l-61 -311l-38 -158l-43 -235l-12 -45q-2 -7 1 -27q64 -15 119 -21q36 -5 66 -10q-1 -29 -7 -58q-7 -31 -9 -41q-18 0 -23 -1q-24 -2 -42 -2q-9 0 -28 3q-19 4 -145 17 l-198 2q-41 1 -174 -11q-74 -7 -98 -9z" />
83
- <glyph unicode="&#xf034;" horiz-adv-x="1792" d="M81 1407l54 -27q20 -5 211 -5h130l19 3l115 1l215 -1h293l34 -2q14 -1 28 7t21 16l7 8l42 1q15 0 28 -1v-104.5t1 -131.5l1 -100l-1 -58q0 -32 -4 -51q-39 -15 -68 -18q-25 43 -54 128q-8 24 -15.5 62.5t-11.5 65.5t-6 29q-13 15 -27 19q-7 2 -42.5 2t-103.5 -1t-111 -1 q-34 0 -67 -5q-10 -97 -8 -136l1 -152v-332l3 -359l-1 -147q-1 -46 11 -85q49 -25 89 -32q2 0 18 -5t44 -13t43 -12q30 -8 50 -18q5 -45 5 -50q0 -10 -3 -29q-14 -1 -34 -1q-110 0 -187 10q-72 8 -238 8q-88 0 -233 -14q-48 -4 -70 -4q-2 22 -2 26l-1 26v9q21 33 79 49 q139 38 159 50q9 21 12 56q8 192 6 433l-5 428q-1 62 -0.5 118.5t0.5 102.5t-2 57t-6 15q-6 5 -14 6q-38 6 -148 6q-43 0 -100 -13.5t-73 -24.5q-13 -9 -22 -33t-22 -75t-24 -84q-6 -19 -19.5 -32t-20.5 -13q-44 27 -56 44v297v86zM1744 128q33 0 42 -18.5t-11 -44.5 l-126 -162q-20 -26 -49 -26t-49 26l-126 162q-20 26 -11 44.5t42 18.5h80v1024h-80q-33 0 -42 18.5t11 44.5l126 162q20 26 49 26t49 -26l126 -162q20 -26 11 -44.5t-42 -18.5h-80v-1024h80z" />
84
- <glyph unicode="&#xf035;" d="M81 1407l54 -27q20 -5 211 -5h130l19 3l115 1l446 -1h318l34 -2q14 -1 28 7t21 16l7 8l42 1q15 0 28 -1v-104.5t1 -131.5l1 -100l-1 -58q0 -32 -4 -51q-39 -15 -68 -18q-25 43 -54 128q-8 24 -15.5 62.5t-11.5 65.5t-6 29q-13 15 -27 19q-7 2 -58.5 2t-138.5 -1t-128 -1 q-94 0 -127 -5q-10 -97 -8 -136l1 -152v52l3 -359l-1 -147q-1 -46 11 -85q49 -25 89 -32q2 0 18 -5t44 -13t43 -12q30 -8 50 -18q5 -45 5 -50q0 -10 -3 -29q-14 -1 -34 -1q-110 0 -187 10q-72 8 -238 8q-82 0 -233 -13q-45 -5 -70 -5q-2 22 -2 26l-1 26v9q21 33 79 49 q139 38 159 50q9 21 12 56q6 137 6 433l-5 44q0 265 -2 278q-2 11 -6 15q-6 5 -14 6q-38 6 -148 6q-50 0 -168.5 -14t-132.5 -24q-13 -9 -22 -33t-22 -75t-24 -84q-6 -19 -19.5 -32t-20.5 -13q-44 27 -56 44v297v86zM1505 113q26 -20 26 -49t-26 -49l-162 -126 q-26 -20 -44.5 -11t-18.5 42v80h-1024v-80q0 -33 -18.5 -42t-44.5 11l-162 126q-26 20 -26 49t26 49l162 126q26 20 44.5 11t18.5 -42v-80h1024v80q0 33 18.5 42t44.5 -11z" />
85
- <glyph unicode="&#xf036;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45 t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
86
- <glyph unicode="&#xf037;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h896q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45t-45 -19 h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h640q26 0 45 -19t19 -45z" />
87
- <glyph unicode="&#xf038;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
88
- <glyph unicode="&#xf039;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" />
89
- <glyph unicode="&#xf03a;" horiz-adv-x="1792" d="M256 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM256 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5 t9.5 -22.5zM256 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344 q13 0 22.5 -9.5t9.5 -22.5zM256 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192 q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5z" />
90
- <glyph unicode="&#xf03b;" horiz-adv-x="1792" d="M384 992v-576q0 -13 -9.5 -22.5t-22.5 -9.5q-14 0 -23 9l-288 288q-9 9 -9 23t9 23l288 288q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
91
- <glyph unicode="&#xf03c;" horiz-adv-x="1792" d="M352 704q0 -14 -9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
92
- <glyph unicode="&#xf03d;" horiz-adv-x="1792" d="M1792 1184v-1088q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-403 403v-166q0 -119 -84.5 -203.5t-203.5 -84.5h-704q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5 q39 -17 39 -59z" />
93
- <glyph unicode="&#xf03e;" horiz-adv-x="1920" d="M640 960q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 576v-448h-1408v192l320 320l160 -160l512 512zM1760 1280h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216 q0 13 -9.5 22.5t-22.5 9.5zM1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
94
- <glyph unicode="&#xf040;" d="M363 0l91 91l-235 235l-91 -91v-107h128v-128h107zM886 928q0 22 -22 22q-10 0 -17 -7l-542 -542q-7 -7 -7 -17q0 -22 22 -22q10 0 17 7l542 542q7 7 7 17zM832 1120l416 -416l-832 -832h-416v416zM1515 1024q0 -53 -37 -90l-166 -166l-416 416l166 165q36 38 90 38 q53 0 91 -38l235 -234q37 -39 37 -91z" />
95
- <glyph unicode="&#xf041;" horiz-adv-x="1024" d="M768 896q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1024 896q0 -109 -33 -179l-364 -774q-16 -33 -47.5 -52t-67.5 -19t-67.5 19t-46.5 52l-365 774q-33 70 -33 179q0 212 150 362t362 150t362 -150t150 -362z" />
96
- <glyph unicode="&#xf042;" d="M768 96v1088q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
97
- <glyph unicode="&#xf043;" horiz-adv-x="1024" d="M512 384q0 36 -20 69q-1 1 -15.5 22.5t-25.5 38t-25 44t-21 50.5q-4 16 -21 16t-21 -16q-7 -23 -21 -50.5t-25 -44t-25.5 -38t-15.5 -22.5q-20 -33 -20 -69q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 512q0 -212 -150 -362t-362 -150t-362 150t-150 362 q0 145 81 275q6 9 62.5 90.5t101 151t99.5 178t83 201.5q9 30 34 47t51 17t51.5 -17t33.5 -47q28 -93 83 -201.5t99.5 -178t101 -151t62.5 -90.5q81 -127 81 -275z" />
98
- <glyph unicode="&#xf044;" horiz-adv-x="1792" d="M888 352l116 116l-152 152l-116 -116v-56h96v-96h56zM1328 1072q-16 16 -33 -1l-350 -350q-17 -17 -1 -33t33 1l350 350q17 17 1 33zM1408 478v-190q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-14 -14 -32 -8q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v126q0 13 9 22l64 64q15 15 35 7t20 -29zM1312 1216l288 -288l-672 -672h-288v288zM1756 1084l-92 -92 l-288 288l92 92q28 28 68 28t68 -28l152 -152q28 -28 28 -68t-28 -68z" />
99
- <glyph unicode="&#xf045;" horiz-adv-x="1664" d="M1408 547v-259q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h255v0q13 0 22.5 -9.5t9.5 -22.5q0 -27 -26 -32q-77 -26 -133 -60q-10 -4 -16 -4h-112q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832 q66 0 113 47t47 113v214q0 19 18 29q28 13 54 37q16 16 35 8q21 -9 21 -29zM1645 1043l-384 -384q-18 -19 -45 -19q-12 0 -25 5q-39 17 -39 59v192h-160q-323 0 -438 -131q-119 -137 -74 -473q3 -23 -20 -34q-8 -2 -12 -2q-16 0 -26 13q-10 14 -21 31t-39.5 68.5t-49.5 99.5 t-38.5 114t-17.5 122q0 49 3.5 91t14 90t28 88t47 81.5t68.5 74t94.5 61.5t124.5 48.5t159.5 30.5t196.5 11h160v192q0 42 39 59q13 5 25 5q26 0 45 -19l384 -384q19 -19 19 -45t-19 -45z" />
100
- <glyph unicode="&#xf046;" horiz-adv-x="1664" d="M1408 606v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832 q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3q20 -8 20 -29zM1639 1095l-814 -814q-24 -24 -57 -24t-57 24l-430 430q-24 24 -24 57t24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110 q24 -24 24 -57t-24 -57z" />
101
- <glyph unicode="&#xf047;" horiz-adv-x="1792" d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-384v-384h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v384h-384v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45 t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h384v384h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-384h384v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
102
- <glyph unicode="&#xf048;" horiz-adv-x="1024" d="M979 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19z" />
103
- <glyph unicode="&#xf049;" horiz-adv-x="1792" d="M1747 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19l710 710 q19 19 32 13t13 -32v-710q4 11 13 19z" />
104
- <glyph unicode="&#xf04a;" horiz-adv-x="1664" d="M1619 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-8 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-19 19 -19 45t19 45l710 710q19 19 32 13t13 -32v-710q5 11 13 19z" />
105
- <glyph unicode="&#xf04b;" horiz-adv-x="1408" d="M1384 609l-1328 -738q-23 -13 -39.5 -3t-16.5 36v1472q0 26 16.5 36t39.5 -3l1328 -738q23 -13 23 -31t-23 -31z" />
106
- <glyph unicode="&#xf04c;" d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45zM640 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45z" />
107
- <glyph unicode="&#xf04d;" d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
108
- <glyph unicode="&#xf04e;" horiz-adv-x="1664" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q19 -19 19 -45t-19 -45l-710 -710q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19z" />
109
- <glyph unicode="&#xf050;" horiz-adv-x="1792" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19l-710 -710 q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19z" />
110
- <glyph unicode="&#xf051;" horiz-adv-x="1024" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19z" />
111
- <glyph unicode="&#xf052;" horiz-adv-x="1538" d="M14 557l710 710q19 19 45 19t45 -19l710 -710q19 -19 13 -32t-32 -13h-1472q-26 0 -32 13t13 32zM1473 0h-1408q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19z" />
112
- <glyph unicode="&#xf053;" horiz-adv-x="1152" d="M742 -37l-652 651q-37 37 -37 90.5t37 90.5l652 651q37 37 90.5 37t90.5 -37l75 -75q37 -37 37 -90.5t-37 -90.5l-486 -486l486 -485q37 -38 37 -91t-37 -90l-75 -75q-37 -37 -90.5 -37t-90.5 37z" />
113
- <glyph unicode="&#xf054;" horiz-adv-x="1152" d="M1099 704q0 -52 -37 -91l-652 -651q-37 -37 -90 -37t-90 37l-76 75q-37 39 -37 91q0 53 37 90l486 486l-486 485q-37 39 -37 91q0 53 37 90l76 75q36 38 90 38t90 -38l652 -651q37 -37 37 -90z" />
114
- <glyph unicode="&#xf055;" d="M1216 576v128q0 26 -19 45t-45 19h-256v256q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-256h-256q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h256v-256q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v256h256q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5 t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
115
- <glyph unicode="&#xf056;" d="M1216 576v128q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5 t103 -385.5z" />
116
- <glyph unicode="&#xf057;" d="M1149 414q0 26 -19 45l-181 181l181 181q19 19 19 45q0 27 -19 46l-90 90q-19 19 -46 19q-26 0 -45 -19l-181 -181l-181 181q-19 19 -45 19q-27 0 -46 -19l-90 -90q-19 -19 -19 -46q0 -26 19 -45l181 -181l-181 -181q-19 -19 -19 -45q0 -27 19 -46l90 -90q19 -19 46 -19 q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19l90 90q19 19 19 46zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
117
- <glyph unicode="&#xf058;" d="M1284 802q0 28 -18 46l-91 90q-19 19 -45 19t-45 -19l-408 -407l-226 226q-19 19 -45 19t-45 -19l-91 -90q-18 -18 -18 -46q0 -27 18 -45l362 -362q19 -19 45 -19q27 0 46 19l543 543q18 18 18 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
118
- <glyph unicode="&#xf059;" d="M896 160v192q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1152 832q0 88 -55.5 163t-138.5 116t-170 41q-243 0 -371 -213q-15 -24 8 -42l132 -100q7 -6 19 -6q16 0 25 12q53 68 86 92q34 24 86 24q48 0 85.5 -26t37.5 -59 q0 -38 -20 -61t-68 -45q-63 -28 -115.5 -86.5t-52.5 -125.5v-36q0 -14 9 -23t23 -9h192q14 0 23 9t9 23q0 19 21.5 49.5t54.5 49.5q32 18 49 28.5t46 35t44.5 48t28 60.5t12.5 81zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
119
- <glyph unicode="&#xf05a;" d="M1024 160v160q0 14 -9 23t-23 9h-96v512q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h96v-320h-96q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h448q14 0 23 9t9 23zM896 1056v160q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23 t23 -9h192q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
120
- <glyph unicode="&#xf05b;" d="M1197 512h-109q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h109q-32 108 -112.5 188.5t-188.5 112.5v-109q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v109q-108 -32 -188.5 -112.5t-112.5 -188.5h109q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-109 q32 -108 112.5 -188.5t188.5 -112.5v109q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-109q108 32 188.5 112.5t112.5 188.5zM1536 704v-128q0 -26 -19 -45t-45 -19h-143q-37 -161 -154.5 -278.5t-278.5 -154.5v-143q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v143 q-161 37 -278.5 154.5t-154.5 278.5h-143q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h143q37 161 154.5 278.5t278.5 154.5v143q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-143q161 -37 278.5 -154.5t154.5 -278.5h143q26 0 45 -19t19 -45z" />
121
- <glyph unicode="&#xf05c;" d="M1097 457l-146 -146q-10 -10 -23 -10t-23 10l-137 137l-137 -137q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l137 137l-137 137q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l137 -137l137 137q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23 l-137 -137l137 -137q10 -10 10 -23t-10 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5 t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
122
- <glyph unicode="&#xf05d;" d="M1171 723l-422 -422q-19 -19 -45 -19t-45 19l-294 294q-19 19 -19 45t19 45l102 102q19 19 45 19t45 -19l147 -147l275 275q19 19 45 19t45 -19l102 -102q19 -19 19 -45t-19 -45zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198 t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
123
- <glyph unicode="&#xf05e;" d="M1312 643q0 161 -87 295l-754 -753q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5zM313 344l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199t-73 -274q0 -162 89 -299zM1536 643q0 -157 -61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61 t-245 164t-163.5 246t-61 300t61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5z" />
124
- <glyph unicode="&#xf060;" d="M1536 640v-128q0 -53 -32.5 -90.5t-84.5 -37.5h-704l293 -294q38 -36 38 -90t-38 -90l-75 -76q-37 -37 -90 -37q-52 0 -91 37l-651 652q-37 37 -37 90q0 52 37 91l651 650q38 38 91 38q52 0 90 -38l75 -74q38 -38 38 -91t-38 -91l-293 -293h704q52 0 84.5 -37.5 t32.5 -90.5z" />
125
- <glyph unicode="&#xf061;" d="M1472 576q0 -54 -37 -91l-651 -651q-39 -37 -91 -37q-51 0 -90 37l-75 75q-38 38 -38 91t38 91l293 293h-704q-52 0 -84.5 37.5t-32.5 90.5v128q0 53 32.5 90.5t84.5 37.5h704l-293 294q-38 36 -38 90t38 90l75 75q38 38 90 38q53 0 91 -38l651 -651q37 -35 37 -90z" />
126
- <glyph unicode="&#xf062;" horiz-adv-x="1664" d="M1611 565q0 -51 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-294 293v-704q0 -52 -37.5 -84.5t-90.5 -32.5h-128q-53 0 -90.5 32.5t-37.5 84.5v704l-294 -293q-36 -38 -90 -38t-90 38l-75 75q-38 38 -38 90q0 53 38 91l651 651q35 37 90 37q54 0 91 -37l651 -651 q37 -39 37 -91z" />
127
- <glyph unicode="&#xf063;" horiz-adv-x="1664" d="M1611 704q0 -53 -37 -90l-651 -652q-39 -37 -91 -37q-53 0 -90 37l-651 652q-38 36 -38 90q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l294 -294v704q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-704l294 294q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91z" />
128
- <glyph unicode="&#xf064;" horiz-adv-x="1792" d="M1792 896q0 -26 -19 -45l-512 -512q-19 -19 -45 -19t-45 19t-19 45v256h-224q-98 0 -175.5 -6t-154 -21.5t-133 -42.5t-105.5 -69.5t-80 -101t-48.5 -138.5t-17.5 -181q0 -55 5 -123q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22 t-13.5 30t-10.5 24q-127 285 -127 451q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45z" />
129
- <glyph unicode="&#xf065;" d="M755 480q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23zM1536 1344v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332 q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45z" />
130
- <glyph unicode="&#xf066;" d="M768 576v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45zM1523 1248q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45 t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23z" />
131
- <glyph unicode="&#xf067;" horiz-adv-x="1408" d="M1408 800v-192q0 -40 -28 -68t-68 -28h-416v-416q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v416h-416q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h416v416q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-416h416q40 0 68 -28t28 -68z" />
132
- <glyph unicode="&#xf068;" horiz-adv-x="1408" d="M1408 800v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68z" />
133
- <glyph unicode="&#xf069;" horiz-adv-x="1664" d="M1482 486q46 -26 59.5 -77.5t-12.5 -97.5l-64 -110q-26 -46 -77.5 -59.5t-97.5 12.5l-266 153v-307q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v307l-266 -153q-46 -26 -97.5 -12.5t-77.5 59.5l-64 110q-26 46 -12.5 97.5t59.5 77.5l266 154l-266 154 q-46 26 -59.5 77.5t12.5 97.5l64 110q26 46 77.5 59.5t97.5 -12.5l266 -153v307q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-307l266 153q46 26 97.5 12.5t77.5 -59.5l64 -110q26 -46 12.5 -97.5t-59.5 -77.5l-266 -154z" />
134
- <glyph unicode="&#xf06a;" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM896 161v190q0 14 -9 23.5t-22 9.5h-192q-13 0 -23 -10t-10 -23v-190q0 -13 10 -23t23 -10h192 q13 0 22 9.5t9 23.5zM894 505l18 621q0 12 -10 18q-10 8 -24 8h-220q-14 0 -24 -8q-10 -6 -10 -18l17 -621q0 -10 10 -17.5t24 -7.5h185q14 0 23.5 7.5t10.5 17.5z" />
135
- <glyph unicode="&#xf06b;" d="M928 180v56v468v192h-320v-192v-468v-56q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5zM472 1024h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68t28 -68t68 -28zM1160 1120q0 40 -28 68t-68 28q-43 0 -69 -31l-125 -161h194q40 0 68 28t28 68zM1536 864v-320 q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h440q-93 0 -158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5q107 0 168 -77l128 -165l128 165q61 77 168 77q93 0 158.5 -65.5t65.5 -158.5 t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23z" />
136
- <glyph unicode="&#xf06c;" horiz-adv-x="1792" d="M1280 832q0 26 -19 45t-45 19q-172 0 -318 -49.5t-259.5 -134t-235.5 -219.5q-19 -21 -19 -45q0 -26 19 -45t45 -19q24 0 45 19q27 24 74 71t67 66q137 124 268.5 176t313.5 52q26 0 45 19t19 45zM1792 1030q0 -95 -20 -193q-46 -224 -184.5 -383t-357.5 -268 q-214 -108 -438 -108q-148 0 -286 47q-15 5 -88 42t-96 37q-16 0 -39.5 -32t-45 -70t-52.5 -70t-60 -32q-30 0 -51 11t-31 24t-27 42q-2 4 -6 11t-5.5 10t-3 9.5t-1.5 13.5q0 35 31 73.5t68 65.5t68 56t31 48q0 4 -14 38t-16 44q-9 51 -9 104q0 115 43.5 220t119 184.5 t170.5 139t204 95.5q55 18 145 25.5t179.5 9t178.5 6t163.5 24t113.5 56.5l29.5 29.5t29.5 28t27 20t36.5 16t43.5 4.5q39 0 70.5 -46t47.5 -112t24 -124t8 -96z" />
137
- <glyph unicode="&#xf06d;" horiz-adv-x="1408" d="M1408 -160v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1152 896q0 -78 -24.5 -144t-64 -112.5t-87.5 -88t-96 -77.5t-87.5 -72t-64 -81.5t-24.5 -96.5q0 -96 67 -224l-4 1l1 -1 q-90 41 -160 83t-138.5 100t-113.5 122.5t-72.5 150.5t-27.5 184q0 78 24.5 144t64 112.5t87.5 88t96 77.5t87.5 72t64 81.5t24.5 96.5q0 94 -66 224l3 -1l-1 1q90 -41 160 -83t138.5 -100t113.5 -122.5t72.5 -150.5t27.5 -184z" />
138
- <glyph unicode="&#xf06e;" horiz-adv-x="1792" d="M1664 576q-152 236 -381 353q61 -104 61 -225q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 121 61 225q-229 -117 -381 -353q133 -205 333.5 -326.5t434.5 -121.5t434.5 121.5t333.5 326.5zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5 t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1792 576q0 -34 -20 -69q-140 -230 -376.5 -368.5t-499.5 -138.5t-499.5 139t-376.5 368q-20 35 -20 69t20 69q140 229 376.5 368t499.5 139t499.5 -139t376.5 -368q20 -35 20 -69z" />
139
- <glyph unicode="&#xf070;" horiz-adv-x="1792" d="M555 201l78 141q-87 63 -136 159t-49 203q0 121 61 225q-229 -117 -381 -353q167 -258 427 -375zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1307 1151q0 -7 -1 -9 q-105 -188 -315 -566t-316 -567l-49 -89q-10 -16 -28 -16q-12 0 -134 70q-16 10 -16 28q0 12 44 87q-143 65 -263.5 173t-208.5 245q-20 31 -20 69t20 69q153 235 380 371t496 136q89 0 180 -17l54 97q10 16 28 16q5 0 18 -6t31 -15.5t33 -18.5t31.5 -18.5t19.5 -11.5 q16 -10 16 -27zM1344 704q0 -139 -79 -253.5t-209 -164.5l280 502q8 -45 8 -84zM1792 576q0 -35 -20 -69q-39 -64 -109 -145q-150 -172 -347.5 -267t-419.5 -95l74 132q212 18 392.5 137t301.5 307q-115 179 -282 294l63 112q95 -64 182.5 -153t144.5 -184q20 -34 20 -69z " />
140
- <glyph unicode="&#xf071;" horiz-adv-x="1792" d="M1024 161v190q0 14 -9.5 23.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -23.5v-190q0 -14 9.5 -23.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 23.5zM1022 535l18 459q0 12 -10 19q-13 11 -24 11h-220q-11 0 -24 -11q-10 -7 -10 -21l17 -457q0 -10 10 -16.5t24 -6.5h185 q14 0 23.5 6.5t10.5 16.5zM1008 1469l768 -1408q35 -63 -2 -126q-17 -29 -46.5 -46t-63.5 -17h-1536q-34 0 -63.5 17t-46.5 46q-37 63 -2 126l768 1408q17 31 47 49t65 18t65 -18t47 -49z" />
141
- <glyph unicode="&#xf072;" horiz-adv-x="1408" d="M1376 1376q44 -52 12 -148t-108 -172l-161 -161l160 -696q5 -19 -12 -33l-128 -96q-7 -6 -19 -6q-4 0 -7 1q-15 3 -21 16l-279 508l-259 -259l53 -194q5 -17 -8 -31l-96 -96q-9 -9 -23 -9h-2q-15 2 -24 13l-189 252l-252 189q-11 7 -13 23q-1 13 9 25l96 97q9 9 23 9 q6 0 8 -1l194 -53l259 259l-508 279q-14 8 -17 24q-2 16 9 27l128 128q14 13 30 8l665 -159l160 160q76 76 172 108t148 -12z" />
142
- <glyph unicode="&#xf073;" horiz-adv-x="1664" d="M128 -128h288v288h-288v-288zM480 -128h320v288h-320v-288zM128 224h288v320h-288v-320zM480 224h320v320h-320v-320zM128 608h288v288h-288v-288zM864 -128h320v288h-320v-288zM480 608h320v288h-320v-288zM1248 -128h288v288h-288v-288zM864 224h320v320h-320v-320z M512 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1248 224h288v320h-288v-320zM864 608h320v288h-320v-288zM1248 608h288v288h-288v-288zM1280 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64 q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47 h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
143
- <glyph unicode="&#xf074;" horiz-adv-x="1792" d="M666 1055q-60 -92 -137 -273q-22 45 -37 72.5t-40.5 63.5t-51 56.5t-63 35t-81.5 14.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q250 0 410 -225zM1792 256q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192q-32 0 -85 -0.5t-81 -1t-73 1 t-71 5t-64 10.5t-63 18.5t-58 28.5t-59 40t-55 53.5t-56 69.5q59 93 136 273q22 -45 37 -72.5t40.5 -63.5t51 -56.5t63 -35t81.5 -14.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1792 1152q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5 v192h-256q-48 0 -87 -15t-69 -45t-51 -61.5t-45 -77.5q-32 -62 -78 -171q-29 -66 -49.5 -111t-54 -105t-64 -100t-74 -83t-90 -68.5t-106.5 -42t-128 -16.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q48 0 87 15t69 45t51 61.5t45 77.5q32 62 78 171q29 66 49.5 111 t54 105t64 100t74 83t90 68.5t106.5 42t128 16.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" />
144
- <glyph unicode="&#xf075;" horiz-adv-x="1792" d="M1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22q-17 -2 -30.5 9t-17.5 29v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281 q0 130 71 248.5t191 204.5t286 136.5t348 50.5q244 0 450 -85.5t326 -233t120 -321.5z" />
145
- <glyph unicode="&#xf076;" d="M1536 704v-128q0 -201 -98.5 -362t-274 -251.5t-395.5 -90.5t-395.5 90.5t-274 251.5t-98.5 362v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -52 23.5 -90t53.5 -57t71 -30t64 -13t44 -2t44 2t64 13t71 30t53.5 57t23.5 90v128q0 26 19 45t45 19h384 q26 0 45 -19t19 -45zM512 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45zM1536 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45z" />
146
- <glyph unicode="&#xf077;" horiz-adv-x="1664" d="M1611 320q0 -53 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-486 485l-486 -485q-36 -38 -90 -38t-90 38l-75 75q-38 36 -38 90q0 53 38 91l651 651q37 37 90 37q52 0 91 -37l650 -651q38 -38 38 -91z" />
147
- <glyph unicode="&#xf078;" horiz-adv-x="1664" d="M1611 832q0 -53 -37 -90l-651 -651q-38 -38 -91 -38q-54 0 -90 38l-651 651q-38 36 -38 90q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l486 -486l486 486q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91z" />
148
- <glyph unicode="&#xf079;" horiz-adv-x="1920" d="M1280 32q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -11 7 -21 zM1920 448q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45z " />
149
- <glyph unicode="&#xf07a;" horiz-adv-x="1664" d="M640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5 l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5 t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
150
- <glyph unicode="&#xf07b;" horiz-adv-x="1664" d="M1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
151
- <glyph unicode="&#xf07c;" horiz-adv-x="1920" d="M1879 584q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43zM1536 928v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5 t-0.5 12.5v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158z" />
152
- <glyph unicode="&#xf07d;" horiz-adv-x="768" d="M704 1216q0 -26 -19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45z" />
153
- <glyph unicode="&#xf07e;" horiz-adv-x="1792" d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
154
- <glyph unicode="&#xf080;" horiz-adv-x="1920" d="M512 512v-384h-256v384h256zM896 1024v-896h-256v896h256zM1280 768v-640h-256v640h256zM1664 1152v-1024h-256v1024h256zM1792 32v1216q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5z M1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
155
- <glyph unicode="&#xf081;" d="M1280 926q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4 q21 -63 74.5 -104t121.5 -42q-116 -90 -261 -90q-26 0 -50 3q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5 t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
156
- <glyph unicode="&#xf082;" d="M1307 618l23 219h-198v109q0 49 15.5 68.5t71.5 19.5h110v219h-175q-152 0 -218 -72t-66 -213v-131h-131v-219h131v-635h262v635h175zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960 q119 0 203.5 -84.5t84.5 -203.5z" />
157
- <glyph unicode="&#xf083;" horiz-adv-x="1792" d="M928 704q0 14 -9 23t-23 9q-66 0 -113 -47t-47 -113q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9t9 23zM1152 574q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM128 0h1536v128h-1536v-128zM1280 574q0 159 -112.5 271.5 t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM256 1216h384v128h-384v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM1792 1280v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5v1280 q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5z" />
158
- <glyph unicode="&#xf084;" horiz-adv-x="1792" d="M832 1024q0 80 -56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136t56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56t56 136zM1683 320q0 -17 -49 -66t-66 -49q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26 l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5 t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41z" />
159
- <glyph unicode="&#xf085;" horiz-adv-x="1920" d="M896 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1664 128q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1152q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5zM1280 731v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -10 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5 l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7 l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8q144 -133 144 -160q0 -9 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 -23q10 -2 17 -10.5t7 -19.5zM1920 198v-140q0 -16 -149 -31 q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20 t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31zM1920 1222v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68 q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70 q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31z" />
160
- <glyph unicode="&#xf086;" horiz-adv-x="1792" d="M1408 768q0 -139 -94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224 q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257zM1792 512q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7 q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230z" />
161
- <glyph unicode="&#xf087;" d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 768q0 51 -39 89.5t-89 38.5h-352q0 58 48 159.5t48 160.5q0 98 -32 145t-128 47q-26 -26 -38 -85t-30.5 -125.5t-59.5 -109.5q-22 -23 -77 -91q-4 -5 -23 -30t-31.5 -41t-34.5 -42.5 t-40 -44t-38.5 -35.5t-40 -27t-35.5 -9h-32v-640h32q13 0 31.5 -3t33 -6.5t38 -11t35 -11.5t35.5 -12.5t29 -10.5q211 -73 342 -73h121q192 0 192 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5q32 1 53.5 47t21.5 81zM1536 769 q0 -89 -49 -163q9 -33 9 -69q0 -77 -38 -144q3 -21 3 -43q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5h-36h-93q-96 0 -189.5 22.5t-216.5 65.5q-116 40 -138 40h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h274q36 24 137 155q58 75 107 128 q24 25 35.5 85.5t30.5 126.5t62 108q39 37 90 37q84 0 151 -32.5t102 -101.5t35 -186q0 -93 -48 -192h176q104 0 180 -76t76 -179z" />
162
- <glyph unicode="&#xf088;" d="M256 1088q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 512q0 35 -21.5 81t-53.5 47q15 17 25 47.5t10 55.5q0 69 -53 119q18 32 18 69t-17.5 73.5t-47.5 52.5q5 30 5 56q0 85 -49 126t-136 41h-128q-131 0 -342 -73q-5 -2 -29 -10.5 t-35.5 -12.5t-35 -11.5t-38 -11t-33 -6.5t-31.5 -3h-32v-640h32q16 0 35.5 -9t40 -27t38.5 -35.5t40 -44t34.5 -42.5t31.5 -41t23 -30q55 -68 77 -91q41 -43 59.5 -109.5t30.5 -125.5t38 -85q96 0 128 47t32 145q0 59 -48 160.5t-48 159.5h352q50 0 89 38.5t39 89.5z M1536 511q0 -103 -76 -179t-180 -76h-176q48 -99 48 -192q0 -118 -35 -186q-35 -69 -102 -101.5t-151 -32.5q-51 0 -90 37q-34 33 -54 82t-25.5 90.5t-17.5 84.5t-31 64q-48 50 -107 127q-101 131 -137 155h-274q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5 h288q22 0 138 40q128 44 223 66t200 22h112q140 0 226.5 -79t85.5 -216v-5q60 -77 60 -178q0 -22 -3 -43q38 -67 38 -144q0 -36 -9 -69q49 -74 49 -163z" />
163
- <glyph unicode="&#xf089;" horiz-adv-x="896" d="M832 1504v-1339l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41z" />
164
- <glyph unicode="&#xf08a;" horiz-adv-x="1792" d="M1664 940q0 81 -21.5 143t-55 98.5t-81.5 59.5t-94 31t-98 8t-112 -25.5t-110.5 -64t-86.5 -72t-60 -61.5q-18 -22 -49 -22t-49 22q-24 28 -60 61.5t-86.5 72t-110.5 64t-112 25.5t-98 -8t-94 -31t-81.5 -59.5t-55 -98.5t-21.5 -143q0 -168 187 -355l581 -560l580 559 q188 188 188 356zM1792 940q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5 q224 0 351 -124t127 -344z" />
165
- <glyph unicode="&#xf08b;" horiz-adv-x="1664" d="M640 96q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h320q13 0 22.5 -9.5t9.5 -22.5q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-66 0 -113 -47t-47 -113v-704 q0 -66 47 -113t113 -47h288h11h13t11.5 -1t11.5 -3t8 -5.5t7 -9t2 -13.5zM1568 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45z" />
166
- <glyph unicode="&#xf08c;" d="M237 122h231v694h-231v-694zM483 1030q-1 52 -36 86t-93 34t-94.5 -34t-36.5 -86q0 -51 35.5 -85.5t92.5 -34.5h1q59 0 95 34.5t36 85.5zM1068 122h231v398q0 154 -73 233t-193 79q-136 0 -209 -117h2v101h-231q3 -66 0 -694h231v388q0 38 7 56q15 35 45 59.5t74 24.5 q116 0 116 -157v-371zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
167
- <glyph unicode="&#xf08d;" horiz-adv-x="1152" d="M480 672v448q0 14 -9 23t-23 9t-23 -9t-9 -23v-448q0 -14 9 -23t23 -9t23 9t9 23zM1152 320q0 -26 -19 -45t-45 -19h-429l-51 -483q-2 -12 -10.5 -20.5t-20.5 -8.5h-1q-27 0 -32 27l-76 485h-404q-26 0 -45 19t-19 45q0 123 78.5 221.5t177.5 98.5v512q-52 0 -90 38 t-38 90t38 90t90 38h640q52 0 90 -38t38 -90t-38 -90t-90 -38v-512q99 0 177.5 -98.5t78.5 -221.5z" />
168
- <glyph unicode="&#xf08e;" horiz-adv-x="1792" d="M1408 608v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1792 1472v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45z" />
169
- <glyph unicode="&#xf090;" d="M1184 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45zM1536 992v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5 q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113t-113 47h-288h-11h-13t-11.5 1t-11.5 3t-8 5.5t-7 9t-2 13.5q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q119 0 203.5 -84.5t84.5 -203.5z" />
170
- <glyph unicode="&#xf091;" horiz-adv-x="1664" d="M458 653q-74 162 -74 371h-256v-96q0 -78 94.5 -162t235.5 -113zM1536 928v96h-256q0 -209 -74 -371q141 29 235.5 113t94.5 162zM1664 1056v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91 t97.5 -37q75 0 133.5 -45.5t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143v128q0 40 28 68t68 28h288v96 q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68z" />
171
- <glyph unicode="&#xf092;" d="M394 184q-8 -9 -20 3q-13 11 -4 19q8 9 20 -3q12 -11 4 -19zM352 245q9 -12 0 -19q-8 -6 -17 7t0 18q9 7 17 -6zM291 305q-5 -7 -13 -2q-10 5 -7 12q3 5 13 2q10 -5 7 -12zM322 271q-6 -7 -16 3q-9 11 -2 16q6 6 16 -3q9 -11 2 -16zM451 159q-4 -12 -19 -6q-17 4 -13 15 t19 7q16 -5 13 -16zM514 154q0 -11 -16 -11q-17 -2 -17 11q0 11 16 11q17 2 17 -11zM572 164q2 -10 -14 -14t-18 8t14 15q16 2 18 -9zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-224q-16 0 -24.5 1t-19.5 5t-16 14.5t-5 27.5v239q0 97 -52 142q57 6 102.5 18t94 39 t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103 q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -103t0.5 -68q0 -22 -11 -33.5t-22 -13t-33 -1.5 h-224q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
172
- <glyph unicode="&#xf093;" horiz-adv-x="1664" d="M1280 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 288v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h427q21 -56 70.5 -92 t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68zM1339 936q-17 -40 -59 -40h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69z" />
173
- <glyph unicode="&#xf094;" d="M1407 710q0 44 -7 113.5t-18 96.5q-12 30 -17 44t-9 36.5t-4 48.5q0 23 5 68.5t5 67.5q0 37 -10 55q-4 1 -13 1q-19 0 -58 -4.5t-59 -4.5q-60 0 -176 24t-175 24q-43 0 -94.5 -11.5t-85 -23.5t-89.5 -34q-137 -54 -202 -103q-96 -73 -159.5 -189.5t-88 -236t-24.5 -248.5 q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5q24 0 72.5 11t73.5 11q57 0 169.5 -15.5t169.5 -15.5q181 0 284 36q129 45 235.5 152.5t166 245.5t59.5 275zM1535 712q0 -165 -70 -327.5t-196 -288t-281 -180.5q-124 -44 -326 -44 q-57 0 -170 14.5t-169 14.5q-24 0 -72.5 -14.5t-73.5 -14.5q-73 0 -123.5 55.5t-50.5 128.5q0 24 11 68t11 67q0 40 -12.5 120.5t-12.5 121.5q0 111 18 217.5t54.5 209.5t100.5 194t150 156q78 59 232 120q194 78 316 78q60 0 175.5 -24t173.5 -24q19 0 57 5t58 5 q81 0 118 -50.5t37 -134.5q0 -23 -5 -68t-5 -68q0 -10 1 -18.5t3 -17t4 -13.5t6.5 -16t6.5 -17q16 -40 25 -118.5t9 -136.5z" />
174
- <glyph unicode="&#xf095;" horiz-adv-x="1408" d="M1408 296q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -52.5 3.5t-57.5 12.5t-47.5 14.5t-55.5 20.5t-49 18q-98 35 -175 83q-128 79 -264.5 215.5t-215.5 264.5q-48 77 -83 175q-3 9 -18 49t-20.5 55.5t-14.5 47.5t-12.5 57.5t-3.5 52.5 q0 92 51 186q56 101 106 122q25 11 68.5 21t70.5 10q14 0 21 -3q18 -6 53 -76q11 -19 30 -54t35 -63.5t31 -53.5q3 -4 17.5 -25t21.5 -35.5t7 -28.5q0 -20 -28.5 -50t-62 -55t-62 -53t-28.5 -46q0 -9 5 -22.5t8.5 -20.5t14 -24t11.5 -19q76 -137 174 -235t235 -174 q2 -1 19 -11.5t24 -14t20.5 -8.5t22.5 -5q18 0 46 28.5t53 62t55 62t50 28.5q14 0 28.5 -7t35.5 -21.5t25 -17.5q25 -15 53.5 -31t63.5 -35t54 -30q70 -35 76 -53q3 -7 3 -21z" />
175
- <glyph unicode="&#xf096;" horiz-adv-x="1408" d="M1120 1280h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 q119 0 203.5 -84.5t84.5 -203.5z" />
176
- <glyph unicode="&#xf097;" horiz-adv-x="1280" d="M1152 1280h-1024v-1242l423 406l89 85l89 -85l423 -406v1242zM1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289 q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
177
- <glyph unicode="&#xf098;" d="M1280 343q0 11 -2 16q-3 8 -38.5 29.5t-88.5 49.5l-53 29q-5 3 -19 13t-25 15t-21 5q-18 0 -47 -32.5t-57 -65.5t-44 -33q-7 0 -16.5 3.5t-15.5 6.5t-17 9.5t-14 8.5q-99 55 -170.5 126.5t-126.5 170.5q-2 3 -8.5 14t-9.5 17t-6.5 15.5t-3.5 16.5q0 13 20.5 33.5t45 38.5 t45 39.5t20.5 36.5q0 10 -5 21t-15 25t-13 19q-3 6 -15 28.5t-25 45.5t-26.5 47.5t-25 40.5t-16.5 18t-16 2q-48 0 -101 -22q-46 -21 -80 -94.5t-34 -130.5q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5t320.5 -216.5q6 -2 30 -11t33 -12.5 t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
178
- <glyph unicode="&#xf099;" horiz-adv-x="1664" d="M1620 1128q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41 q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50z" />
179
- <glyph unicode="&#xf09a;" horiz-adv-x="768" d="M511 980h257l-30 -284h-227v-824h-341v824h-170v284h170v171q0 182 86 275.5t283 93.5h227v-284h-142q-39 0 -62.5 -6.5t-34 -23.5t-13.5 -34.5t-3 -49.5v-142z" />
180
- <glyph unicode="&#xf09b;" d="M1536 640q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -39.5 7t-12.5 30v211q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5 q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23 q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -89t0.5 -54q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
181
- <glyph unicode="&#xf09c;" horiz-adv-x="1664" d="M1664 960v-256q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-192h96q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5 t316.5 -131.5t131.5 -316.5z" />
182
- <glyph unicode="&#xf09d;" horiz-adv-x="1920" d="M1760 1408q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600zM160 1280q-13 0 -22.5 -9.5t-9.5 -22.5v-224h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600zM1760 0q13 0 22.5 9.5t9.5 22.5v608h-1664v-608 q0 -13 9.5 -22.5t22.5 -9.5h1600zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" />
183
- <glyph unicode="&#xf09e;" horiz-adv-x="1408" d="M384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 69q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5t-391.5 184.5q-25 2 -41.5 20t-16.5 43v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5 t259 -181.5q114 -113 181.5 -259t80.5 -306zM1408 67q2 -27 -18 -47q-18 -20 -46 -20h-143q-26 0 -44.5 17.5t-19.5 42.5q-12 215 -101 408.5t-231.5 336t-336 231.5t-408.5 102q-25 1 -42.5 19.5t-17.5 43.5v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294 q187 -186 294 -425.5t120 -501.5z" />
184
- <glyph unicode="&#xf0a0;" d="M1040 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1296 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1408 160v320q0 13 -9.5 22.5t-22.5 9.5 h-1216q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5zM178 640h1180l-157 482q-4 13 -16 21.5t-26 8.5h-782q-14 0 -26 -8.5t-16 -21.5zM1536 480v-320q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v320q0 25 16 75 l197 606q17 53 63 86t101 33h782q55 0 101 -33t63 -86l197 -606q16 -50 16 -75z" />
185
- <glyph unicode="&#xf0a1;" horiz-adv-x="1792" d="M1664 896q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5v-384q0 -52 -38 -90t-90 -38q-417 347 -812 380q-58 -19 -91 -66t-31 -100.5t40 -92.5q-20 -33 -23 -65.5t6 -58t33.5 -55t48 -50t61.5 -50.5q-29 -58 -111.5 -83t-168.5 -11.5t-132 55.5q-7 23 -29.5 87.5 t-32 94.5t-23 89t-15 101t3.5 98.5t22 110.5h-122q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h480q435 0 896 384q52 0 90 -38t38 -90v-384zM1536 292v954q-394 -302 -768 -343v-270q377 -42 768 -341z" />
186
- <glyph unicode="&#xf0a2;" horiz-adv-x="1664" d="M848 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM183 128h1298q-164 181 -246.5 411.5t-82.5 484.5q0 256 -320 256t-320 -256q0 -254 -82.5 -484.5t-246.5 -411.5zM1664 128q0 -52 -38 -90t-90 -38 h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q190 161 287 397.5t97 498.5q0 165 96 262t264 117q-8 18 -8 37q0 40 28 68t68 28t68 -28t28 -68q0 -19 -8 -37q168 -20 264 -117t96 -262q0 -262 97 -498.5t287 -397.5z" />
187
- <glyph unicode="&#xf0a3;" d="M1376 640l138 -135q30 -28 20 -70q-12 -41 -52 -51l-188 -48l53 -186q12 -41 -19 -70q-29 -31 -70 -19l-186 53l-48 -188q-10 -40 -51 -52q-12 -2 -19 -2q-31 0 -51 22l-135 138l-135 -138q-28 -30 -70 -20q-41 11 -51 52l-48 188l-186 -53q-41 -12 -70 19q-31 29 -19 70 l53 186l-188 48q-40 10 -52 51q-10 42 20 70l138 135l-138 135q-30 28 -20 70q12 41 52 51l188 48l-53 186q-12 41 19 70q29 31 70 19l186 -53l48 188q10 41 51 51q41 12 70 -19l135 -139l135 139q29 30 70 19q41 -10 51 -51l48 -188l186 53q41 12 70 -19q31 -29 19 -70 l-53 -186l188 -48q40 -10 52 -51q10 -42 -20 -70z" />
188
- <glyph unicode="&#xf0a4;" horiz-adv-x="1792" d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 768q0 51 -39 89.5t-89 38.5h-576q0 20 15 48.5t33 55t33 68t15 84.5q0 67 -44.5 97.5t-115.5 30.5q-24 0 -90 -139q-24 -44 -37 -65q-40 -64 -112 -145q-71 -81 -101 -106 q-69 -57 -140 -57h-32v-640h32q72 0 167 -32t193.5 -64t179.5 -32q189 0 189 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5h331q52 0 90 38t38 90zM1792 769q0 -105 -75.5 -181t-180.5 -76h-169q-4 -62 -37 -119q3 -21 3 -43 q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5q-133 0 -322 69q-164 59 -223 59h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h288q10 0 21.5 4.5t23.5 14t22.5 18t24 22.5t20.5 21.5t19 21.5t14 17q65 74 100 129q13 21 33 62t37 72t40.5 63t55 49.5 t69.5 17.5q125 0 206.5 -67t81.5 -189q0 -68 -22 -128h374q104 0 180 -76t76 -179z" />
189
- <glyph unicode="&#xf0a5;" horiz-adv-x="1792" d="M1376 128h32v640h-32q-35 0 -67.5 12t-62.5 37t-50 46t-49 54q-2 3 -3.5 4.5t-4 4.5t-4.5 5q-72 81 -112 145q-14 22 -38 68q-1 3 -10.5 22.5t-18.5 36t-20 35.5t-21.5 30.5t-18.5 11.5q-71 0 -115.5 -30.5t-44.5 -97.5q0 -43 15 -84.5t33 -68t33 -55t15 -48.5h-576 q-50 0 -89 -38.5t-39 -89.5q0 -52 38 -90t90 -38h331q-15 -17 -25 -47.5t-10 -55.5q0 -69 53 -119q-18 -32 -18 -69t17.5 -73.5t47.5 -52.5q-4 -24 -4 -56q0 -85 48.5 -126t135.5 -41q84 0 183 32t194 64t167 32zM1664 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45 t45 -19t45 19t19 45zM1792 768v-640q0 -53 -37.5 -90.5t-90.5 -37.5h-288q-59 0 -223 -59q-190 -69 -317 -69q-142 0 -230 77.5t-87 217.5l1 5q-61 76 -61 178q0 22 3 43q-33 57 -37 119h-169q-105 0 -180.5 76t-75.5 181q0 103 76 179t180 76h374q-22 60 -22 128 q0 122 81.5 189t206.5 67q38 0 69.5 -17.5t55 -49.5t40.5 -63t37 -72t33 -62q35 -55 100 -129q2 -3 14 -17t19 -21.5t20.5 -21.5t24 -22.5t22.5 -18t23.5 -14t21.5 -4.5h288q53 0 90.5 -37.5t37.5 -90.5z" />
190
- <glyph unicode="&#xf0a6;" d="M1280 -64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 700q0 189 -167 189q-26 0 -56 -5q-16 30 -52.5 47.5t-73.5 17.5t-69 -18q-50 53 -119 53q-25 0 -55.5 -10t-47.5 -25v331q0 52 -38 90t-90 38q-51 0 -89.5 -39t-38.5 -89v-576 q-20 0 -48.5 15t-55 33t-68 33t-84.5 15q-67 0 -97.5 -44.5t-30.5 -115.5q0 -24 139 -90q44 -24 65 -37q64 -40 145 -112q81 -71 106 -101q57 -69 57 -140v-32h640v32q0 72 32 167t64 193.5t32 179.5zM1536 705q0 -133 -69 -322q-59 -164 -59 -223v-288q0 -53 -37.5 -90.5 t-90.5 -37.5h-640q-53 0 -90.5 37.5t-37.5 90.5v288q0 10 -4.5 21.5t-14 23.5t-18 22.5t-22.5 24t-21.5 20.5t-21.5 19t-17 14q-74 65 -129 100q-21 13 -62 33t-72 37t-63 40.5t-49.5 55t-17.5 69.5q0 125 67 206.5t189 81.5q68 0 128 -22v374q0 104 76 180t179 76 q105 0 181 -75.5t76 -180.5v-169q62 -4 119 -37q21 3 43 3q101 0 178 -60q139 1 219.5 -85t80.5 -227z" />
191
- <glyph unicode="&#xf0a7;" d="M1408 576q0 84 -32 183t-64 194t-32 167v32h-640v-32q0 -35 -12 -67.5t-37 -62.5t-46 -50t-54 -49q-9 -8 -14 -12q-81 -72 -145 -112q-22 -14 -68 -38q-3 -1 -22.5 -10.5t-36 -18.5t-35.5 -20t-30.5 -21.5t-11.5 -18.5q0 -71 30.5 -115.5t97.5 -44.5q43 0 84.5 15t68 33 t55 33t48.5 15v-576q0 -50 38.5 -89t89.5 -39q52 0 90 38t38 90v331q46 -35 103 -35q69 0 119 53q32 -18 69 -18t73.5 17.5t52.5 47.5q24 -4 56 -4q85 0 126 48.5t41 135.5zM1280 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 580 q0 -142 -77.5 -230t-217.5 -87l-5 1q-76 -61 -178 -61q-22 0 -43 3q-54 -30 -119 -37v-169q0 -105 -76 -180.5t-181 -75.5q-103 0 -179 76t-76 180v374q-54 -22 -128 -22q-121 0 -188.5 81.5t-67.5 206.5q0 38 17.5 69.5t49.5 55t63 40.5t72 37t62 33q55 35 129 100 q3 2 17 14t21.5 19t21.5 20.5t22.5 24t18 22.5t14 23.5t4.5 21.5v288q0 53 37.5 90.5t90.5 37.5h640q53 0 90.5 -37.5t37.5 -90.5v-288q0 -59 59 -223q69 -190 69 -317z" />
192
- <glyph unicode="&#xf0a8;" d="M1280 576v128q0 26 -19 45t-45 19h-502l189 189q19 19 19 45t-19 45l-91 91q-18 18 -45 18t-45 -18l-362 -362l-91 -91q-18 -18 -18 -45t18 -45l91 -91l362 -362q18 -18 45 -18t45 18l91 91q18 18 18 45t-18 45l-189 189h502q26 0 45 19t19 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
193
- <glyph unicode="&#xf0a9;" d="M1285 640q0 27 -18 45l-91 91l-362 362q-18 18 -45 18t-45 -18l-91 -91q-18 -18 -18 -45t18 -45l189 -189h-502q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h502l-189 -189q-19 -19 -19 -45t19 -45l91 -91q18 -18 45 -18t45 18l362 362l91 91q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
194
- <glyph unicode="&#xf0aa;" d="M1284 641q0 27 -18 45l-362 362l-91 91q-18 18 -45 18t-45 -18l-91 -91l-362 -362q-18 -18 -18 -45t18 -45l91 -91q18 -18 45 -18t45 18l189 189v-502q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v502l189 -189q19 -19 45 -19t45 19l91 91q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
195
- <glyph unicode="&#xf0ab;" d="M1284 639q0 27 -18 45l-91 91q-18 18 -45 18t-45 -18l-189 -189v502q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-502l-189 189q-19 19 -45 19t-45 -19l-91 -91q-18 -18 -18 -45t18 -45l362 -362l91 -91q18 -18 45 -18t45 18l91 91l362 362q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
196
- <glyph unicode="&#xf0ac;" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1042 887q-2 -1 -9.5 -9.5t-13.5 -9.5q2 0 4.5 5t5 11t3.5 7q6 7 22 15q14 6 52 12q34 8 51 -11 q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8q0 7 -4.5 8t-11.5 -1t-9 -1q-10 3 -15 7.5t-8 16.5t-4 15q-2 5 -9.5 10.5t-9.5 10.5q-1 2 -2.5 5.5t-3 6.5t-4 5.5t-5.5 2.5t-7 -5t-7.5 -10t-4.5 -5q-3 2 -6 1.5t-4.5 -1t-4.5 -3t-5 -3.5 q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5q-1 4 -8.5 8.5t-17.5 8.5t-13 6q-8 5 -34 9.5t-33 0.5q-5 -6 -4.5 -10.5t4 -14t3.5 -12.5q1 -6 -5.5 -13t-6.5 -12q0 -7 14 -15.5t10 -21.5q-3 -8 -16 -16t-16 -12q-5 -8 -1.5 -18.5t10.5 -16.5 q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26q-7 25 -16 30q-23 8 -29 -1q-5 13 -41 26q-25 9 -58 4q6 1 0 15q-7 15 -19 12q3 6 4 17.5t1 13.5q3 13 12 23q1 1 7 8.5t9.5 13.5t0.5 6q35 -4 50 11q5 5 11.5 17t10.5 17q9 6 14 5.5t14.5 -5.5 t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-5 7 -8 9q-12 4 -27 -5q-8 -4 2 -8q-1 1 -9.5 -10.5t-16.5 -17.5t-16 5q-1 1 -5.5 13.5t-9.5 13.5q-8 0 -16 -15q3 8 -11 15t-24 8q19 12 -8 27q-7 4 -20.5 5t-19.5 -4q-5 -7 -5.5 -11.5t5 -8t10.5 -5.5t11.5 -4t8.5 -3 q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14q-5 5 -9 17.5t-7 16.5q7 -9 -25 -6l-10 1q-4 0 -16 -2t-20.5 -1t-13.5 8q-4 8 0 20q1 4 4 2q-4 3 -11 9.5t-10 8.5q-46 -15 -94 -41q6 -1 12 1q5 2 13 6.5t10 5.5q34 14 42 7l5 5q14 -16 20 -25 q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5q-16 0 -22 -1q-146 -80 -235 -222q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5 t-1 -23.5l2 -1q-3 -12 5.5 -34.5t21.5 -19.5q-13 -3 20 -43q6 -8 8 -9q3 -2 12 -7.5t15 -10t10 -10.5q4 -5 10 -22.5t14 -23.5q-2 -6 9.5 -20t10.5 -23q-1 0 -2.5 -1t-2.5 -1q3 -7 15.5 -14t15.5 -13q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-15 25 -17 29q-3 5 -5.5 15.5 t-4.5 14.5q2 0 6 -1.5t8.5 -3.5t7.5 -4t2 -3q-3 -7 2 -17.5t12 -18.5t17 -19t12 -13q6 -6 14 -19.5t0 -13.5q9 0 20 -10t17 -20q5 -8 8 -26t5 -24q2 -7 8.5 -13.5t12.5 -9.5l16 -8t13 -7q5 -2 18.5 -10.5t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21 q36 -19 55 -11q-2 -1 0.5 -7.5t8 -15.5t9 -14.5t5.5 -8.5q5 -6 18 -15t18 -15q6 4 7 9q-3 -8 7 -20t18 -10q14 3 14 32q-31 -15 -49 18q0 1 -2.5 5.5t-4 8.5t-2.5 8.5t0 7.5t5 3q9 0 10 3.5t-2 12.5t-4 13q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5 q-13 0 -15 1q1 3 2.5 17.5t3.5 22.5q1 4 5.5 12t7.5 14.5t4 12.5t-4.5 9.5t-17.5 2.5q-19 -1 -26 -20q-1 -3 -3 -10.5t-5 -11.5t-9 -7q-7 -3 -24 -2t-24 5q-13 8 -22.5 29t-9.5 37q0 10 2.5 26.5t3 25t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3 q-3 3 -4 3q7 -3 28.5 1.5t27.5 -1.5q15 -11 22 2q0 1 -2.5 9.5t-0.5 13.5q5 -27 29 -9q3 -3 15.5 -5t17.5 -5q3 -2 7 -5.5t5.5 -4.5t5 0.5t8.5 6.5q10 -14 12 -24q11 -40 19 -44q7 -3 11 -2t4.5 9.5t0 14t-1.5 12.5l-1 8v18l-1 8q-15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5 t15.5 6.5t12.5 8q21 19 15 35q7 0 11 9q-1 0 -5 3t-7.5 5t-4.5 2q9 5 2 16q5 3 7.5 11t7.5 10q9 -12 21 -2q7 8 1 16q5 7 20.5 10.5t18.5 9.5q7 -2 8 2t1 12t3 12q4 5 15 9t13 5l17 11q3 4 0 4q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5 q15 10 -7 16q-17 5 -43 -12zM879 10q206 36 351 189q-3 3 -12.5 4.5t-12.5 3.5q-18 7 -24 8q1 7 -2.5 13t-8 9t-12.5 8t-11 7q-2 2 -7 6t-7 5.5t-7.5 4.5t-8.5 2t-10 -1l-3 -1q-3 -1 -5.5 -2.5t-5.5 -3t-4 -3t0 -2.5q-21 17 -36 22q-5 1 -11 5.5t-10.5 7t-10 1.5t-11.5 -7 q-5 -5 -6 -15t-2 -13q-7 5 0 17.5t2 18.5q-3 6 -10.5 4.5t-12 -4.5t-11.5 -8.5t-9 -6.5t-8.5 -5.5t-8.5 -7.5q-3 -4 -6 -12t-5 -11q-2 4 -11.5 6.5t-9.5 5.5q2 -10 4 -35t5 -38q7 -31 -12 -48q-27 -25 -29 -40q-4 -22 12 -26q0 -7 -8 -20.5t-7 -21.5q0 -6 2 -16z" />
197
- <glyph unicode="&#xf0ad;" horiz-adv-x="1664" d="M384 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1028 484l-682 -682q-37 -37 -90 -37q-52 0 -91 37l-106 108q-38 36 -38 90q0 53 38 91l681 681q39 -98 114.5 -173.5t173.5 -114.5zM1662 919q0 -39 -23 -106q-47 -134 -164.5 -217.5 t-258.5 -83.5q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q58 0 121.5 -16.5t107.5 -46.5q16 -11 16 -28t-16 -28l-293 -169v-224l193 -107q5 3 79 48.5t135.5 81t70.5 35.5q15 0 23.5 -10t8.5 -25z" />
198
- <glyph unicode="&#xf0ae;" horiz-adv-x="1792" d="M1024 128h640v128h-640v-128zM640 640h1024v128h-1024v-128zM1280 1152h384v128h-384v-128zM1792 320v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 832v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19 t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" />
199
- <glyph unicode="&#xf0b0;" horiz-adv-x="1408" d="M1403 1241q17 -41 -14 -70l-493 -493v-742q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-256 256q-19 19 -19 45v486l-493 493q-31 29 -14 70q17 39 59 39h1280q42 0 59 -39z" />
200
- <glyph unicode="&#xf0b1;" horiz-adv-x="1792" d="M640 1280h512v128h-512v-128zM1792 640v-480q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v480h672v-160q0 -26 19 -45t45 -19h320q26 0 45 19t19 45v160h672zM1024 640v-128h-256v128h256zM1792 1120v-384h-1792v384q0 66 47 113t113 47h352v160q0 40 28 68 t68 28h576q40 0 68 -28t28 -68v-160h352q66 0 113 -47t47 -113z" />
201
- <glyph unicode="&#xf0b2;" d="M1283 995l-355 -355l355 -355l144 144q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l144 144l-355 355l-355 -355l144 -144q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l144 -144 l355 355l-355 355l-144 -144q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v448q0 26 19 45t45 19h448q42 0 59 -40q17 -39 -14 -69l-144 -144l355 -355l355 355l-144 144q-31 30 -14 69q17 40 59 40h448q26 0 45 -19t19 -45v-448q0 -42 -39 -59q-13 -5 -25 -5q-26 0 -45 19z " />
202
- <glyph unicode="&#xf0c0;" horiz-adv-x="1920" d="M593 640q-162 -5 -265 -128h-134q-82 0 -138 40.5t-56 118.5q0 353 124 353q6 0 43.5 -21t97.5 -42.5t119 -21.5q67 0 133 23q-5 -37 -5 -66q0 -139 81 -256zM1664 3q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5 t43 97.5t62 81t85.5 53.5t111.5 20q10 0 43 -21.5t73 -48t107 -48t135 -21.5t135 21.5t107 48t73 48t43 21.5q61 0 111.5 -20t85.5 -53.5t62 -81t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM640 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75 t75 -181zM1344 896q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5zM1920 671q0 -78 -56 -118.5t-138 -40.5h-134q-103 123 -265 128q81 117 81 256q0 29 -5 66q66 -23 133 -23q59 0 119 21.5t97.5 42.5 t43.5 21q124 0 124 -353zM1792 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181z" />
203
- <glyph unicode="&#xf0c1;" horiz-adv-x="1664" d="M1456 320q0 40 -28 68l-208 208q-28 28 -68 28q-42 0 -72 -32q3 -3 19 -18.5t21.5 -21.5t15 -19t13 -25.5t3.5 -27.5q0 -40 -28 -68t-68 -28q-15 0 -27.5 3.5t-25.5 13t-19 15t-21.5 21.5t-18.5 19q-33 -31 -33 -73q0 -40 28 -68l206 -207q27 -27 68 -27q40 0 68 26 l147 146q28 28 28 67zM753 1025q0 40 -28 68l-206 207q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l208 -208q27 -27 68 -27q42 0 72 31q-3 3 -19 18.5t-21.5 21.5t-15 19t-13 25.5t-3.5 27.5q0 40 28 68t68 28q15 0 27.5 -3.5t25.5 -13t19 -15 t21.5 -21.5t18.5 -19q33 31 33 73zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-206 207q-83 83 -83 203q0 123 88 209l-88 88q-86 -88 -208 -88q-120 0 -204 84l-208 208q-84 84 -84 204t85 203l147 146q83 83 203 83q121 0 204 -85l206 -207 q83 -83 83 -203q0 -123 -88 -209l88 -88q86 88 208 88q120 0 204 -84l208 -208q84 -84 84 -204z" />
204
- <glyph unicode="&#xf0c2;" horiz-adv-x="1920" d="M1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5q0 132 71 241.5t187 163.5q-2 28 -2 43q0 212 150 362t362 150q158 0 286.5 -88t187.5 -230q70 62 166 62q106 0 181 -75t75 -181q0 -75 -41 -138q129 -30 213 -134.5t84 -239.5z " />
205
- <glyph unicode="&#xf0c3;" horiz-adv-x="1664" d="M1527 88q56 -89 21.5 -152.5t-140.5 -63.5h-1152q-106 0 -140.5 63.5t21.5 152.5l503 793v399h-64q-26 0 -45 19t-19 45t19 45t45 19h512q26 0 45 -19t19 -45t-19 -45t-45 -19h-64v-399zM748 813l-272 -429h712l-272 429l-20 31v37v399h-128v-399v-37z" />
206
- <glyph unicode="&#xf0c4;" horiz-adv-x="1792" d="M960 640q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1260 576l507 -398q28 -20 25 -56q-5 -35 -35 -51l-128 -64q-13 -7 -29 -7q-17 0 -31 8l-690 387l-110 -66q-8 -4 -12 -5q14 -49 10 -97q-7 -77 -56 -147.5t-132 -123.5q-132 -84 -277 -84 q-136 0 -222 78q-90 84 -79 207q7 76 56 147t131 124q132 84 278 84q83 0 151 -31q9 13 22 22l122 73l-122 73q-13 9 -22 22q-68 -31 -151 -31q-146 0 -278 84q-82 53 -131 124t-56 147q-5 59 15.5 113t63.5 93q85 79 222 79q145 0 277 -84q83 -52 132 -123t56 -148 q4 -48 -10 -97q4 -1 12 -5l110 -66l690 387q14 8 31 8q16 0 29 -7l128 -64q30 -16 35 -51q3 -36 -25 -56zM579 836q46 42 21 108t-106 117q-92 59 -192 59q-74 0 -113 -36q-46 -42 -21 -108t106 -117q92 -59 192 -59q74 0 113 36zM494 91q81 51 106 117t-21 108 q-39 36 -113 36q-100 0 -192 -59q-81 -51 -106 -117t21 -108q39 -36 113 -36q100 0 192 59zM672 704l96 -58v11q0 36 33 56l14 8l-79 47l-26 -26q-3 -3 -10 -11t-12 -12q-2 -2 -4 -3.5t-3 -2.5zM896 480l96 -32l736 576l-128 64l-768 -431v-113l-160 -96l9 -8q2 -2 7 -6 q4 -4 11 -12t11 -12l26 -26zM1600 64l128 64l-520 408l-177 -138q-2 -3 -13 -7z" />
207
- <glyph unicode="&#xf0c5;" horiz-adv-x="1792" d="M1696 1152q40 0 68 -28t28 -68v-1216q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v288h-544q-40 0 -68 28t-28 68v672q0 40 20 88t48 76l408 408q28 28 76 48t88 20h416q40 0 68 -28t28 -68v-328q68 40 128 40h416zM1152 939l-299 -299h299v299zM512 1323l-299 -299 h299v299zM708 676l316 316v416h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h512v256q0 40 20 88t48 76zM1664 -128v1152h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h896z" />
208
- <glyph unicode="&#xf0c6;" horiz-adv-x="1408" d="M1404 151q0 -117 -79 -196t-196 -79q-135 0 -235 100l-777 776q-113 115 -113 271q0 159 110 270t269 111q158 0 273 -113l605 -606q10 -10 10 -22q0 -16 -30.5 -46.5t-46.5 -30.5q-13 0 -23 10l-606 607q-79 77 -181 77q-106 0 -179 -75t-73 -181q0 -105 76 -181 l776 -777q63 -63 145 -63q64 0 106 42t42 106q0 82 -63 145l-581 581q-26 24 -60 24q-29 0 -48 -19t-19 -48q0 -32 25 -59l410 -410q10 -10 10 -22q0 -16 -31 -47t-47 -31q-12 0 -22 10l-410 410q-63 61 -63 149q0 82 57 139t139 57q88 0 149 -63l581 -581q100 -98 100 -235 z" />
209
- <glyph unicode="&#xf0c7;" d="M384 0h768v384h-768v-384zM1280 0h128v896q0 14 -10 38.5t-20 34.5l-281 281q-10 10 -34 20t-39 10v-416q0 -40 -28 -68t-68 -28h-576q-40 0 -68 28t-28 68v416h-128v-1280h128v416q0 40 28 68t68 28h832q40 0 68 -28t28 -68v-416zM896 928v320q0 13 -9.5 22.5t-22.5 9.5 h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5zM1536 896v-928q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h928q40 0 88 -20t76 -48l280 -280q28 -28 48 -76t20 -88z" />
210
- <glyph unicode="&#xf0c8;" d="M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
211
- <glyph unicode="&#xf0c9;" d="M1536 192v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 704v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 1216v-128q0 -26 -19 -45 t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
212
- <glyph unicode="&#xf0ca;" horiz-adv-x="1792" d="M384 128q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 640q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1152q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z M1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" />
213
- <glyph unicode="&#xf0cb;" horiz-adv-x="1792" d="M381 -84q0 -80 -54.5 -126t-135.5 -46q-106 0 -172 66l57 88q49 -45 106 -45q29 0 50.5 14.5t21.5 42.5q0 64 -105 56l-26 56q8 10 32.5 43.5t42.5 54t37 38.5v1q-16 0 -48.5 -1t-48.5 -1v-53h-106v152h333v-88l-95 -115q51 -12 81 -49t30 -88zM383 543v-159h-362 q-6 36 -6 54q0 51 23.5 93t56.5 68t66 47.5t56.5 43.5t23.5 45q0 25 -14.5 38.5t-39.5 13.5q-46 0 -81 -58l-85 59q24 51 71.5 79.5t105.5 28.5q73 0 123 -41.5t50 -112.5q0 -50 -34 -91.5t-75 -64.5t-75.5 -50.5t-35.5 -52.5h127v60h105zM1792 224v-192q0 -13 -9.5 -22.5 t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1123v-99h-335v99h107q0 41 0.5 122t0.5 121v12h-2q-8 -17 -50 -54l-71 76l136 127h106v-404h108zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5 t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" />
214
- <glyph unicode="&#xf0cc;" horiz-adv-x="1792" d="M1760 640q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h1728zM483 704q-28 35 -51 80q-48 97 -48 188q0 181 134 309q133 127 393 127q50 0 167 -19q66 -12 177 -48q10 -38 21 -118q14 -123 14 -183q0 -18 -5 -45l-12 -3l-84 6 l-14 2q-50 149 -103 205q-88 91 -210 91q-114 0 -182 -59q-67 -58 -67 -146q0 -73 66 -140t279 -129q69 -20 173 -66q58 -28 95 -52h-743zM990 448h411q7 -39 7 -92q0 -111 -41 -212q-23 -55 -71 -104q-37 -35 -109 -81q-80 -48 -153 -66q-80 -21 -203 -21q-114 0 -195 23 l-140 40q-57 16 -72 28q-8 8 -8 22v13q0 108 -2 156q-1 30 0 68l2 37v44l102 2q15 -34 30 -71t22.5 -56t12.5 -27q35 -57 80 -94q43 -36 105 -57q59 -22 132 -22q64 0 139 27q77 26 122 86q47 61 47 129q0 84 -81 157q-34 29 -137 71z" />
215
- <glyph unicode="&#xf0cd;" d="M48 1313q-37 2 -45 4l-3 88q13 1 40 1q60 0 112 -4q132 -7 166 -7q86 0 168 3q116 4 146 5q56 0 86 2l-1 -14l2 -64v-9q-60 -9 -124 -9q-60 0 -79 -25q-13 -14 -13 -132q0 -13 0.5 -32.5t0.5 -25.5l1 -229l14 -280q6 -124 51 -202q35 -59 96 -92q88 -47 177 -47 q104 0 191 28q56 18 99 51q48 36 65 64q36 56 53 114q21 73 21 229q0 79 -3.5 128t-11 122.5t-13.5 159.5l-4 59q-5 67 -24 88q-34 35 -77 34l-100 -2l-14 3l2 86h84l205 -10q76 -3 196 10l18 -2q6 -38 6 -51q0 -7 -4 -31q-45 -12 -84 -13q-73 -11 -79 -17q-15 -15 -15 -41 q0 -7 1.5 -27t1.5 -31q8 -19 22 -396q6 -195 -15 -304q-15 -76 -41 -122q-38 -65 -112 -123q-75 -57 -182 -89q-109 -33 -255 -33q-167 0 -284 46q-119 47 -179 122q-61 76 -83 195q-16 80 -16 237v333q0 188 -17 213q-25 36 -147 39zM1536 -96v64q0 14 -9 23t-23 9h-1472 q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h1472q14 0 23 9t9 23z" />
216
- <glyph unicode="&#xf0ce;" horiz-adv-x="1664" d="M512 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23 v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 160v192 q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192 q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1664 1248v-1088q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1344q66 0 113 -47t47 -113 z" />
217
- <glyph unicode="&#xf0d0;" horiz-adv-x="1664" d="M1190 955l293 293l-107 107l-293 -293zM1637 1248q0 -27 -18 -45l-1286 -1286q-18 -18 -45 -18t-45 18l-198 198q-18 18 -18 45t18 45l1286 1286q18 18 45 18t45 -18l198 -198q18 -18 18 -45zM286 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM636 1276 l196 -60l-196 -60l-60 -196l-60 196l-196 60l196 60l60 196zM1566 798l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM926 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98z" />
218
- <glyph unicode="&#xf0d1;" horiz-adv-x="1792" d="M640 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM256 640h384v256h-158q-13 0 -22 -9l-195 -195q-9 -9 -9 -22v-30zM1536 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1792 1216v-1024q0 -15 -4 -26.5t-13.5 -18.5 t-16.5 -11.5t-23.5 -6t-22.5 -2t-25.5 0t-22.5 0.5q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-64q-3 0 -22.5 -0.5t-25.5 0t-22.5 2t-23.5 6t-16.5 11.5t-13.5 18.5t-4 26.5q0 26 19 45t45 19v320q0 8 -0.5 35t0 38 t2.5 34.5t6.5 37t14 30.5t22.5 30l198 198q19 19 50.5 32t58.5 13h160v192q0 26 19 45t45 19h1024q26 0 45 -19t19 -45z" />
219
- <glyph unicode="&#xf0d2;" d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103q-111 0 -218 32q59 93 78 164q9 34 54 211q20 -39 73 -67.5t114 -28.5q121 0 216 68.5t147 188.5t52 270q0 114 -59.5 214t-172.5 163t-255 63q-105 0 -196 -29t-154.5 -77t-109 -110.5t-67 -129.5t-21.5 -134 q0 -104 40 -183t117 -111q30 -12 38 20q2 7 8 31t8 30q6 23 -11 43q-51 61 -51 151q0 151 104.5 259.5t273.5 108.5q151 0 235.5 -82t84.5 -213q0 -170 -68.5 -289t-175.5 -119q-61 0 -98 43.5t-23 104.5q8 35 26.5 93.5t30 103t11.5 75.5q0 50 -27 83t-77 33 q-62 0 -105 -57t-43 -142q0 -73 25 -122l-99 -418q-17 -70 -13 -177q-206 91 -333 281t-127 423q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
220
- <glyph unicode="&#xf0d3;" d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-725q85 122 108 210q9 34 53 209q21 -39 73.5 -67t112.5 -28q181 0 295.5 147.5t114.5 373.5q0 84 -35 162.5t-96.5 139t-152.5 97t-197 36.5q-104 0 -194.5 -28.5t-153 -76.5 t-107.5 -109.5t-66.5 -128t-21.5 -132.5q0 -102 39.5 -180t116.5 -110q13 -5 23.5 0t14.5 19q10 44 15 61q6 23 -11 42q-50 62 -50 150q0 150 103.5 256.5t270.5 106.5q149 0 232.5 -81t83.5 -210q0 -168 -67.5 -286t-173.5 -118q-60 0 -97 43.5t-23 103.5q8 34 26.5 92.5 t29.5 102t11 74.5q0 49 -26.5 81.5t-75.5 32.5q-61 0 -103.5 -56.5t-42.5 -139.5q0 -72 24 -121l-98 -414q-24 -100 -7 -254h-183q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960z" />
221
- <glyph unicode="&#xf0d4;" d="M678 -57q0 -38 -10 -71h-380q-95 0 -171.5 56.5t-103.5 147.5q24 45 69 77.5t100 49.5t107 24t107 7q32 0 49 -2q6 -4 30.5 -21t33 -23t31 -23t32 -25.5t27.5 -25.5t26.5 -29.5t21 -30.5t17.5 -34.5t9.5 -36t4.5 -40.5zM385 294q-234 -7 -385 -85v433q103 -118 273 -118 q32 0 70 5q-21 -61 -21 -86q0 -67 63 -149zM558 805q0 -100 -43.5 -160.5t-140.5 -60.5q-51 0 -97 26t-78 67.5t-56 93.5t-35.5 104t-11.5 99q0 96 51.5 165t144.5 69q66 0 119 -41t84 -104t47 -130t16 -128zM1536 896v-736q0 -119 -84.5 -203.5t-203.5 -84.5h-468 q39 73 39 157q0 66 -22 122.5t-55.5 93t-72 71t-72 59.5t-55.5 54.5t-22 59.5q0 36 23 68t56 61.5t65.5 64.5t55.5 93t23 131t-26.5 145.5t-75.5 118.5q-6 6 -14 11t-12.5 7.5t-10 9.5t-10.5 17h135l135 64h-437q-138 0 -244.5 -38.5t-182.5 -133.5q0 126 81 213t207 87h960 q119 0 203.5 -84.5t84.5 -203.5v-96h-256v256h-128v-256h-256v-128h256v-256h128v256h256z" />
222
- <glyph unicode="&#xf0d5;" horiz-adv-x="1664" d="M876 71q0 21 -4.5 40.5t-9.5 36t-17.5 34.5t-21 30.5t-26.5 29.5t-27.5 25.5t-32 25.5t-31 23t-33 23t-30.5 21q-17 2 -50 2q-54 0 -106 -7t-108 -25t-98 -46t-69 -75t-27 -107q0 -68 35.5 -121.5t93 -84t120.5 -45.5t127 -15q59 0 112.5 12.5t100.5 39t74.5 73.5 t27.5 110zM756 933q0 60 -16.5 127.5t-47 130.5t-84 104t-119.5 41q-93 0 -144 -69t-51 -165q0 -47 11.5 -99t35.5 -104t56 -93.5t78 -67.5t97 -26q97 0 140.5 60.5t43.5 160.5zM625 1408h437l-135 -79h-135q71 -45 110 -126t39 -169q0 -74 -23 -131.5t-56 -92.5t-66 -64.5 t-56 -61t-23 -67.5q0 -26 16.5 -51t43 -48t58.5 -48t64 -55.5t58.5 -66t43 -85t16.5 -106.5q0 -160 -140 -282q-152 -131 -420 -131q-59 0 -119.5 10t-122 33.5t-108.5 58t-77 89t-30 121.5q0 61 37 135q32 64 96 110.5t145 71t155 36t150 13.5q-64 83 -64 149q0 12 2 23.5 t5 19.5t8 21.5t7 21.5q-40 -5 -70 -5q-149 0 -255.5 98t-106.5 246q0 140 95 250.5t234 141.5q94 20 187 20zM1664 1152v-128h-256v-256h-128v256h-256v128h256v256h128v-256h256z" />
223
- <glyph unicode="&#xf0d6;" horiz-adv-x="1920" d="M768 384h384v96h-128v448h-114l-148 -137l77 -80q42 37 55 57h2v-288h-128v-96zM1280 640q0 -70 -21 -142t-59.5 -134t-101.5 -101t-138 -39t-138 39t-101.5 101t-59.5 134t-21 142t21 142t59.5 134t101.5 101t138 39t138 -39t101.5 -101t59.5 -134t21 -142zM1792 384 v512q-106 0 -181 75t-75 181h-1152q0 -106 -75 -181t-181 -75v-512q106 0 181 -75t75 -181h1152q0 106 75 181t181 75zM1920 1216v-1152q0 -26 -19 -45t-45 -19h-1792q-26 0 -45 19t-19 45v1152q0 26 19 45t45 19h1792q26 0 45 -19t19 -45z" />
224
- <glyph unicode="&#xf0d7;" horiz-adv-x="1024" d="M1024 832q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" />
225
- <glyph unicode="&#xf0d8;" horiz-adv-x="1024" d="M1024 320q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
226
- <glyph unicode="&#xf0d9;" horiz-adv-x="640" d="M640 1088v-896q0 -26 -19 -45t-45 -19t-45 19l-448 448q-19 19 -19 45t19 45l448 448q19 19 45 19t45 -19t19 -45z" />
227
- <glyph unicode="&#xf0da;" horiz-adv-x="640" d="M576 640q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19t-19 45v896q0 26 19 45t45 19t45 -19l448 -448q19 -19 19 -45z" />
228
- <glyph unicode="&#xf0db;" horiz-adv-x="1664" d="M160 0h608v1152h-640v-1120q0 -13 9.5 -22.5t22.5 -9.5zM1536 32v1120h-640v-1152h608q13 0 22.5 9.5t9.5 22.5zM1664 1248v-1216q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1344q66 0 113 -47t47 -113z" />
229
- <glyph unicode="&#xf0dc;" horiz-adv-x="1024" d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45zM1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
230
- <glyph unicode="&#xf0dd;" horiz-adv-x="1024" d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" />
231
- <glyph unicode="&#xf0de;" horiz-adv-x="1024" d="M1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
232
- <glyph unicode="&#xf0e0;" horiz-adv-x="1792" d="M1792 826v-794q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v794q44 -49 101 -87q362 -246 497 -345q57 -42 92.5 -65.5t94.5 -48t110 -24.5h1h1q51 0 110 24.5t94.5 48t92.5 65.5q170 123 498 345q57 39 100 87zM1792 1120q0 -79 -49 -151t-122 -123 q-376 -261 -468 -325q-10 -7 -42.5 -30.5t-54 -38t-52 -32.5t-57.5 -27t-50 -9h-1h-1q-23 0 -50 9t-57.5 27t-52 32.5t-54 38t-42.5 30.5q-91 64 -262 182.5t-205 142.5q-62 42 -117 115.5t-55 136.5q0 78 41.5 130t118.5 52h1472q65 0 112.5 -47t47.5 -113z" />
233
- <glyph unicode="&#xf0e1;" d="M349 911v-991h-330v991h330zM370 1217q1 -73 -50.5 -122t-135.5 -49h-2q-82 0 -132 49t-50 122q0 74 51.5 122.5t134.5 48.5t133 -48.5t51 -122.5zM1536 488v-568h-329v530q0 105 -40.5 164.5t-126.5 59.5q-63 0 -105.5 -34.5t-63.5 -85.5q-11 -30 -11 -81v-553h-329 q2 399 2 647t-1 296l-1 48h329v-144h-2q20 32 41 56t56.5 52t87 43.5t114.5 15.5q171 0 275 -113.5t104 -332.5z" />
234
- <glyph unicode="&#xf0e2;" d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5 t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298z" />
235
- <glyph unicode="&#xf0e3;" horiz-adv-x="1792" d="M1771 0q0 -53 -37 -90l-107 -108q-39 -37 -91 -37q-53 0 -90 37l-363 364q-38 36 -38 90q0 53 43 96l-256 256l-126 -126q-14 -14 -34 -14t-34 14q2 -2 12.5 -12t12.5 -13t10 -11.5t10 -13.5t6 -13.5t5.5 -16.5t1.5 -18q0 -38 -28 -68q-3 -3 -16.5 -18t-19 -20.5 t-18.5 -16.5t-22 -15.5t-22 -9t-26 -4.5q-40 0 -68 28l-408 408q-28 28 -28 68q0 13 4.5 26t9 22t15.5 22t16.5 18.5t20.5 19t18 16.5q30 28 68 28q10 0 18 -1.5t16.5 -5.5t13.5 -6t13.5 -10t11.5 -10t13 -12.5t12 -12.5q-14 14 -14 34t14 34l348 348q14 14 34 14t34 -14 q-2 2 -12.5 12t-12.5 13t-10 11.5t-10 13.5t-6 13.5t-5.5 16.5t-1.5 18q0 38 28 68q3 3 16.5 18t19 20.5t18.5 16.5t22 15.5t22 9t26 4.5q40 0 68 -28l408 -408q28 -28 28 -68q0 -13 -4.5 -26t-9 -22t-15.5 -22t-16.5 -18.5t-20.5 -19t-18 -16.5q-30 -28 -68 -28 q-10 0 -18 1.5t-16.5 5.5t-13.5 6t-13.5 10t-11.5 10t-13 12.5t-12 12.5q14 -14 14 -34t-14 -34l-126 -126l256 -256q43 43 96 43q52 0 91 -37l363 -363q37 -39 37 -91z" />
236
- <glyph unicode="&#xf0e4;" horiz-adv-x="1792" d="M384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM576 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1004 351l101 382q6 26 -7.5 48.5t-38.5 29.5 t-48 -6.5t-30 -39.5l-101 -382q-60 -5 -107 -43.5t-63 -98.5q-20 -77 20 -146t117 -89t146 20t89 117q16 60 -6 117t-72 91zM1664 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 1024q0 53 -37.5 90.5 t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1472 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1792 384q0 -261 -141 -483q-19 -29 -54 -29h-1402q-35 0 -54 29 q-141 221 -141 483q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
237
- <glyph unicode="&#xf0e5;" horiz-adv-x="1792" d="M896 1152q-204 0 -381.5 -69.5t-282 -187.5t-104.5 -255q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5t104.5 255t-104.5 255t-282 187.5t-381.5 69.5zM1792 640 q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281q0 174 120 321.5 t326 233t450 85.5t450 -85.5t326 -233t120 -321.5z" />
238
- <glyph unicode="&#xf0e6;" horiz-adv-x="1792" d="M704 1152q-153 0 -286 -52t-211.5 -141t-78.5 -191q0 -82 53 -158t149 -132l97 -56l-35 -84q34 20 62 39l44 31l53 -10q78 -14 153 -14q153 0 286 52t211.5 141t78.5 191t-78.5 191t-211.5 141t-286 52zM704 1280q191 0 353.5 -68.5t256.5 -186.5t94 -257t-94 -257 t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224q0 139 94 257t256.5 186.5 t353.5 68.5zM1526 111q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129 q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5z" />
239
- <glyph unicode="&#xf0e7;" horiz-adv-x="896" d="M885 970q18 -20 7 -44l-540 -1157q-13 -25 -42 -25q-4 0 -14 2q-17 5 -25.5 19t-4.5 30l197 808l-406 -101q-4 -1 -12 -1q-18 0 -31 11q-18 15 -13 39l201 825q4 14 16 23t28 9h328q19 0 32 -12.5t13 -29.5q0 -8 -5 -18l-171 -463l396 98q8 2 12 2q19 0 34 -15z" />
240
- <glyph unicode="&#xf0e8;" horiz-adv-x="1792" d="M1792 288v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320 q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192q0 52 38 90t90 38h512v192h-96q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-96v-192h512q52 0 90 -38t38 -90v-192h96q40 0 68 -28t28 -68 z" />
241
- <glyph unicode="&#xf0e9;" horiz-adv-x="1664" d="M896 708v-580q0 -104 -76 -180t-180 -76t-180 76t-76 180q0 26 19 45t45 19t45 -19t19 -45q0 -50 39 -89t89 -39t89 39t39 89v580q33 11 64 11t64 -11zM1664 681q0 -13 -9.5 -22.5t-22.5 -9.5q-11 0 -23 10q-49 46 -93 69t-102 23q-68 0 -128 -37t-103 -97 q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -28 -17q-18 0 -29 17q-4 6 -14.5 24t-17.5 28q-43 60 -102.5 97t-127.5 37t-127.5 -37t-102.5 -97q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -29 -17q-17 0 -28 17q-4 6 -14.5 24t-17.5 28q-43 60 -103 97t-128 37q-58 0 -102 -23t-93 -69 q-12 -10 -23 -10q-13 0 -22.5 9.5t-9.5 22.5q0 5 1 7q45 183 172.5 319.5t298 204.5t360.5 68q140 0 274.5 -40t246.5 -113.5t194.5 -187t115.5 -251.5q1 -2 1 -7zM896 1408v-98q-42 2 -64 2t-64 -2v98q0 26 19 45t45 19t45 -19t19 -45z" />
242
- <glyph unicode="&#xf0ea;" horiz-adv-x="1792" d="M768 -128h896v640h-416q-40 0 -68 28t-28 68v416h-384v-1152zM1024 1312v64q0 13 -9.5 22.5t-22.5 9.5h-704q-13 0 -22.5 -9.5t-9.5 -22.5v-64q0 -13 9.5 -22.5t22.5 -9.5h704q13 0 22.5 9.5t9.5 22.5zM1280 640h299l-299 299v-299zM1792 512v-672q0 -40 -28 -68t-68 -28 h-960q-40 0 -68 28t-28 68v160h-544q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1088q40 0 68 -28t28 -68v-328q21 -13 36 -28l408 -408q28 -28 48 -76t20 -88z" />
243
- <glyph unicode="&#xf0eb;" horiz-adv-x="1024" d="M736 960q0 -13 -9.5 -22.5t-22.5 -9.5t-22.5 9.5t-9.5 22.5q0 46 -54 71t-106 25q-13 0 -22.5 9.5t-9.5 22.5t9.5 22.5t22.5 9.5q50 0 99.5 -16t87 -54t37.5 -90zM896 960q0 72 -34.5 134t-90 101.5t-123 62t-136.5 22.5t-136.5 -22.5t-123 -62t-90 -101.5t-34.5 -134 q0 -101 68 -180q10 -11 30.5 -33t30.5 -33q128 -153 141 -298h228q13 145 141 298q10 11 30.5 33t30.5 33q68 79 68 180zM1024 960q0 -155 -103 -268q-45 -49 -74.5 -87t-59.5 -95.5t-34 -107.5q47 -28 47 -82q0 -37 -25 -64q25 -27 25 -64q0 -52 -45 -81q13 -23 13 -47 q0 -46 -31.5 -71t-77.5 -25q-20 -44 -60 -70t-87 -26t-87 26t-60 70q-46 0 -77.5 25t-31.5 71q0 24 13 47q-45 29 -45 81q0 37 25 64q-25 27 -25 64q0 54 47 82q-4 50 -34 107.5t-59.5 95.5t-74.5 87q-103 113 -103 268q0 99 44.5 184.5t117 142t164 89t186.5 32.5 t186.5 -32.5t164 -89t117 -142t44.5 -184.5z" />
244
- <glyph unicode="&#xf0ec;" horiz-adv-x="1792" d="M1792 352v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5q-12 0 -24 10l-319 320q-9 9 -9 22q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h1376q13 0 22.5 -9.5t9.5 -22.5zM1792 896q0 -14 -9 -23l-320 -320q-9 -9 -23 -9 q-13 0 -22.5 9.5t-9.5 22.5v192h-1376q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1376v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" />
245
- <glyph unicode="&#xf0ed;" horiz-adv-x="1920" d="M1280 608q0 14 -9 23t-23 9h-224v352q0 13 -9.5 22.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-352h-224q-13 0 -22.5 -9.5t-9.5 -22.5q0 -14 9 -23l352 -352q9 -9 23 -9t23 9l351 351q10 12 10 24zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088 q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" />
246
- <glyph unicode="&#xf0ee;" horiz-adv-x="1920" d="M1280 672q0 14 -9 23l-352 352q-9 9 -23 9t-23 -9l-351 -351q-10 -12 -10 -24q0 -14 9 -23t23 -9h224v-352q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5v352h224q13 0 22.5 9.5t9.5 22.5zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088 q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" />
247
- <glyph unicode="&#xf0f0;" horiz-adv-x="1408" d="M384 192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 68 5.5 131t24 138t47.5 132.5t81 103t120 60.5q-22 -52 -22 -120v-203q-58 -20 -93 -70t-35 -111q0 -80 56 -136t136 -56 t136 56t56 136q0 61 -35.5 111t-92.5 70v203q0 62 25 93q132 -104 295 -104t295 104q25 -31 25 -93v-64q-106 0 -181 -75t-75 -181v-89q-32 -29 -32 -71q0 -40 28 -68t68 -28t68 28t28 68q0 42 -32 71v89q0 52 38 90t90 38t90 -38t38 -90v-89q-32 -29 -32 -71q0 -40 28 -68 t68 -28t68 28t28 68q0 42 -32 71v89q0 68 -34.5 127.5t-93.5 93.5q0 10 0.5 42.5t0 48t-2.5 41.5t-7 47t-13 40q68 -15 120 -60.5t81 -103t47.5 -132.5t24 -138t5.5 -131zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5 t271.5 -112.5t112.5 -271.5z" />
248
- <glyph unicode="&#xf0f1;" horiz-adv-x="1408" d="M1280 832q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 832q0 -62 -35.5 -111t-92.5 -70v-395q0 -159 -131.5 -271.5t-316.5 -112.5t-316.5 112.5t-131.5 271.5v132q-164 20 -274 128t-110 252v512q0 26 19 45t45 19q6 0 16 -2q17 30 47 48 t65 18q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5q-33 0 -64 18v-402q0 -106 94 -181t226 -75t226 75t94 181v402q-31 -18 -64 -18q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5q35 0 65 -18t47 -48q10 2 16 2q26 0 45 -19t19 -45v-512q0 -144 -110 -252 t-274 -128v-132q0 -106 94 -181t226 -75t226 75t94 181v395q-57 21 -92.5 70t-35.5 111q0 80 56 136t136 56t136 -56t56 -136z" />
249
- <glyph unicode="&#xf0f2;" horiz-adv-x="1792" d="M640 1152h512v128h-512v-128zM288 1152v-1280h-64q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h64zM1408 1152v-1280h-1024v1280h128v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h128zM1792 928v-832q0 -92 -66 -158t-158 -66h-64v1280h64q92 0 158 -66 t66 -158z" />
250
- <glyph unicode="&#xf0f3;" horiz-adv-x="1664" d="M848 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM1664 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q190 161 287 397.5t97 498.5 q0 165 96 262t264 117q-8 18 -8 37q0 40 28 68t68 28t68 -28t28 -68q0 -19 -8 -37q168 -20 264 -117t96 -262q0 -262 97 -498.5t287 -397.5z" />
251
- <glyph unicode="&#xf0f4;" horiz-adv-x="1920" d="M1664 896q0 80 -56 136t-136 56h-64v-384h64q80 0 136 56t56 136zM0 128h1792q0 -106 -75 -181t-181 -75h-1280q-106 0 -181 75t-75 181zM1856 896q0 -159 -112.5 -271.5t-271.5 -112.5h-64v-32q0 -92 -66 -158t-158 -66h-704q-92 0 -158 66t-66 158v736q0 26 19 45 t45 19h1152q159 0 271.5 -112.5t112.5 -271.5z" />
252
- <glyph unicode="&#xf0f5;" horiz-adv-x="1408" d="M640 1472v-640q0 -61 -35.5 -111t-92.5 -70v-779q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v779q-57 20 -92.5 70t-35.5 111v640q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45 t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45zM1408 1472v-1600q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v512h-224q-13 0 -22.5 9.5t-9.5 22.5v800q0 132 94 226t226 94h256q26 0 45 -19t19 -45z" />
253
- <glyph unicode="&#xf0f6;" horiz-adv-x="1280" d="M1024 352v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM1024 608v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM128 0h1024v768h-416q-40 0 -68 28t-28 68v416h-512v-1280z M768 896h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376zM1280 864v-896q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h640q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88z" />
254
- <glyph unicode="&#xf0f7;" horiz-adv-x="1408" d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 -128h384v1536h-1152v-1536h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM1408 1472v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45z" />
255
- <glyph unicode="&#xf0f8;" horiz-adv-x="1408" d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 -128h384v1152h-256v-32q0 -40 -28 -68t-68 -28h-448q-40 0 -68 28t-28 68v32h-256v-1152h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM896 1056v320q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-96h-128v96q0 13 -9.5 22.5 t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v96h128v-96q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1408 1088v-1280q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1280q0 26 19 45t45 19h320 v288q0 40 28 68t68 28h448q40 0 68 -28t28 -68v-288h320q26 0 45 -19t19 -45z" />
256
- <glyph unicode="&#xf0f9;" horiz-adv-x="1920" d="M640 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM256 640h384v256h-158q-14 -2 -22 -9l-195 -195q-7 -12 -9 -22v-30zM1536 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5zM1664 800v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM1920 1344v-1152 q0 -26 -19 -45t-45 -19h-192q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-128q-26 0 -45 19t-19 45t19 45t45 19v416q0 26 13 58t32 51l198 198q19 19 51 32t58 13h160v320q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
257
- <glyph unicode="&#xf0fa;" horiz-adv-x="1792" d="M1280 416v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM640 1152h512v128h-512v-128zM256 1152v-1280h-32 q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h32zM1440 1152v-1280h-1088v1280h160v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h160zM1792 928v-832q0 -92 -66 -158t-158 -66h-32v1280h32q92 0 158 -66t66 -158z" />
258
- <glyph unicode="&#xf0fb;" horiz-adv-x="1920" d="M1920 576q-1 -32 -288 -96l-352 -32l-224 -64h-64l-293 -352h69q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-96h-160h-64v32h64v416h-160l-192 -224h-96l-32 32v192h32v32h128v8l-192 24v128l192 24v8h-128v32h-32v192l32 32h96l192 -224h160v416h-64v32h64h160h96 q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-69l293 -352h64l224 -64l352 -32q261 -58 287 -93z" />
259
- <glyph unicode="&#xf0fc;" horiz-adv-x="1664" d="M640 640v384h-256v-256q0 -53 37.5 -90.5t90.5 -37.5h128zM1664 192v-192h-1152v192l128 192h-128q-159 0 -271.5 112.5t-112.5 271.5v320l-64 64l32 128h480l32 128h960l32 -192l-64 -32v-800z" />
260
- <glyph unicode="&#xf0fd;" d="M1280 192v896q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-512v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-896q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h512v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
261
- <glyph unicode="&#xf0fe;" d="M1280 576v128q0 26 -19 45t-45 19h-320v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-320q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h320v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h320q26 0 45 19t19 45zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
262
- <glyph unicode="&#xf100;" horiz-adv-x="1024" d="M627 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23zM1011 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23 t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23z" />
263
- <glyph unicode="&#xf101;" horiz-adv-x="1024" d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM979 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23 l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
264
- <glyph unicode="&#xf102;" horiz-adv-x="1152" d="M1075 224q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM1075 608q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393 q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
265
- <glyph unicode="&#xf103;" horiz-adv-x="1152" d="M1075 672q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23zM1075 1056q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23 t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
266
- <glyph unicode="&#xf104;" horiz-adv-x="640" d="M627 992q0 -13 -10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
267
- <glyph unicode="&#xf105;" horiz-adv-x="640" d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
268
- <glyph unicode="&#xf106;" horiz-adv-x="1152" d="M1075 352q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
269
- <glyph unicode="&#xf107;" horiz-adv-x="1152" d="M1075 800q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
270
- <glyph unicode="&#xf108;" horiz-adv-x="1920" d="M1792 544v832q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1376v-1088q0 -66 -47 -113t-113 -47h-544q0 -37 16 -77.5t32 -71t16 -43.5q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19 t-19 45q0 14 16 44t32 70t16 78h-544q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
271
- <glyph unicode="&#xf109;" horiz-adv-x="1920" d="M416 256q-66 0 -113 47t-47 113v704q0 66 47 113t113 47h1088q66 0 113 -47t47 -113v-704q0 -66 -47 -113t-113 -47h-1088zM384 1120v-704q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5z M1760 192h160v-96q0 -40 -47 -68t-113 -28h-1600q-66 0 -113 28t-47 68v96h160h1600zM1040 96q16 0 16 16t-16 16h-160q-16 0 -16 -16t16 -16h160z" />
272
- <glyph unicode="&#xf10a;" horiz-adv-x="1152" d="M640 128q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1024 288v960q0 13 -9.5 22.5t-22.5 9.5h-832q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h832q13 0 22.5 9.5t9.5 22.5zM1152 1248v-1088q0 -66 -47 -113t-113 -47h-832 q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h832q66 0 113 -47t47 -113z" />
273
- <glyph unicode="&#xf10b;" horiz-adv-x="768" d="M464 128q0 33 -23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5t56.5 23.5t23.5 56.5zM672 288v704q0 13 -9.5 22.5t-22.5 9.5h-512q-13 0 -22.5 -9.5t-9.5 -22.5v-704q0 -13 9.5 -22.5t22.5 -9.5h512q13 0 22.5 9.5t9.5 22.5zM480 1136 q0 16 -16 16h-160q-16 0 -16 -16t16 -16h160q16 0 16 16zM768 1152v-1024q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v1024q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" />
274
- <glyph unicode="&#xf10c;" d="M768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103 t279.5 -279.5t103 -385.5z" />
275
- <glyph unicode="&#xf10d;" horiz-adv-x="1664" d="M768 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z M1664 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z" />
276
- <glyph unicode="&#xf10e;" horiz-adv-x="1664" d="M768 1216v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136zM1664 1216 v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136z" />
277
- <glyph unicode="&#xf110;" horiz-adv-x="1568" d="M496 192q0 -60 -42.5 -102t-101.5 -42q-60 0 -102 42t-42 102t42 102t102 42q59 0 101.5 -42t42.5 -102zM928 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM320 640q0 -66 -47 -113t-113 -47t-113 47t-47 113 t47 113t113 47t113 -47t47 -113zM1360 192q0 -46 -33 -79t-79 -33t-79 33t-33 79t33 79t79 33t79 -33t33 -79zM528 1088q0 -73 -51.5 -124.5t-124.5 -51.5t-124.5 51.5t-51.5 124.5t51.5 124.5t124.5 51.5t124.5 -51.5t51.5 -124.5zM992 1280q0 -80 -56 -136t-136 -56 t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1536 640q0 -40 -28 -68t-68 -28t-68 28t-28 68t28 68t68 28t68 -28t28 -68zM1328 1088q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5z" />
278
- <glyph unicode="&#xf111;" d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
279
- <glyph unicode="&#xf112;" horiz-adv-x="1792" d="M1792 416q0 -166 -127 -451q-3 -7 -10.5 -24t-13.5 -30t-13 -22q-12 -17 -28 -17q-15 0 -23.5 10t-8.5 25q0 9 2.5 26.5t2.5 23.5q5 68 5 123q0 101 -17.5 181t-48.5 138.5t-80 101t-105.5 69.5t-133 42.5t-154 21.5t-175.5 6h-224v-256q0 -26 -19 -45t-45 -19t-45 19 l-512 512q-19 19 -19 45t19 45l512 512q19 19 45 19t45 -19t19 -45v-256h224q713 0 875 -403q53 -134 53 -333z" />
280
- <glyph unicode="&#xf113;" horiz-adv-x="1664" d="M640 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1280 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1440 320 q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11q-152 21 -195 21q-118 0 -187 -84t-69 -204q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5zM1664 496q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86 t-170 -47.5t-171.5 -22t-167 -4.5q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331q0 237 136 396q-27 82 -27 170q0 116 51 218q108 0 190 -39.5t189 -123.5q147 35 309 35q148 0 280 -32q105 82 187 121t189 39q51 -102 51 -218 q0 -87 -27 -168q136 -160 136 -398z" />
281
- <glyph unicode="&#xf114;" horiz-adv-x="1664" d="M1536 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-960q0 -40 28 -68t68 -28h1216q40 0 68 28t28 68zM1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320 q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
282
- <glyph unicode="&#xf115;" horiz-adv-x="1920" d="M1781 605q0 35 -53 35h-1088q-40 0 -85.5 -21.5t-71.5 -52.5l-294 -363q-18 -24 -18 -40q0 -35 53 -35h1088q40 0 86 22t71 53l294 363q18 22 18 39zM640 768h768v160q0 40 -28 68t-68 28h-576q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68 v-853l256 315q44 53 116 87.5t140 34.5zM1909 605q0 -62 -46 -120l-295 -363q-43 -53 -116 -87.5t-140 -34.5h-1088q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h192q54 0 99 -24.5t67 -70.5q15 -32 15 -68z " />
283
- <glyph unicode="&#xf116;" horiz-adv-x="1152" d="M896 608v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224h224q14 0 23 -9t9 -23zM1024 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 -28 t-28 -68v-704q0 -40 28 -68t68 -28h704q40 0 68 28t28 68zM1152 928v-704q0 -92 -65.5 -158t-158.5 -66h-704q-93 0 -158.5 66t-65.5 158v704q0 93 65.5 158.5t158.5 65.5h704q93 0 158.5 -65.5t65.5 -158.5z" />
284
- <glyph unicode="&#xf117;" horiz-adv-x="1152" d="M928 1152q93 0 158.5 -65.5t65.5 -158.5v-704q0 -92 -65.5 -158t-158.5 -66h-704q-93 0 -158.5 66t-65.5 158v704q0 93 65.5 158.5t158.5 65.5h704zM1024 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 -28t-28 -68v-704q0 -40 28 -68t68 -28h704q40 0 68 28t28 68z M864 640q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576z" />
285
- <glyph unicode="&#xf118;" d="M1134 461q-37 -121 -138 -195t-228 -74t-228 74t-138 195q-8 25 4 48.5t38 31.5q25 8 48.5 -4t31.5 -38q25 -80 92.5 -129.5t151.5 -49.5t151.5 49.5t92.5 129.5q8 26 32 38t49 4t37 -31.5t4 -48.5zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5 t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
286
- <glyph unicode="&#xf119;" d="M1134 307q8 -25 -4 -48.5t-37 -31.5t-49 4t-32 38q-25 80 -92.5 129.5t-151.5 49.5t-151.5 -49.5t-92.5 -129.5q-8 -26 -31.5 -38t-48.5 -4q-26 8 -38 31.5t-4 48.5q37 121 138 195t228 74t228 -74t138 -195zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204 t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
287
- <glyph unicode="&#xf11a;" d="M1152 448q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h640q26 0 45 -19t19 -45zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
288
- <glyph unicode="&#xf11b;" horiz-adv-x="1920" d="M832 448v128q0 14 -9 23t-23 9h-192v192q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-192h-192q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h192v-192q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v192h192q14 0 23 9t9 23zM1408 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5 t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1920 512q0 -212 -150 -362t-362 -150q-192 0 -338 128h-220q-146 -128 -338 -128q-212 0 -362 150 t-150 362t150 362t362 150h896q212 0 362 -150t150 -362z" />
289
- <glyph unicode="&#xf11c;" horiz-adv-x="1920" d="M384 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM512 624v-96q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h224q16 0 16 -16zM384 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 368v-96q0 -16 -16 -16 h-864q-16 0 -16 16v96q0 16 16 16h864q16 0 16 -16zM768 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM640 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1024 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16 h96q16 0 16 -16zM896 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1280 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1152 880v-96 q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 880v-352q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h112v240q0 16 16 16h96q16 0 16 -16zM1792 128v896h-1664v-896 h1664zM1920 1024v-896q0 -53 -37.5 -90.5t-90.5 -37.5h-1664q-53 0 -90.5 37.5t-37.5 90.5v896q0 53 37.5 90.5t90.5 37.5h1664q53 0 90.5 -37.5t37.5 -90.5z" />
290
- <glyph unicode="&#xf11d;" horiz-adv-x="1792" d="M1664 491v616q-169 -91 -306 -91q-82 0 -145 32q-100 49 -184 76.5t-178 27.5q-173 0 -403 -127v-599q245 113 433 113q55 0 103.5 -7.5t98 -26t77 -31t82.5 -39.5l28 -14q44 -22 101 -22q120 0 293 92zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9 h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102 q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" />
291
- <glyph unicode="&#xf11e;" horiz-adv-x="1792" d="M832 536v192q-181 -16 -384 -117v-185q205 96 384 110zM832 954v197q-172 -8 -384 -126v-189q215 111 384 118zM1664 491v184q-235 -116 -384 -71v224q-20 6 -39 15q-5 3 -33 17t-34.5 17t-31.5 15t-34.5 15.5t-32.5 13t-36 12.5t-35 8.5t-39.5 7.5t-39.5 4t-44 2 q-23 0 -49 -3v-222h19q102 0 192.5 -29t197.5 -82q19 -9 39 -15v-188q42 -17 91 -17q120 0 293 92zM1664 918v189q-169 -91 -306 -91q-45 0 -78 8v-196q148 -42 384 90zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266 q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102q-15 -9 -33 -9q-16 0 -32 8 q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" />
292
- <glyph unicode="&#xf120;" horiz-adv-x="1664" d="M585 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23zM1664 96v-64q0 -14 -9 -23t-23 -9h-960q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h960q14 0 23 -9 t9 -23z" />
293
- <glyph unicode="&#xf121;" horiz-adv-x="1920" d="M617 137l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23zM1208 1204l-373 -1291q-4 -13 -15.5 -19.5t-23.5 -2.5l-62 17q-13 4 -19.5 15.5t-2.5 24.5 l373 1291q4 13 15.5 19.5t23.5 2.5l62 -17q13 -4 19.5 -15.5t2.5 -24.5zM1865 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23z" />
294
- <glyph unicode="&#xf122;" horiz-adv-x="1792" d="M640 454v-70q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-69l-397 -398q-19 -19 -19 -45t19 -45zM1792 416q0 -58 -17 -133.5t-38.5 -138t-48 -125t-40.5 -90.5l-20 -40q-8 -17 -28 -17q-6 0 -9 1 q-25 8 -23 34q43 400 -106 565q-64 71 -170.5 110.5t-267.5 52.5v-251q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-262q411 -28 599 -221q169 -173 169 -509z" />
295
- <glyph unicode="&#xf123;" horiz-adv-x="1664" d="M1186 579l257 250l-356 52l-66 10l-30 60l-159 322v-963l59 -31l318 -168l-60 355l-12 66zM1638 841l-363 -354l86 -500q5 -33 -6 -51.5t-34 -18.5q-17 0 -40 12l-449 236l-449 -236q-23 -12 -40 -12q-23 0 -34 18.5t-6 51.5l86 500l-364 354q-32 32 -23 59.5t54 34.5 l502 73l225 455q20 41 49 41q28 0 49 -41l225 -455l502 -73q45 -7 54 -34.5t-24 -59.5z" />
296
- <glyph unicode="&#xf124;" horiz-adv-x="1408" d="M1401 1187l-640 -1280q-17 -35 -57 -35q-5 0 -15 2q-22 5 -35.5 22.5t-13.5 39.5v576h-576q-22 0 -39.5 13.5t-22.5 35.5t4 42t29 30l1280 640q13 7 29 7q27 0 45 -19q15 -14 18.5 -34.5t-6.5 -39.5z" />
297
- <glyph unicode="&#xf125;" horiz-adv-x="1664" d="M557 256h595v595zM512 301l595 595h-595v-595zM1664 224v-192q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v224h-864q-14 0 -23 9t-9 23v864h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224v224q0 14 9 23t23 9h192q14 0 23 -9t9 -23 v-224h851l246 247q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-247 -246v-851h224q14 0 23 -9t9 -23z" />
298
- <glyph unicode="&#xf126;" horiz-adv-x="1024" d="M288 64q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM288 1216q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM928 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1024 1088q0 -52 -26 -96.5t-70 -69.5 q-2 -287 -226 -414q-68 -38 -203 -81q-128 -40 -169.5 -71t-41.5 -100v-26q44 -25 70 -69.5t26 -96.5q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 52 26 96.5t70 69.5v820q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136q0 -52 -26 -96.5t-70 -69.5v-497 q54 26 154 57q55 17 87.5 29.5t70.5 31t59 39.5t40.5 51t28 69.5t8.5 91.5q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136z" />
299
- <glyph unicode="&#xf127;" horiz-adv-x="1664" d="M439 265l-256 -256q-10 -9 -23 -9q-12 0 -23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23zM608 224v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM384 448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23t9 23t23 9h320 q14 0 23 -9t9 -23zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-334 335q-21 21 -42 56l239 18l273 -274q27 -27 68 -27.5t68 26.5l147 146q28 28 28 67q0 40 -28 68l-274 275l18 239q35 -21 56 -42l336 -336q84 -86 84 -204zM1031 1044l-239 -18 l-273 274q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l274 -274l-18 -240q-35 21 -56 42l-336 336q-84 86 -84 204q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l334 -335q21 -21 42 -56zM1664 960q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9 t-9 23t9 23t23 9h320q14 0 23 -9t9 -23zM1120 1504v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM1527 1353l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" />
300
- <glyph unicode="&#xf128;" horiz-adv-x="1024" d="M704 280v-240q0 -16 -12 -28t-28 -12h-240q-16 0 -28 12t-12 28v240q0 16 12 28t28 12h240q16 0 28 -12t12 -28zM1020 880q0 -54 -15.5 -101t-35 -76.5t-55 -59.5t-57.5 -43.5t-61 -35.5q-41 -23 -68.5 -65t-27.5 -67q0 -17 -12 -32.5t-28 -15.5h-240q-15 0 -25.5 18.5 t-10.5 37.5v45q0 83 65 156.5t143 108.5q59 27 84 56t25 76q0 42 -46.5 74t-107.5 32q-65 0 -108 -29q-35 -25 -107 -115q-13 -16 -31 -16q-12 0 -25 8l-164 125q-13 10 -15.5 25t5.5 28q160 266 464 266q80 0 161 -31t146 -83t106 -127.5t41 -158.5z" />
301
- <glyph unicode="&#xf129;" horiz-adv-x="640" d="M640 192v-128q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64v384h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-576h64q26 0 45 -19t19 -45zM512 1344v-192q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v192 q0 26 19 45t45 19h256q26 0 45 -19t19 -45z" />
302
- <glyph unicode="&#xf12a;" horiz-adv-x="640" d="M512 288v-224q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v224q0 26 19 45t45 19h256q26 0 45 -19t19 -45zM542 1344l-28 -768q-1 -26 -20.5 -45t-45.5 -19h-256q-26 0 -45.5 19t-20.5 45l-28 768q-1 26 17.5 45t44.5 19h320q26 0 44.5 -19t17.5 -45z" />
303
- <glyph unicode="&#xf12b;" d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109zM1534 846v-206h-514l-3 27 q-4 28 -4 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q83 65 188 65q110 0 178 -59.5t68 -158.5q0 -56 -24.5 -103t-62 -76.5t-81.5 -58.5t-82 -50.5t-65.5 -51.5t-30.5 -63h232v80 h126z" />
304
- <glyph unicode="&#xf12c;" d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109zM1536 -50v-206h-514l-4 27 q-3 45 -3 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q80 65 188 65q110 0 178 -59.5t68 -158.5q0 -66 -34.5 -118.5t-84 -86t-99.5 -62.5t-87 -63t-41 -73h232v80h126z" />
305
- <glyph unicode="&#xf12d;" horiz-adv-x="1920" d="M896 128l336 384h-768l-336 -384h768zM1909 1205q15 -34 9.5 -71.5t-30.5 -65.5l-896 -1024q-38 -44 -96 -44h-768q-38 0 -69.5 20.5t-47.5 54.5q-15 34 -9.5 71.5t30.5 65.5l896 1024q38 44 96 44h768q38 0 69.5 -20.5t47.5 -54.5z" />
306
- <glyph unicode="&#xf12e;" horiz-adv-x="1664" d="M1664 438q0 -81 -44.5 -135t-123.5 -54q-41 0 -77.5 17.5t-59 38t-56.5 38t-71 17.5q-110 0 -110 -124q0 -39 16 -115t15 -115v-5q-22 0 -33 -1q-34 -3 -97.5 -11.5t-115.5 -13.5t-98 -5q-61 0 -103 26.5t-42 83.5q0 37 17.5 71t38 56.5t38 59t17.5 77.5q0 79 -54 123.5 t-135 44.5q-84 0 -143 -45.5t-59 -127.5q0 -43 15 -83t33.5 -64.5t33.5 -53t15 -50.5q0 -45 -46 -89q-37 -35 -117 -35q-95 0 -245 24q-9 2 -27.5 4t-27.5 4l-13 2q-1 0 -3 1q-2 0 -2 1v1024q2 -1 17.5 -3.5t34 -5t21.5 -3.5q150 -24 245 -24q80 0 117 35q46 44 46 89 q0 22 -15 50.5t-33.5 53t-33.5 64.5t-15 83q0 82 59 127.5t144 45.5q80 0 134 -44.5t54 -123.5q0 -41 -17.5 -77.5t-38 -59t-38 -56.5t-17.5 -71q0 -57 42 -83.5t103 -26.5q64 0 180 15t163 17v-2q-1 -2 -3.5 -17.5t-5 -34t-3.5 -21.5q-24 -150 -24 -245q0 -80 35 -117 q44 -46 89 -46q22 0 50.5 15t53 33.5t64.5 33.5t83 15q82 0 127.5 -59t45.5 -143z" />
307
- <glyph unicode="&#xf130;" horiz-adv-x="1152" d="M1152 832v-128q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-217 24 -364.5 187.5t-147.5 384.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -185 131.5 -316.5t316.5 -131.5 t316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45zM896 1216v-512q0 -132 -94 -226t-226 -94t-226 94t-94 226v512q0 132 94 226t226 94t226 -94t94 -226z" />
308
- <glyph unicode="&#xf131;" horiz-adv-x="1408" d="M271 591l-101 -101q-42 103 -42 214v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -53 15 -113zM1385 1193l-361 -361v-128q0 -132 -94 -226t-226 -94q-55 0 -109 19l-96 -96q97 -51 205 -51q185 0 316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45v-128 q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-125 13 -235 81l-254 -254q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23t10 23l1234 1234q10 10 23 10t23 -10l82 -82q10 -10 10 -23 t-10 -23zM1005 1325l-621 -621v512q0 132 94 226t226 94q102 0 184.5 -59t116.5 -152z" />
309
- <glyph unicode="&#xf132;" horiz-adv-x="1280" d="M1088 576v640h-448v-1137q119 63 213 137q235 184 235 360zM1280 1344v-768q0 -86 -33.5 -170.5t-83 -150t-118 -127.5t-126.5 -103t-121 -77.5t-89.5 -49.5t-42.5 -20q-12 -6 -26 -6t-26 6q-16 7 -42.5 20t-89.5 49.5t-121 77.5t-126.5 103t-118 127.5t-83 150 t-33.5 170.5v768q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
310
- <glyph unicode="&#xf133;" horiz-adv-x="1664" d="M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280 q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
311
- <glyph unicode="&#xf134;" horiz-adv-x="1408" d="M512 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 1376v-320q0 -16 -12 -25q-8 -7 -20 -7q-4 0 -7 1l-448 96q-11 2 -18 11t-7 20h-256v-102q111 -23 183.5 -111t72.5 -203v-800q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v800 q0 106 62.5 190.5t161.5 114.5v111h-32q-59 0 -115 -23.5t-91.5 -53t-66 -66.5t-40.5 -53.5t-14 -24.5q-17 -35 -57 -35q-16 0 -29 7q-23 12 -31.5 37t3.5 49q5 10 14.5 26t37.5 53.5t60.5 70t85 67t108.5 52.5q-25 42 -25 86q0 66 47 113t113 47t113 -47t47 -113 q0 -33 -14 -64h302q0 11 7 20t18 11l448 96q3 1 7 1q12 0 20 -7q12 -9 12 -25z" />
312
- <glyph unicode="&#xf135;" horiz-adv-x="1664" d="M1440 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1664 1376q0 -249 -75.5 -430.5t-253.5 -360.5q-81 -80 -195 -176l-20 -379q-2 -16 -16 -26l-384 -224q-7 -4 -16 -4q-12 0 -23 9l-64 64q-13 14 -8 32l85 276l-281 281l-276 -85q-3 -1 -9 -1 q-14 0 -23 9l-64 64q-17 19 -5 39l224 384q10 14 26 16l379 20q96 114 176 195q188 187 358 258t431 71q14 0 24 -9.5t10 -22.5z" />
313
- <glyph unicode="&#xf136;" horiz-adv-x="1792" d="M1708 881l-188 -881h-304l181 849q4 21 1 43q-4 20 -16 35q-10 14 -28 24q-18 9 -40 9h-197l-205 -960h-303l204 960h-304l-205 -960h-304l272 1280h1139q157 0 245 -118q86 -116 52 -281z" />
314
- <glyph unicode="&#xf137;" d="M909 141l102 102q19 19 19 45t-19 45l-307 307l307 307q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
315
- <glyph unicode="&#xf138;" d="M717 141l454 454q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l307 -307l-307 -307q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
316
- <glyph unicode="&#xf139;" d="M1165 397l102 102q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l307 307l307 -307q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
317
- <glyph unicode="&#xf13a;" d="M813 237l454 454q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-307 -307l-307 307q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
318
- <glyph unicode="&#xf13b;" horiz-adv-x="1408" d="M1130 939l16 175h-884l47 -534h612l-22 -228l-197 -53l-196 53l-13 140h-175l22 -278l362 -100h4v1l359 99l50 544h-644l-15 181h674zM0 1408h1408l-128 -1438l-578 -162l-574 162z" />
319
- <glyph unicode="&#xf13c;" horiz-adv-x="1792" d="M275 1408h1505l-266 -1333l-804 -267l-698 267l71 356h297l-29 -147l422 -161l486 161l68 339h-1208l58 297h1209l38 191h-1208z" />
320
- <glyph unicode="&#xf13d;" horiz-adv-x="1792" d="M960 1280q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1792 352v-352q0 -22 -20 -30q-8 -2 -12 -2q-13 0 -23 9l-93 93q-119 -143 -318.5 -226.5t-429.5 -83.5t-429.5 83.5t-318.5 226.5l-93 -93q-9 -9 -23 -9q-4 0 -12 2q-20 8 -20 30v352 q0 14 9 23t23 9h352q22 0 30 -20q8 -19 -7 -35l-100 -100q67 -91 189.5 -153.5t271.5 -82.5v647h-192q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h192v163q-58 34 -93 92.5t-35 128.5q0 106 75 181t181 75t181 -75t75 -181q0 -70 -35 -128.5t-93 -92.5v-163h192q26 0 45 -19 t19 -45v-128q0 -26 -19 -45t-45 -19h-192v-647q149 20 271.5 82.5t189.5 153.5l-100 100q-15 16 -7 35q8 20 30 20h352q14 0 23 -9t9 -23z" />
321
- <glyph unicode="&#xf13e;" horiz-adv-x="1152" d="M1056 768q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v320q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45q0 106 -75 181t-181 75t-181 -75t-75 -181 v-320h736z" />
322
- <glyph unicode="&#xf140;" d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM1152 640q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM1280 640q0 -212 -150 -362t-362 -150t-362 150 t-150 362t150 362t362 150t362 -150t150 -362zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
323
- <glyph unicode="&#xf141;" horiz-adv-x="1408" d="M384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM896 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM1408 800v-192q0 -40 -28 -68t-68 -28h-192 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" />
324
- <glyph unicode="&#xf142;" horiz-adv-x="384" d="M384 288v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 1312v-192q0 -40 -28 -68t-68 -28h-192 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" />
325
- <glyph unicode="&#xf143;" d="M512 256q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM863 162q-13 232 -177 396t-396 177q-14 1 -24 -9t-10 -23v-128q0 -13 8.5 -22t21.5 -10q154 -11 264 -121t121 -264q1 -13 10 -21.5t22 -8.5h128q13 0 23 10 t9 24zM1247 161q-5 154 -56 297.5t-139.5 260t-205 205t-260 139.5t-297.5 56q-14 1 -23 -9q-10 -10 -10 -23v-128q0 -13 9 -22t22 -10q204 -7 378 -111.5t278.5 -278.5t111.5 -378q1 -13 10 -22t22 -9h128q13 0 23 10q11 9 9 23zM1536 1120v-960q0 -119 -84.5 -203.5 t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
326
- <glyph unicode="&#xf144;" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1152 585q32 18 32 55t-32 55l-544 320q-31 19 -64 1q-32 -19 -32 -56v-640q0 -37 32 -56 q16 -8 32 -8q17 0 32 9z" />
327
- <glyph unicode="&#xf145;" horiz-adv-x="1792" d="M1024 1084l316 -316l-572 -572l-316 316zM813 105l618 618q19 19 19 45t-19 45l-362 362q-18 18 -45 18t-45 -18l-618 -618q-19 -19 -19 -45t19 -45l362 -362q18 -18 45 -18t45 18zM1702 742l-907 -908q-37 -37 -90.5 -37t-90.5 37l-126 126q56 56 56 136t-56 136 t-136 56t-136 -56l-125 126q-37 37 -37 90.5t37 90.5l907 906q37 37 90.5 37t90.5 -37l125 -125q-56 -56 -56 -136t56 -136t136 -56t136 56l126 -125q37 -37 37 -90.5t-37 -90.5z" />
328
- <glyph unicode="&#xf146;" d="M1280 576v128q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h896q26 0 45 19t19 45zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 t84.5 -203.5z" />
329
- <glyph unicode="&#xf147;" horiz-adv-x="1408" d="M1152 736v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h832q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5 t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" />
330
- <glyph unicode="&#xf148;" horiz-adv-x="1024" d="M1018 933q-18 -37 -58 -37h-192v-864q0 -14 -9 -23t-23 -9h-704q-21 0 -29 18q-8 20 4 35l160 192q9 11 25 11h320v640h-192q-40 0 -58 37q-17 37 9 68l320 384q18 22 49 22t49 -22l320 -384q27 -32 9 -68z" />
331
- <glyph unicode="&#xf149;" horiz-adv-x="1024" d="M32 1280h704q13 0 22.5 -9.5t9.5 -23.5v-863h192q40 0 58 -37t-9 -69l-320 -384q-18 -22 -49 -22t-49 22l-320 384q-26 31 -9 69q18 37 58 37h192v640h-320q-14 0 -25 11l-160 192q-13 14 -4 34q9 19 29 19z" />
332
- <glyph unicode="&#xf14a;" d="M685 237l614 614q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-467 -467l-211 211q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l358 -358q19 -19 45 -19t45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5 t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
333
- <glyph unicode="&#xf14b;" d="M404 428l152 -152l-52 -52h-56v96h-96v56zM818 818q14 -13 -3 -30l-291 -291q-17 -17 -30 -3q-14 13 3 30l291 291q17 17 30 3zM544 128l544 544l-288 288l-544 -544v-288h288zM1152 736l92 92q28 28 28 68t-28 68l-152 152q-28 28 -68 28t-68 -28l-92 -92zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
334
- <glyph unicode="&#xf14c;" d="M1280 608v480q0 26 -19 45t-45 19h-480q-42 0 -59 -39q-17 -41 14 -70l144 -144l-534 -534q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l534 534l144 -144q18 -19 45 -19q12 0 25 5q39 17 39 59zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960 q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
335
- <glyph unicode="&#xf14d;" d="M1005 435l352 352q19 19 19 45t-19 45l-352 352q-30 31 -69 14q-40 -17 -40 -59v-160q-119 0 -216 -19.5t-162.5 -51t-114 -79t-76.5 -95.5t-44.5 -109t-21.5 -111.5t-5 -110.5q0 -181 167 -404q10 -12 25 -12q7 0 13 3q22 9 19 33q-44 354 62 473q46 52 130 75.5 t224 23.5v-160q0 -42 40 -59q12 -5 24 -5q26 0 45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
336
- <glyph unicode="&#xf14e;" d="M640 448l256 128l-256 128v-256zM1024 1039v-542l-512 -256v542zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
337
- <glyph unicode="&#xf150;" d="M1145 861q18 -35 -5 -66l-320 -448q-19 -27 -52 -27t-52 27l-320 448q-23 31 -5 66q17 35 57 35h640q40 0 57 -35zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
338
- <glyph unicode="&#xf151;" d="M1145 419q-17 -35 -57 -35h-640q-40 0 -57 35q-18 35 5 66l320 448q19 27 52 27t52 -27l320 -448q23 -31 5 -66zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
339
- <glyph unicode="&#xf152;" d="M1088 640q0 -33 -27 -52l-448 -320q-31 -23 -66 -5q-35 17 -35 57v640q0 40 35 57q35 18 66 -5l448 -320q27 -19 27 -52zM1280 160v960q0 14 -9 23t-23 9h-960q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h960q14 0 23 9t9 23zM1536 1120v-960q0 -119 -84.5 -203.5 t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
340
- <glyph unicode="&#xf153;" horiz-adv-x="1024" d="M976 229l35 -159q3 -12 -3 -22.5t-17 -14.5l-5 -1q-4 -2 -10.5 -3.5t-16 -4.5t-21.5 -5.5t-25.5 -5t-30 -5t-33.5 -4.5t-36.5 -3t-38.5 -1q-234 0 -409 130.5t-238 351.5h-95q-13 0 -22.5 9.5t-9.5 22.5v113q0 13 9.5 22.5t22.5 9.5h66q-2 57 1 105h-67q-14 0 -23 9 t-9 23v114q0 14 9 23t23 9h98q67 210 243.5 338t400.5 128q102 0 194 -23q11 -3 20 -15q6 -11 3 -24l-43 -159q-3 -13 -14 -19.5t-24 -2.5l-4 1q-4 1 -11.5 2.5l-17.5 3.5t-22.5 3.5t-26 3t-29 2.5t-29.5 1q-126 0 -226 -64t-150 -176h468q16 0 25 -12q10 -12 7 -26 l-24 -114q-5 -26 -32 -26h-488q-3 -37 0 -105h459q15 0 25 -12q9 -12 6 -27l-24 -112q-2 -11 -11 -18.5t-20 -7.5h-387q48 -117 149.5 -185.5t228.5 -68.5q18 0 36 1.5t33.5 3.5t29.5 4.5t24.5 5t18.5 4.5l12 3l5 2q13 5 26 -2q12 -7 15 -21z" />
341
- <glyph unicode="&#xf154;" horiz-adv-x="1024" d="M1020 399v-367q0 -14 -9 -23t-23 -9h-956q-14 0 -23 9t-9 23v150q0 13 9.5 22.5t22.5 9.5h97v383h-95q-14 0 -23 9.5t-9 22.5v131q0 14 9 23t23 9h95v223q0 171 123.5 282t314.5 111q185 0 335 -125q9 -8 10 -20.5t-7 -22.5l-103 -127q-9 -11 -22 -12q-13 -2 -23 7 q-5 5 -26 19t-69 32t-93 18q-85 0 -137 -47t-52 -123v-215h305q13 0 22.5 -9t9.5 -23v-131q0 -13 -9.5 -22.5t-22.5 -9.5h-305v-379h414v181q0 13 9 22.5t23 9.5h162q14 0 23 -9.5t9 -22.5z" />
342
- <glyph unicode="&#xf155;" horiz-adv-x="1024" d="M978 351q0 -153 -99.5 -263.5t-258.5 -136.5v-175q0 -14 -9 -23t-23 -9h-135q-13 0 -22.5 9.5t-9.5 22.5v175q-66 9 -127.5 31t-101.5 44.5t-74 48t-46.5 37.5t-17.5 18q-17 21 -2 41l103 135q7 10 23 12q15 2 24 -9l2 -2q113 -99 243 -125q37 -8 74 -8q81 0 142.5 43 t61.5 122q0 28 -15 53t-33.5 42t-58.5 37.5t-66 32t-80 32.5q-39 16 -61.5 25t-61.5 26.5t-62.5 31t-56.5 35.5t-53.5 42.5t-43.5 49t-35.5 58t-21 66.5t-8.5 78q0 138 98 242t255 134v180q0 13 9.5 22.5t22.5 9.5h135q14 0 23 -9t9 -23v-176q57 -6 110.5 -23t87 -33.5 t63.5 -37.5t39 -29t15 -14q17 -18 5 -38l-81 -146q-8 -15 -23 -16q-14 -3 -27 7q-3 3 -14.5 12t-39 26.5t-58.5 32t-74.5 26t-85.5 11.5q-95 0 -155 -43t-60 -111q0 -26 8.5 -48t29.5 -41.5t39.5 -33t56 -31t60.5 -27t70 -27.5q53 -20 81 -31.5t76 -35t75.5 -42.5t62 -50 t53 -63.5t31.5 -76.5t13 -94z" />
343
- <glyph unicode="&#xf156;" horiz-adv-x="898" d="M898 1066v-102q0 -14 -9 -23t-23 -9h-168q-23 -144 -129 -234t-276 -110q167 -178 459 -536q14 -16 4 -34q-8 -18 -29 -18h-195q-16 0 -25 12q-306 367 -498 571q-9 9 -9 22v127q0 13 9.5 22.5t22.5 9.5h112q132 0 212.5 43t102.5 125h-427q-14 0 -23 9t-9 23v102 q0 14 9 23t23 9h413q-57 113 -268 113h-145q-13 0 -22.5 9.5t-9.5 22.5v133q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-233q47 -61 64 -144h171q14 0 23 -9t9 -23z" />
344
- <glyph unicode="&#xf157;" horiz-adv-x="1027" d="M603 0h-172q-13 0 -22.5 9t-9.5 23v330h-288q-13 0 -22.5 9t-9.5 23v103q0 13 9.5 22.5t22.5 9.5h288v85h-288q-13 0 -22.5 9t-9.5 23v104q0 13 9.5 22.5t22.5 9.5h214l-321 578q-8 16 0 32q10 16 28 16h194q19 0 29 -18l215 -425q19 -38 56 -125q10 24 30.5 68t27.5 61 l191 420q8 19 29 19h191q17 0 27 -16q9 -14 1 -31l-313 -579h215q13 0 22.5 -9.5t9.5 -22.5v-104q0 -14 -9.5 -23t-22.5 -9h-290v-85h290q13 0 22.5 -9.5t9.5 -22.5v-103q0 -14 -9.5 -23t-22.5 -9h-290v-330q0 -13 -9.5 -22.5t-22.5 -9.5z" />
345
- <glyph unicode="&#xf158;" horiz-adv-x="1664" d="M1664 352v-32q0 -132 -94 -226t-226 -94h-128q-132 0 -226 94t-94 226v480h-224q-2 -102 -14.5 -190.5t-30.5 -156t-48.5 -126.5t-57 -99.5t-67.5 -77.5t-69.5 -58.5t-74 -44t-69 -32t-65.5 -25.5q-4 -2 -32 -13q-8 -2 -12 -2q-22 0 -30 20l-71 178q-5 13 0 25t17 17 q7 3 20 7.5t18 6.5q31 12 46.5 18.5t44.5 20t45.5 26t42 32.5t40.5 42.5t34.5 53.5t30.5 68.5t22.5 83.5t17 103t6.5 123h-256q-14 0 -23 9t-9 23v160q0 14 9 23t23 9h1216q14 0 23 -9t9 -23v-160q0 -14 -9 -23t-23 -9h-224v-512q0 -26 19 -45t45 -19h128q26 0 45 19t19 45 v64q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1280 1376v-160q0 -14 -9 -23t-23 -9h-960q-14 0 -23 9t-9 23v160q0 14 9 23t23 9h960q14 0 23 -9t9 -23z" />
346
- <glyph unicode="&#xf159;" horiz-adv-x="1792" d="M514 341l81 299h-159l75 -300q1 -1 1 -3t1 -3q0 1 0.5 3.5t0.5 3.5zM630 768l35 128h-292l32 -128h225zM822 768h139l-35 128h-70zM1271 340l78 300h-162l81 -299q0 -1 0.5 -3.5t1.5 -3.5q0 1 0.5 3t0.5 3zM1382 768l33 128h-297l34 -128h230zM1792 736v-64q0 -14 -9 -23 t-23 -9h-213l-164 -616q-7 -24 -31 -24h-159q-24 0 -31 24l-166 616h-209l-167 -616q-7 -24 -31 -24h-159q-11 0 -19.5 7t-10.5 17l-160 616h-208q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h175l-33 128h-142q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h109l-89 344q-5 15 5 28 q10 12 26 12h137q26 0 31 -24l90 -360h359l97 360q7 24 31 24h126q24 0 31 -24l98 -360h365l93 360q5 24 31 24h137q16 0 26 -12q10 -13 5 -28l-91 -344h111q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-145l-34 -128h179q14 0 23 -9t9 -23z" />
347
- <glyph unicode="&#xf15a;" horiz-adv-x="1280" d="M1167 896q18 -182 -131 -258q117 -28 175 -103t45 -214q-7 -71 -32.5 -125t-64.5 -89t-97 -58.5t-121.5 -34.5t-145.5 -15v-255h-154v251q-80 0 -122 1v-252h-154v255q-18 0 -54 0.5t-55 0.5h-200l31 183h111q50 0 58 51v402h16q-6 1 -16 1v287q-13 68 -89 68h-111v164 l212 -1q64 0 97 1v252h154v-247q82 2 122 2v245h154v-252q79 -7 140 -22.5t113 -45t82.5 -78t36.5 -114.5zM952 351q0 36 -15 64t-37 46t-57.5 30.5t-65.5 18.5t-74 9t-69 3t-64.5 -1t-47.5 -1v-338q8 0 37 -0.5t48 -0.5t53 1.5t58.5 4t57 8.5t55.5 14t47.5 21t39.5 30 t24.5 40t9.5 51zM881 827q0 33 -12.5 58.5t-30.5 42t-48 28t-55 16.5t-61.5 8t-58 2.5t-54 -1t-39.5 -0.5v-307q5 0 34.5 -0.5t46.5 0t50 2t55 5.5t51.5 11t48.5 18.5t37 27t27 38.5t9 51z" />
348
- <glyph unicode="&#xf15b;" horiz-adv-x="1280" d="M1280 768v-800q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h544v-544q0 -40 28 -68t68 -28h544zM1277 896h-509v509q82 -15 132 -65l312 -312q50 -50 65 -132z" />
349
- <glyph unicode="&#xf15c;" horiz-adv-x="1280" d="M1024 160v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1024 416v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1280 768v-800q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28 t-28 68v1344q0 40 28 68t68 28h544v-544q0 -40 28 -68t68 -28h544zM1277 896h-509v509q82 -15 132 -65l312 -312q50 -50 65 -132z" />
350
- <glyph unicode="&#xf15d;" horiz-adv-x="1664" d="M1191 1128h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1572 -23 v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -11v-2l14 2q9 2 30 2h248v119h121zM1661 874v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162 l230 -662h70z" />
351
- <glyph unicode="&#xf15e;" horiz-adv-x="1664" d="M1191 104h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1661 -150 v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162l230 -662h70zM1572 1001v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -10v-3l14 3q9 1 30 1h248 v119h121z" />
352
- <glyph unicode="&#xf160;" horiz-adv-x="1792" d="M736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1792 -32v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832 q14 0 23 -9t9 -23zM1600 480v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1408 992v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1216 1504v-192q0 -14 -9 -23t-23 -9h-256 q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23z" />
353
- <glyph unicode="&#xf161;" horiz-adv-x="1792" d="M1216 -32v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192 q14 0 23 -9t9 -23zM1408 480v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1600 992v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1792 1504v-192q0 -14 -9 -23t-23 -9h-832 q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832q14 0 23 -9t9 -23z" />
354
- <glyph unicode="&#xf162;" d="M1346 223q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23 zM1486 165q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5 t82 -252.5zM1456 882v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165z" />
355
- <glyph unicode="&#xf163;" d="M1346 1247q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9 t9 -23zM1456 -142v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165zM1486 1189q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13 q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5z" />
356
- <glyph unicode="&#xf164;" horiz-adv-x="1664" d="M256 192q0 26 -19 45t-45 19q-27 0 -45.5 -19t-18.5 -45q0 -27 18.5 -45.5t45.5 -18.5q26 0 45 18.5t19 45.5zM416 704v-640q0 -26 -19 -45t-45 -19h-288q-26 0 -45 19t-19 45v640q0 26 19 45t45 19h288q26 0 45 -19t19 -45zM1600 704q0 -86 -55 -149q15 -44 15 -76 q3 -76 -43 -137q17 -56 0 -117q-15 -57 -54 -94q9 -112 -49 -181q-64 -76 -197 -78h-36h-76h-17q-66 0 -144 15.5t-121.5 29t-120.5 39.5q-123 43 -158 44q-26 1 -45 19.5t-19 44.5v641q0 25 18 43.5t43 20.5q24 2 76 59t101 121q68 87 101 120q18 18 31 48t17.5 48.5 t13.5 60.5q7 39 12.5 61t19.5 52t34 50q19 19 45 19q46 0 82.5 -10.5t60 -26t40 -40.5t24 -45t12 -50t5 -45t0.5 -39q0 -38 -9.5 -76t-19 -60t-27.5 -56q-3 -6 -10 -18t-11 -22t-8 -24h277q78 0 135 -57t57 -135z" />
357
- <glyph unicode="&#xf165;" horiz-adv-x="1664" d="M256 960q0 -26 -19 -45t-45 -19q-27 0 -45.5 19t-18.5 45q0 27 18.5 45.5t45.5 18.5q26 0 45 -18.5t19 -45.5zM416 448v640q0 26 -19 45t-45 19h-288q-26 0 -45 -19t-19 -45v-640q0 -26 19 -45t45 -19h288q26 0 45 19t19 45zM1545 597q55 -61 55 -149q-1 -78 -57.5 -135 t-134.5 -57h-277q4 -14 8 -24t11 -22t10 -18q18 -37 27 -57t19 -58.5t10 -76.5q0 -24 -0.5 -39t-5 -45t-12 -50t-24 -45t-40 -40.5t-60 -26t-82.5 -10.5q-26 0 -45 19q-20 20 -34 50t-19.5 52t-12.5 61q-9 42 -13.5 60.5t-17.5 48.5t-31 48q-33 33 -101 120q-49 64 -101 121 t-76 59q-25 2 -43 20.5t-18 43.5v641q0 26 19 44.5t45 19.5q35 1 158 44q77 26 120.5 39.5t121.5 29t144 15.5h17h76h36q133 -2 197 -78q58 -69 49 -181q39 -37 54 -94q17 -61 0 -117q46 -61 43 -137q0 -32 -15 -76z" />
358
- <glyph unicode="&#xf166;" d="M919 233v157q0 50 -29 50q-17 0 -33 -16v-224q16 -16 33 -16q29 0 29 49zM1103 355h66v34q0 51 -33 51t-33 -51v-34zM532 621v-70h-80v-423h-74v423h-78v70h232zM733 495v-367h-67v40q-39 -45 -76 -45q-33 0 -42 28q-6 16 -6 54v290h66v-270q0 -24 1 -26q1 -15 15 -15 q20 0 42 31v280h67zM985 384v-146q0 -52 -7 -73q-12 -42 -53 -42q-35 0 -68 41v-36h-67v493h67v-161q32 40 68 40q41 0 53 -42q7 -21 7 -74zM1236 255v-9q0 -29 -2 -43q-3 -22 -15 -40q-27 -40 -80 -40q-52 0 -81 38q-21 27 -21 86v129q0 59 20 86q29 38 80 38t78 -38 q21 -28 21 -86v-76h-133v-65q0 -51 34 -51q24 0 30 26q0 1 0.5 7t0.5 16.5v21.5h68zM785 1079v-156q0 -51 -32 -51t-32 51v156q0 52 32 52t32 -52zM1318 366q0 177 -19 260q-10 44 -43 73.5t-76 34.5q-136 15 -412 15q-275 0 -411 -15q-44 -5 -76.5 -34.5t-42.5 -73.5 q-20 -87 -20 -260q0 -176 20 -260q10 -43 42.5 -73t75.5 -35q137 -15 412 -15t412 15q43 5 75.5 35t42.5 73q20 84 20 260zM563 1017l90 296h-75l-51 -195l-53 195h-78l24 -69t23 -69q35 -103 46 -158v-201h74v201zM852 936v130q0 58 -21 87q-29 38 -78 38q-51 0 -78 -38 q-21 -29 -21 -87v-130q0 -58 21 -87q27 -38 78 -38q49 0 78 38q21 27 21 87zM1033 816h67v370h-67v-283q-22 -31 -42 -31q-15 0 -16 16q-1 2 -1 26v272h-67v-293q0 -37 6 -55q11 -27 43 -27q36 0 77 45v-40zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960 q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
359
- <glyph unicode="&#xf167;" d="M971 292v-211q0 -67 -39 -67q-23 0 -45 22v301q22 22 45 22q39 0 39 -67zM1309 291v-46h-90v46q0 68 45 68t45 -68zM343 509h107v94h-312v-94h105v-569h100v569zM631 -60h89v494h-89v-378q-30 -42 -57 -42q-18 0 -21 21q-1 3 -1 35v364h-89v-391q0 -49 8 -73 q12 -37 58 -37q48 0 102 61v-54zM1060 88v197q0 73 -9 99q-17 56 -71 56q-50 0 -93 -54v217h-89v-663h89v48q45 -55 93 -55q54 0 71 55q9 27 9 100zM1398 98v13h-91q0 -51 -2 -61q-7 -36 -40 -36q-46 0 -46 69v87h179v103q0 79 -27 116q-39 51 -106 51q-68 0 -107 -51 q-28 -37 -28 -116v-173q0 -79 29 -116q39 -51 108 -51q72 0 108 53q18 27 21 54q2 9 2 58zM790 1011v210q0 69 -43 69t-43 -69v-210q0 -70 43 -70t43 70zM1509 260q0 -234 -26 -350q-14 -59 -58 -99t-102 -46q-184 -21 -555 -21t-555 21q-58 6 -102.5 46t-57.5 99 q-26 112 -26 350q0 234 26 350q14 59 58 99t103 47q183 20 554 20t555 -20q58 -7 102.5 -47t57.5 -99q26 -112 26 -350zM511 1536h102l-121 -399v-271h-100v271q-14 74 -61 212q-37 103 -65 187h106l71 -263zM881 1203v-175q0 -81 -28 -118q-37 -51 -106 -51q-67 0 -105 51 q-28 38 -28 118v175q0 80 28 117q38 51 105 51q69 0 106 -51q28 -37 28 -117zM1216 1365v-499h-91v55q-53 -62 -103 -62q-46 0 -59 37q-8 24 -8 75v394h91v-367q0 -33 1 -35q3 -22 21 -22q27 0 57 43v381h91z" />
360
- <glyph unicode="&#xf168;" horiz-adv-x="1408" d="M597 869q-10 -18 -257 -456q-27 -46 -65 -46h-239q-21 0 -31 17t0 36l253 448q1 0 0 1l-161 279q-12 22 -1 37q9 15 32 15h239q40 0 66 -45zM1403 1511q11 -16 0 -37l-528 -934v-1l336 -615q11 -20 1 -37q-10 -15 -32 -15h-239q-42 0 -66 45l-339 622q18 32 531 942 q25 45 64 45h241q22 0 31 -15z" />
361
- <glyph unicode="&#xf169;" d="M685 771q0 1 -126 222q-21 34 -52 34h-184q-18 0 -26 -11q-7 -12 1 -29l125 -216v-1l-196 -346q-9 -14 0 -28q8 -13 24 -13h185q31 0 50 36zM1309 1268q-7 12 -24 12h-187q-30 0 -49 -35l-411 -729q1 -2 262 -481q20 -35 52 -35h184q18 0 25 12q8 13 -1 28l-260 476v1 l409 723q8 16 0 28zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
362
- <glyph unicode="&#xf16a;" horiz-adv-x="1792" d="M1280 640q0 37 -30 54l-512 320q-31 20 -65 2q-33 -18 -33 -56v-640q0 -38 33 -56q16 -8 31 -8q20 0 34 10l512 320q30 17 30 54zM1792 640q0 -96 -1 -150t-8.5 -136.5t-22.5 -147.5q-16 -73 -69 -123t-124 -58q-222 -25 -671 -25t-671 25q-71 8 -124.5 58t-69.5 123 q-14 65 -21.5 147.5t-8.5 136.5t-1 150t1 150t8.5 136.5t22.5 147.5q16 73 69 123t124 58q222 25 671 25t671 -25q71 -8 124.5 -58t69.5 -123q14 -65 21.5 -147.5t8.5 -136.5t1 -150z" />
363
- <glyph unicode="&#xf16b;" horiz-adv-x="1792" d="M402 829l494 -305l-342 -285l-490 319zM1388 274v-108l-490 -293v-1l-1 1l-1 -1v1l-489 293v108l147 -96l342 284v2l1 -1l1 1v-2l343 -284zM554 1418l342 -285l-494 -304l-338 270zM1390 829l338 -271l-489 -319l-343 285zM1239 1418l489 -319l-338 -270l-494 304z" />
364
- <glyph unicode="&#xf16c;" horiz-adv-x="1408" d="M928 135v-151l-707 -1v151zM1169 481v-701l-1 -35v-1h-1132l-35 1h-1v736h121v-618h928v618h120zM241 393l704 -65l-13 -150l-705 65zM309 709l683 -183l-39 -146l-683 183zM472 1058l609 -360l-77 -130l-609 360zM832 1389l398 -585l-124 -85l-399 584zM1285 1536 l121 -697l-149 -26l-121 697z" />
365
- <glyph unicode="&#xf16d;" d="M1362 110v648h-135q20 -63 20 -131q0 -126 -64 -232.5t-174 -168.5t-240 -62q-197 0 -337 135.5t-140 327.5q0 68 20 131h-141v-648q0 -26 17.5 -43.5t43.5 -17.5h1069q25 0 43 17.5t18 43.5zM1078 643q0 124 -90.5 211.5t-218.5 87.5q-127 0 -217.5 -87.5t-90.5 -211.5 t90.5 -211.5t217.5 -87.5q128 0 218.5 87.5t90.5 211.5zM1362 1003v165q0 28 -20 48.5t-49 20.5h-174q-29 0 -49 -20.5t-20 -48.5v-165q0 -29 20 -49t49 -20h174q29 0 49 20t20 49zM1536 1211v-1142q0 -81 -58 -139t-139 -58h-1142q-81 0 -139 58t-58 139v1142q0 81 58 139 t139 58h1142q81 0 139 -58t58 -139z" />
366
- <glyph unicode="&#xf16e;" d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM698 640q0 88 -62 150t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150zM1262 640q0 88 -62 150 t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150z" />
367
- <glyph unicode="&#xf170;" d="M768 914l201 -306h-402zM1133 384h94l-459 691l-459 -691h94l104 160h522zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
368
- <glyph unicode="&#xf171;" horiz-adv-x="1408" d="M815 677q8 -63 -50.5 -101t-111.5 -6q-39 17 -53.5 58t-0.5 82t52 58q36 18 72.5 12t64 -35.5t27.5 -67.5zM926 698q-14 107 -113 164t-197 13q-63 -28 -100.5 -88.5t-34.5 -129.5q4 -91 77.5 -155t165.5 -56q91 8 152 84t50 168zM1165 1240q-20 27 -56 44.5t-58 22 t-71 12.5q-291 47 -566 -2q-43 -7 -66 -12t-55 -22t-50 -43q30 -28 76 -45.5t73.5 -22t87.5 -11.5q228 -29 448 -1q63 8 89.5 12t72.5 21.5t75 46.5zM1222 205q-8 -26 -15.5 -76.5t-14 -84t-28.5 -70t-58 -56.5q-86 -48 -189.5 -71.5t-202 -22t-201.5 18.5q-46 8 -81.5 18 t-76.5 27t-73 43.5t-52 61.5q-25 96 -57 292l6 16l18 9q223 -148 506.5 -148t507.5 148q21 -6 24 -23t-5 -45t-8 -37zM1403 1166q-26 -167 -111 -655q-5 -30 -27 -56t-43.5 -40t-54.5 -31q-252 -126 -610 -88q-248 27 -394 139q-15 12 -25.5 26.5t-17 35t-9 34t-6 39.5 t-5.5 35q-9 50 -26.5 150t-28 161.5t-23.5 147.5t-22 158q3 26 17.5 48.5t31.5 37.5t45 30t46 22.5t48 18.5q125 46 313 64q379 37 676 -50q155 -46 215 -122q16 -20 16.5 -51t-5.5 -54z" />
369
- <glyph unicode="&#xf172;" d="M848 666q0 43 -41 66t-77 1q-43 -20 -42.5 -72.5t43.5 -70.5q39 -23 81 4t36 72zM928 682q8 -66 -36 -121t-110 -61t-119 40t-56 113q-2 49 25.5 93t72.5 64q70 31 141.5 -10t81.5 -118zM1100 1073q-20 -21 -53.5 -34t-53 -16t-63.5 -8q-155 -20 -324 0q-44 6 -63 9.5 t-52.5 16t-54.5 32.5q13 19 36 31t40 15.5t47 8.5q198 35 408 1q33 -5 51 -8.5t43 -16t39 -31.5zM1142 327q0 7 5.5 26.5t3 32t-17.5 16.5q-161 -106 -365 -106t-366 106l-12 -6l-5 -12q26 -154 41 -210q47 -81 204 -108q249 -46 428 53q34 19 49 51.5t22.5 85.5t12.5 71z M1272 1020q9 53 -8 75q-43 55 -155 88q-216 63 -487 36q-132 -12 -226 -46q-38 -15 -59.5 -25t-47 -34t-29.5 -54q8 -68 19 -138t29 -171t24 -137q1 -5 5 -31t7 -36t12 -27t22 -28q105 -80 284 -100q259 -28 440 63q24 13 39.5 23t31 29t19.5 40q48 267 80 473zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
370
- <glyph unicode="&#xf173;" horiz-adv-x="1024" d="M390 1408h219v-388h364v-241h-364v-394q0 -136 14 -172q13 -37 52 -60q50 -31 117 -31q117 0 232 76v-242q-102 -48 -178 -65q-77 -19 -173 -19q-105 0 -186 27q-78 25 -138 75q-58 51 -79 105q-22 54 -22 161v539h-170v217q91 30 155 84q64 55 103 132q39 78 54 196z " />
371
- <glyph unicode="&#xf174;" d="M1123 127v181q-88 -56 -174 -56q-51 0 -88 23q-29 17 -39 45q-11 30 -11 129v295h274v181h-274v291h-164q-11 -90 -40 -147t-78 -99q-48 -40 -116 -63v-163h127v-404q0 -78 17 -121q17 -42 59 -78q43 -37 104 -57q62 -20 140 -20q67 0 129 14q57 13 134 49zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
372
- <glyph unicode="&#xf175;" horiz-adv-x="768" d="M765 237q8 -19 -5 -35l-350 -384q-10 -10 -23 -10q-14 0 -24 10l-355 384q-13 16 -5 35q9 19 29 19h224v1248q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1248h224q21 0 29 -19z" />
373
- <glyph unicode="&#xf176;" horiz-adv-x="768" d="M765 1043q-9 -19 -29 -19h-224v-1248q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1248h-224q-21 0 -29 19t5 35l350 384q10 10 23 10q14 0 24 -10l355 -384q13 -16 5 -35z" />
374
- <glyph unicode="&#xf177;" horiz-adv-x="1792" d="M1792 736v-192q0 -14 -9 -23t-23 -9h-1248v-224q0 -21 -19 -29t-35 5l-384 350q-10 10 -10 23q0 14 10 24l384 354q16 14 35 6q19 -9 19 -29v-224h1248q14 0 23 -9t9 -23z" />
375
- <glyph unicode="&#xf178;" horiz-adv-x="1792" d="M1728 643q0 -14 -10 -24l-384 -354q-16 -14 -35 -6q-19 9 -19 29v224h-1248q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h1248v224q0 21 19 29t35 -5l384 -350q10 -10 10 -23z" />
376
- <glyph unicode="&#xf179;" horiz-adv-x="1408" d="M1393 321q-39 -125 -123 -250q-129 -196 -257 -196q-49 0 -140 32q-86 32 -151 32q-61 0 -142 -33q-81 -34 -132 -34q-152 0 -301 259q-147 261 -147 503q0 228 113 374q112 144 284 144q72 0 177 -30q104 -30 138 -30q45 0 143 34q102 34 173 34q119 0 213 -65 q52 -36 104 -100q-79 -67 -114 -118q-65 -94 -65 -207q0 -124 69 -223t158 -126zM1017 1494q0 -61 -29 -136q-30 -75 -93 -138q-54 -54 -108 -72q-37 -11 -104 -17q3 149 78 257q74 107 250 148q1 -3 2.5 -11t2.5 -11q0 -4 0.5 -10t0.5 -10z" />
377
- <glyph unicode="&#xf17a;" horiz-adv-x="1664" d="M682 530v-651l-682 94v557h682zM682 1273v-659h-682v565zM1664 530v-786l-907 125v661h907zM1664 1408v-794h-907v669z" />
378
- <glyph unicode="&#xf17b;" horiz-adv-x="1408" d="M493 1053q16 0 27.5 11.5t11.5 27.5t-11.5 27.5t-27.5 11.5t-27 -11.5t-11 -27.5t11 -27.5t27 -11.5zM915 1053q16 0 27 11.5t11 27.5t-11 27.5t-27 11.5t-27.5 -11.5t-11.5 -27.5t11.5 -27.5t27.5 -11.5zM103 869q42 0 72 -30t30 -72v-430q0 -43 -29.5 -73t-72.5 -30 t-73 30t-30 73v430q0 42 30 72t73 30zM1163 850v-666q0 -46 -32 -78t-77 -32h-75v-227q0 -43 -30 -73t-73 -30t-73 30t-30 73v227h-138v-227q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73l-1 227h-74q-46 0 -78 32t-32 78v666h918zM931 1255q107 -55 171 -153.5t64 -215.5 h-925q0 117 64 215.5t172 153.5l-71 131q-7 13 5 20q13 6 20 -6l72 -132q95 42 201 42t201 -42l72 132q7 12 20 6q12 -7 5 -20zM1408 767v-430q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73v430q0 43 30 72.5t72 29.5q43 0 73 -29.5t30 -72.5z" />
379
- <glyph unicode="&#xf17c;" d="M663 1125q-11 -1 -15.5 -10.5t-8.5 -9.5q-5 -1 -5 5q0 12 19 15h10zM750 1111q-4 -1 -11.5 6.5t-17.5 4.5q24 11 32 -2q3 -6 -3 -9zM399 684q-4 1 -6 -3t-4.5 -12.5t-5.5 -13.5t-10 -13q-7 -10 -1 -12q4 -1 12.5 7t12.5 18q1 3 2 7t2 6t1.5 4.5t0.5 4v3t-1 2.5t-3 2z M1254 325q0 18 -55 42q4 15 7.5 27.5t5 26t3 21.5t0.5 22.5t-1 19.5t-3.5 22t-4 20.5t-5 25t-5.5 26.5q-10 48 -47 103t-72 75q24 -20 57 -83q87 -162 54 -278q-11 -40 -50 -42q-31 -4 -38.5 18.5t-8 83.5t-11.5 107q-9 39 -19.5 69t-19.5 45.5t-15.5 24.5t-13 15t-7.5 7 q-14 62 -31 103t-29.5 56t-23.5 33t-15 40q-4 21 6 53.5t4.5 49.5t-44.5 25q-15 3 -44.5 18t-35.5 16q-8 1 -11 26t8 51t36 27q37 3 51 -30t4 -58q-11 -19 -2 -26.5t30 -0.5q13 4 13 36v37q-5 30 -13.5 50t-21 30.5t-23.5 15t-27 7.5q-107 -8 -89 -134q0 -15 -1 -15 q-9 9 -29.5 10.5t-33 -0.5t-15.5 5q1 57 -16 90t-45 34q-27 1 -41.5 -27.5t-16.5 -59.5q-1 -15 3.5 -37t13 -37.5t15.5 -13.5q10 3 16 14q4 9 -7 8q-7 0 -15.5 14.5t-9.5 33.5q-1 22 9 37t34 14q17 0 27 -21t9.5 -39t-1.5 -22q-22 -15 -31 -29q-8 -12 -27.5 -23.5 t-20.5 -12.5q-13 -14 -15.5 -27t7.5 -18q14 -8 25 -19.5t16 -19t18.5 -13t35.5 -6.5q47 -2 102 15q2 1 23 7t34.5 10.5t29.5 13t21 17.5q9 14 20 8q5 -3 6.5 -8.5t-3 -12t-16.5 -9.5q-20 -6 -56.5 -21.5t-45.5 -19.5q-44 -19 -70 -23q-25 -5 -79 2q-10 2 -9 -2t17 -19 q25 -23 67 -22q17 1 36 7t36 14t33.5 17.5t30 17t24.5 12t17.5 2.5t8.5 -11q0 -2 -1 -4.5t-4 -5t-6 -4.5t-8.5 -5t-9 -4.5t-10 -5t-9.5 -4.5q-28 -14 -67.5 -44t-66.5 -43t-49 -1q-21 11 -63 73q-22 31 -25 22q-1 -3 -1 -10q0 -25 -15 -56.5t-29.5 -55.5t-21 -58t11.5 -63 q-23 -6 -62.5 -90t-47.5 -141q-2 -18 -1.5 -69t-5.5 -59q-8 -24 -29 -3q-32 31 -36 94q-2 28 4 56q4 19 -1 18l-4 -5q-36 -65 10 -166q5 -12 25 -28t24 -20q20 -23 104 -90.5t93 -76.5q16 -15 17.5 -38t-14 -43t-45.5 -23q8 -15 29 -44.5t28 -54t7 -70.5q46 24 7 92 q-4 8 -10.5 16t-9.5 12t-2 6q3 5 13 9.5t20 -2.5q46 -52 166 -36q133 15 177 87q23 38 34 30q12 -6 10 -52q-1 -25 -23 -92q-9 -23 -6 -37.5t24 -15.5q3 19 14.5 77t13.5 90q2 21 -6.5 73.5t-7.5 97t23 70.5q15 18 51 18q1 37 34.5 53t72.5 10.5t60 -22.5zM626 1152 q3 17 -2.5 30t-11.5 15q-9 2 -9 -7q2 -5 5 -6q10 0 7 -15q-3 -20 8 -20q3 0 3 3zM1045 955q-2 8 -6.5 11.5t-13 5t-14.5 5.5q-5 3 -9.5 8t-7 8t-5.5 6.5t-4 4t-4 -1.5q-14 -16 7 -43.5t39 -31.5q9 -1 14.5 8t3.5 20zM867 1168q0 11 -5 19.5t-11 12.5t-9 3q-14 -1 -7 -7l4 -2 q14 -4 18 -31q0 -3 8 2zM921 1401q0 2 -2.5 5t-9 7t-9.5 6q-15 15 -24 15q-9 -1 -11.5 -7.5t-1 -13t-0.5 -12.5q-1 -4 -6 -10.5t-6 -9t3 -8.5q4 -3 8 0t11 9t15 9q1 1 9 1t15 2t9 7zM1486 60q20 -12 31 -24.5t12 -24t-2.5 -22.5t-15.5 -22t-23.5 -19.5t-30 -18.5 t-31.5 -16.5t-32 -15.5t-27 -13q-38 -19 -85.5 -56t-75.5 -64q-17 -16 -68 -19.5t-89 14.5q-18 9 -29.5 23.5t-16.5 25.5t-22 19.5t-47 9.5q-44 1 -130 1q-19 0 -57 -1.5t-58 -2.5q-44 -1 -79.5 -15t-53.5 -30t-43.5 -28.5t-53.5 -11.5q-29 1 -111 31t-146 43q-19 4 -51 9.5 t-50 9t-39.5 9.5t-33.5 14.5t-17 19.5q-10 23 7 66.5t18 54.5q1 16 -4 40t-10 42.5t-4.5 36.5t10.5 27q14 12 57 14t60 12q30 18 42 35t12 51q21 -73 -32 -106q-32 -20 -83 -15q-34 3 -43 -10q-13 -15 5 -57q2 -6 8 -18t8.5 -18t4.5 -17t1 -22q0 -15 -17 -49t-14 -48 q3 -17 37 -26q20 -6 84.5 -18.5t99.5 -20.5q24 -6 74 -22t82.5 -23t55.5 -4q43 6 64.5 28t23 48t-7.5 58.5t-19 52t-20 36.5q-121 190 -169 242q-68 74 -113 40q-11 -9 -15 15q-3 16 -2 38q1 29 10 52t24 47t22 42q8 21 26.5 72t29.5 78t30 61t39 54q110 143 124 195 q-12 112 -16 310q-2 90 24 151.5t106 104.5q39 21 104 21q53 1 106 -13.5t89 -41.5q57 -42 91.5 -121.5t29.5 -147.5q-5 -95 30 -214q34 -113 133 -218q55 -59 99.5 -163t59.5 -191q8 -49 5 -84.5t-12 -55.5t-20 -22q-10 -2 -23.5 -19t-27 -35.5t-40.5 -33.5t-61 -14 q-18 1 -31.5 5t-22.5 13.5t-13.5 15.5t-11.5 20.5t-9 19.5q-22 37 -41 30t-28 -49t7 -97q20 -70 1 -195q-10 -65 18 -100.5t73 -33t85 35.5q59 49 89.5 66.5t103.5 42.5q53 18 77 36.5t18.5 34.5t-25 28.5t-51.5 23.5q-33 11 -49.5 48t-15 72.5t15.5 47.5q1 -31 8 -56.5 t14.5 -40.5t20.5 -28.5t21 -19t21.5 -13t16.5 -9.5z" />
380
- <glyph unicode="&#xf17d;" d="M1024 36q-42 241 -140 498h-2l-2 -1q-16 -6 -43 -16.5t-101 -49t-137 -82t-131 -114.5t-103 -148l-15 11q184 -150 418 -150q132 0 256 52zM839 643q-21 49 -53 111q-311 -93 -673 -93q-1 -7 -1 -21q0 -124 44 -236.5t124 -201.5q50 89 123.5 166.5t142.5 124.5t130.5 81 t99.5 48l37 13q4 1 13 3.5t13 4.5zM732 855q-120 213 -244 378q-138 -65 -234 -186t-128 -272q302 0 606 80zM1416 536q-210 60 -409 29q87 -239 128 -469q111 75 185 189.5t96 250.5zM611 1277q-1 0 -2 -1q1 1 2 1zM1201 1132q-185 164 -433 164q-76 0 -155 -19 q131 -170 246 -382q69 26 130 60.5t96.5 61.5t65.5 57t37.5 40.5zM1424 647q-3 232 -149 410l-1 -1q-9 -12 -19 -24.5t-43.5 -44.5t-71 -60.5t-100 -65t-131.5 -64.5q25 -53 44 -95q2 -6 6.5 -17.5t7.5 -16.5q36 5 74.5 7t73.5 2t69 -1.5t64 -4t56.5 -5.5t48 -6.5t36.5 -6 t25 -4.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
381
- <glyph unicode="&#xf17e;" d="M1173 473q0 50 -19.5 91.5t-48.5 68.5t-73 49t-82.5 34t-87.5 23l-104 24q-30 7 -44 10.5t-35 11.5t-30 16t-16.5 21t-7.5 30q0 77 144 77q43 0 77 -12t54 -28.5t38 -33.5t40 -29t48 -12q47 0 75.5 32t28.5 77q0 55 -56 99.5t-142 67.5t-182 23q-68 0 -132 -15.5 t-119.5 -47t-89 -87t-33.5 -128.5q0 -61 19 -106.5t56 -75.5t80 -48.5t103 -32.5l146 -36q90 -22 112 -36q32 -20 32 -60q0 -39 -40 -64.5t-105 -25.5q-51 0 -91.5 16t-65 38.5t-45.5 45t-46 38.5t-54 16q-50 0 -75.5 -30t-25.5 -75q0 -92 122 -157.5t291 -65.5 q73 0 140 18.5t122.5 53.5t88.5 93.5t33 131.5zM1536 256q0 -159 -112.5 -271.5t-271.5 -112.5q-130 0 -234 80q-77 -16 -150 -16q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5q0 73 16 150q-80 104 -80 234q0 159 112.5 271.5t271.5 112.5q130 0 234 -80 q77 16 150 16q143 0 273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -73 -16 -150q80 -104 80 -234z" />
382
- <glyph unicode="&#xf180;" horiz-adv-x="1664" d="M1483 512l-587 -587q-52 -53 -127.5 -53t-128.5 53l-587 587q-53 53 -53 128t53 128l587 587q53 53 128 53t128 -53l265 -265l-398 -399l-188 188q-42 42 -99 42q-59 0 -100 -41l-120 -121q-42 -40 -42 -99q0 -58 42 -100l406 -408q30 -28 67 -37l6 -4h28q60 0 99 41 l619 619l2 -3q53 -53 53 -128t-53 -128zM1406 1138l120 -120q14 -15 14 -36t-14 -36l-730 -730q-17 -15 -37 -15v0q-4 0 -6 1q-18 2 -30 14l-407 408q-14 15 -14 36t14 35l121 120q13 15 35 15t36 -15l252 -252l574 575q15 15 36 15t36 -15z" />
383
- <glyph unicode="&#xf181;" d="M704 192v1024q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-1024q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1376 576v640q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-640q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408 q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
384
- <glyph unicode="&#xf182;" horiz-adv-x="1280" d="M1280 480q0 -40 -28 -68t-68 -28q-51 0 -80 43l-227 341h-45v-132l247 -411q9 -15 9 -33q0 -26 -19 -45t-45 -19h-192v-272q0 -46 -33 -79t-79 -33h-160q-46 0 -79 33t-33 79v272h-192q-26 0 -45 19t-19 45q0 18 9 33l247 411v132h-45l-227 -341q-29 -43 -80 -43 q-40 0 -68 28t-28 68q0 29 16 53l256 384q73 107 176 107h384q103 0 176 -107l256 -384q16 -24 16 -53zM864 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
385
- <glyph unicode="&#xf183;" horiz-adv-x="1024" d="M1024 832v-416q0 -40 -28 -68t-68 -28t-68 28t-28 68v352h-64v-912q0 -46 -33 -79t-79 -33t-79 33t-33 79v464h-64v-464q0 -46 -33 -79t-79 -33t-79 33t-33 79v912h-64v-352q0 -40 -28 -68t-68 -28t-68 28t-28 68v416q0 80 56 136t136 56h640q80 0 136 -56t56 -136z M736 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
386
- <glyph unicode="&#xf184;" d="M773 234l350 473q16 22 24.5 59t-6 85t-61.5 79q-40 26 -83 25.5t-73.5 -17.5t-54.5 -45q-36 -40 -96 -40q-59 0 -95 40q-24 28 -54.5 45t-73.5 17.5t-84 -25.5q-46 -31 -60.5 -79t-6 -85t24.5 -59zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
387
- <glyph unicode="&#xf185;" horiz-adv-x="1792" d="M1472 640q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5zM1748 363q-4 -15 -20 -20l-292 -96v-306q0 -16 -13 -26q-15 -10 -29 -4 l-292 94l-180 -248q-10 -13 -26 -13t-26 13l-180 248l-292 -94q-14 -6 -29 4q-13 10 -13 26v306l-292 96q-16 5 -20 20q-5 17 4 29l180 248l-180 248q-9 13 -4 29q4 15 20 20l292 96v306q0 16 13 26q15 10 29 4l292 -94l180 248q9 12 26 12t26 -12l180 -248l292 94 q14 6 29 -4q13 -10 13 -26v-306l292 -96q16 -5 20 -20q5 -16 -4 -29l-180 -248l180 -248q9 -12 4 -29z" />
388
- <glyph unicode="&#xf186;" d="M1262 233q-54 -9 -110 -9q-182 0 -337 90t-245 245t-90 337q0 192 104 357q-201 -60 -328.5 -229t-127.5 -384q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51q144 0 273.5 61.5t220.5 171.5zM1465 318q-94 -203 -283.5 -324.5t-413.5 -121.5q-156 0 -298 61 t-245 164t-164 245t-61 298q0 153 57.5 292.5t156 241.5t235.5 164.5t290 68.5q44 2 61 -39q18 -41 -15 -72q-86 -78 -131.5 -181.5t-45.5 -218.5q0 -148 73 -273t198 -198t273 -73q118 0 228 51q41 18 72 -13q14 -14 17.5 -34t-4.5 -38z" />
389
- <glyph unicode="&#xf187;" horiz-adv-x="1792" d="M1088 704q0 26 -19 45t-45 19h-256q-26 0 -45 -19t-19 -45t19 -45t45 -19h256q26 0 45 19t19 45zM1664 896v-960q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v960q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1728 1344v-256q0 -26 -19 -45t-45 -19h-1536 q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1536q26 0 45 -19t19 -45z" />
390
- <glyph unicode="&#xf188;" horiz-adv-x="1664" d="M1632 576q0 -26 -19 -45t-45 -19h-224q0 -171 -67 -290l208 -209q19 -19 19 -45t-19 -45q-18 -19 -45 -19t-45 19l-198 197q-5 -5 -15 -13t-42 -28.5t-65 -36.5t-82 -29t-97 -13v896h-128v-896q-51 0 -101.5 13.5t-87 33t-66 39t-43.5 32.5l-15 14l-183 -207 q-20 -21 -48 -21q-24 0 -43 16q-19 18 -20.5 44.5t15.5 46.5l202 227q-58 114 -58 274h-224q-26 0 -45 19t-19 45t19 45t45 19h224v294l-173 173q-19 19 -19 45t19 45t45 19t45 -19l173 -173h844l173 173q19 19 45 19t45 -19t19 -45t-19 -45l-173 -173v-294h224q26 0 45 -19 t19 -45zM1152 1152h-640q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5z" />
391
- <glyph unicode="&#xf189;" horiz-adv-x="1920" d="M1917 1016q23 -64 -150 -294q-24 -32 -65 -85q-78 -100 -90 -131q-17 -41 14 -81q17 -21 81 -82h1l1 -1l1 -1l2 -2q141 -131 191 -221q3 -5 6.5 -12.5t7 -26.5t-0.5 -34t-25 -27.5t-59 -12.5l-256 -4q-24 -5 -56 5t-52 22l-20 12q-30 21 -70 64t-68.5 77.5t-61 58 t-56.5 15.5q-3 -1 -8 -3.5t-17 -14.5t-21.5 -29.5t-17 -52t-6.5 -77.5q0 -15 -3.5 -27.5t-7.5 -18.5l-4 -5q-18 -19 -53 -22h-115q-71 -4 -146 16.5t-131.5 53t-103 66t-70.5 57.5l-25 24q-10 10 -27.5 30t-71.5 91t-106 151t-122.5 211t-130.5 272q-6 16 -6 27t3 16l4 6 q15 19 57 19l274 2q12 -2 23 -6.5t16 -8.5l5 -3q16 -11 24 -32q20 -50 46 -103.5t41 -81.5l16 -29q29 -60 56 -104t48.5 -68.5t41.5 -38.5t34 -14t27 5q2 1 5 5t12 22t13.5 47t9.5 81t0 125q-2 40 -9 73t-14 46l-6 12q-25 34 -85 43q-13 2 5 24q17 19 38 30q53 26 239 24 q82 -1 135 -13q20 -5 33.5 -13.5t20.5 -24t10.5 -32t3.5 -45.5t-1 -55t-2.5 -70.5t-1.5 -82.5q0 -11 -1 -42t-0.5 -48t3.5 -40.5t11.5 -39t22.5 -24.5q8 -2 17 -4t26 11t38 34.5t52 67t68 107.5q60 104 107 225q4 10 10 17.5t11 10.5l4 3l5 2.5t13 3t20 0.5l288 2 q39 5 64 -2.5t31 -16.5z" />
392
- <glyph unicode="&#xf18a;" horiz-adv-x="1792" d="M675 252q21 34 11 69t-45 50q-34 14 -73 1t-60 -46q-22 -34 -13 -68.5t43 -50.5t74.5 -2.5t62.5 47.5zM769 373q8 13 3.5 26.5t-17.5 18.5q-14 5 -28.5 -0.5t-21.5 -18.5q-17 -31 13 -45q14 -5 29 0.5t22 18.5zM943 266q-45 -102 -158 -150t-224 -12 q-107 34 -147.5 126.5t6.5 187.5q47 93 151.5 139t210.5 19q111 -29 158.5 -119.5t2.5 -190.5zM1255 426q-9 96 -89 170t-208.5 109t-274.5 21q-223 -23 -369.5 -141.5t-132.5 -264.5q9 -96 89 -170t208.5 -109t274.5 -21q223 23 369.5 141.5t132.5 264.5zM1563 422 q0 -68 -37 -139.5t-109 -137t-168.5 -117.5t-226 -83t-270.5 -31t-275 33.5t-240.5 93t-171.5 151t-65 199.5q0 115 69.5 245t197.5 258q169 169 341.5 236t246.5 -7q65 -64 20 -209q-4 -14 -1 -20t10 -7t14.5 0.5t13.5 3.5l6 2q139 59 246 59t153 -61q45 -63 0 -178 q-2 -13 -4.5 -20t4.5 -12.5t12 -7.5t17 -6q57 -18 103 -47t80 -81.5t34 -116.5zM1489 1046q42 -47 54.5 -108.5t-6.5 -117.5q-8 -23 -29.5 -34t-44.5 -4q-23 8 -34 29.5t-4 44.5q20 63 -24 111t-107 35q-24 -5 -45 8t-25 37q-5 24 8 44.5t37 25.5q60 13 119 -5.5t101 -65.5z M1670 1209q87 -96 112.5 -222.5t-13.5 -241.5q-9 -27 -34 -40t-52 -4t-40 34t-5 52q28 82 10 172t-80 158q-62 69 -148 95.5t-173 8.5q-28 -6 -52 9.5t-30 43.5t9.5 51.5t43.5 29.5q123 26 244 -11.5t208 -134.5z" />
393
- <glyph unicode="&#xf18b;" horiz-adv-x="1920" d="M805 163q-122 -67 -261 -67q-141 0 -261 67q98 61 167 149t94 191q25 -103 94 -191t167 -149zM453 1176v-344q0 -179 -89.5 -326t-234.5 -217q-129 152 -129 351q0 200 129.5 352t323.5 184zM958 991q-128 -152 -128 -351q0 -201 128 -351q-145 70 -234.5 218t-89.5 328 v341q196 -33 324 -185zM1638 163q-122 -67 -261 -67q-141 0 -261 67q98 61 167 149t94 191q25 -103 94 -191t167 -149zM1286 1176v-344q0 -179 -91 -326t-237 -217v0q133 154 133 351q0 195 -133 351q129 151 328 185zM1920 640q0 -201 -129 -351q-145 70 -234.5 218 t-89.5 328v341q194 -32 323.5 -184t129.5 -352z" />
394
- <glyph unicode="&#xf18c;" horiz-adv-x="1792" />
395
- <glyph unicode="&#xf18d;" horiz-adv-x="1792" />
396
- <glyph unicode="&#xf18e;" horiz-adv-x="1792" />
397
- <glyph unicode="&#xf500;" horiz-adv-x="1792" />
398
- </font>
399
- </defs></svg>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/font/fontawesome-webfont.ttf DELETED
Binary file
assets/font/fontawesome-webfont.woff DELETED
Binary file
assets/images/icon-woo-downloadable.png DELETED
Binary file
assets/images/icon-woo-external.png DELETED
Binary file
assets/images/icon-woo-grouped.png DELETED
Binary file
assets/images/icon-woo-simple.png DELETED
Binary file
assets/images/icon-woo-variable.png DELETED
Binary file
assets/images/icon-woo-virtual.png DELETED
Binary file
assets/images/image_10.png DELETED
Binary file
assets/js/jquery.cleditor.min.js DELETED
@@ -1,8 +0,0 @@
1
- /*!
2
- CLEditor WYSIWYG HTML Editor v1.4.5
3
- http://premiumsoftware.net/CLEditor
4
- requires jQuery v1.4.2 or later
5
- Copyright 2010, Chris Landowski, Premium Software, LLC
6
- Dual licensed under the MIT or GPL Version 2 licenses.
7
- */
8
- !function(e){function t(t){var n=this,r=t.target,o=e.data(r,R),a=ot[o],i=a.popupName,s=rt[i],l={editor:n,button:r,buttonName:o,popup:s,popupName:i,command:a.command,useCSS:n.options.useCSS};if(a.buttonClick&&a.buttonClick(t,l)===!1)return!1;if("source"===o)T(n)?(delete n.range,n.$area.hide(),n.$frame.show(),r.title=a.title):(n.$frame.hide(),n.$area.show(),r.title="Show Rich Text");else if(!T(n)){if(i){var u=e(s);if("url"===i){if("link"===o&&""===w(n))return S(n,"A selection is required when inserting a link.",r),!1;u.children(":button").unbind(z).bind(z,function(){var t=u.find(":text"),r=e.trim(t.val());""!==r&&d(n,l.command,r,null,l.button),t.val("http://"),h(),c(n)})}else"pastetext"===i&&u.children(":button").unbind(z).bind(z,function(){var e=u.find("textarea"),t=e.val().replace(/\n/g,"<br />");""!==t&&d(n,l.command,t,null,l.button),e.val(""),h(),c(n)});if(r!==e.data(s,M))return k(n,s,r),!1;return}if("print"===o)n.$frame[0].contentWindow.print();else if(!d(n,l.command,l.value,l.useCSS,r))return!1}c(n)}function n(t){var n=e(t.target).closest("div");n.css(N,n.data(R)?"#FFF":"#FFC")}function r(t){e(t.target).closest("div").css(N,"transparent")}function o(t){var n=this,r=t.data.popup,o=t.target;if(r!==rt.msg&&!e(r).hasClass(Y)){var a,i=e.data(r,M),s=e.data(i,R),l=ot[s],u=l.command,p=n.options.useCSS;"font"===s?a=o.style.fontFamily.replace(/"/g,""):"size"===s?("DIV"===o.tagName.toUpperCase()&&(o=o.children[0]),a=o.innerHTML):"style"===s?a="<"+o.tagName+">":"color"===s?a=f(o.style.backgroundColor):"highlight"===s&&(a=f(o.style.backgroundColor),Z?u="backcolor":p=!0);var m={editor:n,button:i,buttonName:s,popup:r,popupName:l.popupName,command:u,value:a,useCSS:p};if(!l.popupClick||l.popupClick(t,m)!==!1){if(m.command&&!d(n,m.command,m.value,m.useCSS,i))return!1;h(),c(n)}}}function a(e){for(var t=1,n=0,r=0;r<e.length;++r)t=(t+e.charCodeAt(r))%65521,n=(n+t)%65521;return n<<16|t}function i(e){e.$area.val(""),x(e)}function s(t,o,a,i,s){if(rt[t])return rt[t];var l=e(E).hide().addClass(V).appendTo("body");if(i)l.html(i);else if("color"===t){var d=o.colors.split(" ");d.length<10&&l.width("auto"),e.each(d,function(t,n){e(E).appendTo(l).css(N,"#"+n)}),a=X}else"font"===t?e.each(o.fonts.split(","),function(t,n){e(E).appendTo(l).css("fontFamily",n).html(n)}):"size"===t?e.each(o.sizes.split(","),function(t,n){e(E).appendTo(l).html('<font size="'+n+'">'+n+"</font>")}):"style"===t?e.each(o.styles,function(t,n){e(E).appendTo(l).html(n[1]+n[0]+n[1].replace("<","</"))}):"url"===t?(l.html('<label>Enter URL:<br /><input type="text" value="http://" style="width:200px" /></label><br /><input type="button" value="Submit" />'),a=Y):"pastetext"===t&&(l.html('<label>Paste your content here:<br /><textarea rows="3" style="width:200px"></textarea></label><br /><input type="button" value="Submit" />'),a=Y);return a||i||(a=Q),l.addClass(a),Z&&l.attr(D,"on").find("div,font,p,h1,h2,h3,h4,h5,h6").attr(D,"on"),(l.hasClass(Q)||s===!0)&&l.children().hover(n,r),rt[t]=l[0],l[0]}function l(e,t){t?(e.$area.attr(I,I),e.disabled=!0):(e.$area.removeAttr(I),delete e.disabled);try{Z?e.doc.body.contentEditable=!t:e.doc.designMode=t?"off":"on"}catch(n){}v(e)}function d(e,t,n,r,o){C(e),Z||((void 0===r||null===r)&&(r=e.options.useCSS),e.doc.execCommand("styleWithCSS",0,r.toString()));var a="inserthtml"===t.toLowerCase();if(Z&&a)u(e).pasteHTML(n);else if(et&&a){var i=p(e),s=i.getRangeAt(0);s.deleteContents(),s.insertNode(s.createContextualFragment(n)),i.removeAllRanges(),i.addRange(s)}else{var l,d=!0;try{d=e.doc.execCommand(t,0,n||null)}catch(c){l=c.message,d=!1}d||("cutcopypaste".indexOf(t)>-1?S(e,"For security reasons, your browser does not support the "+t+" command. Try using the keyboard shortcut or context menu instead.",o):S(e,l?l:"Error executing the "+t+" command.",o))}return v(e),$(e,!0),d}function c(e){setTimeout(function(){T(e)?e.$area.focus():e.$frame[0].contentWindow.focus(),v(e)},0)}function u(e){return Z?p(e).createRange():p(e).getRangeAt(0)}function p(e){return Z?e.doc.selection:e.$frame[0].contentWindow.getSelection()}function f(e){var t=/rgba?\((\d+), (\d+), (\d+)/.exec(e);if(t){for(e=(t[1]<<16|t[2]<<8|t[3]).toString(16);e.length<6;)e="0"+e;return"#"+e}var n=e.split("");return 4===e.length?"#"+n[1]+n[1]+n[2]+n[2]+n[3]+n[3]:e}function h(){e.each(rt,function(t,n){e(n).hide().unbind(z).removeData(M)})}function m(){var t=e("link[href*=cleditor]").attr("href");return t.replace(/^(.*\/)[^\/]+$/,"$1")+"images/"}function g(e){return"url("+m()+e+")"}function b(t){var n=t.$main,r=t.options;t.$frame&&t.$frame.remove();var o=t.$frame=e('<iframe frameborder="0" src="javascript:true;" />').hide().appendTo(n),a=o[0].contentWindow,i=t.doc=a.document,s=e(i);i.open(),i.write(r.docType+"<html>"+(""===r.docCSSFile?"":'<head><link rel="stylesheet" type="text/css" href="'+r.docCSSFile+'" /></head>')+'<body style="'+r.bodyStyle+'"></body></html>'),i.close(),(Z||et)&&s.click(function(){c(t)}),x(t),Z||et?(s.bind("beforedeactivate beforeactivate selectionchange keypress keyup",function(e){if("beforedeactivate"===e.type)t.inactive=!0;else if("beforeactivate"===e.type)!t.inactive&&t.range&&t.range.length>1&&t.range.shift(),delete t.inactive;else if(!t.inactive)for(t.range||(t.range=[]),t.range.unshift(u(t));t.range.length>2;)t.range.pop()}),o.focus(function(){C(t),e(t).triggerHandler(j)}),o.blur(function(){e(t).triggerHandler(A)})):e(o[0].contentWindow).focus(function(){e(t).triggerHandler(j)}).blur(function(){e(t).triggerHandler(A)}),s.click(h).keydown(function(e){Z&&"Control"==p(t).type&&8==e.keyCode&&(p(t).clear(),e.preventDefault())}).bind("keyup mouseup",function(){v(t),$(t,!0)}),nt?t.$area.show():o.show(),e(function(){var e=t.$toolbar,a=e.children("div:last"),i=n.width(),s=a.offset().top+a.outerHeight()-e.offset().top+1;e.height(s),s=(/%/.test(""+r.height)?n.height():parseInt(r.height,10))-s,o.width(i).height(s),t.$area.width(i).height(_?s-2:s),l(t,t.disabled),v(t)})}function v(t){nt||!tt||t.focused||(t.$frame[0].contentWindow.focus(),window.focus(),t.focused=!0);var n=t.doc;Z&&(n=u(t));var r=T(t);e.each(t.$toolbar.find("."+O),function(o,a){var i=e(a),s=e.cleditor.buttons[e.data(a,R)],l=s.command,d=!0;if(t.disabled)d=!1;else if(s.getEnabled){var c={editor:t,button:a,buttonName:s.name,popup:rt[s.popupName],popupName:s.popupName,command:s.command,useCSS:t.options.useCSS};d=s.getEnabled(c),void 0===d&&(d=!0)}else if((r||nt)&&"source"!==s.name||Z&&("undo"===l||"redo"===l))d=!1;else if(l&&"print"!==l&&(Z&&"hilitecolor"===l&&(l="backcolor"),!Z&&!et||"inserthtml"!==l))try{d=n.queryCommandEnabled(l)}catch(u){d=!1}d?(i.removeClass(q),i.removeAttr(I)):(i.addClass(q),i.attr(I,I))})}function C(e){e.range&&(Z?e.range[0].select():et&&p(e).addRange(e.range[0]))}function y(e){setTimeout(function(){T(e)?e.$area.select():d(e,"selectall")},0)}function F(t){C(t);var n=u(t);if(Z)return n.htmlText;var r=e("<layer>")[0];r.appendChild(n.cloneContents());var o=r.innerHTML;return r=null,o}function w(e){return C(e),Z?u(e).text:p(e).toString()}function S(e,t,n){var r=s("msg",e.options,J);r.innerHTML=t,k(e,r,n)}function k(t,n,r){var a,i,s,l=e(n);if(r){var d=e(r);a=d.offset(),i=--a.left,s=a.top+d.height()}else{var c=t.$toolbar;a=c.offset(),i=Math.floor((c.width()-l.width())/2)+a.left,s=a.top+c.height()-2}h(),l.css({left:i,top:s}).show(),r&&(e.data(n,M,r),l.bind(z,{popup:n},e.proxy(o,t))),setTimeout(function(){l.find(":text,textarea").eq(0).focus().select()},100)}function T(e){return e.$area.is(":visible")}function x(t,n){var r=t.$area.val(),o=t.options,i=o.updateFrame,s=e(t.doc.body);if(i){var l=a(r);if(n&&t.areaChecksum===l)return;t.areaChecksum=l}var d=i?i(r):r;d=d.replace(/<(?=\/?script)/gi,"&lt;"),o.updateTextArea&&(t.frameChecksum=a(d)),d!==s.html()&&(s.html(d),e(t).triggerHandler(L))}function $(t,n){var r=e(t.doc.body).html(),o=t.options,i=o.updateTextArea,s=t.$area;if(i){var l=a(r);if(n&&t.frameChecksum===l)return;t.frameChecksum=l}var d=i?i(r):r;o.updateFrame&&(t.areaChecksum=a(d)),d!==s.val()&&(s.val(d),e(t).triggerHandler(L))}e.cleditor={defaultOptions:{width:"auto",height:250,controls:"bold italic underline strikethrough subscript superscript | font size style | color highlight removeformat | bullets numbering | outdent indent | alignleft center alignright justify | undo redo | rule image link unlink | cut copy paste pastetext | print source",colors:"FFF FCC FC9 FF9 FFC 9F9 9FF CFF CCF FCF CCC F66 F96 FF6 FF3 6F9 3FF 6FF 99F F9F BBB F00 F90 FC6 FF0 3F3 6CC 3CF 66C C6C 999 C00 F60 FC3 FC0 3C0 0CC 36F 63F C3C 666 900 C60 C93 990 090 399 33F 60C 939 333 600 930 963 660 060 366 009 339 636 000 300 630 633 330 030 033 006 309 303",fonts:"Arial,Arial Black,Comic Sans MS,Courier New,Narrow,Garamond,Georgia,Impact,Sans Serif,Serif,Tahoma,Trebuchet MS,Verdana",sizes:"1,2,3,4,5,6,7",styles:[["Paragraph","<p>"],["Header 1","<h1>"],["Header 2","<h2>"],["Header 3","<h3>"],["Header 4","<h4>"],["Header 5","<h5>"],["Header 6","<h6>"]],useCSS:!0,docType:'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',docCSSFile:"",bodyStyle:"margin:4px; font:10pt Arial,Verdana; cursor:text"},buttons:{init:"bold,,|italic,,|underline,,|strikethrough,,|subscript,,|superscript,,|font,,fontname,|size,Font Size,fontsize,|style,,formatblock,|color,Font Color,forecolor,|highlight,Text Highlight Color,hilitecolor,color|removeformat,Remove Formatting,|bullets,,insertunorderedlist|numbering,,insertorderedlist|outdent,,|indent,,|alignleft,Align Text Left,justifyleft|center,,justifycenter|alignright,Align Text Right,justifyright|justify,,justifyfull|undo,,|redo,,|rule,Insert Horizontal Rule,inserthorizontalrule|image,Insert Image,insertimage,url|link,Insert Hyperlink,createlink,url|unlink,Remove Hyperlink,|cut,,|copy,,|paste,,|pastetext,Paste as Text,inserthtml,|print,,|source,Show Source"},imagesPath:function(){return m()}},e.fn.cleditor=function(t){var n=e([]);return this.each(function(r,o){if("TEXTAREA"===o.tagName.toUpperCase()){var a=e.data(o,P);a||(a=new cleditor(o,t)),n=n.add(a)}}),n};var H,N="backgroundColor",A="blurred",M="button",R="buttonName",L="change",P="cleditor",z="click",I="disabled",E="<div>",j="focused",D="unselectable",W="cleditorMain",B="cleditorToolbar",U="cleditorGroup",O="cleditorButton",q="cleditorDisabled",G="cleditorDivider",V="cleditorPopup",Q="cleditorList",X="cleditorColor",Y="cleditorPrompt",J="cleditorMsg",K=navigator.userAgent.toLowerCase(),Z=/msie/.test(K),_=/msie\s6/.test(K),et=/(trident)(?:.*rv:([\w.]+))?/.test(K),tt=/webkit/.test(K),nt=/iPhone|iPad|iPod/i.test(K),rt={},ot=e.cleditor.buttons;e.each(ot.init.split("|"),function(e,t){var n=t.split(","),r=n[0];ot[r]={stripIndex:e,name:r,title:""===n[1]?r.charAt(0).toUpperCase()+r.substr(1):n[1],command:""===n[2]?r:n[2],popupName:""===n[3]?r:n[3]}}),delete ot.init,cleditor=function(o,a){var i=this;i.options=a=e.extend({},e.cleditor.defaultOptions,a);var l=i.$area=e(o).css({border:"none",margin:0,padding:0}).hide().data(P,i).blur(function(){x(i,!0)}),d=i.$main=e(E).addClass(W).width(a.width).height(a.height),c=i.$toolbar=e(E).addClass(B).appendTo(d),u=e(E).addClass(U).appendTo(c),p=0;e.each(a.controls.split(" "),function(o,l){if(""===l)return!0;if("|"===l){{e(E).addClass(G).appendTo(u)}u.width(p+1),p=0,u=e(E).addClass(U).appendTo(c)}else{var d=ot[l],f=e(E).data(R,d.name).addClass(O).attr("title",d.title).bind(z,e.proxy(t,i)).appendTo(u).hover(n,r);p+=24,u.width(p+1);var h={};d.css?h=d.css:d.image&&(h.backgroundImage=g(d.image)),d.stripIndex&&(h.backgroundPosition=-24*d.stripIndex),f.css(h),Z&&f.attr(D,"on"),d.popupName&&s(d.popupName,a,d.popupClass,d.popupContent,d.popupHover)}}),d.insertBefore(l).append(l),H||(e(document).click(function(t){var n=e(t.target);n.add(n.parents()).is("."+Y)||h()}),H=!0),/auto|%/.test(""+a.width+a.height)&&e(window).bind("resize.cleditor",function(){b(i)}),b(i)};var at=cleditor.prototype,it=[["clear",i],["disable",l],["execCommand",d],["focus",c],["hidePopups",h],["sourceMode",T,!0],["refresh",b],["select",y],["selectedHTML",F,!0],["selectedText",w,!0],["showMessage",S],["updateFrame",x],["updateTextArea",$]];e.each(it,function(e,t){at[t[0]]=function(){for(var e=this,n=[e],r=0;r<arguments.length;r++)n.push(arguments[r]);var o=t[1].apply(e,n);return t[2]?o:e}}),at.blurred=function(t){var n=e(this);return t?n.bind(A,t):n.trigger(A)},at.change=function(t){var n=e(this);return t?n.bind(L,t):n.trigger(L)},at.focused=function(t){var n=e(this);return t?n.bind(j,t):n.trigger(j)}}(jQuery);
 
 
 
 
 
 
 
 
assets/js/scripts.js DELETED
@@ -1,1466 +0,0 @@
1
- jQuery(document).ready(function($){
2
-
3
- var discard = false;
4
-
5
- window.onbeforeunload = function(e) {
6
- if(discard){
7
- return $('#wcml_warn_message').val();
8
- }
9
- }
10
-
11
- $('.wcml-section input[type="submit"]').click(function(){
12
- discard = false;
13
- });
14
-
15
- $('.wcml-section input[type="radio"],#wcml_products_sync_date,#wcml_products_sync_order,#display_custom_prices').click(function(){
16
- discard = true;
17
- $(this).closest('.wcml-section').find('.button-wrap input').css("border-color","#1e8cbe");
18
- });
19
-
20
- $('#wcmp_hide').click(function(){
21
- $('.wcml_miss_lang').slideUp('3000',function(){$('#wcmp_show').show();});
22
- });
23
-
24
- $('#wcmp_show').click(function(){
25
- $('#wcmp_show').hide();
26
- $('.wcml_miss_lang').slideDown('3000');
27
- });
28
-
29
- $('.wcml_check_all').click(function(){
30
- if($(this).is(":checked")){
31
- $("table.wcml_products input[type='checkbox']").each(function(){
32
- $(this).attr("checked","checked");
33
- });
34
- }else{
35
- $("table.wcml_products input[type='checkbox']").each(function(){
36
- $(this).removeAttr("checked");
37
- });
38
- }
39
- });
40
-
41
- $('.wcml_search').click(function(){
42
- window.location = $('.wcml_products_admin_url').val()+'&s='+$('.wcml_product_name').val()+'&cat='+$('.wcml_product_category').val()+'&trst='+$('.wcml_translation_status').val()+'&st='+$('.wcml_product_status').val()+'&slang='+$('.wcml_translation_status_lang').val();
43
- });
44
-
45
- $('.wcml_reset_search').click(function(){
46
- window.location = $('.wcml_products_admin_url').val();
47
- });
48
-
49
- $('.wcml_pagin').keypress(function(e) {
50
- if(e.which == 13) {
51
- window.location = $('.wcml_pagination_url').val()+$(this).val();
52
- return false;
53
- }
54
- });
55
-
56
- $('.wcml_details').click(function(e){
57
- e.preventDefault();
58
- var element = $(this),
59
- textClosed = element.data('text-closed'),
60
- textOpened = element.data('text-opened'),
61
- $table = $(element.attr('href')),
62
- parent = element.closest('tr');
63
-
64
- if ( $table.is(':visible') ){
65
- $table.find('input').each(function(){
66
- element.val(element.data('def'));
67
- });
68
- $table.closest('.outer').hide();
69
- element.text(textClosed);
70
- }else {
71
- if($table.size() > 0){
72
- //set def data
73
- $table.find('input').each(function(){
74
- element.data('def',element.val());
75
- });
76
- $table.closest('.outer').show();
77
- element.text(textOpened);
78
- }else{
79
- //load product data
80
- var id = $(this).attr('href').replace(/#prid_/, '');
81
- var job_id = $(this).attr('job_id');
82
- element.parent().find('.spinner').show();
83
- $.ajax({
84
- type : "post",
85
- url : ajaxurl,
86
- dataType: 'json',
87
- data : {
88
- action: "wcml_product_data",
89
- product_id : id,
90
- job_id : job_id,
91
- wcml_nonce: $('#get_product_data_nonce').val()
92
- },
93
- success: function(response) {
94
- if(typeof response.error !== "undefined"){
95
- alert(response.error);
96
- }else{
97
- //update status block
98
- $(response.html).insertAfter(parent).css('display','table-row');
99
-
100
- //set def data
101
- $table.find('input').each(function(){
102
- element.data('def',element.val());
103
- });
104
- element.text(textOpened);
105
- element.parent().find('.spinner').hide();
106
- wpLink.init();
107
- }
108
- }
109
- });
110
- }
111
-
112
- }
113
- return false;
114
- });
115
-
116
- $(document).on('click', 'button[name="cancel"]', function(){
117
- var $outer = $(this).closest('.outer');
118
-
119
- $outer.find('input').each(function(){
120
- $(this).val($(this).data('def'));
121
- });
122
-
123
- var prid = $outer.data('prid');
124
- $outer.hide('fast', function(){
125
- var $closeButton = $('#wcml_details_' + prid);
126
- $closeButton.text( $closeButton.data('text-closed') );
127
- });
128
-
129
- $(this).parent().find('input').each(function(){
130
- $(this).val($(this).data('def'));
131
- });
132
- $(this).closest('.outer').slideUp('3000');
133
-
134
- });
135
-
136
- $(document).on('click','.wcml_update', function() {
137
- var field = $(this);
138
-
139
- var spl = $(this).attr('name').split('#');
140
-
141
- var product_id = spl[1];
142
- var language = spl[2];
143
-
144
- var records = '';
145
- field.closest('tr').find("input").each(function(){
146
- records += $(this).serialize()+"&";
147
- });
148
- field.closest('tr').find("textarea").each(function(){
149
- records += $(this).serialize()+"&";
150
- });
151
- field.hide();
152
- field.parent().find('.wcml_spinner').css('display','inline-block');
153
-
154
- $.ajax({
155
- type : "post",
156
- url : ajaxurl,
157
- dataType: 'json',
158
- data : {
159
- action: "wcml_update_product",
160
- product_id : product_id,
161
- language : language,
162
- job_id : field.closest('tr').find('input[name="job_id"]').val(),
163
- records : records,
164
- slang : $('.wcml_translation_status_lang').val(),
165
- wcml_nonce: $('#upd_product_nonce').val()
166
- },
167
- success: function(response) {
168
- if(typeof response.error !== "undefined"){
169
- alert(response.error);
170
- }else{
171
- //update status block
172
- $('.translations_statuses.prid_'+product_id).html(response.status);
173
-
174
- //update slug
175
- if( field.closest('.outer').find('.edit_slug_warning').size() >0 ){
176
- field.closest('.outer').find('input[name="post_name_'+language+'"]').removeAttr('disabled').removeClass('hidden');
177
- field.closest('.outer').find('.edit_slug_show_link').removeClass('hidden');
178
- field.closest('.outer').find('.edit_slug_hide_link').removeClass('hidden');
179
- field.closest('.outer').find('.edit_slug_warning').remove();
180
- }
181
- field.closest('.outer').find('input[name="post_name_'+language+'"]').val(response.slug);
182
-
183
- //update images block
184
- if(language in response.images){
185
- var value = response.images[language];
186
- field.closest('.outer').find('tr[rel="'+language+'"] .prod_images').closest('td').html(value).find('.prod_images').css('display','none');
187
- }
188
-
189
- //update variations block
190
-
191
- if(typeof response.variations !== "undefined" && (language in response.variations)){
192
- var value = response.variations[language];
193
- field.closest('.outer').find('tr[rel="'+language+'"] .prod_variations').closest('td').html(value).find('.prod_variations').css('display','none');
194
- }
195
-
196
- //set def data
197
- field.closest('.outer').find('input').each(function(){
198
- $(this).data('def',$(this).val());
199
- });
200
-
201
-
202
-
203
- field.val($('#wcml_product_update_button_label').html());
204
-
205
- }
206
- field.parent().find('.wcml_spinner').hide();
207
- field.prop('disabled', true).removeClass('button-primary').addClass('button-secondary');
208
- field.show();
209
-
210
- $('#prid_' + product_id + ' .js-wcml_duplicate_product_undo_' + language).fadeOut();
211
-
212
- }
213
- });
214
-
215
- return false;
216
- });
217
-
218
- if(typeof WPML_Translate_taxonomy != 'undefined' && typeof WPML_Translate_taxonomy.callbacks != 'undefined'){
219
-
220
- WPML_Translate_taxonomy.callbacks.add(function(func, taxonomy){
221
-
222
- if($('.js-tax-tab-' + taxonomy + ' i.icon-warning-sign').length){
223
-
224
- $.ajax({
225
- type : "post",
226
- url : ajaxurl,
227
- dataType: 'json',
228
- data : {
229
- action: "wcml_update_term_translated_warnings",
230
- taxonomy: taxonomy,
231
- wcml_nonce: $('#wcml_update_term_translated_warnings_nonce').val()
232
- },
233
- success: function(response) {
234
- if(response.hide){
235
- $('.js-tax-tab-' + taxonomy).removeAttr('title');
236
- $('.js-tax-tab-' + taxonomy + ' i.icon-warning-sign').remove();
237
- }
238
- }
239
- })
240
-
241
- }
242
-
243
- return false;
244
-
245
- });
246
- }
247
-
248
- $(document).on('click', '.wcml_duplicate_product_notice a[href^="#edit-"]', function(){
249
-
250
- var spl = $(this).attr('href').replace(/#edit-/, '').split('_');
251
- var pid = spl[0];
252
- var lng = spl[1];
253
-
254
- $('#prid_' + pid + ' tr[rel=' + lng + '] .js-dup-disabled').removeAttr('disabled');
255
- $('#prid_' + pid + ' tr[rel=' + lng + '] input[name^=end_duplication]').val(1);
256
- $('#prid_' + pid + ' .js-wcml_duplicate_product_notice_'+lng).hide();
257
- $('#prid_' + pid + ' .js-wcml_duplicate_product_undo_'+lng).show();
258
-
259
- return false;
260
-
261
- });
262
-
263
- $(document).on('click', '.wcml_duplicate_product_notice a[href^="#undo-"]', function(){
264
-
265
- var spl = $(this).attr('href').replace(/#undo-/, '').split('_');
266
- var pid = spl[0];
267
- var lng = spl[1];
268
-
269
- $('#prid_' + pid + ' tr[rel=' + lng + '] .js-dup-disabled').attr('disabled', 'disabled');
270
- $('#prid_' + pid + ' tr[rel=' + lng + '] input[name^="end_duplication"]').val(0);
271
- $('#prid_' + pid + ' .js-wcml_duplicate_product_undo_'+lng).hide();
272
- $('#prid_' + pid + ' .js-wcml_duplicate_product_notice_'+lng).show();
273
-
274
- return false;
275
-
276
- });
277
-
278
- $(document).on('click', '.js-tax-translation li a[href^="#ignore-"]', function(){
279
-
280
- var taxonomy = $(this).attr('href').replace(/#ignore-/, '');
281
-
282
- $.ajax({
283
- type : "post",
284
- url : ajaxurl,
285
- dataType: 'json',
286
- data : {
287
- action: "wcml_ingore_taxonomy_translation",
288
- taxonomy: taxonomy,
289
- wcml_nonce: $('#wcml_ingore_taxonomy_translation_nonce').val()
290
- },
291
- success: function(response) {
292
-
293
- if(response.html){
294
-
295
- $('.js-tax-translation li.js-tax-translation-' + taxonomy).html(response.html);
296
-
297
- $('.js-tax-tab-' + taxonomy).removeAttr('title');
298
- $('.js-tax-tab-' + taxonomy + ' i.icon-warning-sign').remove();
299
-
300
-
301
- }
302
-
303
- }
304
- })
305
-
306
- return false;
307
- })
308
-
309
- $(document).on('click', '.js-tax-translation li a[href^="#unignore-"]', function(){
310
-
311
- var taxonomy = $(this).attr('href').replace(/#unignore-/, '');
312
-
313
- $.ajax({
314
- type : "post",
315
- url : ajaxurl,
316
- dataType: 'json',
317
- data : {
318
- action: "wcml_uningore_taxonomy_translation",
319
- taxonomy: taxonomy,
320
- wcml_nonce: $('#wcml_ingore_taxonomy_translation_nonce').val()
321
- },
322
- success: function(response) {
323
- if(response.html){
324
- $('.js-tax-translation li.js-tax-translation-' + taxonomy).html(response.html);
325
- if(response.warn){
326
- $('.js-tax-tab-' + taxonomy).append('&nbsp;<i class="icon-warning-sign"></i>');
327
- }
328
-
329
- }
330
- }
331
- })
332
-
333
- return false;
334
- })
335
-
336
-
337
- $(document).on('submit', '#wcml_tt_sync_variations', function(){
338
-
339
- var this_form = $('#wcml_tt_sync_variations');
340
- var data = this_form.serialize();
341
- this_form.find('.wpml_tt_spinner').fadeIn();
342
- this_form.find('input[type=submit]').attr('disabled', 'disabled');
343
-
344
- $.ajax({
345
- type : "post",
346
- url : ajaxurl,
347
- dataType: 'json',
348
- data : data,
349
- success: function(response) {
350
- this_form.find('.wcml_tt_sycn_preview').html(response.progress);
351
- if(response.go){
352
- this_form.find('input[name=last_post_id]').val(response.last_post_id);
353
- this_form.find('input[name=languages_processed]').val(response.languages_processed);
354
- this_form.trigger('submit');
355
- }else{
356
- this_form.find('input[name=last_post_id]').val(0);
357
- this_form.find('.wpml_tt_spinner').fadeOut();
358
- this_form.find('input').removeAttr('disabled');
359
- }
360
-
361
- }
362
- });
363
-
364
- return false;
365
-
366
-
367
- });
368
-
369
-
370
- $(document).on('submit', '#wcml_tt_sync_assignment', function(){
371
-
372
- var this_form = $('#wcml_tt_sync_assignment');;
373
- var parameters = this_form.serialize();
374
-
375
- this_form.find('.wpml_tt_spinner').fadeIn();
376
- this_form.find('input').attr('disabled', 'disabled');
377
-
378
- $('.wcml_tt_sync_row').remove();
379
-
380
- $.ajax({
381
- type: "POST",
382
- dataType: 'json',
383
- url: ajaxurl,
384
- data: 'action=wcml_tt_sync_taxonomies_in_content_preview&wcml_nonce='+$('#wcml_sync_taxonomies_in_content_preview_nonce').val()+'&' + parameters,
385
- success:
386
- function(ret){
387
-
388
- this_form.find('.wpml_tt_spinner').fadeOut();
389
- this_form.find('input').removeAttr('disabled');
390
-
391
- if(ret.errors){
392
- this_form.find('.errors').html(ret.errors);
393
- }else{
394
- jQuery('#wcml_tt_sync_preview').html(ret.html);
395
- }
396
-
397
- }
398
-
399
- });
400
-
401
- return false;
402
-
403
-
404
- });
405
-
406
- $(document).on('click', 'form.wcml_tt_do_sync a.submit', function(){
407
-
408
- var this_form = $('form.wcml_tt_do_sync');
409
- var parameters = this_form.serialize();
410
-
411
- this_form.find('.wpml_tt_spinner').fadeIn();
412
- this_form.find('input').attr('disabled', 'disabled');
413
-
414
- jQuery.ajax({
415
- type: "POST",
416
- dataType: 'json',
417
- url: ajaxurl,
418
- data: 'action=wcml_tt_sync_taxonomies_in_content&wcml_nonce='+$('#wcml_sync_taxonomies_in_content_nonce').val()+'&' + parameters,
419
- success:
420
- function(ret){
421
-
422
- this_form.find('.wpml_tt_spinner').fadeOut();
423
- this_form.find('input').removeAttr('disabled');
424
-
425
- if(ret.errors){
426
- this_form.find('.errors').html(ret.errors);
427
- }else{
428
- this_form.closest('.wcml_tt_sync_row').html(ret.html);
429
- }
430
-
431
- }
432
-
433
- });
434
-
435
- return false;
436
-
437
-
438
- });
439
-
440
- var wcml_product_rows_data = new Array();
441
- var wcml_get_product_fields_string = function(row){
442
- var string = '';
443
- row.find('input[type=text], textarea').each(function(){
444
- string += $(this).val();
445
- });
446
-
447
- return string;
448
- }
449
-
450
- $(document).on('focus','.wcml_products_translation input[type=text], .wcml_products_translation textarea',function(){
451
-
452
- var row_lang = $(this).closest('tr[rel]').attr('rel');
453
- var prod_id = $(this).closest('div.wcml_product_row').attr('id');
454
-
455
- wcml_product_rows_data[prod_id + '_' + row_lang] = wcml_get_product_fields_string($(this).closest('tr'));
456
-
457
- });
458
-
459
- $(document).on('input keyup change paste mouseup','.wcml_products_translation input[type=text], .wcml_products_translation textarea',function(){
460
-
461
- if($(this).attr('disabled')) return;
462
-
463
- var row_lang = $(this).closest('tr[rel]').attr('rel');
464
- var prod_id = $(this).closest('div.wcml_product_row').attr('id');
465
-
466
- if($(this).closest('tr[rel]').find('.wcml_update').prop('disabled')){
467
-
468
- if(wcml_product_rows_data[prod_id + '_' + row_lang] != wcml_get_product_fields_string($(this).closest('tr'))){
469
- $(this).closest('tr[rel]').find('.wcml_update').prop('disabled',false).removeClass('button-secondary').addClass('button-primary');;
470
- }
471
-
472
- }
473
-
474
- })
475
-
476
- $(document).on('click','.wcml_edit_content',function(){
477
- $(".wcml_fade").show();
478
- $(this).parent().find('.wcml_editor').show();
479
-
480
- var txt_height = '90%';
481
- $(this).parent().find('.wcml_original_content').cleditor({
482
- height: txt_height,
483
- controls: // controls to add to the toolbar
484
- " | source "
485
- });
486
- $(this).parent().find('.wcml_original_content').cleditor()[0].disable(true);
487
-
488
- if( !$(this).hasClass('origin_content') ){
489
- $(this).parent().find('textarea.wcml_content_tr').data('def',$(this).parent().find('textarea.wcml_content_tr').val());
490
- $(this).parent().find('.wcml_editor table.mceLayout').css('height','auto');
491
- $(this).parent().find('.wcml_editor table.mceLayout iframe').css('min-height','150px');
492
- var id = $(this).parent().find('.switch-tmce').attr('id').replace(/-tmce/, '');
493
- $(this).parent().find('.wp-editor-wrap').removeClass('html-active').addClass('tmce-active');
494
-
495
- if( window.parent.tinyMCE.get(id) == null ){
496
- tinymce.execCommand( 'mceAddEditor', false, id);
497
- }
498
-
499
- $(this).parent().find('.wp-editor-wrap').find('.mce-tinymce').show();
500
- $(this).parent().find('textarea.wcml_content_tr').hide();
501
- }
502
-
503
- });
504
-
505
- $(document).on('click','.cleditorButton',function(){
506
- if($(this).closest('.cleditorMain').find('textarea').is(':visible')){
507
- $(this).closest('.cleditorMain').find('textarea').hide();
508
- $(this).closest('.cleditorMain').find('iframe').show();
509
- }else{
510
- $(this).closest('.cleditorMain').find('textarea').show();
511
- $(this).closest('.cleditorMain').find('iframe').hide();
512
- }
513
- });
514
-
515
- $(document).on('click','.wcml_close_cross,.wcml_popup_cancel',function(){
516
- $(".wcml_fade").hide();
517
- if(tinyMCE.activeEditor != null){
518
- if($(this).closest('.wcml_editor').find('.wcml_editor_translation textarea').size() >0){
519
- tinyMCE.activeEditor.setContent($(this).closest('.wcml_editor').find('.wcml_editor_translation textarea').data('def'));
520
- }
521
- }
522
- $(this).closest('.wcml_editor').css('display','none');
523
- $(this).closest('.wcml_editor').find('.wcml_editor_translation textarea').val($(this).closest('.wcml_editor').find('.wcml_editor_translation textarea').data('def'));
524
- });
525
-
526
- $(document).on('click','.switch-tmce',function(){
527
- var id = $(this).attr('id').replace(/-tmce/, '');
528
- $(this).closest('.wp-editor-wrap').removeClass('html-active').addClass('tmce-active');
529
- $(this).closest('.wp-editor-wrap').find('textarea.wcml_content_tr').hide();
530
- if( window.parent.tinyMCE.get(id) == null ){
531
- tinymce.execCommand( 'mceAddEditor', false, id);
532
- }else{
533
- $(this).closest('.wp-editor-wrap').find('.mce-tinymce').show();
534
- }
535
-
536
- window.parent.tinyMCE.get(id).setContent( $(this).closest('.wp-editor-wrap').find('textarea.wcml_content_tr').val() );
537
-
538
- });
539
-
540
- $(document).on('click','.switch-html',function(){
541
- var id = $(this).attr('id').replace(/-html/, '');
542
- $(this).closest('.wp-editor-wrap').removeClass('tmce-active').addClass('html-active');
543
- $('#qt_'+id+'_toolbar').remove();
544
- QTags(id);
545
- QTags._buttonsInit();
546
- $(this).closest('.wp-editor-wrap').find('.mce-tinymce').hide();
547
-
548
- if( window.parent.tinyMCE.get(id) != null ){
549
- $(this).closest('.wp-editor-wrap').find('textarea.wcml_content_tr').val( window.parent.tinyMCE.get(id).getContent() );
550
- }
551
-
552
- $(this).closest('.wp-editor-wrap').find('textarea.wcml_content_tr').show();
553
- });
554
-
555
- $(document).on('click','.wcml_popup_close',function(){
556
- $(".wcml_fade").hide();
557
- $(this).closest('.wcml_editor').css('display','none');
558
- });
559
-
560
-
561
- $(document).on('click','.wcml_popup_ok',function(){
562
- var text_area = $(this).closest('.wcml_editor').find('.wcml_editor_translation textarea');
563
- $(".wcml_fade").hide();
564
-
565
- if(text_area.size()>0 && !text_area.is(':visible')){
566
- text_area.val(window.parent.tinyMCE.get(text_area.attr('id')).getContent());
567
- }
568
- $(this).closest('.wcml_editor').css('display','none');
569
- window.parent.tinyMCE.get(text_area.attr('id')).setContent( text_area.val() );
570
-
571
- var row_lang = $(this).closest('tr[rel]').attr('rel');
572
- var prod_id = $(this).closest('div.wcml_product_row').attr('id');
573
-
574
- if(text_area.val() != ''){
575
- $(this).closest('tr').find('.wcml_field_translation_' + text_area.attr('name')).hide();
576
- }else{
577
- if($(this).closest('tr').find('.wcml_field_translation_' + text_area.attr('name')).length){
578
- $(this).closest('tr').find('.wcml_field_translation_' + text_area.attr('name')).show();
579
- }
580
- }
581
-
582
- if(wcml_product_rows_data[prod_id + '_' + row_lang] != wcml_get_product_fields_string($(this).closest('tr'))){
583
- $(this).closest('tr[rel]').find('.wcml_update').prop('disabled',false);
584
- }
585
-
586
- });
587
-
588
- $(document).on('click','.edit_slug_show_link,.edit_slug_hide_link',function(){
589
- if($(this).closest('div').find('.edit_slug_input').is(':visible')){
590
- $(this).closest('div').find('.edit_slug_input').hide();
591
- $(this).closest('div').find('.edit_slug_hide_link').hide();
592
- $(this).closest('div').find('.edit_slug_show_link').show();
593
- }else{
594
- $(this).closest('div').find('.edit_slug_input').show();
595
- $(this).closest('div').find('.edit_slug_hide_link').show();
596
- $(this).closest('div').find('.edit_slug_show_link').hide();
597
- }
598
- });
599
-
600
-
601
- //wc 2.0.*
602
- if($('.wcml_file_paths').size()>0){
603
- // Uploading files
604
- var downloadable_file_frame;
605
- var file_path_field;
606
- var file_paths;
607
-
608
- $(document).on( 'click', '.wcml_file_paths', function( event ){
609
-
610
- var $el = $(this);
611
-
612
- file_path_field = $el.parent().find('textarea');
613
- file_paths = file_path_field.val();
614
-
615
- event.preventDefault();
616
-
617
- // If the media frame already exists, reopen it.
618
- if ( downloadable_file_frame ) {
619
- downloadable_file_frame.open();
620
- return;
621
- }
622
-
623
- var downloadable_file_states = [
624
- // Main states.
625
- new wp.media.controller.Library({
626
- library: wp.media.query(),
627
- multiple: true,
628
- title: $el.data('choose'),
629
- priority: 20,
630
- filterable: 'uploaded'
631
- })
632
- ];
633
-
634
- // Create the media frame.
635
- downloadable_file_frame = wp.media.frames.downloadable_file = wp.media({
636
- // Set the title of the modal.
637
- title: $el.data('choose'),
638
- library: {
639
- type: ''
640
- },
641
- button: {
642
- text: $el.data('update')
643
- },
644
- multiple: true,
645
- states: downloadable_file_states
646
- });
647
-
648
- // When an image is selected, run a callback.
649
- downloadable_file_frame.on( 'select', function() {
650
-
651
- var selection = downloadable_file_frame.state().get('selection');
652
-
653
- selection.map( function( attachment ) {
654
-
655
- attachment = attachment.toJSON();
656
-
657
- if ( attachment.url )
658
- file_paths = file_paths ? file_paths + "\n" + attachment.url : attachment.url
659
-
660
- } );
661
-
662
- file_path_field.val( file_paths );
663
- });
664
-
665
- // Set post to 0 and set our custom type
666
- downloadable_file_frame.on( 'ready', function() {
667
- downloadable_file_frame.uploader.options.uploader.params = {
668
- type: 'downloadable_product'
669
- };
670
- });
671
-
672
- downloadable_file_frame.on( 'close', function() {
673
- // TODO: /wp-admin should be a variable. Some plugions, like WP Better Security changes the name of this dir.
674
- $.removeCookie('_icl_current_language', { path: '/wp-admin' });
675
- });
676
-
677
- // Finally, open the modal.
678
- downloadable_file_frame.open();
679
- });
680
- }
681
-
682
- //wc 2.1.*
683
- if($('.wcml_file_paths_button').size()>0){
684
- // Uploading files
685
- var downloadable_file_frame;
686
- var file_path_field;
687
- var file_paths;
688
-
689
- $(document).on( 'click', '.wcml_file_paths_button', function( event ){
690
-
691
- var $el = $(this);
692
-
693
- file_path_field = $el.parent().find('.wcml_file_paths_file');
694
- file_paths = file_path_field.val();
695
-
696
- event.preventDefault();
697
-
698
- // If the media frame already exists, reopen it.
699
- if ( downloadable_file_frame ) {
700
- downloadable_file_frame.open();
701
- return;
702
- }
703
-
704
- var downloadable_file_states = [
705
- // Main states.
706
- new wp.media.controller.Library({
707
- library: wp.media.query(),
708
- multiple: true,
709
- title: $el.data('choose'),
710
- priority: 20,
711
- filterable: 'uploaded'
712
- })
713
- ];
714
-
715
- // Create the media frame.
716
- downloadable_file_frame = wp.media.frames.downloadable_file = wp.media({
717
- // Set the title of the modal.
718
- title: $el.data('choose'),
719
- library: {
720
- type: ''
721
- },
722
- button: {
723
- text: $el.data('update')
724
- },
725
- multiple: true,
726
- states: downloadable_file_states
727
- });
728
-
729
- // When an image is selected, run a callback.
730
- downloadable_file_frame.on( 'select', function() {
731
-
732
- var selection = downloadable_file_frame.state().get('selection');
733
-
734
- selection.map( function( attachment ) {
735
-
736
- attachment = attachment.toJSON();
737
-
738
- if ( attachment.url )
739
- file_paths = attachment.url
740
-
741
- } );
742
-
743
- file_path_field.val( file_paths );
744
- });
745
-
746
- // Set post to 0 and set our custom type
747
- downloadable_file_frame.on( 'ready', function() {
748
- downloadable_file_frame.uploader.options.uploader.params = {
749
- type: 'downloadable_product'
750
- };
751
- });
752
-
753
- downloadable_file_frame.on( 'close', function() {
754
- // TODO: /wp-admin should be a variable. Some plugions, like WP Better Security changes the name of this dir.
755
- $.removeCookie('_icl_current_language', { path: '/wp-admin' });
756
- });
757
-
758
- // Finally, open the modal.
759
- downloadable_file_frame.open();
760
- });
761
- }
762
-
763
- if($(".wcml_editor_original").size() > 0 ){
764
- $(".wcml_editor_original").resizable({
765
- handles: 'n, s',
766
- resize: function( event, ui ) {
767
- $(this).find('.cleditorMain').css('height',$(this).height() - 60)
768
- },
769
- start: function(event, ui) {
770
- $('<div class="ui-resizable-iframeFix" style="background: #FFF;"></div>')
771
- .css({
772
- width:'100%', height: '100%',
773
- position: "absolute", opacity: "0.001", zIndex: 160001
774
- })
775
- .prependTo(".wcml_editor_original");
776
- },
777
- stop: function(event, ui) {
778
- $('.ui-resizable-iframeFix').remove()
779
- }
780
- });
781
- }
782
-
783
- $('#multi_currency_option_select input[name=multi_currency]').change(function(){
784
-
785
- if($(this).attr('id') != 'multi_currency_independent'){
786
- $('.currencies-table-content').fadeOut();
787
- $('.wcml_add_currency').fadeOut();
788
- $('#currency-switcher').fadeOut();
789
- $('#display_custom_prices_select').fadeOut();
790
- }else{
791
- $('.currencies-table-content').fadeIn();
792
- $('.wcml_add_currency').fadeIn();
793
- $('#currency-switcher').fadeIn();
794
- $('#multi-currency-per-language-details').fadeIn();
795
- $('#display_custom_prices_select').fadeIn();
796
- }
797
-
798
- })
799
-
800
- $('#wcml_custom_exchange_rates').submit(function(){
801
-
802
- var thisf = $(this);
803
-
804
- thisf.find(':submit').parent().prepend(icl_ajxloaderimg + '&nbsp;')
805
- thisf.find(':submit').prop('disabled', true);
806
-
807
- $.ajax({
808
-
809
- type: 'post',
810
- dataType: 'json',
811
- url: ajaxurl,
812
- data: thisf.serialize(),
813
- success: function(){
814
- thisf.find(':submit').prev().remove();
815
- thisf.find(':submit').prop('disabled', false);
816
- }
817
-
818
- })
819
-
820
- return false;
821
- })
822
-
823
- function wcml_remove_custom_rates(post_id){
824
-
825
- var thisa = $(this);
826
-
827
- $.ajax({
828
-
829
- type: 'post',
830
- dataType: 'json',
831
- url: ajaxurl,
832
- data: {action: 'wcml_remove_custom_rates', 'post_id': post_id},
833
- success: function(){
834
- thisa.parent().parent().parent().fadeOut(function(){ $(this).remove()});
835
- }
836
-
837
- })
838
-
839
- return false;
840
-
841
- }
842
-
843
- $(document).on('click', '#wcml_fix_strings_language', function(){ // TODO: remove after WPML release with support strings in different languages
844
-
845
- var thisb = $(this);
846
- thisb.prop('disabled', true);
847
- var $ajaxLoader = $('<span>&nbsp;</span>' + icl_ajxloaderimg);
848
- $ajaxLoader.insertAfter(thisb).show();
849
-
850
- $.ajax({
851
-
852
- type : "post",
853
- dataType:'json',
854
- url : ajaxurl,
855
- data : {
856
- action: "wcml_fix_strings_language",
857
- wcml_nonce: $('#wcml_fix_strings_language_nonce').val()
858
- },
859
- error: function(respnse) {
860
- thisb.prop('disabled', false);
861
- },
862
- success: function(response) {
863
-
864
- var sucess_1 = response.success_1;
865
-
866
- $.ajax({
867
- type : "post",
868
- dataType:'json',
869
- url : icl_ajx_url,
870
- data : {
871
- iclt_st_sw_save: 1,
872
- icl_st_sw: {strings_language: 'en'},
873
- _wpnonce: response._wpnonce
874
- },
875
- complete: function(response){
876
- $ajaxLoader.remove();
877
- thisb.after(sucess_1);
878
- }
879
- });
880
-
881
-
882
- }
883
- })
884
-
885
- });
886
-
887
- /*
888
- $(document).on('click','.edit_currency',function(){
889
- var $tableRow = $(this).closest('tr');
890
- $tableRow.addClass('edit-mode');
891
- $tableRow.find('.currency_code .code_val').hide();
892
- $tableRow.find('.currency_code select').show();
893
- $tableRow.find('.currency_value span.curr_val').hide();
894
- $tableRow.find('.currency_value input').show();
895
- $tableRow.find('.currency_changed').hide();
896
- $tableRow.find('.edit_currency').hide();
897
- $tableRow.find('.delete_currency').hide();
898
- $tableRow.find('.save_currency').show();
899
- $tableRow.find('.cancel_currency').show();
900
- });
901
- */
902
-
903
-
904
- $(document).on('click', '.edit_currency', function(){
905
- $('.wcml_currency_options_popup').hide();
906
-
907
- var popup = $('#wcml_currency_options_' + $(this).data('currency'));
908
- popup.fadeIn();
909
-
910
- var win = $(window);
911
- var viewport = {
912
- top : win.scrollTop(),
913
- left : win.scrollLeft()
914
- };
915
- //viewport.right = viewport.left + win.width();
916
- viewport.bottom = viewport.top + win.height();
917
-
918
- var bounds = popup.offset();
919
- //bounds.right = bounds.left + popup.outerWidth();
920
- bounds.bottom = bounds.top + popup.outerHeight();
921
-
922
- var incr = 0;
923
- while(viewport.bottom < bounds.bottom){
924
-
925
- var top = popup.css('top');
926
- if(top == 'auto'){
927
- top = parseInt(viewport.bottom) - parseInt(popup.outerHeight()) - 50;
928
- }else{
929
- top = parseInt(top) - 50;
930
- }
931
- popup.css({'top': top + 'px'});
932
-
933
-
934
- var bounds = popup.offset();
935
- //bounds.right = bounds.left + popup.outerWidth();
936
- bounds.bottom = bounds.top + popup.outerHeight();
937
-
938
-
939
- incr++;
940
- if(incr == 10) break;
941
-
942
- }
943
-
944
- });
945
-
946
- $(document).on('click', '.currency_options_cancel', function(){
947
- var currency = $(this).data('currency');
948
- $('#wcml_currency_options_' + currency).fadeOut(function(){
949
-
950
- $('#wcml_currency_options_' + currency).css('top', 'auto');
951
-
952
- });
953
-
954
- });
955
-
956
-
957
- $(document).on('click','.cancel_currency',function(){
958
- var $tableRow = $(this).closest('tr');
959
- $tableRow.removeClass('edit-mode');
960
- if($tableRow.find('.currency_current_code').val()){
961
- $tableRow.find('.currency_code .code_val').show();
962
- $tableRow.find('.currency_code select').hide();
963
- $tableRow.find('.currency_value span.curr_val').show();
964
- $tableRow.find('.currency_value input').hide();
965
- $tableRow.find('.currency_changed').show();
966
- $tableRow.find('.edit_currency').show();
967
- $tableRow.find('.delete_currency').show();
968
- $tableRow.find('.save_currency').hide();
969
- $tableRow.find('.cancel_currency').hide();
970
- $tableRow.find('.wcml-error').remove();
971
- }else{
972
- var index = $tableRow[0].rowIndex;
973
- $('#currency-lang-table tr').eq(index).remove();
974
- $tableRow.remove();
975
- }
976
- });
977
-
978
- $(document).on('change','.currency_code select',function(){
979
- $(this).parent().find('.curr_val_code').html($(this).val());
980
- });
981
-
982
- $('.wcml_add_currency button').click(function(){
983
- discard = true;
984
- $('.js-table-row-wrapper .curr_val_code').html($('.js-table-row-wrapper select').val());
985
- var $tableRow = $('.js-table-row-wrapper .js-table-row').clone();
986
- var $LangTableRow = $('.js-currency_lang_table tr').clone();
987
- $('#currency-table').find('tr.default_currency').before( $tableRow );
988
- $('#currency-lang-table').find('tr.default_currency').before( $LangTableRow );
989
- });
990
-
991
- $(document).on('click','.save_currency',function(e){
992
- discard = false;
993
- e.preventDefault();
994
-
995
- var $this = $(this);
996
- var $ajaxLoader = $('<span class="spinner">');
997
- var $messageContainer = $('<span class="wcml-error">');
998
-
999
- $this.prop('disabled',true);
1000
-
1001
- var parent = $(this).closest('tr');
1002
-
1003
- parent.find('.save_currency').hide();
1004
- parent.find('.cancel_currency').hide();
1005
- $ajaxLoader.insertBefore($this).show();
1006
-
1007
- $currencyCodeWraper = parent.find('.currency_code');
1008
- $currencyValueWraper = parent.find('.currency_value');
1009
-
1010
- var currency_code = $currencyCodeWraper.find('select[name=code]').val();
1011
- var currency_value = $currencyValueWraper.find('input').val();
1012
- var flag = false;
1013
-
1014
- if(currency_code == ''){
1015
- if(parent.find('.currency_code .wcml-error').size() == 0){
1016
- parent.find('.currency_code').append( $messageContainer );
1017
- $messageContainer.text( $currencyCodeWraper.data('message') );
1018
- // empty
1019
- }
1020
- flag = true;
1021
- }else{
1022
- if(parent.find('.currency_code .wcml-error').size() > 0){
1023
- parent.find('.currency_code .wcml-error').remove();
1024
- }
1025
- }
1026
-
1027
- if(currency_value == ''){
1028
- if(parent.find('.currency_value .wcml-error').size() == 0){
1029
-
1030
- parent.find('.currency_value').append( $messageContainer );
1031
- $messageContainer.text( $currencyCodeWraper.data('message') );
1032
- // empty
1033
- }
1034
- flag = true;
1035
- }else{
1036
- if(parent.find('.currency_value .wcml-error').size() > 0){
1037
- parent.find('.currency_value .wcml-error').remove();
1038
- }
1039
- }
1040
-
1041
- if(!isNumber(currency_value)){
1042
- if(parent.find('.currency_value .wcml-error').size() == 0){
1043
- parent.find('.currency_value').append( $messageContainer );
1044
- $messageContainer.text( $currencyValueWraper.data('message') );
1045
- // numeric
1046
- }
1047
- flag = true;
1048
- }else{
1049
- if(parent.find('.currency_value .wcml-error').size() > 0){
1050
- parent.find('.currency_value .wcml-error').remove();
1051
- }
1052
- }
1053
-
1054
- if(flag){
1055
- $ajaxLoader.remove();
1056
- $this.prop('disabled',false);
1057
- parent.find('.save_currency').show();
1058
- parent.find('.cancel_currency').show();
1059
- return false;
1060
- }
1061
-
1062
- $.ajax({
1063
- type : "post",
1064
- url : ajaxurl,
1065
- dataType: 'json',
1066
- data : {
1067
- action: "wcml_new_currency",
1068
- wcml_nonce: $('#new_currency_nonce').val(),
1069
- currency_code : currency_code,
1070
- currency_value : currency_value
1071
- },
1072
- error: function(respnse) {
1073
- // TODO: add error handling
1074
- },
1075
- success: function(response) {
1076
-
1077
- parent.closest('tr').attr('id', 'currency_row_' + currency_code);
1078
- $('#currency-lang-table tr:last').prev().attr('id', 'currency_row_langs_' + currency_code);
1079
-
1080
- $('#currency_row_langs_' + currency_code + ' .off_btn').attr('data-currency', currency_code);
1081
- $('#currency_row_langs_' + currency_code + ' .on_btn').attr('data-currency', currency_code);
1082
-
1083
- parent.find('.currency_code .code_val').html(response.currency_name_formatted);
1084
- parent.find('.currency_code .currency_value span').html(response.currency_meta_info);
1085
-
1086
- parent.find('.currency_code').prepend(response.currency_options);
1087
-
1088
- parent.find('.currency_code select[name="code"]').remove();
1089
- parent.find('.currency_value input').remove();
1090
-
1091
- parent.find('.edit_currency').data('currency', currency_code).show();
1092
- parent.find('.delete_currency').data('currency', currency_code).show();
1093
-
1094
- $('.js-table-row-wrapper select option[value="'+currency_code+'"]').remove();
1095
- $('.currency_languages select').each(function(){
1096
- $(this).append('<option value="'+currency_code+'">'+currency_code+'</option>');
1097
- });
1098
-
1099
- $('#wcml_currencies_order').append('<li class="wcml_currencies_order_'+currency_code+'" cur="'+currency_code+'>'+response.currency_name_formatted_without_rate+'</li>');
1100
- currency_switcher_preview();
1101
- },
1102
- complete: function() {
1103
- $ajaxLoader.remove();
1104
- $this.prop('disabled',false);
1105
- }
1106
- });
1107
-
1108
- return false;
1109
- });
1110
-
1111
-
1112
- $(document).on('click','.delete_currency',function(e){
1113
- e.preventDefault();
1114
-
1115
- var currency = $(this).data('currency');
1116
-
1117
-
1118
- $('#currency_row_' + currency + ' .currency_action_update').hide();
1119
- var ajaxLoader = $('<span class="spinner">');
1120
- $(this).hide();
1121
- $(this).parent().append(ajaxLoader).show();
1122
-
1123
- $.ajax({
1124
- type : "post",
1125
- url : ajaxurl,
1126
- data : {
1127
- action: "wcml_delete_currency",
1128
- wcml_nonce: $('#del_currency_nonce').val(),
1129
- code: currency
1130
- },
1131
- success: function(response) {
1132
- $('#currency_row_' + currency).remove();
1133
- $('#currency_row_langs_' + currency).remove();
1134
- $('#wcml_currencies_order .wcml_currencies_order_'+ currency).remove();
1135
-
1136
- $.ajax({
1137
- type : "post",
1138
- url : ajaxurl,
1139
- data : {
1140
- action: "wcml_currencies_list",
1141
- wcml_nonce: $('#currencies_list_nonce').val()
1142
- },
1143
- success: function(response) {
1144
- $('.js-table-row-wrapper select').html(response);
1145
- }
1146
- });
1147
- currency_switcher_preview();
1148
- },
1149
- done: function() {
1150
- ajaxLoader.remove();
1151
- }
1152
- });
1153
-
1154
- return false;
1155
- });
1156
-
1157
-
1158
- $(document).on('click', '.wcml_currency_options_popup :submit', function(){
1159
- var parent = $(this).closest('.wcml_currency_options_popup');
1160
-
1161
- var chk_rate = check_on_numeric(parent,'.ext_rate');
1162
- var chk_deci = check_on_numeric(parent,'.decimals_number');
1163
- var chk_autosub = check_on_numeric(parent,'.abstract_amount');
1164
-
1165
- if(chk_rate || chk_deci || chk_autosub){
1166
- return false;
1167
- }
1168
-
1169
-
1170
- $('.wcml_currency_options_popup :submit, .wcml_currency_options_popup :button').prop('disabled', true);
1171
- var currency = $(this).data('currency');
1172
-
1173
- var ajaxLoader = $('<span class="spinner" style="position:absolute;margin-left:-30px;"></span>');
1174
-
1175
- ajaxLoader.show();
1176
- $(this).parent().prepend(ajaxLoader);
1177
-
1178
- $.ajax({
1179
- url: ajaxurl,
1180
- type: 'POST',
1181
- dataType: 'json',
1182
- data: $('#wcml_mc_options').serialize() + '&action=wcml_save_currency&currency='+currency+'&wcml_nonce='+ $('#save_currency_nonce').val(),
1183
- success: function(response){
1184
- $('.wcml_currency_options_popup').fadeOut(function(){
1185
- ajaxLoader.remove();
1186
- $('.wcml_currency_options_popup :submit, .wcml_currency_options_popup :button').prop('disabled', false);
1187
-
1188
- $('#currency_row_' + currency + ' .currency_code .code_val').html(response.currency_name_formatted);
1189
- $('#currency_row_' + currency + ' .currency_value span').html(response.currency_meta_info);
1190
-
1191
-
1192
- });
1193
- }
1194
-
1195
- })
1196
-
1197
- return false;
1198
- })
1199
-
1200
-
1201
- function check_on_numeric(parent, elem){
1202
- var messageContainer = $('<span class="wcml-error">');
1203
-
1204
- if(!isNumber(parent.find(elem).val())){
1205
- if(parent.find(elem).parent().find('.wcml-error').size() == 0){
1206
- parent.find(elem).parent().append( messageContainer );
1207
- messageContainer.text( parent.find(elem).data('message') );
1208
- }
1209
- return true;
1210
- }else{
1211
- if(parent.find(elem).parent().find('.wcml-error').size() > 0){
1212
- parent.find(elem).parent().find('.wcml-error').remove();
1213
- }
1214
- return false;
1215
- }
1216
- }
1217
-
1218
-
1219
- // expand|collapse for product images and product variations tables
1220
- $(document).on('click','.js-table-toggle',function(e){
1221
-
1222
- e.preventDefault();
1223
-
1224
- var textOpened = $(this).data('text-opened');
1225
- var textClosed = $(this).data('text-closed');
1226
- var $table = $(this).next('.js-table');
1227
-
1228
- var this_id = $(this).attr('id');
1229
- if($(this).hasClass('prod_images_link')){
1230
- var id_and_language = this_id.replace(/^prod_images_link_/, '');
1231
- }else{
1232
- var id_and_language = this_id.replace(/^prod_variations_link_/, '');
1233
- }
1234
- var spl = id_and_language.split('_');
1235
- var language = spl[1];
1236
- var product_id = spl[0];
1237
-
1238
- if ( $table.is(':visible') ) {
1239
- $table.hide();
1240
- $(this)
1241
- .find('span')
1242
- .text( textClosed );
1243
- $(this)
1244
- .find('i')
1245
- .removeClass('icon-caret-up')
1246
- .addClass('icon-caret-down');
1247
- if($(this).hasClass('prod_images_link')){
1248
- $('#prod_images_' + product_id + '_' + language).hide();
1249
- }else{
1250
- $('#prod_variations_' + product_id + language).hide();
1251
- }
1252
-
1253
- }
1254
- else {
1255
- $table.show();
1256
- if($(this).hasClass('prod_images_link')){
1257
- $('#prod_images' + product_id + language).show();
1258
- }else{
1259
- $('#prod_variations_' + product_id + language).show();
1260
- }
1261
- $(this)
1262
- .find('span')
1263
- .text( textOpened );
1264
- $(this)
1265
- .find('i')
1266
- .removeClass('icon-caret-down')
1267
- .addClass('icon-caret-up');
1268
- }
1269
-
1270
- return false;
1271
- });
1272
-
1273
- // wp-pointers
1274
- $('.js-display-tooltip').click(function(){
1275
- var $thiz = $(this);
1276
-
1277
- // hide this pointer if other pointer is opened.
1278
- $('.wp-pointer').fadeOut(100);
1279
-
1280
- $(this).pointer({
1281
- content: '<h3>'+$thiz.data('header')+'</h3><p>'+$thiz.data('content')+'</p>',
1282
- position: {
1283
- edge: 'left',
1284
- align: 'center',
1285
- offset: '15 0'
1286
- }
1287
- }).pointer('open');
1288
- });
1289
-
1290
- $(document).on('click','.currency_languages a.on_btn',function(e){
1291
- $(this).closest('ul').find('.on').removeClass('on');
1292
- $(this).parent().addClass('on');
1293
- var index = $(this).closest('tr')[0].rowIndex;
1294
- $('.currency_languages select[rel="'+$(this).data('language')+'"]').append('<option value="'+$(this).data('currency')+'">'+$(this).data('currency')+'</option>');
1295
- update_currency_lang($(this),1,0);
1296
- });
1297
-
1298
- $(document).on('click','.currency_languages a.off_btn',function(e){
1299
- var enbl_elem = $(this).closest('ul').find('.on').removeClass('on');
1300
- var flag = true;
1301
- var lang = $(this).data('language');
1302
- $('#currency-lang-table .on_btn[data-language="'+lang+'"]').each(function(){
1303
- if($(this).parent().hasClass('on'))
1304
- flag = false;
1305
- });
1306
-
1307
- if(flag){
1308
- enbl_elem.addClass('on');
1309
- alert($('#wcml_warn_disable_language_massage').val());
1310
- return;
1311
- }
1312
-
1313
- $(this).parent().addClass('on');
1314
- var index = $(this).closest('tr')[0].rowIndex;
1315
-
1316
- if($('.currency_languages select[rel="'+$(this).data('language')+'"]').val() == $(this).data('currency')){
1317
- update_currency_lang($(this),0,1);
1318
- }else{
1319
- update_currency_lang($(this),0,0);
1320
- }
1321
- $('.currency_languages select[rel="'+$(this).data('language')+'"] option[value="'+$(this).data('currency')+'"]').remove();
1322
- });
1323
-
1324
- function update_currency_lang(elem, value, upd_def){
1325
- $('input[name="wcml_mc_options"]').attr('disabled','disabled');
1326
- var lang = elem.data('language');
1327
- var code = elem.data('currency');
1328
- discard = true;
1329
- $.ajax({
1330
- type: 'post',
1331
- url: ajaxurl,
1332
- data: {
1333
- action: 'wcml_update_currency_lang',
1334
- value: value,
1335
- lang: lang,
1336
- code: code,
1337
- wcml_nonce: $('#update_currency_lang_nonce').val()
1338
- },
1339
- success: function(){
1340
- if(upd_def){
1341
- update_default_currency(lang,0);
1342
- }
1343
- },
1344
- complete: function() {
1345
- $('input[name="wcml_mc_options"]').removeAttr('disabled');
1346
- discard = false;
1347
- }
1348
- });
1349
- }
1350
-
1351
- $('.default_currency select').change(function(){
1352
- update_default_currency($(this).attr('rel'), $(this).val());
1353
- });
1354
-
1355
- function update_default_currency(lang,code){
1356
- discard = true;
1357
- $.ajax({
1358
- type: 'post',
1359
- url: ajaxurl,
1360
- data: {
1361
- action: 'wcml_update_default_currency',
1362
- lang: lang,
1363
- code: code,
1364
- wcml_nonce: $('#wcml_update_default_currency_nonce').val()
1365
- },
1366
- complete: function(){
1367
- discard = false;
1368
- }
1369
- });
1370
- }
1371
-
1372
- function isNumber(n) {
1373
- return !isNaN(parseFloat(n)) && isFinite(n);
1374
- }
1375
-
1376
- $(document).on('click', '#wcml_dimiss_non_default_language_warning', function(){
1377
- $(this).attr('disabled', 'disabled');
1378
- var ajaxLoader = $('<span class="spinner">');
1379
- $(this).parent().append(ajaxLoader);
1380
- ajaxLoader.show();
1381
- $.ajax({
1382
- type: 'post',
1383
- url: ajaxurl,
1384
- dataType:'json',
1385
- data: {
1386
- action: 'wcml_update_setting_ajx',
1387
- setting: 'dismiss_non_default_language_warning',
1388
- value: 1,
1389
- nonce: $('#wcml_settings_nonce').val()
1390
- },
1391
- success: function(response){
1392
- location.reload();
1393
- }
1394
- });
1395
- });
1396
-
1397
-
1398
- $('#wcml_currencies_order').sortable({
1399
- update: function(){
1400
- $('.wcml_currencies_order_ajx_resp').fadeIn();
1401
- var currencies_order = [];
1402
- $('#wcml_currencies_order').find('li').each(function(){
1403
- currencies_order.push($(this).attr('cur'));
1404
- });
1405
- $.ajax({
1406
- type: "POST",
1407
- url: ajaxurl,
1408
- dataType: 'json',
1409
- data: {
1410
- action: 'wcml_currencies_order',
1411
- wcml_nonce: $('#wcml_currencies_order_order_nonce').val(),
1412
- order: currencies_order.join(';')
1413
- },
1414
- success: function(resp){
1415
- fadeInAjxResp('.wcml_currencies_order_ajx_resp', resp.message);
1416
- currency_switcher_preview();
1417
- }
1418
- });
1419
- }
1420
- });
1421
-
1422
- $(document).on('click','input[name="currency_switcher_style"]',function(e){
1423
- $(this).closest('ul').find('select').hide();
1424
- $(this).closest('li').find('select').show();
1425
- currency_switcher_preview();
1426
- });
1427
-
1428
- $(document).on('change','#wcml_curr_sel_orientation',function(e){
1429
- currency_switcher_preview();
1430
- });
1431
-
1432
- $(document).on('keyup','input[name="wcml_curr_template"]',function(e){
1433
- discard = true;
1434
- $(this).closest('.wcml-section').find('.button-wrap input').css("border-color","#1e8cbe");
1435
- currency_switcher_preview();
1436
- });
1437
-
1438
- $(document).on('change','input[name="wcml_curr_template"]',function(e){
1439
- if(!$(this).val()){
1440
- $('input[name="wcml_curr_template"]').val($('#currency_switcher_default').val())
1441
- }
1442
- });
1443
-
1444
- function currency_switcher_preview(){
1445
- var template = $('input[name="wcml_curr_template"]').val();
1446
- if(!template){
1447
- template = $('#currency_switcher_default').val();
1448
- }
1449
- $.ajax({
1450
- type: "POST",
1451
- url: ajaxurl,
1452
- data: {
1453
- action: 'wcml_currencies_switcher_preview',
1454
- wcml_nonce: $('#wcml_currencies_switcher_preview_nonce').val(),
1455
- switcher_type: $('input[name="currency_switcher_style"]:checked').val(),
1456
- orientation: $('#wcml_curr_sel_orientation').val(),
1457
- template: template
1458
- },
1459
- success: function(resp){
1460
- $('#wcml_curr_sel_preview').html(resp);
1461
- }
1462
- });
1463
- }
1464
-
1465
- });
1466
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/js/tooltip_init.js DELETED
@@ -1,11 +0,0 @@
1
- jQuery(document).ready(function($){
2
- // Tooltips
3
- var tiptip_args = {
4
- 'attribute' : 'data-tip',
5
- 'fadeIn' : 50,
6
- 'fadeOut' : 50,
7
- 'delay' : 200
8
- };
9
- $(".icon-question-sign").tipTip( tiptip_args );
10
- });
11
-
 
 
 
 
 
 
 
 
 
 
 
compatibility/assets/js/wcml-bookings.js DELETED
@@ -1,96 +0,0 @@
1
- jQuery( document ).ready( function( $ ){
2
-
3
- if( $( '.wcml_custom_costs_input:checked' ).val() == 1 ){
4
-
5
- $( '.wcml_custom_cost_field' ).show();
6
-
7
- }
8
-
9
- $(document).on( 'change', '.wcml_custom_costs_input', function(){
10
-
11
- if( $(this).val() == 1 ){
12
-
13
- $( '.wcml_custom_cost_field' ).show();
14
-
15
- }else{
16
-
17
- $( '.wcml_custom_cost_field' ).hide();
18
-
19
- }
20
-
21
- });
22
-
23
- $(document).on( 'mouseout', '.add_row', function(){
24
-
25
- if( $( '.wcml_custom_costs_input:checked' ).val() == 1 ) {
26
-
27
- $( '.wcml_custom_cost_field' ).show();
28
-
29
- }
30
-
31
- });
32
-
33
- $(document).on( 'mouseout', '.add_person', function(){
34
-
35
- if( $( '.wcml_custom_costs_input:checked' ).val() == 1 ) {
36
-
37
- setTimeout(
38
- function() {
39
- $( '.wcml_custom_cost_field' ).show();
40
- }, 3000);
41
-
42
- }
43
-
44
- });
45
-
46
-
47
- //lock fields
48
- if( lock_fields == 1 ){
49
-
50
- $('#bookings_pricing input[type="number"],#accommodation_bookings_rates input[type="number"], #bookings_resources input[type="number"], #bookings_availability input[type="number"], #bookings_availability input[type="text"], #bookings_persons input[type="number"]').each(function(){
51
- $(this).attr('readonly','readonly');
52
- $(this).after($('.wcml_lock_img').clone().removeClass('wcml_lock_img').show());
53
- });
54
-
55
-
56
- $('#bookings_pricing select, #bookings_resources select, #bookings_availability select,#bookings_persons input[type="checkbox"]').each(function(){
57
- $(this).attr('disabled','disabled');
58
- $(this).after($('.wcml_lock_img').clone().removeClass('wcml_lock_img').show());
59
- });
60
-
61
- var ids = [ '_wc_booking_has_resources', '_wc_booking_has_persons', '_wc_booking_duration_type', '_wc_booking_duration',
62
- '_wc_booking_duration_unit', '_wc_booking_calendar_display_mode', '_wc_booking_requires_confirmation', '_wc_booking_user_can_cancel',
63
- '_wc_accommodation_booking_min_duration', '_wc_accommodation_booking_max_duration', '_wc_accommodation_booking_max_duration', '_wc_accommodation_booking_calendar_display_mode',
64
- '_wc_accommodation_booking_requires_confirmation', '_wc_accommodation_booking_user_can_cancel', '_wc_accommodation_booking_cancel_limit', '_wc_accommodation_booking_cancel_limit_unit',
65
- '_wc_accommodation_booking_qty', '_wc_accommodation_booking_min_date', '_wc_accommodation_booking_min_date_unit', '_wc_accommodation_booking_max_date', '_wc_accommodation_booking_max_date_unit'
66
- ];
67
-
68
- for (i = 0; i < ids.length; i++) {
69
- $('#'+ids[i]).attr('disabled','disabled');
70
- $('#'+ids[i]).after($('.wcml_lock_img').clone().removeClass('wcml_lock_img').show());
71
- }
72
-
73
- var buttons = [ 'add_resource', 'add_row' ];
74
-
75
- for (i = 0; i < buttons.length; i++) {
76
- $('.'+buttons[i]).attr('disabled','disabled');
77
- $('.'+buttons[i]).unbind('click');
78
- $('.'+buttons[i]).after($('.wcml_lock_img').clone().removeClass('wcml_lock_img').show());
79
- }
80
-
81
- $('form#post input[type="submit"]').click(function(){
82
-
83
- for (i = 0; i < ids.length; i++) {
84
- $('#'+ids[i]).removeAttr('disabled');
85
- }
86
-
87
- $('#bookings_pricing select, #bookings_resources select, #bookings_availability select,#bookings_persons input[type="checkbox"]').each(function(){
88
- $(this).removeAttr('disabled');
89
- });
90
-
91
- });
92
-
93
-
94
- }
95
- });
96
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
compatibility/class-wcml-accommodation-bookings.php CHANGED
@@ -1,171 +1,171 @@
1
- <?php
2
-
3
- class WCML_Accommodation_Bookings{
4
-
5
- function __construct(){
6
-
7
- add_action( 'woocommerce_accommodation_bookings_after_booking_base_cost' , array( $this, 'wcml_price_field_after_booking_base_cost' ) );
8
- add_action( 'woocommerce_accommodation_bookings_after_booking_pricing_override_block_cost' , array( $this, 'wcml_price_field_after_booking_pricing_override_block_cost' ), 10, 2 );
9
- add_action( 'woocommerce_accommodation_bookings_after_bookings_pricing' , array( $this , 'after_bookings_pricing' ) );
10
-
11
- add_action( 'save_post', array( $this, 'save_custom_costs' ), 110, 2 );
12
- add_filter( 'get_post_metadata', array( $this, 'product_price_filter'), 9, 4 );
13
- }
14
-
15
- function wcml_price_field_after_booking_base_cost( $post_id ){
16
-
17
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_base_cost' );
18
-
19
- }
20
-
21
- function wcml_price_field_after_booking_pricing_override_block_cost( $pricing, $post_id ){
22
-
23
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_pricing_override_block_cost', $pricing );
24
-
25
- }
26
-
27
- function after_bookings_pricing( $post_id ){
28
- global $woocommerce_wpml;
29
-
30
- if( $woocommerce_wpml->products->is_original_product( $post_id ) && $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
31
-
32
- $custom_costs_status = get_post_meta( $post_id, '_wcml_custom_costs_status', true );
33
-
34
- $checked = !$custom_costs_status ? 'checked="checked"' : ' ';
35
-
36
- echo '<div class="wcml_custom_costs">';
37
-
38
- echo '<input type="radio" name="_wcml_custom_costs" id="wcml_custom_costs_auto" value="0" class="wcml_custom_costs_input" '. $checked .' />';
39
- echo '<label for="wcml_custom_costs_auto">'. __('Calculate costs in other currencies automatically', 'woocommerce-multilingual') .'</label>';
40
-
41
- $checked = $custom_costs_status == 1 ? 'checked="checked"' : ' ';
42
-
43
- echo '<input type="radio" name="_wcml_custom_costs" value="1" id="wcml_custom_costs_manually" class="wcml_custom_costs_input" '. $checked .' />';
44
- echo '<label for="wcml_custom_costs_manually">'. __('Set costs in other currencies manually', 'woocommerce-multilingual') .'</label>';
45
-
46
- wp_nonce_field( 'wcml_save_accommodation_bookings_custom_costs', '_wcml_custom_costs_nonce' );
47
-
48
- echo '</div>';
49
- }
50
-
51
- }
52
-
53
- function echo_wcml_price_field( $post_id, $field, $pricing = false, $check = true, $resource_id = false ){
54
- global $woocommerce_wpml;
55
-
56
- if( ( !$check || $woocommerce_wpml->products->is_original_product( $post_id ) ) && $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
57
-
58
- $currencies = $woocommerce_wpml->multi_currency_support->get_currencies();
59
-
60
- $wc_currencies = get_woocommerce_currencies();
61
-
62
- echo '<div class="wcml_custom_cost_field" >';
63
-
64
- foreach($currencies as $currency_code => $currency){
65
-
66
- switch( $field ){
67
- case 'wcml_wc_booking_base_cost':
68
- woocommerce_wp_text_input( array( 'id' => 'wcml_wc_booking_base_cost', 'class'=>'wcml_bookings_custom_price', 'name' => 'wcml_wc_accommodation_booking_base_cost['.$currency_code.']', 'label' => get_woocommerce_currency_symbol($currency_code), 'description' => __( 'This is the cost per block booked. All other costs (for resources and persons) are added to this.', 'woocommerce-bookings' ), 'value' => get_post_meta( $post_id, '_wc_booking_base_cost_'.$currency_code, true ), 'type' => 'number', 'desc_tip' => true, 'custom_attributes' => array(
69
- 'min' => '',
70
- 'step' => '0.01'
71
- ) ) );
72
- break;
73
-
74
-
75
- case 'wcml_wc_booking_pricing_override_block_cost':
76
-
77
- if( isset( $pricing[ 'override_block_'.$currency_code ] ) ){
78
- $value = $pricing[ 'override_block_'.$currency_code ];
79
- }else{
80
- $value = '';
81
- }
82
-
83
- echo '<div class="wcml_bookings_range_block" >';
84
- echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
85
- echo '<input type="number" step="0.01" name="wcml_wc_accommodation_booking_pricing_override_block_cost['.$currency_code.']" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
86
- echo '</div>';
87
- break;
88
-
89
- default:
90
- break;
91
-
92
- }
93
-
94
- }
95
-
96
- echo '</div>';
97
-
98
- }
99
- }
100
-
101
- function save_custom_costs( $post_id, $post ){
102
- global $woocommerce_wpml;
103
-
104
- $nonce = filter_input( INPUT_POST, '_wcml_custom_costs_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
105
-
106
- if( isset( $_POST['_wcml_custom_costs'] ) && isset( $nonce ) && wp_verify_nonce( $nonce, 'wcml_save_accommodation_bookings_custom_costs' ) ){
107
-
108
- update_post_meta( $post_id, '_wcml_custom_costs_status', $_POST['_wcml_custom_costs'] );
109
-
110
- if( $_POST['_wcml_custom_costs'] == 1 ){
111
-
112
- $currencies = $woocommerce_wpml->multi_currency_support->get_currencies();
113
-
114
- foreach( $currencies as $code => $currency ){
115
-
116
- $wc_booking_base_cost = $_POST[ 'wcml_wc_accommodation_booking_base_cost' ][ $code ];
117
- update_post_meta( $post_id, '_wc_booking_base_cost_'.$code, $wc_booking_base_cost );
118
- update_post_meta( $post_id, '_price_'.$code, $wc_booking_base_cost );
119
-
120
- }
121
-
122
- $updated_meta = array();
123
- $booking_pricing = get_post_meta( $post_id, '_wc_booking_pricing', true );
124
-
125
- foreach ( maybe_unserialize( $booking_pricing ) as $key => $prices ) {
126
-
127
- $updated_meta[ $key ] = $prices;
128
-
129
- foreach ( $currencies as $code => $currency ) {
130
-
131
- $updated_meta[ $key ][ 'override_block_'.$code ] = $_POST[ 'wcml_wc_accommodation_booking_pricing_override_block_cost' ][ $code ];
132
-
133
- }
134
-
135
- }
136
-
137
- update_post_meta( $post_id, '_wc_booking_pricing', $updated_meta );
138
-
139
- }
140
- }
141
-
142
- }
143
-
144
- function product_price_filter( $value, $object_id, $meta_key, $single ){
145
- global $woocommerce_wpml;
146
-
147
- if(
148
- get_post_type( $object_id ) == 'product' &&
149
- $meta_key == '_price' &&
150
- $woocommerce_wpml->settings[ 'enable_multi_currency' ] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
151
- !is_admin() &&
152
- ( $currency = $woocommerce_wpml->multi_currency_support->get_client_currency() ) != get_option( 'woocommerce_currency' )
153
- ) {
154
-
155
- remove_filter( 'get_post_metadata', array( $this, 'product_price_filter' ), 9, 4 );
156
-
157
- $original_language = $woocommerce_wpml->products->get_original_product_language( $object_id );
158
- $original_product = apply_filters( 'translate_object_id', $object_id, 'product', true, $original_language );
159
-
160
- if ( get_post_meta( $original_product, '_wcml_custom_costs_status' ) ) {
161
-
162
- $price = get_post_meta( $object_id, '_price_' . $currency , true );
163
- }
164
-
165
- add_filter( 'get_post_metadata', array( $this, 'product_price_filter' ), 9, 4 );
166
- }
167
-
168
- return isset( $price) ? $price : $value;
169
- }
170
-
171
  }
1
+ <?php
2
+
3
+ class WCML_Accommodation_Bookings{
4
+
5
+ function __construct(){
6
+
7
+ add_action( 'woocommerce_accommodation_bookings_after_booking_base_cost' , array( $this, 'wcml_price_field_after_booking_base_cost' ) );
8
+ add_action( 'woocommerce_accommodation_bookings_after_booking_pricing_override_block_cost' , array( $this, 'wcml_price_field_after_booking_pricing_override_block_cost' ), 10, 2 );
9
+ add_action( 'woocommerce_accommodation_bookings_after_bookings_pricing' , array( $this , 'after_bookings_pricing' ) );
10
+
11
+ add_action( 'save_post', array( $this, 'save_custom_costs' ), 110, 2 );
12
+ add_filter( 'get_post_metadata', array( $this, 'product_price_filter'), 9, 4 );
13
+ }
14
+
15
+ function wcml_price_field_after_booking_base_cost( $post_id ){
16
+
17
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_base_cost' );
18
+
19
+ }
20
+
21
+ function wcml_price_field_after_booking_pricing_override_block_cost( $pricing, $post_id ){
22
+
23
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_pricing_override_block_cost', $pricing );
24
+
25
+ }
26
+
27
+ function after_bookings_pricing( $post_id ){
28
+ global $woocommerce_wpml;
29
+
30
+ if( $woocommerce_wpml->products->is_original_product( $post_id ) && $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
31
+
32
+ $custom_costs_status = get_post_meta( $post_id, '_wcml_custom_costs_status', true );
33
+
34
+ $checked = !$custom_costs_status ? 'checked="checked"' : ' ';
35
+
36
+ echo '<div class="wcml_custom_costs">';
37
+
38
+ echo '<input type="radio" name="_wcml_custom_costs" id="wcml_custom_costs_auto" value="0" class="wcml_custom_costs_input" '. $checked .' />';
39
+ echo '<label for="wcml_custom_costs_auto">'. __('Calculate costs in other currencies automatically', 'woocommerce-multilingual') .'</label>';
40
+
41
+ $checked = $custom_costs_status == 1 ? 'checked="checked"' : ' ';
42
+
43
+ echo '<input type="radio" name="_wcml_custom_costs" value="1" id="wcml_custom_costs_manually" class="wcml_custom_costs_input" '. $checked .' />';
44
+ echo '<label for="wcml_custom_costs_manually">'. __('Set costs in other currencies manually', 'woocommerce-multilingual') .'</label>';
45
+
46
+ wp_nonce_field( 'wcml_save_accommodation_bookings_custom_costs', '_wcml_custom_costs_nonce' );
47
+
48
+ echo '</div>';
49
+ }
50
+
51
+ }
52
+
53
+ function echo_wcml_price_field( $post_id, $field, $pricing = false, $check = true, $resource_id = false ){
54
+ global $woocommerce_wpml;
55
+
56
+ if( ( !$check || $woocommerce_wpml->products->is_original_product( $post_id ) ) && $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
57
+
58
+ $currencies = $woocommerce_wpml->multi_currency->get_currencies();
59
+
60
+ $wc_currencies = get_woocommerce_currencies();
61
+
62
+ echo '<div class="wcml_custom_cost_field" >';
63
+
64
+ foreach($currencies as $currency_code => $currency){
65
+
66
+ switch( $field ){
67
+ case 'wcml_wc_booking_base_cost':
68
+ woocommerce_wp_text_input( array( 'id' => 'wcml_wc_booking_base_cost', 'class'=>'wcml_bookings_custom_price', 'name' => 'wcml_wc_accommodation_booking_base_cost['.$currency_code.']', 'label' => get_woocommerce_currency_symbol($currency_code), 'description' => __( 'This is the cost per block booked. All other costs (for resources and persons) are added to this.', 'woocommerce-bookings' ), 'value' => get_post_meta( $post_id, '_wc_booking_base_cost_'.$currency_code, true ), 'type' => 'number', 'desc_tip' => true, 'custom_attributes' => array(
69
+ 'min' => '',
70
+ 'step' => '0.01'
71
+ ) ) );
72
+ break;
73
+
74
+
75
+ case 'wcml_wc_booking_pricing_override_block_cost':
76
+
77
+ if( isset( $pricing[ 'override_block_'.$currency_code ] ) ){
78
+ $value = $pricing[ 'override_block_'.$currency_code ];
79
+ }else{
80
+ $value = '';
81
+ }
82
+
83
+ echo '<div class="wcml_bookings_range_block" >';
84
+ echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
85
+ echo '<input type="number" step="0.01" name="wcml_wc_accommodation_booking_pricing_override_block_cost['.$currency_code.']" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
86
+ echo '</div>';
87
+ break;
88
+
89
+ default:
90
+ break;
91
+
92
+ }
93
+
94
+ }
95
+
96
+ echo '</div>';
97
+
98
+ }
99
+ }
100
+
101
+ function save_custom_costs( $post_id, $post ){
102
+ global $woocommerce_wpml;
103
+
104
+ $nonce = filter_input( INPUT_POST, '_wcml_custom_costs_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
105
+
106
+ if( isset( $_POST['_wcml_custom_costs'] ) && isset( $nonce ) && wp_verify_nonce( $nonce, 'wcml_save_accommodation_bookings_custom_costs' ) ){
107
+
108
+ update_post_meta( $post_id, '_wcml_custom_costs_status', $_POST['_wcml_custom_costs'] );
109
+
110
+ if( $_POST['_wcml_custom_costs'] == 1 ){
111
+
112
+ $currencies = $woocommerce_wpml->multi_currency->get_currencies();
113
+
114
+ foreach( $currencies as $code => $currency ){
115
+
116
+ $wc_booking_base_cost = $_POST[ 'wcml_wc_accommodation_booking_base_cost' ][ $code ];
117
+ update_post_meta( $post_id, '_wc_booking_base_cost_'.$code, $wc_booking_base_cost );
118
+ update_post_meta( $post_id, '_price_'.$code, $wc_booking_base_cost );
119
+
120
+ }
121
+
122
+ $updated_meta = array();
123
+ $booking_pricing = get_post_meta( $post_id, '_wc_booking_pricing', true );
124
+
125
+ foreach ( maybe_unserialize( $booking_pricing ) as $key => $prices ) {
126
+
127
+ $updated_meta[ $key ] = $prices;
128
+
129
+ foreach ( $currencies as $code => $currency ) {
130
+
131
+ $updated_meta[ $key ][ 'override_block_'.$code ] = $_POST[ 'wcml_wc_accommodation_booking_pricing_override_block_cost' ][ $code ];
132
+
133
+ }
134
+
135
+ }
136
+
137
+ update_post_meta( $post_id, '_wc_booking_pricing', $updated_meta );
138
+
139
+ }
140
+ }
141
+
142
+ }
143
+
144
+ function product_price_filter( $value, $object_id, $meta_key, $single ){
145
+ global $woocommerce_wpml;
146
+
147
+ if(
148
+ get_post_type( $object_id ) == 'product' &&
149
+ $meta_key == '_price' &&
150
+ $woocommerce_wpml->settings[ 'enable_multi_currency' ] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
151
+ !is_admin() &&
152
+ ( $currency = $woocommerce_wpml->multi_currency->get_client_currency() ) != get_option( 'woocommerce_currency' )
153
+ ) {
154
+
155
+ remove_filter( 'get_post_metadata', array( $this, 'product_price_filter' ), 9, 4 );
156
+
157
+ $original_language = $woocommerce_wpml->products->get_original_product_language( $object_id );
158
+ $original_product = apply_filters( 'translate_object_id', $object_id, 'product', true, $original_language );
159
+
160
+ if ( get_post_meta( $original_product, '_wcml_custom_costs_status' ) ) {
161
+
162
+ $price = get_post_meta( $object_id, '_price_' . $currency , true );
163
+ }
164
+
165
+ add_filter( 'get_post_metadata', array( $this, 'product_price_filter' ), 9, 4 );
166
+ }
167
+
168
+ return isset( $price) ? $price : $value;
169
+ }
170
+
171
  }
compatibility/class-wcml-adventure-tours.php ADDED
@@ -0,0 +1,365 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_Adventure_tours{
4
+
5
+ private $tp;
6
+
7
+ function __construct(){
8
+ add_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
9
+ add_filter( 'get_post_metadata', array( $this, 'product_price_filter'), 9, 4 );
10
+
11
+ if (is_admin()) {
12
+
13
+ add_action('wcml_gui_additional_box_html', array($this, 'custom_box_html'), 10, 3);
14
+ add_filter('wcml_gui_additional_box_data', array($this, 'custom_box_html_data'), 10, 4);
15
+ add_action('wcml_update_extra_fields', array($this, 'tour_data_update'), 10, 3);
16
+
17
+ $this->tp = new WPML_Element_Translation_Package();
18
+
19
+ add_filter('wpml_tm_translation_job_data', array($this, 'append_tour_data_translation_package'), 10, 2);
20
+ add_action('wpml_translation_job_saved', array($this, 'save_tour_data_translation'), 10, 3);
21
+
22
+ add_action( 'admin_footer', array( $this, 'load_assets' ) );
23
+ add_action( 'wcml_after_custom_prices_block', array( $this, 'add_custom_prices_block' ) );
24
+ add_action( 'wcml_after_save_custom_prices', array( $this, 'save_custom_costs' ) );
25
+
26
+ add_filter( 'wcml_is_variable_product', array( $this, 'is_variable_tour' ), 10, 2 );
27
+ add_filter( 'wcml_variation_term_taxonomy_ids', array( $this, 'add_tour_tax_id' ) );
28
+ add_filter( 'wcml_is_attributes_page', array( $this, 'is_attributes_page' ) );
29
+ }
30
+ }
31
+
32
+
33
+ function sync_tour_data_across_translations($meta_id, $post_id, $meta_key, $tour_tabs_meta)
34
+ {
35
+ if ($meta_key != 'tour_tabs_meta')
36
+ return false;
37
+
38
+
39
+ global $sitepress, $woocommerce_wpml;
40
+
41
+ $post = get_post($post_id);
42
+
43
+ // skip auto-drafts // skip autosave
44
+ if ( $post->post_status == 'auto-draft' || isset( $_POST['autosave'] ) ) {
45
+ return false;
46
+ }
47
+
48
+ if ($post->post_type == 'product') {
49
+
50
+ remove_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
51
+
52
+ if ( $woocommerce_wpml->products->is_original_product( $post_id ) ) {
53
+
54
+ $original_product_id = $post_id;
55
+
56
+ } else {
57
+
58
+ $original_product_language = $woocommerce_wpml->products->get_original_product_language( $post_id );
59
+ $original_product_id = apply_filters( 'translate_object_id', $post_id, 'product', true, $original_product_language);
60
+
61
+ }
62
+
63
+ $product_trid = $sitepress->get_element_trid( $original_product_id, 'post_product' );
64
+ $product_translations = $sitepress->get_element_translations( $product_trid, 'post_product' );
65
+
66
+ foreach ($product_translations as $product_translation) {
67
+
68
+ if ( empty( $product_translation->original ) ) {
69
+
70
+ $trnsl_tour_tabs_meta = get_post_meta( $product_translation->element_id, 'tour_tabs_meta', true );
71
+
72
+ $trnsl_tour_tabs_meta['tour_badge'] = $tour_tabs_meta['tour_badge'];
73
+
74
+ update_post_meta( $product_translation->element_id, '_bto_data', $trnsl_tour_tabs_meta);
75
+
76
+ }
77
+
78
+ }
79
+
80
+ add_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
81
+
82
+ }
83
+
84
+ }
85
+
86
+ function custom_box_html($obj, $product_id, $data)
87
+ {
88
+
89
+ if ( $tour_tabs_meta = get_post_meta( $product_id, 'tour_tabs_meta', true ) ) {
90
+
91
+ $tour_section = new WPML_Editor_UI_Field_Section( __('Tour Data', 'woocommerce-multilingual'));
92
+
93
+ $divider = true;
94
+
95
+ foreach( $tour_tabs_meta['tabs'] as $tour_tab_id => $tour_tab_meta) {
96
+
97
+ $group = new WPML_Editor_UI_Field_Group('', $divider);
98
+ $composite_field = new WPML_Editor_UI_Single_Line_Field('adventure_tour_' . $tour_tab_id . '_title', __('Title', 'woocommerce-multilingual'), $data, false);
99
+ $group->add_field($composite_field);
100
+ $composite_field = new WPML_Editor_UI_Single_Line_Field('adventure_tour_' . $tour_tab_id . '_content', __('Content', 'woocommerce-multilingual'), $data, false);
101
+ $group->add_field($composite_field);
102
+ $tour_section->add_field($group);
103
+
104
+ }
105
+
106
+ if ( !empty( $tour_tabs_meta['tabs'] ) ) {
107
+ $obj->add_field( $tour_section );
108
+ }
109
+
110
+ }
111
+
112
+ }
113
+
114
+ function custom_box_html_data($data, $product_id, $translation, $lang){
115
+
116
+ if ( $tour_tabs_meta = get_post_meta( $product_id, 'tour_tabs_meta', true ) ) {
117
+
118
+ foreach ( $tour_tabs_meta['tabs'] as $tour_tab_id => $tour_tab_meta ) {
119
+ $data['adventure_tour_' . $tour_tab_id . '_title'] = array('original' => $tour_tab_meta['title'] );
120
+ $data['adventure_tour_' . $tour_tab_id . '_content'] = array('original' => $tour_tab_meta['content'] );
121
+ }
122
+
123
+ if ($translation) {
124
+ $translated_tour_tabs_meta = get_post_meta( $translation->ID, 'tour_tabs_meta', true );
125
+
126
+ if( $translated_tour_tabs_meta ){
127
+ foreach ( $translated_tour_tabs_meta['tabs'] as $tour_tab_id => $tour_tab_meta) {
128
+ $data['adventure_tour_' . $tour_tab_id . '_title']['translation'] = $tour_tab_meta['title'];
129
+ $data['adventure_tour_' . $tour_tab_id . '_content']['translation'] = $tour_tab_meta['content'];
130
+ }
131
+ }
132
+ }
133
+
134
+ }
135
+
136
+ return $data;
137
+ }
138
+
139
+ function tour_data_update( $original_product_id, $product_id, $data)
140
+ {
141
+
142
+ $tour_tabs_meta = get_post_meta( $original_product_id, 'tour_tabs_meta', true );
143
+
144
+ if( isset( $tour_tabs_meta['tabs'] ) && is_array( $tour_tabs_meta['tabs'] ) ){
145
+ foreach ( $tour_tabs_meta['tabs'] as $tour_tab_id => $tour_tab_meta ) {
146
+
147
+ if (!empty($data[md5('adventure_tour_' . $tour_tab_id . '_title')])) {
148
+ $tour_tabs_meta['tabs'][$tour_tab_id]['title'] = $data[md5('adventure_tour_' . $tour_tab_id . '_title')];
149
+ }
150
+
151
+ if (!empty($data[md5('adventure_tour_' . $tour_tab_id . '_content')])) {
152
+ $tour_tabs_meta['tabs'][$tour_tab_id]['content'] = $data[md5('adventure_tour_' . $tour_tab_id . '_content')];
153
+ }
154
+ }
155
+ remove_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
156
+
157
+ update_post_meta($product_id, 'tour_tabs_meta', $tour_tabs_meta);
158
+
159
+ add_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
160
+ }
161
+
162
+ }
163
+
164
+ function append_tour_data_translation_package($package, $post)
165
+ {
166
+
167
+ if ($post->post_type == 'product') {
168
+
169
+ $tour_tabs_meta = get_post_meta( $post->ID, 'tour_tabs_meta', true );
170
+
171
+ if ($tour_tabs_meta) {
172
+
173
+ $fields = array('title', 'content');
174
+
175
+ foreach ( $tour_tabs_meta['tabs'] as $tour_tab_id => $tour_tab_meta) {
176
+
177
+ foreach ($fields as $field) {
178
+ if (!empty($tour_tab_meta[$field])) {
179
+
180
+ $package['contents']['wc_adventure_tour:' . $tour_tab_id . ':' . $field] = array(
181
+ 'translate' => 1,
182
+ 'data' => $this->tp->encode_field_data($tour_tab_meta[$field], 'base64'),
183
+ 'format' => 'base64'
184
+ );
185
+
186
+ }
187
+ }
188
+
189
+ }
190
+
191
+ }
192
+
193
+ }
194
+
195
+ return $package;
196
+
197
+ }
198
+
199
+ function save_tour_data_translation($post_id, $data, $job)
200
+ {
201
+
202
+
203
+ $translated_tour_data = array();
204
+ foreach ($data as $value) {
205
+
206
+ if (preg_match('/wc_adventure_tour:([0-9]+):(.+)/', $value['field_type'], $matches)) {
207
+
208
+ $tour_tab_id = $matches[1];
209
+ $field = $matches[2];
210
+
211
+ $translated_tour_data[$tour_tab_id][$field] = $value['data'];
212
+
213
+ }
214
+
215
+ }
216
+
217
+ if ($translated_tour_data) {
218
+
219
+ $tour_tabs_meta = get_post_meta( $job->original_doc_id, 'tour_tabs_meta', true );
220
+
221
+
222
+ foreach ( $tour_tabs_meta['tabs'] as $tour_tab_id => $tour_tab_meta) {
223
+
224
+ if (isset($translated_tour_data[$tour_tab_id]['title'])) {
225
+ $tour_tabs_meta['tabs'][$tour_tab_id]['title'] = $translated_tour_data[$tour_tab_id]['title'];
226
+ }
227
+
228
+ if (isset($translated_tour_data[$tour_tab_id]['content'])) {
229
+ $tour_tabs_meta['tabs'][$tour_tab_id]['content'] = $translated_tour_data[$tour_tab_id]['content'];
230
+ }
231
+ }
232
+
233
+ }
234
+ remove_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
235
+ update_post_meta($post_id, 'tour_tabs_meta', $tour_tabs_meta);
236
+ add_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
237
+
238
+ }
239
+
240
+ function load_assets(){
241
+ global $pagenow, $woocommerce_wpml;
242
+
243
+ if( $pagenow == 'post.php' || $pagenow == 'post-new.php' ){
244
+ wp_register_script( 'wcml-adventure-tours', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-adventure-tours.js', array( 'jquery' ), WCML_VERSION );
245
+ wp_enqueue_script( 'wcml-adventure-tours' );
246
+ }
247
+ }
248
+
249
+ function add_custom_prices_block( $product_id ){
250
+ global $woocommerce_wpml;
251
+
252
+ if( $product_id != 'new' ){
253
+ $currencies = $woocommerce_wpml->multi_currency->get_currencies();
254
+ $tour_booking_periods = get_post_meta( $product_id, 'tour_booking_periods', true );
255
+ $custom_periods_prices = get_post_meta( $product_id, 'custom_booking_periods_prices', true );
256
+ if( $tour_booking_periods ){
257
+ foreach( $tour_booking_periods as $per_key => $tour_booking_period ){
258
+ foreach( $currencies as $key => $currency ){
259
+
260
+ $value = isset($custom_periods_prices[ $per_key ][ $key ]) ? $custom_periods_prices[ $per_key ][ $key ]: '';
261
+
262
+ echo '<div class="wcml_custom_cost_field" data-tour="'.$per_key.'" style="display: none;">';
263
+ echo '<div>'.get_woocommerce_currency_symbol($key).'</div>';
264
+ echo '<input type="text" class="wc_input_price" style="width: 60px;" name="tour_spec_price['.$per_key.']['.$key.']" value="'.$value.'" />';
265
+ echo '</div>';
266
+ }
267
+ }
268
+ }
269
+
270
+ echo '<div class="wcml_custom_cost_field_empty" style="display: none;">';
271
+ echo '<div></div>';
272
+ echo '<input type="text" class="wc_input_price" style="width: 60px;" name="tour_spec_price" value="" />';
273
+ echo '</div>';
274
+ }
275
+ }
276
+
277
+ function save_custom_costs( $post_id ){
278
+ global $woocommerce_wpml;
279
+
280
+ $tour_spec_price = array();
281
+ $currencies = $woocommerce_wpml->multi_currency->get_currencies();
282
+
283
+ if( isset( $_POST[ 'tour_spec_price' ] ) && is_array( $_POST[ 'tour_spec_price' ] ) ) {
284
+
285
+ foreach( $_POST[ 'tour_spec_price' ] as $per_key => $costs ) {
286
+
287
+ foreach( $currencies as $code => $currency ) {
288
+
289
+ $tour_spec_price[ $per_key ][ $code ] = $costs[ $code ];
290
+
291
+ }
292
+ }
293
+
294
+ update_post_meta( $post_id, 'custom_booking_periods_prices', $tour_spec_price );
295
+ }
296
+ }
297
+
298
+ function product_price_filter( $value, $object_id, $meta_key, $single ){
299
+ global $woocommerce_wpml;
300
+
301
+ if(
302
+ get_post_type( $object_id ) == 'product' &&
303
+ $meta_key == 'tour_booking_periods' &&
304
+ $woocommerce_wpml->settings[ 'enable_multi_currency' ] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
305
+ !is_admin() &&
306
+ ( $currency = $woocommerce_wpml->multi_currency->get_client_currency() ) != get_option( 'woocommerce_currency' )
307
+ ) {
308
+
309
+ remove_filter( 'get_post_metadata', array( $this, 'product_price_filter' ), 9, 4 );
310
+
311
+ $original_language = $woocommerce_wpml->products->get_original_product_language( $object_id );
312
+ $original_product = apply_filters( 'translate_object_id', $object_id, 'product', true, $original_language );
313
+
314
+ if ( get_post_meta( $original_product, '_wcml_custom_prices_status' ) ) {
315
+ $custom_periods_prices = get_post_meta( $object_id, 'custom_booking_periods_prices', true );
316
+ $tours_data = get_post_meta( $object_id, 'tour_booking_periods', true );
317
+ if( $tours_data ){
318
+ foreach( $tours_data as $key => $periods ){
319
+ if( isset( $custom_periods_prices[ $key ][ $currency ] ) ){
320
+ $tours_data[ $key ][ 'spec_price' ] = $custom_periods_prices[ $key ][ $currency ];
321
+ }
322
+ }
323
+
324
+ if( $single ){
325
+ $value[0] = $tours_data;
326
+ }else{
327
+ $value = $tours_data;
328
+ }
329
+
330
+ }
331
+ }
332
+ add_filter( 'get_post_metadata', array( $this, 'product_price_filter' ), 9, 4 );
333
+ }
334
+
335
+ return $value;
336
+ }
337
+
338
+ function add_tour_tax_id( $variation_term_taxonomy_ids ){
339
+ global $wpdb;
340
+ $tour_taxonomy_id = $wpdb->get_var( "SELECT tt.term_taxonomy_id FROM {$wpdb->terms} AS t LEFT JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id WHERE t.name = 'tour' AND tt.taxonomy = 'product_type'" );
341
+ $variation_term_taxonomy_ids[] = $tour_taxonomy_id;
342
+
343
+ return $variation_term_taxonomy_ids;
344
+
345
+ }
346
+
347
+ function is_variable_tour( $is_variable, $product_id ){
348
+
349
+ if( $is_variable && get_post_meta( $product_id, '_variable_tour', true ) == 'yes' ){
350
+ $is_variable = true;
351
+ }
352
+
353
+ return $is_variable;
354
+ }
355
+
356
+ function is_attributes_page( $is_attributes_page ){
357
+
358
+ if( isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'product_attributes_extended' && isset( $_GET[ 'post_type' ] ) && $_GET[ 'post_type' ] == 'product' ){
359
+ $is_attributes_page = true;
360
+ }
361
+
362
+ return $is_attributes_page;
363
+ }
364
+
365
+ }
compatibility/class-wcml-ajax-layered-nav-widget.php CHANGED
@@ -1,38 +1,38 @@
1
- <?php
2
-
3
- /**
4
- Class for WooCommerce Advanced Ajax Layered Navigation
5
- */
6
-
7
- class WCML_Ajax_Layered_Nav_Widget {
8
- function __construct() {
9
- add_filter('wc_ajax_layered_nav_sizeselector_term_id', array($this, 'wc_ajax_layered_nav_sizeselector_term_id'));
10
- add_filter('wc_ajax_layered_nav_query_editor', array($this, 'wc_ajax_layered_nav_query_editor'),10,3);
11
- }
12
-
13
- function wc_ajax_layered_nav_sizeselector_term_id($term_id) {
14
- $ulanguage_code = apply_filters( 'wpml_default_language', null );
15
- $term_id = apply_filters( 'wpml_object_id', $term_id, 'category', true, $ulanguage_code );
16
- return $term_id;
17
- }
18
-
19
- function wc_ajax_layered_nav_query_editor($posts, $attribute, $value){
20
- $posts = get_posts(
21
- array(
22
- 'post_type' => 'product',
23
- 'numberposts' => -1,
24
- 'post_status' => 'publish',
25
- 'fields' => 'ids',
26
- 'no_found_rows' => true,
27
- 'tax_query' => array(
28
- array(
29
- 'taxonomy' => $attribute,
30
- 'terms' => $value,
31
- 'field' => 'term_id'
32
- )
33
- )
34
- )
35
- );
36
- return $posts;
37
- }
38
- }
1
+ <?php
2
+
3
+ /**
4
+ Class for WooCommerce Advanced Ajax Layered Navigation
5
+ */
6
+
7
+ class WCML_Ajax_Layered_Nav_Widget {
8
+ function __construct() {
9
+ add_filter('wc_ajax_layered_nav_sizeselector_term_id', array($this, 'wc_ajax_layered_nav_sizeselector_term_id'));
10
+ add_filter('wc_ajax_layered_nav_query_editor', array($this, 'wc_ajax_layered_nav_query_editor'),10,3);
11
+ }
12
+
13
+ function wc_ajax_layered_nav_sizeselector_term_id($term_id) {
14
+ $ulanguage_code = apply_filters( 'wpml_default_language', null );
15
+ $term_id = apply_filters( 'wpml_object_id', $term_id, 'category', true, $ulanguage_code );
16
+ return $term_id;
17
+ }
18
+
19
+ function wc_ajax_layered_nav_query_editor($posts, $attribute, $value){
20
+ $posts = get_posts(
21
+ array(
22
+ 'post_type' => 'product',
23
+ 'numberposts' => -1,
24
+ 'post_status' => 'publish',
25
+ 'fields' => 'ids',
26
+ 'no_found_rows' => true,
27
+ 'tax_query' => array(
28
+ array(
29
+ 'taxonomy' => $attribute,
30
+ 'terms' => $value,
31
+ 'field' => 'term_id'
32
+ )
33
+ )
34
+ )
35
+ );
36
+ return $posts;
37
+ }
38
+ }
compatibility/class-wcml-bookings.php CHANGED
@@ -1,1882 +1,1912 @@
1
- <?php
2
-
3
- class WCML_Bookings{
4
-
5
- public $tp;
6
-
7
- function __construct(){
8
-
9
- add_action( 'woocommerce_bookings_after_booking_base_cost' , array( $this, 'wcml_price_field_after_booking_base_cost' ) );
10
- add_action( 'woocommerce_bookings_after_booking_block_cost' , array( $this, 'wcml_price_field_after_booking_block_cost' ) );
11
- add_action( 'woocommerce_bookings_after_display_cost' , array( $this, 'wcml_price_field_after_display_cost' ) );
12
- add_action( 'woocommerce_bookings_after_booking_pricing_base_cost' , array( $this, 'wcml_price_field_after_booking_pricing_base_cost' ), 10, 2 );
13
- add_action( 'woocommerce_bookings_after_booking_pricing_cost' , array( $this, 'wcml_price_field_after_booking_pricing_cost' ), 10, 2 );
14
- add_action( 'woocommerce_bookings_after_person_cost' , array( $this, 'wcml_price_field_after_person_cost' ) );
15
- add_action( 'woocommerce_bookings_after_person_block_cost' , array( $this, 'wcml_price_field_after_person_block_cost' ) );
16
- add_action( 'woocommerce_bookings_after_resource_cost' , array( $this, 'wcml_price_field_after_resource_cost' ), 10, 2 );
17
- add_action( 'woocommerce_bookings_after_resource_block_cost' , array( $this, 'wcml_price_field_after_resource_block_cost' ), 10, 2 );
18
- add_action( 'woocommerce_bookings_after_bookings_pricing' , array( $this, 'after_bookings_pricing' ) );
19
-
20
- add_action( 'admin_footer', array( $this, 'load_assets' ) );
21
-
22
- add_action( 'save_post', array( $this, 'save_custom_costs' ), 110, 2 );
23
- add_action( 'wcml_before_sync_product_data', array( $this, 'sync_bookings' ), 10, 3 );
24
- add_action( 'wcml_before_sync_product', array( $this, 'sync_booking_data' ), 10, 2 );
25
-
26
- add_action( 'updated_post_meta', array( $this, 'update_wc_booking_costs' ), 10, 4 );
27
-
28
- add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
29
- add_filter( 'woocommerce_bookings_process_cost_rules_cost', array( $this, 'wc_bookings_process_cost_rules_cost' ), 10, 3 );
30
- add_filter( 'woocommerce_bookings_process_cost_rules_base_cost', array( $this, 'wc_bookings_process_cost_rules_base_cost' ), 10, 3 );
31
- add_filter( 'woocommerce_bookings_process_cost_rules_override_block', array( $this, 'wc_bookings_process_cost_rules_override_block_cost' ), 10, 3 );
32
-
33
- add_filter( 'wcml_multi_currency_is_ajax', array( $this, 'wcml_multi_currency_is_ajax' ) );
34
-
35
- add_filter( 'wcml_cart_contents_not_changed', array( $this, 'filter_bundled_product_in_cart_contents' ), 10, 3 );
36
-
37
- add_action( 'woocommerce_bookings_after_create_booking_page', array( $this, 'booking_currency_dropdown' ) );
38
- add_action( 'init', array( $this, 'set_booking_currency') );
39
- add_action( 'wp_ajax_wcml_booking_set_currency', array( $this, 'set_booking_currency_ajax' ) );
40
- add_action( 'woocommerce_bookings_create_booking_page_add_order_item', array( $this, 'set_order_currency_on_create_booking_page' ) );
41
- add_filter( 'woocommerce_currency_symbol', array( $this, 'filter_booking_currency_symbol' ) );
42
- add_filter( 'get_booking_products_args', array( $this, 'filter_get_booking_products_args' ) );
43
- add_filter( 'wcml_filter_currency_position', array( $this, 'create_booking_page_client_currency' ) );
44
-
45
- add_filter( 'wcml_client_currency', array( $this, 'create_booking_page_client_currency' ) );
46
-
47
- add_filter( 'wcml_custom_box_html', array( $this, 'custom_box_html'), 10, 3 );
48
- add_filter( 'wcml_product_content_fields', array( $this, 'product_content_fields'), 10, 2 );
49
- add_filter( 'wcml_product_content_fields_label', array( $this, 'product_content_fields_label'), 10, 2 );
50
- add_filter( 'wcml_check_is_single', array( $this, 'show_custom_blocks_for_resources_and_persons'), 10, 3 );
51
- add_filter( 'wcml_product_content_exception', array( $this, 'remove_custom_fields_to_translate' ), 10, 3 );
52
- add_filter( 'wcml_product_content_label', array( $this, 'product_content_resource_label' ), 10, 2 );
53
- add_action( 'wcml_update_extra_fields', array( $this, 'wcml_products_tab_sync_resources_and_persons'), 10, 3 );
54
-
55
- add_action( 'woocommerce_new_booking', array( $this, 'duplicate_booking_for_translations') );
56
-
57
- $bookings_statuses = array( 'unpaid', 'pending-confirmation', 'confirmed', 'paid', 'cancelled', 'complete', 'in-cart', 'was-in-cart' );
58
- foreach( $bookings_statuses as $status ){
59
- add_action('woocommerce_booking_' . $status, array( $this, 'update_status_for_translations' ) );
60
- }
61
-
62
- add_filter( 'parse_query', array( $this, 'booking_filters_query' ) );
63
- add_filter('woocommerce_bookings_in_date_range_query', array($this, 'bookings_in_date_range_query'));
64
- add_action( 'before_delete_post', array( $this, 'delete_bookings' ) );
65
- add_action( 'wp_trash_post', array( $this, 'trash_bookings' ) );
66
-
67
- if( is_admin() ){
68
-
69
- $this->tp = new WPML_Element_Translation_Package;
70
-
71
- add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_persons_to_translation_package' ), 10, 2 );
72
- add_action( 'wpml_translation_job_saved', array( $this, 'save_person_translation' ), 10, 3 );
73
-
74
- add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_resources_to_translation_package' ), 10, 2 );
75
- add_action( 'wpml_translation_job_saved', array( $this, 'save_resource_translation' ), 10, 3 );
76
- }
77
-
78
- $this->clear_transient_fields();
79
-
80
- }
81
-
82
- function wcml_price_field_after_booking_base_cost( $post_id ){
83
-
84
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_cost' );
85
-
86
- }
87
-
88
- function wcml_price_field_after_booking_block_cost( $post_id ){
89
-
90
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_base_cost' );
91
-
92
- }
93
-
94
- function wcml_price_field_after_display_cost( $post_id ){
95
-
96
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_display_cost' );
97
-
98
- }
99
-
100
- function wcml_price_field_after_booking_pricing_base_cost( $pricing, $post_id ){
101
-
102
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_pricing_base_cost', $pricing );
103
-
104
- }
105
-
106
- function wcml_price_field_after_booking_pricing_cost( $pricing, $post_id ){
107
-
108
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_pricing_cost', $pricing );
109
-
110
- }
111
-
112
- function wcml_price_field_after_person_cost( $person_type_id ){
113
-
114
- $this->echo_wcml_price_field( $person_type_id, 'wcml_wc_booking_person_cost', false, false );
115
-
116
- }
117
-
118
- function wcml_price_field_after_person_block_cost( $person_type_id ){
119
-
120
- $this->echo_wcml_price_field( $person_type_id, 'wcml_wc_booking_person_block_cost', false, false );
121
-
122
- }
123
-
124
- function wcml_price_field_after_resource_cost( $resource_id, $post_id ){
125
-
126
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_resource_cost', false, true, $resource_id );
127
-
128
- }
129
-
130
- function wcml_price_field_after_resource_block_cost( $resource_id, $post_id ){
131
-
132
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_resource_block_cost', false, true, $resource_id );
133
-
134
- }
135
-
136
- function echo_wcml_price_field( $post_id, $field, $pricing = false, $check = true, $resource_id = false ){
137
- global $woocommerce_wpml;
138
-
139
- if( ( !$check || $woocommerce_wpml->products->is_original_product( $post_id ) ) && $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
140
-
141
- $currencies = $woocommerce_wpml->multi_currency_support->get_currencies();
142
-
143
- $wc_currencies = get_woocommerce_currencies();
144
-
145
- echo '<div class="wcml_custom_cost_field" >';
146
-
147
- foreach($currencies as $currency_code => $currency){
148
-
149
- switch( $field ){
150
- case 'wcml_wc_booking_cost':
151
- woocommerce_wp_text_input( array( 'id' => 'wcml_wc_booking_cost', 'class'=>'wcml_bookings_custom_price', 'name' => 'wcml_wc_booking_cost['.$currency_code.']', 'label' => get_woocommerce_currency_symbol($currency_code), 'description' => __( 'One-off cost for the booking as a whole.', 'woocommerce-bookings' ), 'value' => get_post_meta( $post_id, '_wc_booking_cost_'.$currency_code, true ), 'type' => 'number', 'desc_tip' => true, 'custom_attributes' => array(
152
- 'min' => '',
153
- 'step' => '0.01'
154
- ) ) );
155
- break;
156
- case 'wcml_wc_booking_base_cost':
157
- woocommerce_wp_text_input( array( 'id' => 'wcml_wc_booking_base_cost', 'class'=>'wcml_bookings_custom_price', 'name' => 'wcml_wc_booking_base_cost['.$currency_code.']', 'label' => get_woocommerce_currency_symbol($currency_code), 'description' => __( 'This is the cost per block booked. All other costs (for resources and persons) are added to this.', 'woocommerce-bookings' ), 'value' => get_post_meta( $post_id, '_wc_booking_base_cost_'.$currency_code, true ), 'type' => 'number', 'desc_tip' => true, 'custom_attributes' => array(
158
- 'min' => '',
159
- 'step' => '0.01'
160
- ) ) );
161
- break;
162
- case 'wcml_wc_display_cost':
163
- woocommerce_wp_text_input( array( 'id' => 'wcml_wc_display_cost', 'class'=>'wcml_bookings_custom_price', 'name' => 'wcml_wc_display_cost['.$currency_code.']', 'label' => get_woocommerce_currency_symbol($currency_code), 'description' => __( 'The cost is displayed to the user on the frontend. Leave blank to have it calculated for you. If a booking has varying costs, this will be prefixed with the word "from:".', 'woocommerce-bookings' ), 'value' => get_post_meta( $post_id, '_wc_display_cost_'.$currency_code, true ), 'type' => 'number', 'desc_tip' => true, 'custom_attributes' => array(
164
- 'min' => '',
165
- 'step' => '0.01'
166
- ) ) );
167
- break;
168
-
169
- case 'wcml_wc_booking_pricing_base_cost':
170
-
171
- if( isset( $pricing[ 'base_cost_'.$currency_code ] ) ){
172
- $value = $pricing[ 'base_cost_'.$currency_code ];
173
- }else{
174
- $value = '';
175
- }
176
-
177
- echo '<div class="wcml_bookings_range_block" >';
178
- echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
179
- echo '<input type="number" step="0.01" name="wcml_wc_booking_pricing_base_cost['.$currency_code.'][]" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
180
- echo '</div>';
181
- break;
182
-
183
- case 'wcml_wc_booking_pricing_cost':
184
-
185
- if( isset( $pricing[ 'cost_'.$currency_code ] ) ){
186
- $value = $pricing[ 'cost_'.$currency_code ];
187
- }else{
188
- $value = '';
189
- }
190
-
191
- echo '<div class="wcml_bookings_range_block" >';
192
- echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
193
- echo '<input type="number" step="0.01" name="wcml_wc_booking_pricing_cost['.$currency_code.'][]" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
194
- echo '</div>';
195
- break;
196
-
197
- case 'wcml_wc_booking_person_cost':
198
-
199
- $value = get_post_meta( $post_id, 'cost_'.$currency_code, true );
200
-
201
- echo '<div class="wcml_bookings_person_block" >';
202
- echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
203
- echo '<input type="number" step="0.01" name="wcml_wc_booking_person_cost['.$post_id.']['.$currency_code.']" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
204
- echo '</div>';
205
- break;
206
-
207
- case 'wcml_wc_booking_person_block_cost':
208
-
209
- $value = get_post_meta( $post_id, 'block_cost_'.$currency_code, true );
210
-
211
- echo '<div class="wcml_bookings_person_block" >';
212
- echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
213
- echo '<input type="number" step="0.01" name="wcml_wc_booking_person_block_cost['.$post_id.']['.$currency_code.']" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
214
- echo '</div>';
215
- break;
216
-
217
- case 'wcml_wc_booking_resource_cost':
218
-
219
- $resource_base_costs = maybe_unserialize( get_post_meta( $post_id, '_resource_base_costs', true ) );
220
-
221
- if( isset( $resource_base_costs[ 'custom_costs' ][ $currency_code ][ $resource_id ] ) ){
222
- $value = $resource_base_costs[ 'custom_costs' ][ $currency_code ][ $resource_id ];
223
- }else{
224
- $value = '';
225
- }
226
-
227
- echo '<div class="wcml_bookings_resource_block" >';
228
- echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
229
- echo '<input type="number" step="0.01" name="wcml_wc_booking_resource_cost['.$resource_id.']['.$currency_code.']" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
230
- echo '</div>';
231
- break;
232
-
233
- case 'wcml_wc_booking_resource_block_cost':
234
-
235
- $resource_block_costs = maybe_unserialize( get_post_meta( $post_id, '_resource_block_costs', true ) );
236
-
237
- if( isset( $resource_block_costs[ 'custom_costs' ][ $currency_code ][ $resource_id ] ) ){
238
- $value = $resource_block_costs[ 'custom_costs' ][ $currency_code ][ $resource_id ];
239
- }else{
240
- $value = '';
241
- }
242
-
243
- echo '<div class="wcml_bookings_resource_block" >';
244
- echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
245
- echo '<input type="number" step="0.01" name="wcml_wc_booking_resource_block_cost['.$resource_id.']['.$currency_code.']" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
246
- echo '</div>';
247
- break;
248
-
249
- default:
250
- break;
251
-
252
- }
253
-
254
- }
255
-
256
- echo '</div>';
257
-
258
- }
259
- }
260
-
261
- function after_bookings_pricing( $post_id ){
262
- global $woocommerce_wpml;
263
-
264
- if( in_array( 'booking', wp_get_post_terms( $post_id, 'product_type', array( "fields" => "names" ) ) ) && $woocommerce_wpml->products->is_original_product( $post_id ) && $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
265
-
266
- $custom_costs_status = get_post_meta( $post_id, '_wcml_custom_costs_status', true );
267
-
268
- $checked = !$custom_costs_status ? 'checked="checked"' : ' ';
269
-
270
- echo '<div class="wcml_custom_costs">';
271
-
272
- echo '<input type="radio" name="_wcml_custom_costs" id="wcml_custom_costs_auto" value="0" class="wcml_custom_costs_input" '. $checked .' />';
273
- echo '<label for="wcml_custom_costs_auto">'. __('Calculate costs in other currencies automatically', 'woocommerce-multilingual') .'</label>';
274
-
275
- $checked = $custom_costs_status == 1 ? 'checked="checked"' : ' ';
276
-
277
- echo '<input type="radio" name="_wcml_custom_costs" value="1" id="wcml_custom_costs_manually" class="wcml_custom_costs_input" '. $checked .' />';
278
- echo '<label for="wcml_custom_costs_manually">'. __('Set costs in other currencies manually', 'woocommerce-multilingual') .'</label>';
279
-
280
- wp_nonce_field( 'wcml_save_custom_costs', '_wcml_custom_costs_nonce' );
281
-
282
- echo '</div>';
283
- }
284
-
285
- }
286
-
287
- function save_custom_costs( $post_id, $post ){
288
- global $woocommerce_wpml;
289
-
290
- $nonce = filter_input( INPUT_POST, '_wcml_custom_costs_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
291
-
292
- if( isset( $_POST['_wcml_custom_costs'] ) && isset( $nonce ) && wp_verify_nonce( $nonce, 'wcml_save_custom_costs' ) ){
293
-
294
- update_post_meta( $post_id, '_wcml_custom_costs_status', $_POST['_wcml_custom_costs'] );
295
-
296
- if( $_POST['_wcml_custom_costs'] == 1 ){
297
-
298
- $currencies = $woocommerce_wpml->multi_currency_support->get_currencies();
299
-
300
- foreach( $currencies as $code => $currency ){
301
-
302
- $wc_booking_cost = $_POST[ 'wcml_wc_booking_cost' ][ $code ];
303
- update_post_meta( $post_id, '_wc_booking_cost_'.$code, $wc_booking_cost );
304
-
305
- $wc_booking_base_cost = $_POST[ 'wcml_wc_booking_base_cost' ][ $code ];
306
- update_post_meta( $post_id, '_wc_booking_base_cost_'.$code, $wc_booking_base_cost );
307
-
308
- $wc_display_cost = $_POST[ 'wcml_wc_display_cost' ][ $code ];
309
- update_post_meta( $post_id, '_wc_display_cost_'.$code, $wc_display_cost );
310
-
311
- }
312
-
313
- //person costs
314
- if( isset( $_POST[ 'wcml_wc_booking_person_cost' ] ) ) {
315
-
316
- foreach ($_POST['wcml_wc_booking_person_cost'] as $person_id => $costs) {
317
-
318
- foreach ($currencies as $code => $currency) {
319
-
320
- $wc_booking_person_cost = $costs[$code];
321
- update_post_meta($person_id, 'cost_' . $code, $wc_booking_person_cost);
322
-
323
- }
324
-
325
- }
326
-
327
- }
328
-
329
- if( isset( $_POST[ 'wcml_wc_booking_person_cost' ] ) ){
330
-
331
- foreach( $_POST[ 'wcml_wc_booking_person_block_cost' ] as $person_id => $costs ){
332
-
333
- foreach( $currencies as $code => $currency ){
334
-
335
- $wc_booking_person_block_cost = $costs[ $code ];
336
- update_post_meta( $person_id, 'block_cost_'.$code, $wc_booking_person_block_cost );
337
-
338
- }
339
-
340
- }
341
-
342
- }
343
-
344
- }
345
- }
346
-
347
- }
348
-
349
- // sync existing product bookings for translations
350
- function sync_bookings( $original_product_id, $product_id, $lang ){
351
- global $wpdb;
352
-
353
- $all_bookings_for_product = $wpdb->get_results( $wpdb->prepare( "SELECT post_id as id FROM $wpdb->postmeta WHERE meta_key = '_booking_product_id' AND meta_value = %d", $original_product_id ) );
354
-
355
- foreach($all_bookings_for_product as $booking ){
356
- $check_if_exists = $wpdb->get_row( $wpdb->prepare( "SELECT pm3.* FROM {$wpdb->postmeta} AS pm1
357
- LEFT JOIN {$wpdb->postmeta} AS pm2 ON pm1.post_id = pm2.post_id
358
- LEFT JOIN {$wpdb->postmeta} AS pm3 ON pm1.post_id = pm3.post_id
359
- WHERE pm1.meta_key = '_booking_duplicate_of' AND pm1.meta_value = %s AND pm2.meta_key = '_language_code' AND pm2.meta_value = %s AND pm3.meta_key = '_booking_product_id'"
360
- , $booking->id, $lang ) );
361
-
362
- if( is_null( $check_if_exists ) ){
363
- $this->duplicate_booking_for_translations( $booking->id, $lang );
364
- }elseif( $check_if_exists->meta_value === '' ){
365
- update_post_meta( $check_if_exists->post_id, '_booking_product_id', $this->get_translated_booking_product_id( $booking->id, $lang ) );
366
- update_post_meta( $check_if_exists->post_id, '_booking_resource_id', $this->get_translated_booking_resource_id( $booking->id, $lang ) );
367
- update_post_meta( $check_if_exists->post_id, '_booking_persons', $this->get_translated_booking_persons_ids( $booking->id, $lang ) );
368
- }
369
- }
370
-
371
-
372
- }
373
-
374
- function sync_booking_data( $original_product_id, $current_product_id ){
375
-
376
- if( has_term( 'booking', 'product_type', $original_product_id ) ){
377
- global $wpdb, $sitepress, $pagenow, $iclTranslationManagement;
378
-
379
- // get language code
380
- $language_details = $sitepress->get_element_language_details( $original_product_id, 'post_product' );
381
- if ( $pagenow == 'admin.php' && empty( $language_details ) ) {
382
- //translation editor support: sidestep icl_translations_cache
383
- $language_details = $wpdb->get_row( $wpdb->prepare( "SELECT element_id, trid, language_code, source_language_code FROM {$wpdb->prefix}icl_translations WHERE element_id = %d AND element_type = 'post_product'", $original_product_id ) );
384
- }
385
- if ( empty( $language_details ) ) {
386
- return;
387
- }
388
-
389
- // pick posts to sync
390
- $posts = array();
391
- $translations = $sitepress->get_element_translations( $language_details->trid, 'post_product' );
392
- foreach ( $translations as $translation ) {
393
-
394
- if ( !$translation->original ) {
395
- $posts[ $translation->element_id ] = $translation;
396
- }
397
- }
398
-
399
- foreach ( $posts as $post_id => $translation ) {
400
-
401
- $trn_lang = $sitepress->get_language_for_element( $post_id, 'post_product' );
402
-
403
- //sync_resources
404
- $this->sync_resources( $original_product_id, $post_id, $trn_lang );
405
-
406
- //sync_persons
407
- $this->sync_persons( $original_product_id, $post_id, $trn_lang );
408
- }
409
-
410
- }
411
-
412
- }
413
-
414
- function sync_resources( $original_product_id, $trnsl_product_id, $lang_code, $duplicate = true ){
415
- global $wpdb;
416
-
417
- $orig_resources = $wpdb->get_results( $wpdb->prepare( "SELECT resource_id, sort_order FROM {$wpdb->prefix}wc_booking_relationships WHERE product_id = %d", $original_product_id ) );
418
-
419
- $trnsl_product_resources = $wpdb->get_col( $wpdb->prepare( "SELECT resource_id FROM {$wpdb->prefix}wc_booking_relationships WHERE product_id = %d", $trnsl_product_id ) );
420
-
421
- foreach ($orig_resources as $resource) {
422
-
423
- $trns_resource_id = apply_filters( 'translate_object_id', $resource->resource_id, 'bookable_resource', false, $lang_code );
424
-
425
- if ( !is_null( $trns_resource_id ) && in_array( $trns_resource_id, $trnsl_product_resources ) ) {
426
-
427
- if ( ( $key = array_search( $trns_resource_id, $trnsl_product_resources ) ) !== false ) {
428
-
429
- unset($trnsl_product_resources[$key]);
430
-
431
- $wpdb->update(
432
- $wpdb->prefix . 'wc_booking_relationships',
433
- array(
434
- 'sort_order' => $resource->sort_order
435
- ),
436
- array(
437
- 'product_id' => $trnsl_product_id,
438
- 'resource_id' => $trns_resource_id
439
- )
440
- );
441
-
442
- update_post_meta( $trns_resource_id, 'qty', get_post_meta( $resource->resource_id, 'qty', true ) );
443
- update_post_meta( $trns_resource_id, '_wc_booking_availability', get_post_meta( $resource->resource_id, '_wc_booking_availability', true ) );
444
-
445
- }
446
-
447
- } else {
448
-
449
- if( $duplicate ){
450
-
451
- $trns_resource_id = $this->duplicate_resource( $trnsl_product_id, $resource, $lang_code );
452
-
453
- }else{
454
-
455
- continue;
456
-
457
- }
458
-
459
-
460
- }
461
-
462
- }
463
-
464
- foreach ($trnsl_product_resources as $trnsl_product_resource) {
465
-
466
- $wpdb->delete(
467
- $wpdb->prefix . 'wc_booking_relationships',
468
- array(
469
- 'product_id' => $trnsl_product_id,
470
- 'resource_id' => $trnsl_product_resource
471
- )
472
- );
473
-
474
- wp_delete_post( $trnsl_product_resource );
475
-
476
- }
477
-
478
- remove_action( 'updated_post_meta', array( $this, 'update_wc_booking_costs' ), 10, 4 );
479
- $this->sync_resource_costs( $original_product_id, $trnsl_product_id, '_resource_base_costs', $lang_code );
480
- $this->sync_resource_costs( $original_product_id, $trnsl_product_id, '_resource_block_costs', $lang_code );
481
- add_action( 'updated_post_meta', array( $this, 'update_wc_booking_costs' ), 10, 4 );
482
-
483
- }
484
-
485
- function duplicate_resource( $tr_product_id, $resource, $lang_code){
486
- global $sitepress, $wpdb, $iclTranslationManagement;
487
-
488
- if( method_exists( $sitepress, 'make_duplicate' ) ){
489
-
490
- $trns_resource_id = $sitepress->make_duplicate( $resource->resource_id, $lang_code );
491
-
492
- }else{
493
-
494
- if ( !isset( $iclTranslationManagement ) ) {
495
- $iclTranslationManagement = new TranslationManagement;
496
- }
497
-
498
- $trns_resource_id = $iclTranslationManagement->make_duplicate( $resource->resource_id, $lang_code );
499
-
500
- }
501
-
502
- $wpdb->insert(
503
- $wpdb->prefix . 'wc_booking_relationships',
504
- array(
505
- 'product_id' => $tr_product_id,
506
- 'resource_id' => $trns_resource_id,
507
- 'sort_order' => $resource->sort_order
508
- )
509
- );
510
-
511
- delete_post_meta( $trns_resource_id, '_icl_lang_duplicate_of' );
512
-
513
- return $trns_resource_id;
514
- }
515
-
516
- function sync_persons( $original_product_id, $tr_product_id, $lang_code, $duplicate = true ){
517
- global $wpdb, $woocommerce_wpml;
518
-
519
- $orig_persons = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'bookable_person'", $original_product_id ) );
520
-
521
- $trnsl_persons = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'bookable_person'", $tr_product_id ) );
522
-
523
-
524
- foreach ($orig_persons as $person) {
525
-
526
- $trnsl_person_id = apply_filters( 'translate_object_id', $person, 'bookable_person', false, $lang_code );
527
-
528
- if ( !is_null( $trnsl_person_id ) && in_array( $trnsl_person_id, $trnsl_persons ) ) {
529
-
530
- if ( ( $key = array_search( $trnsl_person_id, $trnsl_persons ) ) !== false ) {
531
-
532
- unset($trnsl_persons[$key]);
533
-
534
- update_post_meta( $trnsl_person_id, 'block_cost', get_post_meta( $person, 'block_cost', true ) );
535
- update_post_meta( $trnsl_person_id, 'cost', get_post_meta( $person, 'cost', true ) );
536
- update_post_meta( $trnsl_person_id, 'max', get_post_meta( $person, 'max', true ) );
537
- update_post_meta( $trnsl_person_id, 'min', get_post_meta( $person, 'min', true ) );
538
-
539
-
540
- if( get_post_meta( $person, '_wcml_custom_costs_status', true ) && $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT){
541
- $currencies = $woocommerce_wpml->multi_currency_support->get_currencies();
542
-
543
- foreach( $currencies as $code => $currency ){
544
-
545
- update_post_meta( $trnsl_person_id, 'block_cost_'.$code, get_post_meta( $person, 'block_cost_'.$code, true ) );
546
- update_post_meta( $trnsl_person_id, 'block_cost_'.$code, get_post_meta( $person, 'cost_'.$code, true ) );
547
-
548
- }
549
- }
550
-
551
- }
552
-
553
- }else{
554
-
555
- if( $duplicate ) {
556
-
557
- $this->duplicate_person($tr_product_id, $person, $lang_code);
558
-
559
- }else{
560
-
561
- continue;
562
-
563
- }
564
-
565
- }
566
-
567
- }
568
-
569
- foreach ($trnsl_persons as $trnsl_person) {
570
-
571
- wp_delete_post( $trnsl_person );
572
-
573
- }
574
-
575
- }
576
-
577
- function duplicate_person( $tr_product_id, $person_id, $lang_code ){
578
- global $sitepress, $wpdb, $iclTranslationManagement;
579
-
580
- if( method_exists( $sitepress, 'make_duplicate' ) ){
581
-
582
- $new_person_id = $sitepress->make_duplicate( $person_id, $lang_code );
583
-
584
- }else{
585
-
586
- if ( !isset( $iclTranslationManagement ) ) {
587
- $iclTranslationManagement = new TranslationManagement;
588
- }
589
-
590
- $new_person_id = $iclTranslationManagement->make_duplicate( $person_id, $lang_code );
591
-
592
- }
593
-
594
- $wpdb->update(
595
- $wpdb->posts,
596
- array(
597
- 'post_parent' => $tr_product_id
598
- ),
599
- array(
600
- 'ID' => $new_person_id
601
- )
602
- );
603
-
604
- delete_post_meta( $new_person_id, '_icl_lang_duplicate_of' );
605
-
606
- return $new_person_id;
607
- }
608
-
609
- function filter_wc_booking_cost( $check, $object_id, $meta_key, $single ){
610
-
611
- if( in_array( $meta_key, array( '_wc_booking_cost', '_wc_booking_base_cost', '_wc_display_cost', '_wc_booking_pricing', 'cost', 'block_cost', '_resource_base_costs', '_resource_block_costs' ) ) ){
612
-
613
- global $woocommerce_wpml;
614
-
615
- if( $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
616
-
617
- $original_id = apply_filters( 'translate_object_id', $object_id, 'product', true, $woocommerce_wpml->products->get_original_product_language( $object_id ) );
618
-
619
- $cost_status = get_post_meta( $original_id, '_wcml_custom_costs_status', true );
620
-
621
- $currency = $woocommerce_wpml->multi_currency_support->get_client_currency();
622
-
623
- if ( $currency == get_option('woocommerce_currency') ){
624
- return $check;
625
- }
626
-
627
- if( in_array( $meta_key, array( 'cost', 'block_cost' ) ) ) {
628
-
629
- if ( get_post_type($object_id) == 'bookable_person' ) {
630
-
631
- $value = get_post_meta($object_id, $meta_key . '_' . $currency, true);
632
-
633
- if ( $cost_status && $value ) {
634
-
635
- return $value;
636
-
637
- } else {
638
-
639
- remove_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
640
-
641
- $cost = get_post_meta( $object_id, $meta_key, true);
642
-
643
- add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
644
-
645
- return $woocommerce_wpml->multi_currency->convert_price_amount( $cost, $currency );
646
- }
647
-
648
- } else {
649
-
650
- return $check;
651
-
652
- }
653
-
654
- }
655
-
656
- if( in_array ( $meta_key, array( '_wc_booking_pricing', '_resource_base_costs', '_resource_block_costs' ) ) ){
657
-
658
- remove_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
659
-
660
- if( $meta_key == '_wc_booking_pricing' ){
661
-
662
- if( $original_id != $object_id ){
663
- $value = get_post_meta( $original_id, $meta_key );
664
- }else{
665
- $value = $check;
666
- }
667
-
668
- }else{
669
-
670
- $costs = maybe_unserialize( get_post_meta( $object_id, $meta_key, true ) );
671
-
672
- if( !$costs ){
673
- $value = $check;
674
- }elseif( $cost_status && isset( $costs[ 'custom_costs' ][ $currency ] ) ){
675
- $value = array( 0 => $costs[ 'custom_costs' ][ $currency ] );
676
- }elseif( $cost_status && isset( $costs[ 0 ][ 'custom_costs' ][ $currency ] )){
677
- $value = array( 0 => $costs[ 0 ][ 'custom_costs' ][ $currency ] );
678
- }else{
679
-
680
- $converted_values = array();
681
-
682
- foreach( $costs as $resource_id => $cost ){
683
- $converted_values[0][ $resource_id ] = $woocommerce_wpml->multi_currency->convert_price_amount( $cost, $currency );
684
- }
685
-
686
- $value = $converted_values;
687
- }
688
-
689
- }
690
-
691
- add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
692
-
693
- return $value;
694
-
695
- }
696
-
697
- $value = get_post_meta( $original_id, $meta_key.'_'.$currency, true );
698
-
699
- if( $cost_status && ( !empty($value) || ( empty($value) && $meta_key == '_wc_display_cost' ) ) ){
700
-
701
- return $value;
702
-
703
- }else{
704
-
705
- remove_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
706
-
707
- $value = get_post_meta( $original_id, $meta_key, true );
708
-
709
- $value = $woocommerce_wpml->multi_currency->convert_price_amount( $value, $currency );
710
-
711
- add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
712
-
713
- return $value;
714
-
715
- }
716
-
717
- }
718
-
719
- }
720
-
721
- return $check;
722
- }
723
-
724
- function update_wc_booking_costs( $check, $object_id, $meta_key, $meta_value ){
725
-
726
- if( in_array( $meta_key, array( '_wc_booking_pricing', '_resource_base_costs', '_resource_block_costs' ) ) ){
727
-
728
- global $woocommerce_wpml;
729
-
730
- remove_action( 'updated_post_meta', array( $this, 'update_wc_booking_costs' ), 10, 4 );
731
-
732
- $nonce = filter_input( INPUT_POST, '_wcml_custom_costs_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
733
-
734
- if( isset( $_POST['_wcml_custom_costs'] ) && isset( $nonce ) && wp_verify_nonce( $nonce, 'wcml_save_custom_costs' ) && $_POST['_wcml_custom_costs'] == 1 ) {
735
-
736
- $currencies = $woocommerce_wpml->multi_currency_support->get_currencies();
737
-
738
- $updated_meta = array();
739
-
740
- if( $meta_key == '_wc_booking_pricing' ){
741
-
742
- foreach (maybe_unserialize($meta_value) as $key => $prices) {
743
-
744
- $updated_meta[ $key ] = $prices;
745
-
746
- foreach ($currencies as $code => $currency) {
747
-
748
- $updated_meta[ $key ][ 'base_cost_'.$code ] = $_POST[ 'wcml_wc_booking_pricing_base_cost' ][ $code ][ $key ];
749
- $updated_meta[ $key ][ 'cost_'.$code ] = $_POST[ 'wcml_wc_booking_pricing_cost' ][ $code ][ $key ];
750
-
751
- }
752
-
753
- }
754
-
755
- update_post_meta( $object_id, '_wc_booking_pricing', $updated_meta );
756
-
757
- }elseif( $meta_key == '_resource_base_costs' ){
758
-
759
- if( isset( $_POST[ 'wcml_wc_booking_resource_cost' ] ) ) {
760
-
761
- $updated_meta = $meta_value;
762
-
763
- $wc_booking_resource_costs = array();
764
-
765
- foreach ( $_POST['wcml_wc_booking_resource_cost'] as $resource_id => $costs) {
766
-
767
- foreach ($currencies as $code => $currency) {
768
-
769
- $wc_booking_resource_costs[ $code ][ $resource_id ] = $costs[ $code ];
770
-
771
- }
772
-
773
- }
774
-
775
- $updated_meta[ 'custom_costs' ] = $wc_booking_resource_costs;
776
-
777
- update_post_meta( $object_id, '_resource_base_costs', $updated_meta );
778
-
779
- $this->sync_resource_costs_with_translations( $object_id, $meta_key );
780
-
781
- }
782
-
783
- }elseif( $meta_key == '_resource_block_costs' ){
784
-
785
- if( isset( $_POST[ 'wcml_wc_booking_resource_block_cost' ] ) ){
786
-
787
- $updated_meta = $meta_value;
788
-
789
- $wc_booking_resource_block_costs = array();
790
-
791
- foreach( $_POST[ 'wcml_wc_booking_resource_block_cost' ] as $resource_id => $costs ){
792
-
793
- foreach( $currencies as $code => $currency ){
794
-
795
- $wc_booking_resource_block_costs[ $code ][ $resource_id ] = $costs[ $code ];
796
-
797
- }
798
-
799
- }
800
-
801
- $updated_meta[ 'custom_costs' ] = $wc_booking_resource_block_costs;
802
-
803
- update_post_meta( $object_id, '_resource_block_costs', $updated_meta );
804
-
805
- $this->sync_resource_costs_with_translations( $object_id, $meta_key );
806
-
807
- }
808
-
809
- }
810
-
811
- add_action( 'updated_post_meta', array( $this, 'update_wc_booking_costs' ), 10, 4 );
812
-
813
- }elseif( in_array( $meta_key, array( '_resource_base_costs', '_resource_block_costs' ) ) ){
814
-
815
- $return = $this->sync_resource_costs_with_translations( $object_id, $meta_key, $check );
816
-
817
- add_action( 'updated_post_meta', array( $this, 'update_wc_booking_costs' ), 10, 4 );
818
-
819
- }else{
820
-
821
- add_action( 'updated_post_meta', array( $this, 'update_wc_booking_costs' ), 10, 4 );
822
-
823
- }
824
-
825
- }
826
-
827
- }
828
-
829
- function sync_resource_costs_with_translations( $object_id, $meta_key, $check = false ){
830
- global $sitepress,$woocommerce_wpml;
831
-
832
- $original_product_id = apply_filters( 'translate_object_id', $object_id, 'product', true, $woocommerce_wpml->products->get_original_product_language( $object_id ) );
833
-
834
- if( $object_id == $original_product_id ){
835
-
836
- $trid = $sitepress->get_element_trid( $object_id, 'post_product' );
837
- $translations = $sitepress->get_element_translations( $trid, 'post_product' );
838
-
839
- foreach ( $translations as $translation ) {
840
-
841
- if ( !$translation->original ) {
842
-
843
- $this->sync_resource_costs( $original_product_id, $translation->element_id, $meta_key, $translation->language_code );
844
-
845
- }
846
- }
847
-
848
- return $check;
849
-
850
- }else{
851
-
852
- $language_code = $sitepress->get_language_for_element( $object_id, 'post_product' );
853
-
854
- $this->sync_resource_costs( $original_product_id, $object_id, $meta_key, $language_code );
855
-
856
- return true;
857
-
858
- }
859
-
860
- }
861
-
862
- function sync_resource_costs( $original_product_id, $object_id, $meta_key, $language_code ){
863
-
864
- $original_costs = maybe_unserialize( get_post_meta( $original_product_id, $meta_key, true ) );
865
-
866
- $wc_booking_resource_costs = array();
867
-
868
- foreach ( $original_costs as $resource_id => $costs ) {
869
-
870
- if ( $resource_id == 'custom_costs' && isset($costs[ 'custom_costs']) ){
871
-
872
- foreach ( $costs[ 'custom_costs'] as $code => $currencies ) {
873
-
874
- foreach( $currencies as $custom_costs_resource_id => $custom_cost ){
875
-
876
- $trns_resource_id = apply_filters( 'translate_object_id', $custom_costs_resource_id, 'bookable_resource', true, $language_code );
877
-
878
- $wc_booking_resource_costs[ 'custom_costs' ][ $code ][ $trns_resource_id ] = $custom_cost;
879
-
880
- }
881
-
882
- }
883
-
884
- }else{
885
-
886
- $trns_resource_id = apply_filters( 'translate_object_id', $resource_id, 'bookable_resource', true, $language_code );
887
-
888
- $wc_booking_resource_costs[ $trns_resource_id ] = $costs;
889
-
890
- }
891
-
892
- }
893
-
894
- update_post_meta( $object_id, $meta_key, $wc_booking_resource_costs );
895
-
896
- }
897
-
898
- function wc_bookings_process_cost_rules_cost( $cost, $fields, $key ){
899
- return $this->filter_pricing_cost( $cost, $fields, 'cost_', $key );
900
- }
901
-
902
- function wc_bookings_process_cost_rules_base_cost( $base_cost, $fields, $key ){
903
- return $this->filter_pricing_cost( $base_cost, $fields, 'base_cost_', $key );
904
- }
905
-
906
- function wc_bookings_process_cost_rules_override_block_cost( $override_cost, $fields, $key ){
907
- return $this->filter_pricing_cost( $override_cost, $fields, 'override_block_', $key );
908
- }
909
-
910
- function filter_pricing_cost( $cost, $fields, $name, $key ){
911
- global $woocommerce_wpml, $product;
912
-
913
- if( $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
914
-
915
- $currency = $woocommerce_wpml->multi_currency_support->get_client_currency();
916
-
917
- if ( $currency == get_option('woocommerce_currency') ) {
918
- return $cost;
919
- }
920
-
921
- if( isset( $_POST[ 'form' ] ) ){
922
- parse_str( $_POST[ 'form' ], $posted );
923
-
924
- $booking_id = $posted[ 'add-to-cart' ];
925
-
926
- }elseif( isset( $_POST[ 'add-to-cart' ] ) ){
927
-
928
- $booking_id = $_POST[ 'add-to-cart' ];
929
-
930
- }
931
-
932
- if( isset( $booking_id ) ){
933
- $original_id = apply_filters( 'translate_object_id', $booking_id, 'product', true, $woocommerce_wpml->products->get_original_product_language( $booking_id ) );
934
-
935
- if( $booking_id != $original_id ){
936
- $fields = maybe_unserialize( get_post_meta( $original_id, '_wc_booking_pricing', true ) );
937
- $fields = $fields[$key];
938
- }
939
- }
940
-
941
- if( isset( $fields[ $name.$currency ] ) ){
942
- return $fields[ $name.$currency ];
943
- }else{
944
- return $woocommerce_wpml->multi_currency->convert_price_amount( $cost, $currency );
945
- }
946
-
947
- }
948
-
949
- return $cost;
950
-
951
- }
952
-
953
- function load_assets( ){
954
- global $pagenow, $woocommerce_wpml;
955
-
956
- if( $pagenow == 'post.php' || $pagenow == 'post-new.php' ){
957
-
958
- wp_register_style( 'wcml-bookings-css', WCML_PLUGIN_URL . '/compatibility/assets/css/wcml-bookings.css', array(), WCML_VERSION );
959
- wp_enqueue_style( 'wcml-bookings-css' );
960
-
961
- wp_register_script( 'wcml-bookings-js' , WCML_PLUGIN_URL . '/compatibility/assets/js/wcml-bookings.js', array('jquery'), WCML_VERSION);
962
- wp_enqueue_script( 'wcml-bookings-js' );
963
- wp_localize_script( 'wcml-bookings-js', 'lock_fields', ( isset( $_GET[ 'post' ] ) && get_post_type( $_GET[ 'post' ] ) == 'product' && !$woocommerce_wpml->products->is_original_product( $_GET[ 'post' ] ) ) ||
964
- ( $pagenow == 'post-new.php' && isset( $_GET[ 'source_lang' ] ) ) ? 1 : false );
965
- }
966
-
967
- }
968
-
969
- function wcml_multi_currency_is_ajax( $actions ){
970
-
971
- $actions[] = 'wc_bookings_calculate_costs';
972
-
973
- return $actions;
974
- }
975
-
976
- function filter_bundled_product_in_cart_contents( $cart_item, $key, $current_language ){
977
-
978
- if( $cart_item[ 'data' ] instanceof WC_Product_Booking && isset( $cart_item[ 'booking' ] ) ){
979
- global $woocommerce_wpml;
980
-
981
- $current_id = apply_filters( 'translate_object_id', $cart_item[ 'data' ]->id, 'product', true, $current_language );
982
- $cart_product_id = $cart_item['data']->id;
983
-
984
- if( $current_id != $cart_product_id ) {
985
-
986
- $cart_item['data'] = new WC_Product_Booking( $current_id );
987
-
988
- }
989
-
990
- if( $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT || $current_id != $cart_product_id ){
991
-
992
- $booking_info = array(
993
- 'wc_bookings_field_start_date_year' => $cart_item[ 'booking' ][ '_year' ],
994
- 'wc_bookings_field_start_date_month' => $cart_item[ 'booking' ][ '_month' ],
995
- 'wc_bookings_field_start_date_day' => $cart_item[ 'booking' ][ '_day' ],
996
- 'add-to-cart' => $current_id,
997
- '_persons' => isset( $cart_item[ 'booking' ][ '_persons' ] ) ? isset( $cart_item[ 'booking' ][ '_persons' ] ) : array()
998
- );
999
-
1000
- if( isset( $cart_item[ 'booking' ][ '_resource_id' ] ) ){
1001
- $booking_info[ 'wc_bookings_field_resource' ] = $cart_item[ 'booking' ][ '_resource_id' ];
1002
- }
1003
-
1004
- if( isset( $cart_item[ 'booking' ][ '_duration' ] ) ){
1005
- $booking_info[ 'wc_bookings_field_duration' ] = $cart_item[ 'booking' ][ '_duration' ];
1006
- }
1007
-
1008
- if( isset( $cart_item[ 'booking' ][ '_time' ] ) ){
1009
- $booking_info[ 'wc_bookings_field_start_date_time' ] = $cart_item[ 'booking' ][ '_time' ];
1010
- }
1011
-
1012
- $booking_form = new WC_Booking_Form( wc_get_product( $current_id ) );
1013
-
1014
- $prod_qty = get_post_meta( $current_id, '_wc_booking_qty', true );
1015
- update_post_meta( $current_id, '_wc_booking_qty', intval( $prod_qty + $cart_item[ 'booking' ][ '_qty' ] ) );
1016
- $cost = $booking_form->calculate_booking_cost( $booking_info );
1017
- update_post_meta( $current_id, '_wc_booking_qty', $prod_qty );
1018
-
1019
- if( !is_wp_error( $cost ) ){
1020
- $cart_item[ 'data' ]->set_price( $cost );
1021
- }
1022
- }
1023
-
1024
- }
1025
-
1026
- return $cart_item;
1027
-
1028
- }
1029
-
1030
- function booking_currency_dropdown(){
1031
- global $woocommerce_wpml, $sitepress;
1032
-
1033
- if( $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
1034
- $current_booking_currency = $this->get_cookie_booking_currency();
1035
-
1036
- $wc_currencies = get_woocommerce_currencies();
1037
- $order_currencies = $woocommerce_wpml->multi_currency->get_orders_currencies();
1038
- ?>
1039
- <tr valign="top">
1040
- <th scope="row"><?php _e( 'Booking currency', 'woocommerce-multilingual' ); ?></th>
1041
- <td>
1042
- <select id="dropdown_booking_currency">
1043
-
1044
- <?php foreach($order_currencies as $currency => $count ): ?>
1045
-
1046
- <option value="<?php echo $currency ?>" <?php echo $current_booking_currency == $currency ? 'selected="selected"':''; ?>><?php echo $wc_currencies[$currency]; ?></option>
1047
-
1048
- <?php endforeach; ?>
1049
-
1050
- </select>
1051
- </td>
1052
- </tr>
1053
-
1054
- <?php
1055
-
1056
- $wcml_booking_set_currency_nonce = wp_create_nonce( 'booking_set_currency' );
1057
-
1058
- wc_enqueue_js( "
1059
-
1060
- jQuery(document).on('change', '#dropdown_booking_currency', function(){
1061
- jQuery.ajax({
1062
- url: ajaxurl,
1063
- type: 'post',
1064
- data: {
1065
- action: 'wcml_booking_set_currency',
1066
- currency: jQuery('#dropdown_booking_currency').val(),
1067
- wcml_nonce: '".$wcml_booking_set_currency_nonce."'
1068
- },
1069
- success: function( response ){
1070
- if(typeof response.error !== 'undefined'){
1071
- alert(response.error);
1072
- }else{
1073
- window.location = window.location.href;
1074
- }
1075
- }
1076
- })
1077
- });
1078
- ");
1079
-
1080
- }
1081
-
1082
- }
1083
-
1084
- function set_booking_currency_ajax(){
1085
-
1086
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
1087
- if(!$nonce || !wp_verify_nonce($nonce, 'booking_set_currency')){
1088
- echo json_encode(array('error' => __('Invalid nonce', 'woocommerce-multilingual')));
1089
- die();
1090
- }
1091
-
1092
- $this->set_booking_currency(filter_input( INPUT_POST, 'currency', FILTER_SANITIZE_FULL_SPECIAL_CHARS ));
1093
-
1094
- die();
1095
- }
1096
-
1097
- function set_booking_currency( $currency_code = false ){
1098
-
1099
- if( !isset( $_COOKIE [ '_wcml_booking_currency' ]) && !headers_sent()) {
1100
- global $woocommerce_wpml;
1101
-
1102
- $currency_code = get_woocommerce_currency();
1103
-
1104
- if ( $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
1105
- $order_currencies = $woocommerce_wpml->multi_currency->get_orders_currencies();
1106
-
1107
- if (!isset($order_currencies[$currency_code])) {
1108
- foreach ($order_currencies as $currency_code => $count) {
1109
- $currency_code = $currency_code;
1110
- break;
1111
- }
1112
- }
1113
- }
1114
- }
1115
-
1116
- if( $currency_code ){
1117
- setcookie('_wcml_booking_currency', $currency_code , time() + 86400, COOKIEPATH, COOKIE_DOMAIN);
1118
- }
1119
-
1120
- }
1121
-
1122
- function get_cookie_booking_currency(){
1123
-
1124
- if( isset( $_COOKIE [ '_wcml_booking_currency' ] ) ){
1125
- $currency = $_COOKIE[ '_wcml_booking_currency' ];
1126
- }else{
1127
- $currency = get_woocommerce_currency();
1128
- }
1129
-
1130
- return $currency;
1131
- }
1132
-
1133
- function filter_booking_currency_symbol( $currency ){
1134
- global $pagenow;
1135
-
1136
- remove_filter( 'woocommerce_currency_symbol', array( $this, 'filter_booking_currency_symbol' ) );
1137
- if( isset( $_COOKIE [ '_wcml_booking_currency' ] ) && $pagenow == 'edit.php' && isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'create_booking' ){
1138
- $currency = get_woocommerce_currency_symbol( $_COOKIE [ '_wcml_booking_currency' ] );
1139
- }
1140
- add_filter( 'woocommerce_currency_symbol', array( $this, 'filter_booking_currency_symbol' ) );
1141
-
1142
- return $currency;
1143
- }
1144
-
1145
- function create_booking_page_client_currency( $currency ){
1146
- global $pagenow;
1147
-
1148
- if( wpml_is_ajax() && isset( $_POST[ 'form' ] ) ){
1149
- parse_str( $_POST[ 'form' ], $posted );
1150
- }
1151
-
1152
- if( ( $pagenow == 'edit.php' && isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'create_booking' ) || ( isset( $posted[ '_wp_http_referer' ] ) && strpos( $posted[ '_wp_http_referer' ], 'page=create_booking' ) !== false ) ){
1153
- $currency = $this->get_cookie_booking_currency();
1154
- }
1155
-
1156
- return $currency;
1157
- }
1158
-
1159
- function set_order_currency_on_create_booking_page( $order_id ){
1160
- global $sitepress;
1161
-
1162
- update_post_meta( $order_id, '_order_currency', $this->get_cookie_booking_currency() );
1163
-
1164
- update_post_meta( $order_id, 'wpml_language', $sitepress->get_current_language() );
1165
-
1166
- }
1167
-
1168
- function filter_get_booking_products_args( $args ){
1169
- if( isset( $args['suppress_filters'] ) ){
1170
- $args['suppress_filters'] = false;
1171
- }
1172
- return $args;
1173
- }
1174
-
1175
- function custom_box_html( $html, $template_data, $lang ){
1176
-
1177
- if( in_array( $template_data[ 'product_content' ], array( 'wc_booking_resources', 'wc_booking_persons' ) ) ){
1178
-
1179
- switch( $template_data[ 'product_content' ] ){
1180
- case 'wc_booking_resources':
1181
-
1182
- $resources = array();
1183
-
1184
- foreach( maybe_unserialize( get_post_meta( $template_data[ 'product_id' ], '_resource_base_costs', true ) ) as $resource_id => $cost ){
1185
-
1186
- if( $resource_id == 'custom_costs' ) continue;
1187
-
1188
- $trns_resource_id = apply_filters( 'translate_object_id', $resource_id, 'bookable_resource', false, $template_data[ 'lang' ] );
1189
-
1190
- if( !empty( $trns_resource_id ) && $template_data[ 'translation_exist' ] ){
1191
- $resources[ $resource_id ] = $trns_resource_id;
1192
- }else{
1193
- $resources[ $resource_id ] = false;
1194
- }
1195
-
1196
- }
1197
- $template_data[ 'resources' ] = $resources;
1198
-
1199
- break;
1200
- case 'wc_booking_persons':
1201
- global $wpdb;
1202
-
1203
- $persons = array();
1204
-
1205
- $original_persons = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'bookable_person' AND post_status = 'publish'", $template_data[ 'product_id' ] ) );
1206
-
1207
- foreach( $original_persons as $person ){
1208
-
1209
- $trnsl_person_id = apply_filters( 'translate_object_id', $person, 'bookable_person', false, $template_data[ 'lang' ] );
1210
-
1211
- if( !empty( $trnsl_person_id ) && $template_data[ 'translation_exist' ] ){
1212
- $persons[ $person ] = $trnsl_person_id;
1213
- }else{
1214
- $persons[ $person ] = false;
1215
- }
1216
-
1217
- }
1218
-
1219
- $template_data[ 'persons' ] = $persons;
1220
-
1221
- break;
1222
- }
1223
-
1224
- return include WCML_PLUGIN_PATH . '/compatibility/templates/wc_bookings_custom_box_html.php';
1225
-
1226
- }
1227
-
1228
- return $html;
1229
- }
1230
-
1231
- function product_content_fields( $fields, $product_id ){
1232
-
1233
- return $this->product_content_fields_data( $fields, $product_id );
1234
-
1235
- }
1236
-
1237
- function product_content_fields_label( $fields, $product_id ){
1238
-
1239
- return $this->product_content_fields_data( $fields, $product_id, 'label' );
1240
-
1241
- }
1242
-
1243
- function product_content_fields_data( $fields, $product_id, $data = false ){
1244
-
1245
- if( get_post_meta( $product_id, '_resource_base_costs', true ) ){
1246
- if( $data == 'label' ){
1247
- $fields[] = __( 'Resources', 'woocommerce-multilingual' );
1248
- }else{
1249
- $fields[] = 'wc_booking_resources';
1250
- }
1251
- }
1252
-
1253
- if( has_term( 'booking', 'product_type', $product_id ) ){
1254
- global $wpdb;
1255
-
1256
- $persons = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'bookable_person'", $product_id ) );
1257
-
1258
- if( $persons ){
1259
- if( $data == 'label' ){
1260
- $fields[] = __( 'Person types', 'woocommerce-multilingual' );
1261
- }else{
1262
- $fields[] = 'wc_booking_persons';
1263
- }
1264
- }
1265
-
1266
- }
1267
-
1268
- return $fields;
1269
-
1270
- }
1271
-
1272
- function show_custom_blocks_for_resources_and_persons( $check, $product_id, $product_content ){
1273
- if( in_array( $product_content, array( 'wc_booking_resources', 'wc_booking_persons' ) ) ){
1274
- return false;
1275
- }
1276
- return $check;
1277
- }
1278
-
1279
- function remove_custom_fields_to_translate( $exception, $product_id, $meta_key ){
1280
- if( in_array( $meta_key, array( '_resource_base_costs', '_resource_block_costs' ) ) ){
1281
- $exception = true;
1282
- }
1283
- return $exception;
1284
- }
1285
-
1286
- function product_content_resource_label( $meta_key, $product_id ){
1287
- if ($meta_key == '_wc_booking_resouce_label'){
1288
- return __( 'Resources label', 'woocommerce-multilingual' );
1289
- }
1290
- return $meta_key;
1291
- }
1292
-
1293
- function wcml_products_tab_sync_resources_and_persons( $tr_product_id, $data, $language ){
1294
- global $wpdb, $woocommerce_wpml;
1295
-
1296
- //sync resources
1297
- if( isset( $data[ 'wc_booking_resources_'.$language ] ) ){
1298
-
1299
- $original_product_lang = $woocommerce_wpml->products->get_original_product_language( $tr_product_id );
1300
- $original_product_id = apply_filters( 'translate_object_id', $tr_product_id, 'product', true, $original_product_lang );
1301
-
1302
- foreach( $data[ 'wc_booking_resources_'.$language ][ 'id' ] as $key => $resource_id ){
1303
-
1304
- if( !$resource_id ){
1305
-
1306
- $resource_id = apply_filters( 'translate_object_id', $data[ 'wc_booking_resources_'.$language ][ 'orig_id' ][ $key ], 'bookable_resource', false, $language );
1307
-
1308
- $orig_resource = $wpdb->get_row( $wpdb->prepare( "SELECT resource_id, sort_order FROM {$wpdb->prefix}wc_booking_relationships WHERE resource_id = %d AND product_id = %d", $data[ 'wc_booking_resources_'.$language ][ 'orig_id' ][ $key ], $original_product_id ), OBJECT );
1309
-
1310
- if( is_null( $resource_id ) ){
1311
-
1312
- if( $orig_resource ) {
1313
- $resource_id = $this->duplicate_resource($tr_product_id, $orig_resource, $language);
1314
- }else{
1315
- continue;
1316
- }
1317
-
1318
- }else{
1319
- //update_relationship
1320
-
1321
- $exist = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->prefix}wc_booking_relationships WHERE resource_id = %d AND product_id = %d", $resource_id, $tr_product_id ) );
1322
-
1323
- if( !$exist ){
1324
-
1325
- $wpdb->insert(
1326
- $wpdb->prefix . 'wc_booking_relationships',
1327
- array(
1328
- 'product_id' => $tr_product_id,
1329
- 'resource_id' => $resource_id,
1330
- 'sort_order' => $orig_resource->sort_order
1331
- )
1332
- );
1333
-
1334
- }
1335
-
1336
- }
1337
-
1338
- }
1339
-
1340
- $wpdb->update(
1341
- $wpdb->posts,
1342
- array(
1343
- 'post_title' => $data[ 'wc_booking_resources_'.$language ][ 'title' ][ $key ]
1344
- ),
1345
- array(
1346
- 'ID' => $resource_id
1347
- )
1348
- );
1349
-
1350
- }
1351
-
1352
- //sync resources data
1353
- $this->sync_resources( $original_product_id, $tr_product_id, $language, false );
1354
-
1355
- }
1356
-
1357
-
1358
- //sync persons
1359
- if( isset( $data[ 'wc_booking_persons_'.$language ] ) ){
1360
-
1361
- $original_product_lang = $woocommerce_wpml->products->get_original_product_language( $tr_product_id );
1362
- $original_product_id = apply_filters( 'translate_object_id', $tr_product_id, 'product', true, $original_product_lang );
1363
-
1364
- foreach( $data[ 'wc_booking_persons_'.$language ][ 'id' ] as $key => $person_id ) {
1365
-
1366
- if ( !$person_id ) {
1367
-
1368
- $person_id = apply_filters( 'translate_object_id', $data[ 'wc_booking_persons_'.$language ][ 'orig_id' ][ $key ], 'bookable_person', false, $language );
1369
-
1370
- if( is_null( $person_id ) ){
1371
-
1372
- $person_id = $this->duplicate_person( $tr_product_id, $data['wc_booking_persons_' . $language]['orig_id'][$key], $language);
1373
-
1374
- }else{
1375
-
1376
- $wpdb->update(
1377
- $wpdb->posts,
1378
- array(
1379
- 'post_parent' => $tr_product_id
1380
- ),
1381
- array(
1382
- 'ID' => $person_id
1383
- )
1384
- );
1385
-
1386
- }
1387
-
1388
- }
1389
-
1390
- $wpdb->update(
1391
- $wpdb->posts,
1392
- array(
1393
- 'post_title' => $data[ 'wc_booking_persons_' . $language ][ 'title' ][ $key ],
1394
- 'post_excerpt' => $data[ 'wc_booking_persons_' . $language ][ 'description' ][ $key ],
1395
- ),
1396
- array(
1397
- 'ID' => $person_id
1398
- )
1399
- );
1400
-
1401
- }
1402
-
1403
- //sync persons data
1404
- $this->sync_persons( $original_product_id, $tr_product_id, $language, false );
1405
-
1406
- }
1407
-
1408
- }
1409
-
1410
- function duplicate_booking_for_translations( $booking_id, $lang = false ){
1411
- global $sitepress;
1412
-
1413
- $booking_object = get_post( $booking_id );
1414
-
1415
- $booking_data = array(
1416
- 'post_type' => 'wc_booking',
1417
- 'post_title' => $booking_object->post_title,
1418
- 'post_status' => $booking_object->post_status,
1419
- 'ping_status' => 'closed',
1420
- 'post_parent' => $booking_object->post_parent,
1421
- );
1422
-
1423
- $active_languages = $sitepress->get_active_languages();
1424
-
1425
- foreach( $active_languages as $language ){
1426
-
1427
- $booking_product_id = get_post_meta( $booking_id, '_booking_product_id', true );
1428
-
1429
- if( !$lang ){
1430
- $booking_language = $sitepress->get_element_language_details( $booking_product_id, 'post_product' );
1431
- if ( $booking_language->language_code == $language['code'] ) {
1432
- continue;
1433
- }
1434
- }elseif( $lang != $language['code'] ){
1435
- continue;
1436
- }
1437
-
1438
- $booking_persons = maybe_unserialize( get_post_meta( $booking_id, '_booking_persons', true ) );
1439
- $trnsl_booking_persons = array();
1440
-
1441
- foreach( $booking_persons as $person_id => $person_count ){
1442
-
1443
- $trnsl_person_id = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $language['code'] );
1444
-
1445
- if( is_null( $trnsl_person_id ) ){
1446
- $trnsl_booking_persons[] = $person_count;
1447
- }else{
1448
- $trnsl_booking_persons[ $trnsl_person_id ] = $person_count;
1449
- }
1450
-
1451
- }
1452
-
1453
- $trnsl_booking_id = wp_insert_post( $booking_data );
1454
-
1455
- $meta_args = array(
1456
- '_booking_order_item_id' => get_post_meta( $booking_id, '_booking_order_item_id', true ),
1457
- '_booking_product_id' => $this->get_translated_booking_product_id( $booking_id, $language['code'] ),
1458
- '_booking_resource_id' => $this->get_translated_booking_resource_id( $booking_id, $language['code'] ),
1459
- '_booking_persons' => $this->get_translated_booking_persons_ids( $booking_id, $language['code'] ),
1460
- '_booking_cost' => get_post_meta( $booking_id, '_booking_cost', true ),
1461
- '_booking_start' => get_post_meta( $booking_id, '_booking_start', true ),
1462
- '_booking_end' => get_post_meta( $booking_id, '_booking_end', true ),
1463
- '_booking_all_day' => intval( get_post_meta( $booking_id, '_booking_all_day', true ) ),
1464
- '_booking_parent_id' => get_post_meta( $booking_id, '_booking_parent_id', true ),
1465
- '_booking_customer_id' => get_post_meta( $booking_id, '_booking_customer_id', true ),
1466
- '_booking_duplicate_of' => $booking_id,
1467
- '_language_code' => $language['code'],
1468
- );
1469
-
1470
- foreach ( $meta_args as $key => $value ) {
1471
- update_post_meta( $trnsl_booking_id, $key, $value );
1472
- }
1473
-
1474
- WC_Cache_Helper::get_transient_version( 'bookings', true );
1475
-
1476
- }
1477
-
1478
-
1479
- }
1480
-
1481
- function get_translated_booking_product_id( $booking_id, $language ){
1482
-
1483
- $booking_product_id = get_post_meta( $booking_id, '_booking_product_id', true );
1484
-
1485
- if( $booking_product_id ){
1486
- $trnsl_booking_product_id = apply_filters( 'translate_object_id', $booking_product_id, 'product', false, $language );
1487
- if( is_null( $trnsl_booking_product_id ) ){
1488
- $trnsl_booking_product_id = '';
1489
- }
1490
- }
1491
-
1492
- return $trnsl_booking_product_id;
1493
-
1494
- }
1495
-
1496
- function get_translated_booking_resource_id( $booking_id, $language ){
1497
-
1498
- $booking_resource_id = get_post_meta( $booking_id, '_booking_resource_id', true );
1499
- $trnsl_booking_resource_id = '';
1500
-
1501
- if( $booking_resource_id ){
1502
- $trnsl_booking_resource_id = apply_filters( 'translate_object_id', $booking_resource_id, 'bookable_resource', false, $language );
1503
-
1504
- if( is_null( $trnsl_booking_resource_id ) ){
1505
- $trnsl_booking_resource_id = '';
1506
- }
1507
- }
1508
-
1509
- return $trnsl_booking_resource_id;
1510
- }
1511
-
1512
- function get_translated_booking_persons_ids( $booking_id, $language ){
1513
-
1514
- $booking_persons = maybe_unserialize( get_post_meta( $booking_id, '_booking_persons', true ) );
1515
- $trnsl_booking_persons = array();
1516
-
1517
- foreach( $booking_persons as $person_id => $person_count ){
1518
-
1519
- $trnsl_person_id = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $language );
1520
-
1521
- if( is_null( $trnsl_person_id ) ){
1522
- $trnsl_booking_persons[] = $person_count;
1523
- }else{
1524
- $trnsl_booking_persons[ $trnsl_person_id ] = $person_count;
1525
- }
1526
-
1527
- }
1528
-
1529
- return $trnsl_booking_persons;
1530
-
1531
- }
1532
-
1533
- function update_status_for_translations( $booking_id ){
1534
- global $wpdb;
1535
-
1536
- $translated_bookings = $this->get_translated_bookings( $booking_id );
1537
-
1538
- foreach( $translated_bookings as $booking ){
1539
-
1540
- $status = $wpdb->get_var( $wpdb->prepare( "SELECT post_status FROM {$wpdb->posts} WHERE ID = %d", $booking_id ) ); //get_post_status( $booking_id );
1541
- $language = get_post_meta( $booking->post_id, '_language_code', true );
1542
-
1543
- $wpdb->update(
1544
- $wpdb->posts,
1545
- array(
1546
- 'post_status' => $status,
1547
- 'post_parent' => wp_get_post_parent_id( $booking_id ),
1548
- ),
1549
- array(
1550
- 'ID' => $booking->post_id
1551
- )
1552
- );
1553
-
1554
- update_post_meta( $booking->post_id, '_booking_product_id', $this->get_translated_booking_product_id( $booking_id, $language ) );
1555
- update_post_meta( $booking->post_id, '_booking_resource_id', $this->get_translated_booking_resource_id( $booking_id, $language ) );
1556
- update_post_meta( $booking->post_id, '_booking_persons', $this->get_translated_booking_persons_ids( $booking_id, $language ) );
1557
-
1558
- }
1559
-
1560
- }
1561
-
1562
- function get_translated_bookings($booking_id){
1563
- global $wpdb;
1564
-
1565
- $translated_bookings = $wpdb->get_results( $wpdb->prepare( "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_booking_duplicate_of' AND meta_value = %d", $booking_id ) );
1566
-
1567
- return $translated_bookings;
1568
- }
1569
-
1570
- public function booking_filters_query( $query ) {
1571
- global $typenow, $sitepress, $wpdb;
1572
-
1573
- if ( ( isset( $query->query_vars['post_type'] ) && $query->query_vars['post_type'] == 'wc_booking' ) ) {
1574
-
1575
- $product_ids = $wpdb->get_col( $wpdb->prepare(
1576
- "SELECT element_id
1577
- FROM {$wpdb->prefix}icl_translations
1578
- WHERE language_code = %s AND element_type = 'post_product'", $sitepress->get_current_language() ) );
1579
-
1580
- $query->query_vars[ 'meta_query' ][] = array(
1581
- array(
1582
- 'key' => '_booking_product_id',
1583
- 'value' => $product_ids,
1584
- 'compare ' => 'IN'
1585
- )
1586
- );
1587
- }
1588
- }
1589
-
1590
- function bookings_in_date_range_query($booking_ids){
1591
- global $sitepress;
1592
-
1593
- foreach ( $booking_ids as $key => $booking_id ) {
1594
-
1595
- $language_code = $sitepress->get_language_for_element( get_post_meta( $booking_id, '_booking_product_id', true ) , 'post_product' );
1596
- $current_language = $sitepress->get_current_language();
1597
-
1598
- if( $language_code != $current_language ){
1599
- unset( $booking_ids[$key] );
1600
- }
1601
-
1602
- }
1603
-
1604
- return $booking_ids;
1605
-
1606
- }
1607
-
1608
- function clear_transient_fields(){
1609
-
1610
- if ( isset( $_GET['post_type'] ) && $_GET['post_type'] == 'wc_booking' && isset( $_GET['page'] ) && $_GET['page'] == 'booking_calendar' ) {
1611
-
1612
- global $wpdb;
1613
- //delete transient fields
1614
- $wpdb->query("
1615
- DELETE FROM $wpdb->options
1616
- WHERE option_name LIKE '%book_dr_%'
1617
- ");
1618
-
1619
- }
1620
-
1621
- }
1622
-
1623
- function delete_bookings( $booking_id ){
1624
-
1625
- if( $booking_id > 0 && get_post_type( $booking_id ) == 'wc_booking' ){
1626
-
1627
- $translated_bookings = $this->get_translated_bookings( $booking_id );
1628
-
1629
- remove_action( 'before_delete_post', array( $this, 'delete_bookings' ) );
1630
-
1631
- foreach( $translated_bookings as $booking ){
1632
-
1633
- global $wpdb;
1634
-
1635
- $wpdb->update(
1636
- $wpdb->posts,
1637
- array(
1638
- 'post_parent' => 0
1639
- ),
1640
- array(
1641
- 'ID' => $booking->post_id
1642
- )
1643
- );
1644
-
1645
- wp_delete_post( $booking->post_id );
1646
-
1647
- }
1648
-
1649
- add_action( 'before_delete_post', array( $this, 'delete_bookings' ) );
1650
- }
1651
-
1652
- }
1653
-
1654
- function trash_bookings( $booking_id ){
1655
-
1656
- if( $booking_id > 0 && get_post_type( $booking_id ) == 'wc_booking' ){
1657
-
1658
- $translated_bookings = $this->get_translated_bookings( $booking_id );
1659
-
1660
- foreach( $translated_bookings as $booking ){
1661
- global $wpdb;
1662
-
1663
- $wpdb->update(
1664
- $wpdb->posts,
1665
- array(
1666
- 'post_status' => 'trash'
1667
- ),
1668
- array(
1669
- 'ID' => $booking->post_id
1670
- )
1671
- );
1672
-
1673
- }
1674
-
1675
- }
1676
-
1677
- }
1678
-
1679
- function append_persons_to_translation_package( $package, $post ){
1680
-
1681
- if( $post->post_type == 'product' ){
1682
- $product = wc_get_product( $post->ID );
1683
-
1684
- //WC_Product::get_type() available from WooCommerce 2.4.0
1685
- $product_type = method_exists($product, 'get_type') ? $product->get_type() : $product->product_type;
1686
-
1687
- if( $product_type == 'booking' ){
1688
-
1689
- $bookable_product = new WC_Product_Booking( $post->ID );
1690
-
1691
- $person_types = $bookable_product->get_person_types();
1692
-
1693
- foreach( $person_types as $person_type ) {
1694
-
1695
- $package['contents']['wc_bookings:person:' . $person_type->ID . ':name'] = array(
1696
- 'translate' => 1,
1697
- 'data' => $this->tp->encode_field_data( $person_type->post_title, 'base64' ),
1698
- 'format' => 'base64'
1699
- );
1700
-
1701
- $package['contents']['wc_bookings:person:' . $person_type->ID . ':description'] = array(
1702
- 'translate' => 1,
1703
- 'data' => $this->tp->encode_field_data( $person_type->post_excerpt, 'base64' ),
1704
- 'format' => 'base64'
1705
- );
1706
-
1707
- }
1708
-
1709
- }
1710
-
1711
- }
1712
-
1713
- return $package;
1714
-
1715
- }
1716
-
1717
- function save_person_translation($post_id, $data, $job ){
1718
- global $sitepress;
1719
-
1720
- $person_translations = array();
1721
-
1722
- foreach($data as $value){
1723
-
1724
- if( $value['finished'] && strpos( $value['field_type'], 'wc_bookings:person:' ) === 0 ) {
1725
-
1726
- $exp = explode( ':', $value['field_type'] );
1727
-
1728
- $person_id = $exp[2];
1729
- $field = $exp[3];
1730
-
1731
- $person_translations[$person_id][$field] = $value['data'];
1732
-
1733
- }
1734
-
1735
- }
1736
-
1737
- if( $person_translations ){
1738
-
1739
- foreach( $person_translations as $person_id => $pt ){
1740
-
1741
- $person_trid = $sitepress->get_element_trid( $person_id, 'post_bookable_person');
1742
-
1743
-
1744
- $person_id_translated = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $job->language_code );
1745
-
1746
- if( empty($person_id_translated) ) {
1747
-
1748
- $person_post = array(
1749
-
1750
- 'post_type' => 'bookable_person',
1751
- 'post_status' => 'publish',
1752
- 'post_title' => $pt['name'],
1753
- 'post_parent' => $post_id,
1754
- 'post_excerpt' => isset($pt['description']) ? $pt['description'] : ''
1755
-
1756
- );
1757
-
1758
- $person_id_translated = wp_insert_post( $person_post );
1759
-
1760
- $sitepress->set_element_language_details( $person_id_translated, 'post_bookable_person', $person_trid, $job->language_code );
1761
-
1762
- } else {
1763
-
1764
- $person_post = array(
1765
- 'ID' => $person_id_translated,
1766
- 'post_title' => $pt['name'],
1767
- 'post_excerpt' => isset($pt['description']) ? $pt['description'] : ''
1768
- );
1769
-
1770
- wp_update_post( $person_post );
1771
-
1772
- }
1773
-
1774
- }
1775
-
1776
- }
1777
-
1778
- }
1779
-
1780
- function append_resources_to_translation_package( $package, $post ){
1781
-
1782
- if( $post->post_type == 'product' ){
1783
- $product = wc_get_product( $post->ID );
1784
-
1785
- //WC_Product::get_type() available from WooCommerce 2.4.0
1786
- $product_type = method_exists($product, 'get_type') ? $product->get_type() : $product->product_type;
1787
-
1788
- if( $product_type == 'booking' && $product->has_resources() ){
1789
-
1790
- $resources = $product->get_resources();
1791
-
1792
- foreach( $resources as $resource ) {
1793
-
1794
- $package['contents']['wc_bookings:resource:' . $resource->ID . ':name'] = array(
1795
- 'translate' => 1,
1796
- 'data' => $this->tp->encode_field_data( $resource->post_title, 'base64' ),
1797
- 'format' => 'base64'
1798
- );
1799
-
1800
- }
1801
-
1802
- }
1803
-
1804
- }
1805
-
1806
- return $package;
1807
-
1808
- }
1809
-
1810
- function save_resource_translation( $post_id, $data, $job ){
1811
- global $sitepress, $wpdb;
1812
-
1813
- $resource_translations = array();
1814
-
1815
- foreach($data as $value){
1816
-
1817
- if( $value['finished'] && strpos( $value['field_type'], 'wc_bookings:resource:' ) === 0 ) {
1818
-
1819
- $exp = explode( ':', $value['field_type'] );
1820
-
1821
- $resource_id = $exp[2];
1822
- $field = $exp[3];
1823
-
1824
- $resource_translations[$resource_id][$field] = $value['data'];
1825
-
1826
- }
1827
-
1828
- }
1829
-
1830
- if( $resource_translations ){
1831
-
1832
- foreach( $resource_translations as $resource_id => $rt ){
1833
-
1834
- $resource_trid = $sitepress->get_element_trid( $resource_id, 'post_bookable_person');
1835
-
1836
- $resource_id_translated = apply_filters( 'translate_object_id', $resource_id, 'bookable_resource', false, $job->language_code );
1837
-
1838
- if( empty($resource_id_translated) ) {
1839
-
1840
- $resource_post = array(
1841
-
1842
- 'post_type' => 'bookable_resource',
1843
- 'post_status' => 'publish',
1844
- 'post_title' => $rt['name'],
1845
- 'post_parent' => $post_id
1846
- );
1847
-
1848
- $resource_id_translated = wp_insert_post( $resource_post );
1849
-
1850
- $sitepress->set_element_language_details( $resource_id_translated, 'post_bookable_person', $resource_trid, $job->language_code );
1851
-
1852
- $sort_order = $wpdb->get_var( $wpdb->prepare( "SELECT sort_order FROM {$wpdb->prefix}wc_booking_relationships WHERE resource_id=%d", $resource_id ) );
1853
- $relationship = array(
1854
- 'product_id' => $post_id,
1855
- 'resource_id' => $resource_id_translated,
1856
- 'sort_order' => $sort_order
1857
- );
1858
- $wpdb->insert( $wpdb->prefix . 'wc_booking_relationships', $relationship);
1859
-
1860
- } else {
1861
-
1862
- $resource_post = array(
1863
- 'ID' => $resource_id_translated,
1864
- 'post_title' => $rt['name']
1865
- );
1866
-
1867
- wp_update_post( $resource_post );
1868
-
1869
- $sort_order = $wpdb->get_var( $wpdb->prepare( "SELECT sort_order FROM {$wpdb->prefix}wc_booking_relationships WHERE resource_id=%d", $resource_id ) );
1870
- $wpdb->update( $wpdb->prefix . 'wc_booking_relationships', array( 'sort_order' => $sort_order ),
1871
- array ( 'product_id' => $post_id, 'resource_id' => $resource_id_translated) );
1872
-
1873
-
1874
- }
1875
-
1876
-
1877
- }
1878
-
1879
- }
1880
-
1881
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1882
  }
1
+ <?php
2
+
3
+ class WCML_Bookings{
4
+
5
+ public $tp;
6
+
7
+ function __construct(){
8
+
9
+ add_action( 'woocommerce_bookings_after_booking_base_cost' , array( $this, 'wcml_price_field_after_booking_base_cost' ) );
10
+ add_action( 'woocommerce_bookings_after_booking_block_cost' , array( $this, 'wcml_price_field_after_booking_block_cost' ) );
11
+ add_action( 'woocommerce_bookings_after_display_cost' , array( $this, 'wcml_price_field_after_display_cost' ) );
12
+ add_action( 'woocommerce_bookings_after_booking_pricing_base_cost' , array( $this, 'wcml_price_field_after_booking_pricing_base_cost' ), 10, 2 );
13
+ add_action( 'woocommerce_bookings_after_booking_pricing_cost' , array( $this, 'wcml_price_field_after_booking_pricing_cost' ), 10, 2 );
14
+ add_action( 'woocommerce_bookings_after_person_cost' , array( $this, 'wcml_price_field_after_person_cost' ) );
15
+ add_action( 'woocommerce_bookings_after_person_block_cost' , array( $this, 'wcml_price_field_after_person_block_cost' ) );
16
+ add_action( 'woocommerce_bookings_after_resource_cost' , array( $this, 'wcml_price_field_after_resource_cost' ), 10, 2 );
17
+ add_action( 'woocommerce_bookings_after_resource_block_cost' , array( $this, 'wcml_price_field_after_resource_block_cost' ), 10, 2 );
18
+ add_action( 'woocommerce_bookings_after_bookings_pricing' , array( $this, 'after_bookings_pricing' ) );
19
+
20
+ add_action( 'init', array( $this, 'load_assets' ) );
21
+
22
+ add_action( 'save_post', array( $this, 'save_custom_costs' ), 110, 2 );
23
+ add_action( 'wcml_before_sync_product_data', array( $this, 'sync_bookings' ), 10, 3 );
24
+ add_action( 'wcml_before_sync_product', array( $this, 'sync_booking_data' ), 10, 2 );
25
+
26
+ add_filter( 'woocommerce_bookings_process_cost_rules_cost', array( $this, 'wc_bookings_process_cost_rules_cost' ), 10, 3 );
27
+ add_filter( 'woocommerce_bookings_process_cost_rules_base_cost', array( $this, 'wc_bookings_process_cost_rules_base_cost' ), 10, 3 );
28
+ add_filter( 'woocommerce_bookings_process_cost_rules_override_block', array( $this, 'wc_bookings_process_cost_rules_override_block_cost' ), 10, 3 );
29
+
30
+ add_filter( 'wcml_multi_currency_is_ajax', array( $this, 'wcml_multi_currency_is_ajax' ) );
31
+
32
+ add_filter( 'wcml_cart_contents_not_changed', array( $this, 'filter_bundled_product_in_cart_contents' ), 10, 3 );
33
+
34
+ add_action( 'woocommerce_bookings_after_create_booking_page', array( $this, 'booking_currency_dropdown' ) );
35
+ add_action( 'init', array( $this, 'set_booking_currency') );
36
+
37
+ add_action( 'wp_ajax_wcml_booking_set_currency', array( $this, 'set_booking_currency_ajax' ) );
38
+ add_action( 'woocommerce_bookings_create_booking_page_add_order_item', array( $this, 'set_order_currency_on_create_booking_page' ) );
39
+ add_filter( 'woocommerce_currency_symbol', array( $this, 'filter_booking_currency_symbol' ) );
40
+ add_filter( 'get_booking_products_args', array( $this, 'filter_get_booking_products_args' ) );
41
+ add_filter( 'wcml_filter_currency_position', array( $this, 'create_booking_page_client_currency' ) );
42
+
43
+ add_filter( 'wcml_client_currency', array( $this, 'create_booking_page_client_currency' ) );
44
+
45
+ add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html'), 10, 3 );
46
+ add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data'), 10, 4 );
47
+ add_filter( 'wcml_check_is_single', array( $this, 'show_custom_blocks_for_resources_and_persons'), 10, 3 );
48
+ add_filter( 'wcml_product_content_exception', array( $this, 'remove_custom_fields_to_translate' ), 10, 3 );
49
+ add_filter( 'wcml_not_display_single_fields_to_translate', array( $this, 'remove_single_custom_fields_to_translate' ) );
50
+ add_filter( 'wcml_product_content_label', array( $this, 'product_content_resource_label' ), 10, 2 );
51
+ add_action( 'wcml_update_extra_fields', array( $this, 'wcml_products_tab_sync_resources_and_persons'), 10, 4 );
52
+
53
+ add_action( 'woocommerce_new_booking', array( $this, 'duplicate_booking_for_translations') );
54
+
55
+ $bookings_statuses = array( 'unpaid', 'pending-confirmation', 'confirmed', 'paid', 'cancelled', 'complete', 'in-cart', 'was-in-cart' );
56
+ foreach( $bookings_statuses as $status ){
57
+ add_action('woocommerce_booking_' . $status, array( $this, 'update_status_for_translations' ) );
58
+ }
59
+
60
+ add_filter( 'parse_query', array( $this, 'booking_filters_query' ) );
61
+ add_filter( 'woocommerce_bookings_in_date_range_query', array( $this, 'bookings_in_date_range_query') );
62
+ add_action( 'before_delete_post', array( $this, 'delete_bookings' ) );
63
+ add_action( 'wp_trash_post', array( $this, 'trash_bookings' ) );
64
+
65
+ if( is_admin() ){
66
+
67
+ $this->tp = new WPML_Element_Translation_Package;
68
+
69
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_persons_to_translation_package' ), 10, 2 );
70
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_person_translation' ), 10, 3 );
71
+
72
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_resources_to_translation_package' ), 10, 2 );
73
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_resource_translation' ), 10, 3 );
74
+
75
+ //lock fields on translations pages
76
+ add_filter( 'wcml_js_lock_fields_ids', array( $this, 'wcml_js_lock_fields_ids' ) );
77
+ add_filter( 'wcml_after_load_lock_fields_js', array( $this, 'localize_lock_fields_js' ) );
78
+ }
79
+
80
+ if( !is_admin() || isset( $_POST['action'] ) && $_POST['action'] == 'wc_bookings_calculate_costs' ){
81
+ add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
82
+ }
83
+
84
+
85
+ $this->clear_transient_fields();
86
+
87
+ }
88
+
89
+ function wcml_price_field_after_booking_base_cost( $post_id ){
90
+
91
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_cost' );
92
+
93
+ }
94
+
95
+ function wcml_price_field_after_booking_block_cost( $post_id ){
96
+
97
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_base_cost' );
98
+
99
+ }
100
+
101
+ function wcml_price_field_after_display_cost( $post_id ){
102
+
103
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_display_cost' );
104
+
105
+ }
106
+
107
+ function wcml_price_field_after_booking_pricing_base_cost( $pricing, $post_id ){
108
+
109
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_pricing_base_cost', $pricing );
110
+
111
+ }
112
+
113
+ function wcml_price_field_after_booking_pricing_cost( $pricing, $post_id ){
114
+
115
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_pricing_cost', $pricing );
116
+
117
+ }
118
+
119
+ function wcml_price_field_after_person_cost( $person_type_id ){
120
+
121
+ $this->echo_wcml_price_field( $person_type_id, 'wcml_wc_booking_person_cost', false, false );
122
+
123
+ }
124
+
125
+ function wcml_price_field_after_person_block_cost( $person_type_id ){
126
+
127
+ $this->echo_wcml_price_field( $person_type_id, 'wcml_wc_booking_person_block_cost', false, false );
128
+
129
+ }
130
+
131
+ function wcml_price_field_after_resource_cost( $resource_id, $post_id ){
132
+
133
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_resource_cost', false, true, $resource_id );
134
+
135
+ }
136
+
137
+ function wcml_price_field_after_resource_block_cost( $resource_id, $post_id ){
138
+
139
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_resource_block_cost', false, true, $resource_id );
140
+
141
+ }
142
+
143
+ function echo_wcml_price_field( $post_id, $field, $pricing = false, $check = true, $resource_id = false ){
144
+ global $woocommerce_wpml;
145
+
146
+ if( ( !$check || $woocommerce_wpml->products->is_original_product( $post_id ) ) && $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
147
+
148
+ $currencies = $woocommerce_wpml->multi_currency->get_currencies();
149
+
150
+ $wc_currencies = get_woocommerce_currencies();
151
+
152
+ echo '<div class="wcml_custom_cost_field" >';
153
+
154
+ foreach($currencies as $currency_code => $currency){
155
+
156
+ switch( $field ){
157
+ case 'wcml_wc_booking_cost':
158
+ woocommerce_wp_text_input( array( 'id' => 'wcml_wc_booking_cost', 'class'=>'wcml_bookings_custom_price', 'name' => 'wcml_wc_booking_cost['.$currency_code.']', 'label' => get_woocommerce_currency_symbol($currency_code), 'description' => __( 'One-off cost for the booking as a whole.', 'woocommerce-bookings' ), 'value' => get_post_meta( $post_id, '_wc_booking_cost_'.$currency_code, true ), 'type' => 'number', 'desc_tip' => true, 'custom_attributes' => array(
159
+ 'min' => '',
160
+ 'step' => '0.01'
161
+ ) ) );
162
+ break;
163
+ case 'wcml_wc_booking_base_cost':
164
+ woocommerce_wp_text_input( array( 'id' => 'wcml_wc_booking_base_cost', 'class'=>'wcml_bookings_custom_price', 'name' => 'wcml_wc_booking_base_cost['.$currency_code.']', 'label' => get_woocommerce_currency_symbol($currency_code), 'description' => __( 'This is the cost per block booked. All other costs (for resources and persons) are added to this.', 'woocommerce-bookings' ), 'value' => get_post_meta( $post_id, '_wc_booking_base_cost_'.$currency_code, true ), 'type' => 'number', 'desc_tip' => true, 'custom_attributes' => array(
165
+ 'min' => '',
166
+ 'step' => '0.01'
167
+ ) ) );
168
+ break;
169
+ case 'wcml_wc_display_cost':
170
+ woocommerce_wp_text_input( array( 'id' => 'wcml_wc_display_cost', 'class'=>'wcml_bookings_custom_price', 'name' => 'wcml_wc_display_cost['.$currency_code.']', 'label' => get_woocommerce_currency_symbol($currency_code), 'description' => __( 'The cost is displayed to the user on the frontend. Leave blank to have it calculated for you. If a booking has varying costs, this will be prefixed with the word "from:".', 'woocommerce-bookings' ), 'value' => get_post_meta( $post_id, '_wc_display_cost_'.$currency_code, true ), 'type' => 'number', 'desc_tip' => true, 'custom_attributes' => array(
171
+ 'min' => '',
172
+ 'step' => '0.01'
173
+ ) ) );
174
+ break;
175
+
176
+ case 'wcml_wc_booking_pricing_base_cost':
177
+
178
+ if( isset( $pricing[ 'base_cost_'.$currency_code ] ) ){
179
+ $value = $pricing[ 'base_cost_'.$currency_code ];
180
+ }else{
181
+ $value = '';
182
+ }
183
+
184
+ echo '<div class="wcml_bookings_range_block" >';
185
+ echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
186
+ echo '<input type="number" step="0.01" name="wcml_wc_booking_pricing_base_cost['.$currency_code.'][]" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
187
+ echo '</div>';
188
+ break;
189
+
190
+ case 'wcml_wc_booking_pricing_cost':
191
+
192
+ if( isset( $pricing[ 'cost_'.$currency_code ] ) ){
193
+ $value = $pricing[ 'cost_'.$currency_code ];
194
+ }else{
195
+ $value = '';
196
+ }
197
+
198
+ echo '<div class="wcml_bookings_range_block" >';
199
+ echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
200
+ echo '<input type="number" step="0.01" name="wcml_wc_booking_pricing_cost['.$currency_code.'][]" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
201
+ echo '</div>';
202
+ break;
203
+
204
+ case 'wcml_wc_booking_person_cost':
205
+
206
+ $value = get_post_meta( $post_id, 'cost_'.$currency_code, true );
207
+
208
+ echo '<div class="wcml_bookings_person_block" >';
209
+ echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
210
+ echo '<input type="number" step="0.01" name="wcml_wc_booking_person_cost['.$post_id.']['.$currency_code.']" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
211
+ echo '</div>';
212
+ break;
213
+
214
+ case 'wcml_wc_booking_person_block_cost':
215
+
216
+ $value = get_post_meta( $post_id, 'block_cost_'.$currency_code, true );
217
+
218
+ echo '<div class="wcml_bookings_person_block" >';
219
+ echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
220
+ echo '<input type="number" step="0.01" name="wcml_wc_booking_person_block_cost['.$post_id.']['.$currency_code.']" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
221
+ echo '</div>';
222
+ break;
223
+
224
+ case 'wcml_wc_booking_resource_cost':
225
+
226
+ $resource_base_costs = maybe_unserialize( get_post_meta( $post_id, '_resource_base_costs', true ) );
227
+
228
+ if( isset( $resource_base_costs[ 'custom_costs' ][ $currency_code ][ $resource_id ] ) ){
229
+ $value = $resource_base_costs[ 'custom_costs' ][ $currency_code ][ $resource_id ];
230
+ }else{
231
+ $value = '';
232
+ }
233
+
234
+ echo '<div class="wcml_bookings_resource_block" >';
235
+ echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
236
+ echo '<input type="number" step="0.01" name="wcml_wc_booking_resource_cost['.$resource_id.']['.$currency_code.']" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
237
+ echo '</div>';
238
+ break;
239
+
240
+ case 'wcml_wc_booking_resource_block_cost':
241
+
242
+ $resource_block_costs = maybe_unserialize( get_post_meta( $post_id, '_resource_block_costs', true ) );
243
+
244
+ if( isset( $resource_block_costs[ 'custom_costs' ][ $currency_code ][ $resource_id ] ) ){
245
+ $value = $resource_block_costs[ 'custom_costs' ][ $currency_code ][ $resource_id ];
246
+ }else{
247
+ $value = '';
248
+ }
249
+
250
+ echo '<div class="wcml_bookings_resource_block" >';
251
+ echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
252
+ echo '<input type="number" step="0.01" name="wcml_wc_booking_resource_block_cost['.$resource_id.']['.$currency_code.']" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
253
+ echo '</div>';
254
+ break;
255
+
256
+ default:
257
+ break;
258
+
259
+ }
260
+
261
+ }
262
+
263
+ echo '</div>';
264
+
265
+ }
266
+ }
267
+
268
+ function after_bookings_pricing( $post_id ){
269
+ global $woocommerce_wpml;
270
+
271
+ if( in_array( 'booking', wp_get_post_terms( $post_id, 'product_type', array( "fields" => "names" ) ) ) && $woocommerce_wpml->products->is_original_product( $post_id ) && $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
272
+
273
+ $custom_costs_status = get_post_meta( $post_id, '_wcml_custom_costs_status', true );
274
+
275
+ $checked = !$custom_costs_status ? 'checked="checked"' : ' ';
276
+
277
+ echo '<div class="wcml_custom_costs">';
278
+
279
+ echo '<input type="radio" name="_wcml_custom_costs" id="wcml_custom_costs_auto" value="0" class="wcml_custom_costs_input" '. $checked .' />';
280
+ echo '<label for="wcml_custom_costs_auto">'. __('Calculate costs in other currencies automatically', 'woocommerce-multilingual') .'</label>';
281
+
282
+ $checked = $custom_costs_status == 1 ? 'checked="checked"' : ' ';
283
+
284
+ echo '<input type="radio" name="_wcml_custom_costs" value="1" id="wcml_custom_costs_manually" class="wcml_custom_costs_input" '. $checked .' />';
285
+ echo '<label for="wcml_custom_costs_manually">'. __('Set costs in other currencies manually', 'woocommerce-multilingual') .'</label>';
286
+
287
+ wp_nonce_field( 'wcml_save_custom_costs', '_wcml_custom_costs_nonce' );
288
+
289
+ echo '</div>';
290
+ }
291
+
292
+ }
293
+
294
+ function save_custom_costs( $post_id, $post ){
295
+ global $woocommerce_wpml;
296
+
297
+ $nonce = filter_input( INPUT_POST, '_wcml_custom_costs_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
298
+
299
+ if( isset( $_POST['_wcml_custom_costs'] ) && isset( $nonce ) && wp_verify_nonce( $nonce, 'wcml_save_custom_costs' ) ){
300
+
301
+ update_post_meta( $post_id, '_wcml_custom_costs_status', $_POST['_wcml_custom_costs'] );
302
+
303
+ if( $_POST['_wcml_custom_costs'] == 1 ){
304
+
305
+ $currencies = $woocommerce_wpml->multi_currency->get_currencies();
306
+
307
+ foreach( $currencies as $code => $currency ){
308
+
309
+ $wc_booking_cost = $_POST[ 'wcml_wc_booking_cost' ][ $code ];
310
+ update_post_meta( $post_id, '_wc_booking_cost_'.$code, $wc_booking_cost );
311
+
312
+ $wc_booking_base_cost = $_POST[ 'wcml_wc_booking_base_cost' ][ $code ];
313
+ update_post_meta( $post_id, '_wc_booking_base_cost_'.$code, $wc_booking_base_cost );
314
+
315
+ $wc_display_cost = $_POST[ 'wcml_wc_display_cost' ][ $code ];
316
+ update_post_meta( $post_id, '_wc_display_cost_'.$code, $wc_display_cost );
317
+
318
+ }
319
+
320
+ $booking_pricing = get_post_meta( $post_id, '_wc_booking_pricing', true );
321
+ foreach ( $booking_pricing as $key => $prices) {
322
+
323
+ $updated_meta[$key] = $prices;
324
+
325
+ foreach ($currencies as $code => $currency) {
326
+
327
+ $updated_meta[$key]['base_cost_' . $code] = $_POST['wcml_wc_booking_pricing_base_cost'][$code][$key];
328
+ $updated_meta[$key]['cost_' . $code] = $_POST['wcml_wc_booking_pricing_cost'][$code][$key];
329
+
330
+ }
331
+
332
+ }
333
+
334
+ update_post_meta($post_id, '_wc_booking_pricing', $updated_meta);
335
+
336
+ //person costs
337
+ if( isset( $_POST[ 'wcml_wc_booking_person_cost' ] ) ) {
338
+
339
+ foreach ($_POST['wcml_wc_booking_person_cost'] as $person_id => $costs) {
340
+
341
+ foreach ($currencies as $code => $currency) {
342
+
343
+ $wc_booking_person_cost = $costs[$code];
344
+ update_post_meta($person_id, 'cost_' . $code, $wc_booking_person_cost);
345
+
346
+ }
347
+
348
+ }
349
+
350
+ }
351
+
352
+ if( isset( $_POST[ 'wcml_wc_booking_person_cost' ] ) ){
353
+
354
+ foreach( $_POST[ 'wcml_wc_booking_person_block_cost' ] as $person_id => $costs ){
355
+
356
+ foreach( $currencies as $code => $currency ){
357
+
358
+ $wc_booking_person_block_cost = $costs[ $code ];
359
+ update_post_meta( $person_id, 'block_cost_'.$code, $wc_booking_person_block_cost );
360
+
361
+ }
362
+
363
+ }
364
+
365
+ }
366
+
367
+ if( isset( $_POST[ 'wcml_wc_booking_resource_cost' ] ) ) {
368
+
369
+ $updated_meta = get_post_meta( $post_id, '_resource_base_costs', true );
370
+
371
+ $wc_booking_resource_costs = array();
372
+
373
+ foreach ( $_POST['wcml_wc_booking_resource_cost'] as $resource_id => $costs) {
374
+
375
+ foreach ($currencies as $code => $currency) {
376
+
377
+ $wc_booking_resource_costs[ $code ][ $resource_id ] = $costs[ $code ];
378
+
379
+ }
380
+
381
+ }
382
+
383
+ $updated_meta[ 'custom_costs' ] = $wc_booking_resource_costs;
384
+
385
+ update_post_meta( $post_id, '_resource_base_costs', $updated_meta );
386
+
387
+ $this->sync_resource_costs_with_translations( $post_id, '_resource_base_costs' );
388
+
389
+ }
390
+
391
+ if( isset( $_POST[ 'wcml_wc_booking_resource_block_cost' ] ) ){
392
+
393
+ $updated_meta = get_post_meta( $post_id, '_resource_block_costs', true );
394
+
395
+ $wc_booking_resource_block_costs = array();
396
+
397
+ foreach( $_POST[ 'wcml_wc_booking_resource_block_cost' ] as $resource_id => $costs ){
398
+
399
+ foreach( $currencies as $code => $currency ){
400
+
401
+ $wc_booking_resource_block_costs[ $code ][ $resource_id ] = $costs[ $code ];
402
+
403
+ }
404
+
405
+ }
406
+
407
+ $updated_meta[ 'custom_costs' ] = $wc_booking_resource_block_costs;
408
+
409
+ update_post_meta( $post_id, '_resource_block_costs', $updated_meta );
410
+
411
+ $this->sync_resource_costs_with_translations( $post_id, '_resource_block_costs' );
412
+
413
+ }
414
+
415
+
416
+ }
417
+ }
418
+
419
+ }
420
+
421
+ // sync existing product bookings for translations
422
+ function sync_bookings( $original_product_id, $product_id, $lang ){
423
+ global $wpdb;
424
+
425
+ $all_bookings_for_product = $wpdb->get_results( $wpdb->prepare( "SELECT post_id as id FROM $wpdb->postmeta WHERE meta_key = '_booking_product_id' AND meta_value = %d", $original_product_id ) );
426
+
427
+ foreach($all_bookings_for_product as $booking ){
428
+ $check_if_exists = $wpdb->get_row( $wpdb->prepare( "SELECT pm3.* FROM {$wpdb->postmeta} AS pm1
429
+ LEFT JOIN {$wpdb->postmeta} AS pm2 ON pm1.post_id = pm2.post_id
430
+ LEFT JOIN {$wpdb->postmeta} AS pm3 ON pm1.post_id = pm3.post_id
431
+ WHERE pm1.meta_key = '_booking_duplicate_of' AND pm1.meta_value = %s AND pm2.meta_key = '_language_code' AND pm2.meta_value = %s AND pm3.meta_key = '_booking_product_id'"
432
+ , $booking->id, $lang ) );
433
+
434
+ if( is_null( $check_if_exists ) ){
435
+ $this->duplicate_booking_for_translations( $booking->id, $lang );
436
+ }elseif( $check_if_exists->meta_value === '' ){
437
+ update_post_meta( $check_if_exists->post_id, '_booking_product_id', $this->get_translated_booking_product_id( $booking->id, $lang ) );
438
+ update_post_meta( $check_if_exists->post_id, '_booking_resource_id', $this->get_translated_booking_resource_id( $booking->id, $lang ) );
439
+ update_post_meta( $check_if_exists->post_id, '_booking_persons', $this->get_translated_booking_persons_ids( $booking->id, $lang ) );
440
+ }
441
+ }
442
+
443
+
444
+ }
445
+
446
+ function sync_booking_data( $original_product_id, $current_product_id ){
447
+
448
+ if( has_term( 'booking', 'product_type', $original_product_id ) ){
449
+ global $wpdb, $sitepress, $pagenow, $iclTranslationManagement;
450
+
451
+ // get language code
452
+ $language_details = $sitepress->get_element_language_details( $original_product_id, 'post_product' );
453
+ if ( $pagenow == 'admin.php' && empty( $language_details ) ) {
454
+ //translation editor support: sidestep icl_translations_cache
455
+ $language_details = $wpdb->get_row( $wpdb->prepare( "SELECT element_id, trid, language_code, source_language_code FROM {$wpdb->prefix}icl_translations WHERE element_id = %d AND element_type = 'post_product'", $original_product_id ) );
456
+ }
457
+ if ( empty( $language_details ) ) {
458
+ return;
459
+ }
460
+
461
+ // pick posts to sync
462
+ $posts = array();
463
+ $translations = $sitepress->get_element_translations( $language_details->trid, 'post_product' );
464
+ foreach ( $translations as $translation ) {
465
+
466
+ if ( !$translation->original ) {
467
+ $posts[ $translation->element_id ] = $translation;
468
+ }
469
+ }
470
+
471
+ foreach ( $posts as $post_id => $translation ) {
472
+
473
+ $trn_lang = $sitepress->get_language_for_element( $post_id, 'post_product' );
474
+
475
+ //sync_resources
476
+ $this->sync_resources( $original_product_id, $post_id, $trn_lang );
477
+
478
+ //sync_persons
479
+ $this->sync_persons( $original_product_id, $post_id, $trn_lang );
480
+ }
481
+
482
+ }
483
+
484
+ }
485
+
486
+ function sync_resources( $original_product_id, $trnsl_product_id, $lang_code, $duplicate = true ){
487
+ global $wpdb;
488
+
489
+ $orig_resources = $wpdb->get_results( $wpdb->prepare( "SELECT resource_id, sort_order FROM {$wpdb->prefix}wc_booking_relationships WHERE product_id = %d", $original_product_id ) );
490
+
491
+ $trnsl_product_resources = $wpdb->get_col( $wpdb->prepare( "SELECT resource_id FROM {$wpdb->prefix}wc_booking_relationships WHERE product_id = %d", $trnsl_product_id ) );
492
+
493
+ foreach ($orig_resources as $resource) {
494
+
495
+ $trns_resource_id = apply_filters( 'translate_object_id', $resource->resource_id, 'bookable_resource', false, $lang_code );
496
+
497
+ if ( !is_null( $trns_resource_id ) && in_array( $trns_resource_id, $trnsl_product_resources ) ) {
498
+
499
+ if ( ( $key = array_search( $trns_resource_id, $trnsl_product_resources ) ) !== false ) {
500
+
501
+ unset($trnsl_product_resources[$key]);
502
+
503
+ $wpdb->update(
504
+ $wpdb->prefix . 'wc_booking_relationships',
505
+ array(
506
+ 'sort_order' => $resource->sort_order
507
+ ),
508
+ array(
509
+ 'product_id' => $trnsl_product_id,
510
+ 'resource_id' => $trns_resource_id
511
+ )
512
+ );
513
+
514
+ update_post_meta( $trns_resource_id, 'qty', get_post_meta( $resource->resource_id, 'qty', true ) );
515
+ update_post_meta( $trns_resource_id, '_wc_booking_availability', get_post_meta( $resource->resource_id, '_wc_booking_availability', true ) );
516
+
517
+ }
518
+
519
+ } else {
520
+
521
+ if( $duplicate ){
522
+
523
+ $trns_resource_id = $this->duplicate_resource( $trnsl_product_id, $resource, $lang_code );
524
+
525
+ }else{
526
+
527
+ continue;
528
+
529
+ }
530
+
531
+
532
+ }
533
+
534
+ }
535
+
536
+ foreach ($trnsl_product_resources as $trnsl_product_resource) {
537
+
538
+ $wpdb->delete(
539
+ $wpdb->prefix . 'wc_booking_relationships',
540
+ array(
541
+ 'product_id' => $trnsl_product_id,
542
+ 'resource_id' => $trnsl_product_resource
543
+ )
544
+ );
545
+
546
+ wp_delete_post( $trnsl_product_resource );
547
+
548
+ }
549
+
550
+ $this->sync_resource_costs( $original_product_id, $trnsl_product_id, '_resource_base_costs', $lang_code );
551
+ $this->sync_resource_costs( $original_product_id, $trnsl_product_id, '_resource_block_costs', $lang_code );
552
+
553
+ }
554
+
555
+ function duplicate_resource( $tr_product_id, $resource, $lang_code){
556
+ global $sitepress, $wpdb, $iclTranslationManagement;
557
+
558
+ if( method_exists( $sitepress, 'make_duplicate' ) ){
559
+
560
+ $trns_resource_id = $sitepress->make_duplicate( $resource->resource_id, $lang_code );
561
+
562
+ }else{
563
+
564
+ if ( !isset( $iclTranslationManagement ) ) {
565
+ $iclTranslationManagement = new TranslationManagement;
566
+ }
567
+
568
+ $trns_resource_id = $iclTranslationManagement->make_duplicate( $resource->resource_id, $lang_code );
569
+
570
+ }
571
+
572
+ $wpdb->insert(
573
+ $wpdb->prefix . 'wc_booking_relationships',
574
+ array(
575
+ 'product_id' => $tr_product_id,
576
+ 'resource_id' => $trns_resource_id,
577
+ 'sort_order' => $resource->sort_order
578
+ )
579
+ );
580
+
581
+ delete_post_meta( $trns_resource_id, '_icl_lang_duplicate_of' );
582
+
583
+ return $trns_resource_id;
584
+ }
585
+
586
+ function sync_persons( $original_product_id, $tr_product_id, $lang_code, $duplicate = true ){
587
+ global $wpdb, $woocommerce_wpml;
588
+
589
+ $orig_persons = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'bookable_person'", $original_product_id ) );
590
+
591
+ $trnsl_persons = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'bookable_person'", $tr_product_id ) );
592
+
593
+
594
+ foreach ($orig_persons as $person) {
595
+
596
+ $trnsl_person_id = apply_filters( 'translate_object_id', $person, 'bookable_person', false, $lang_code );
597
+
598
+ if ( !is_null( $trnsl_person_id ) && in_array( $trnsl_person_id, $trnsl_persons ) ) {
599
+
600
+ if ( ( $key = array_search( $trnsl_person_id, $trnsl_persons ) ) !== false ) {
601
+
602
+ unset($trnsl_persons[$key]);
603
+
604
+ update_post_meta( $trnsl_person_id, 'block_cost', get_post_meta( $person, 'block_cost', true ) );
605
+ update_post_meta( $trnsl_person_id, 'cost', get_post_meta( $person, 'cost', true ) );
606
+ update_post_meta( $trnsl_person_id, 'max', get_post_meta( $person, 'max', true ) );
607
+ update_post_meta( $trnsl_person_id, 'min', get_post_meta( $person, 'min', true ) );
608
+
609
+
610
+ if( get_post_meta( $person, '_wcml_custom_costs_status', true ) && $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT){
611
+ $currencies = $woocommerce_wpml->multi_currency->get_currencies();
612
+
613
+ foreach( $currencies as $code => $currency ){
614
+
615
+ update_post_meta( $trnsl_person_id, 'block_cost_'.$code, get_post_meta( $person, 'block_cost_'.$code, true ) );
616
+ update_post_meta( $trnsl_person_id, 'block_cost_'.$code, get_post_meta( $person, 'cost_'.$code, true ) );
617
+
618
+ }
619
+ }
620
+
621
+ }
622
+
623
+ }else{
624
+
625
+ if( $duplicate ) {
626
+
627
+ $this->duplicate_person($tr_product_id, $person, $lang_code);
628
+
629
+ }else{
630
+
631
+ continue;
632
+
633
+ }
634
+
635
+ }
636
+
637
+ }
638
+
639
+ foreach ($trnsl_persons as $trnsl_person) {
640
+
641
+ wp_delete_post( $trnsl_person );
642
+
643
+ }
644
+
645
+ }
646
+
647
+ function duplicate_person( $tr_product_id, $person_id, $lang_code ){
648
+ global $sitepress, $wpdb, $iclTranslationManagement;
649
+
650
+ if( method_exists( $sitepress, 'make_duplicate' ) ){
651
+
652
+ $new_person_id = $sitepress->make_duplicate( $person_id, $lang_code );
653
+
654
+ }else{
655
+
656
+ if ( !isset( $iclTranslationManagement ) ) {
657
+ $iclTranslationManagement = new TranslationManagement;
658
+ }
659
+
660
+ $new_person_id = $iclTranslationManagement->make_duplicate( $person_id, $lang_code );
661
+
662
+ }
663
+
664
+ $wpdb->update(
665
+ $wpdb->posts,
666
+ array(
667
+ 'post_parent' => $tr_product_id
668
+ ),
669
+ array(
670
+ 'ID' => $new_person_id
671
+ )
672
+ );
673
+
674
+ delete_post_meta( $new_person_id, '_icl_lang_duplicate_of' );
675
+
676
+ return $new_person_id;
677
+ }
678
+
679
+ function filter_wc_booking_cost( $check, $object_id, $meta_key, $single ){
680
+
681
+ if( in_array( $meta_key, array( '_wc_booking_cost', '_wc_booking_base_cost', '_wc_display_cost', '_wc_booking_pricing', 'cost', 'block_cost', '_resource_base_costs', '_resource_block_costs' ) ) ){
682
+
683
+ global $woocommerce_wpml;
684
+
685
+ if( $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
686
+
687
+ $original_id = apply_filters( 'translate_object_id', $object_id, 'product', true, $woocommerce_wpml->products->get_original_product_language( $object_id ) );
688
+
689
+ $cost_status = get_post_meta( $original_id, '_wcml_custom_costs_status', true );
690
+
691
+ $currency = $woocommerce_wpml->multi_currency->get_client_currency();
692
+
693
+ if ( $currency == get_option('woocommerce_currency') ){
694
+ return $check;
695
+ }
696
+
697
+ if( in_array( $meta_key, array( 'cost', 'block_cost' ) ) ) {
698
+
699
+ if ( get_post_type($object_id) == 'bookable_person' ) {
700
+
701
+ $value = get_post_meta($object_id, $meta_key . '_' . $currency, true);
702
+
703
+ if ( $cost_status && $value ) {
704
+
705
+ return $value;
706
+
707
+ } else {
708
+
709
+ remove_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
710
+
711
+ $cost = get_post_meta( $object_id, $meta_key, true);
712
+
713
+ add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
714
+
715
+ return $woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
716
+ }
717
+
718
+ } else {
719
+
720
+ return $check;
721
+
722
+ }
723
+
724
+ }
725
+
726
+ if( in_array ( $meta_key, array( '_wc_booking_pricing', '_resource_base_costs', '_resource_block_costs' ) ) ){
727
+
728
+ remove_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
729
+
730
+ if( $meta_key == '_wc_booking_pricing' ){
731
+
732
+ if( $original_id != $object_id ){
733
+ $value = get_post_meta( $original_id, $meta_key );
734
+ }else{
735
+ $value = $check;
736
+ }
737
+
738
+ }else{
739
+
740
+ $costs = maybe_unserialize( get_post_meta( $object_id, $meta_key, true ) );
741
+
742
+ if( !$costs ){
743
+ $value = $check;
744
+ }elseif( $cost_status && isset( $costs[ 'custom_costs' ][ $currency ] ) ){
745
+ $value = array( 0 => $costs[ 'custom_costs' ][ $currency ] );
746
+ }elseif( $cost_status && isset( $costs[ 0 ][ 'custom_costs' ][ $currency ] )){
747
+ $value = array( 0 => $costs[ 0 ][ 'custom_costs' ][ $currency ] );
748
+ }else{
749
+
750
+ $converted_values = array();
751
+
752
+ foreach( $costs as $resource_id => $cost ){
753
+ $converted_values[0][ $resource_id ] = $woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
754
+ }
755
+
756
+ $value = $converted_values;
757
+ }
758
+
759
+ }
760
+
761
+ add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
762
+
763
+ return $value;
764
+
765
+ }
766
+
767
+ $value = get_post_meta( $original_id, $meta_key.'_'.$currency, true );
768
+
769
+ if( $cost_status && ( !empty($value) || ( empty($value) && $meta_key == '_wc_display_cost' ) ) ){
770
+
771
+ return $value;
772
+
773
+ }else{
774
+
775
+ remove_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
776
+
777
+ $value = get_post_meta( $original_id, $meta_key, true );
778
+
779
+ $value = $woocommerce_wpml->multi_currency->prices->convert_price_amount( $value, $currency );
780
+
781
+ add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
782
+
783
+ return $value;
784
+
785
+ }
786
+
787
+ }
788
+
789
+ }
790
+
791
+ return $check;
792
+ }
793
+
794
+ function sync_resource_costs_with_translations( $object_id, $meta_key, $check = false ){
795
+ global $sitepress,$woocommerce_wpml;
796
+
797
+ $original_product_id = apply_filters( 'translate_object_id', $object_id, 'product', true, $woocommerce_wpml->products->get_original_product_language( $object_id ) );
798
+
799
+ if( $object_id == $original_product_id ){
800
+
801
+ $trid = $sitepress->get_element_trid( $object_id, 'post_product' );
802
+ $translations = $sitepress->get_element_translations( $trid, 'post_product' );
803
+
804
+ foreach ( $translations as $translation ) {
805
+
806
+ if ( !$translation->original ) {
807
+
808
+ $this->sync_resource_costs( $original_product_id, $translation->element_id, $meta_key, $translation->language_code );
809
+
810
+ }
811
+ }
812
+
813
+ return $check;
814
+
815
+ }else{
816
+
817
+ $language_code = $sitepress->get_language_for_element( $object_id, 'post_product' );
818
+
819
+ $this->sync_resource_costs( $original_product_id, $object_id, $meta_key, $language_code );
820
+
821
+ return true;
822
+
823
+ }
824
+
825
+ }
826
+
827
+ function sync_resource_costs( $original_product_id, $object_id, $meta_key, $language_code ){
828
+
829
+ $original_costs = maybe_unserialize( get_post_meta( $original_product_id, $meta_key, true ) );
830
+
831
+ $wc_booking_resource_costs = array();
832
+ if( !empty( $original_costs ) ) {
833
+ foreach ($original_costs as $resource_id => $costs) {
834
+
835
+ if ($resource_id == 'custom_costs' && isset($costs['custom_costs'])) {
836
+
837
+ foreach ($costs['custom_costs'] as $code => $currencies) {
838
+
839
+ foreach ($currencies as $custom_costs_resource_id => $custom_cost) {
840
+
841
+ $trns_resource_id = apply_filters('translate_object_id', $custom_costs_resource_id, 'bookable_resource', true, $language_code);
842
+
843
+ $wc_booking_resource_costs['custom_costs'][$code][$trns_resource_id] = $custom_cost;
844
+
845
+ }
846
+
847
+ }
848
+
849
+ } else {
850
+
851
+ $trns_resource_id = apply_filters('translate_object_id', $resource_id, 'bookable_resource', true, $language_code);
852
+
853
+ $wc_booking_resource_costs[$trns_resource_id] = $costs;
854
+
855
+ }
856
+
857
+ }
858
+ }
859
+
860
+ update_post_meta( $object_id, $meta_key, $wc_booking_resource_costs );
861
+
862
+ }
863
+
864
+ function wc_bookings_process_cost_rules_cost( $cost, $fields, $key ){
865
+ return $this->filter_pricing_cost( $cost, $fields, 'cost_', $key );
866
+ }
867
+
868
+ function wc_bookings_process_cost_rules_base_cost( $base_cost, $fields, $key ){
869
+ return $this->filter_pricing_cost( $base_cost, $fields, 'base_cost_', $key );
870
+ }
871
+
872
+ function wc_bookings_process_cost_rules_override_block_cost( $override_cost, $fields, $key ){
873
+ return $this->filter_pricing_cost( $override_cost, $fields, 'override_block_', $key );
874
+ }
875
+
876
+ function filter_pricing_cost( $cost, $fields, $name, $key ){
877
+ global $woocommerce_wpml, $product;
878
+
879
+ if( $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
880
+
881
+ $currency = $woocommerce_wpml->multi_currency->get_client_currency();
882
+
883
+ if ( $currency == get_option('woocommerce_currency') ) {
884
+ return $cost;
885
+ }
886
+
887
+ if( isset( $_POST[ 'form' ] ) ){
888
+ parse_str( $_POST[ 'form' ], $posted );
889
+
890
+ $booking_id = $posted[ 'add-to-cart' ];
891
+
892
+ }elseif( isset( $_POST[ 'add-to-cart' ] ) ){
893
+
894
+ $booking_id = $_POST[ 'add-to-cart' ];
895
+
896
+ }
897
+
898
+ if( isset( $booking_id ) ){
899
+ $original_id = apply_filters( 'translate_object_id', $booking_id, 'product', true, $woocommerce_wpml->products->get_original_product_language( $booking_id ) );
900
+
901
+ if( $booking_id != $original_id ){
902
+ $fields = maybe_unserialize( get_post_meta( $original_id, '_wc_booking_pricing', true ) );
903
+ $fields = $fields[$key];
904
+ }
905
+ }
906
+
907
+ if( isset( $fields[ $name.$currency ] ) ){
908
+ return $fields[ $name.$currency ];
909
+ }else{
910
+ return $woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
911
+ }
912
+
913
+ }
914
+
915
+ return $cost;
916
+
917
+ }
918
+
919
+ function load_assets( ){
920
+ global $pagenow, $woocommerce_wpml;
921
+
922
+ if( $pagenow == 'post.php' || $pagenow == 'post-new.php' ){
923
+
924
+ wp_register_style( 'wcml-bookings-css', WCML_PLUGIN_URL . '/compatibility/res/css/wcml-bookings.css', array(), WCML_VERSION );
925
+ wp_enqueue_style( 'wcml-bookings-css' );
926
+
927
+ wp_register_script( 'wcml-bookings-js', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-bookings.js', array( 'jquery' ), WCML_VERSION );
928
+ wp_enqueue_script( 'wcml-bookings-js' );
929
+
930
+ }
931
+
932
+ }
933
+
934
+ function localize_lock_fields_js(){
935
+ wp_localize_script( 'wcml-bookings-js', 'lock_settings' , array( 'lock_fields' => 1 ) );
936
+ }
937
+
938
+ function wcml_multi_currency_is_ajax( $actions ){
939
+
940
+ $actions[] = 'wc_bookings_calculate_costs';
941
+
942
+ return $actions;
943
+ }
944
+
945
+ function filter_bundled_product_in_cart_contents( $cart_item, $key, $current_language ){
946
+
947
+ if( $cart_item[ 'data' ] instanceof WC_Product_Booking && isset( $cart_item[ 'booking' ] ) ){
948
+ global $woocommerce_wpml;
949
+
950
+ $current_id = apply_filters( 'translate_object_id', $cart_item[ 'data' ]->id, 'product', true, $current_language );
951
+ $cart_product_id = $cart_item['data']->id;
952
+
953
+ if( $current_id != $cart_product_id ) {
954
+
955
+ $cart_item['data'] = new WC_Product_Booking( $current_id );
956
+
957
+ }
958
+
959
+ if( $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT || $current_id != $cart_product_id ){
960
+
961
+ $booking_info = array(
962
+ 'wc_bookings_field_start_date_year' => $cart_item[ 'booking' ][ '_year' ],
963
+ 'wc_bookings_field_start_date_month' => $cart_item[ 'booking' ][ '_month' ],
964
+ 'wc_bookings_field_start_date_day' => $cart_item[ 'booking' ][ '_day' ],
965
+ 'add-to-cart' => $current_id
966
+ );
967
+
968
+ if( isset( $cart_item[ 'booking' ][ '_persons' ] ) ){
969
+ foreach( $cart_item[ 'booking' ][ '_persons' ] as $person_id => $value ){
970
+ $booking_info[ 'wc_bookings_field_persons_' . apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $current_language ) ] = $value;
971
+ }
972
+ }
973
+
974
+ if( isset( $cart_item[ 'booking' ][ '_resource_id' ] ) ){
975
+ $booking_info[ 'wc_bookings_field_resource' ] = apply_filters( 'translate_object_id', $cart_item[ 'booking' ][ '_resource_id' ], 'bookable_resource', false, $current_language);
976
+ }
977
+
978
+ if( isset( $cart_item[ 'booking' ][ '_duration' ] ) ){
979
+ $booking_info[ 'wc_bookings_field_duration' ] = $cart_item[ 'booking' ][ '_duration' ];
980
+ }
981
+
982
+ if( isset( $cart_item[ 'booking' ][ '_time' ] ) ){
983
+ $booking_info[ 'wc_bookings_field_start_date_time' ] = $cart_item[ 'booking' ][ '_time' ];
984
+ }
985
+
986
+ $booking_form = new WC_Booking_Form( wc_get_product( $current_id ) );
987
+
988
+ $prod_qty = get_post_meta( $current_id, '_wc_booking_qty', true );
989
+ update_post_meta( $current_id, '_wc_booking_qty', intval( $prod_qty + $cart_item[ 'booking' ][ '_qty' ] ) );
990
+ $cost = $booking_form->calculate_booking_cost( $booking_info );
991
+ update_post_meta( $current_id, '_wc_booking_qty', $prod_qty );
992
+
993
+ if( !is_wp_error( $cost ) ){
994
+ $cart_item[ 'data' ]->set_price( $cost );
995
+ }
996
+ }
997
+
998
+ }
999
+
1000
+ return $cart_item;
1001
+
1002
+ }
1003
+
1004
+ function booking_currency_dropdown(){
1005
+ global $woocommerce_wpml, $sitepress;
1006
+
1007
+ if( $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
1008
+ $current_booking_currency = $this->get_cookie_booking_currency();
1009
+
1010
+ $wc_currencies = get_woocommerce_currencies();
1011
+ $currencies = $woocommerce_wpml->multi_currency->get_currencies( $include_default = true );
1012
+ ?>
1013
+ <tr valign="top">
1014
+ <th scope="row"><?php _e( 'Booking currency', 'woocommerce-multilingual' ); ?></th>
1015
+ <td>
1016
+ <select id="dropdown_booking_currency">
1017
+
1018
+ <?php foreach($currencies as $currency => $count ): ?>
1019
+
1020
+ <option value="<?php echo $currency ?>" <?php echo $current_booking_currency == $currency ? 'selected="selected"':''; ?>><?php echo $wc_currencies[$currency]; ?></option>
1021
+
1022
+ <?php endforeach; ?>
1023
+
1024
+ </select>
1025
+ </td>
1026
+ </tr>
1027
+
1028
+ <?php
1029
+
1030
+ $wcml_booking_set_currency_nonce = wp_create_nonce( 'booking_set_currency' );
1031
+
1032
+ wc_enqueue_js( "
1033
+
1034
+ jQuery(document).on('change', '#dropdown_booking_currency', function(){
1035
+ jQuery.ajax({
1036
+ url: ajaxurl,
1037
+ type: 'post',
1038
+ data: {
1039
+ action: 'wcml_booking_set_currency',
1040
+ currency: jQuery('#dropdown_booking_currency').val(),
1041
+ wcml_nonce: '".$wcml_booking_set_currency_nonce."'
1042
+ },
1043
+ success: function( response ){
1044
+ if(typeof response.error !== 'undefined'){
1045
+ alert(response.error);
1046
+ }else{
1047
+ window.location = window.location.href;
1048
+ }
1049
+ }
1050
+ })
1051
+ });
1052
+ ");
1053
+
1054
+ }
1055
+
1056
+ }
1057
+
1058
+ function set_booking_currency_ajax(){
1059
+
1060
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
1061
+ if(!$nonce || !wp_verify_nonce($nonce, 'booking_set_currency')){
1062
+ echo json_encode(array('error' => __('Invalid nonce', 'woocommerce-multilingual')));
1063
+ die();
1064
+ }
1065
+
1066
+ $this->set_booking_currency(filter_input( INPUT_POST, 'currency', FILTER_SANITIZE_FULL_SPECIAL_CHARS ));
1067
+
1068
+ die();
1069
+ }
1070
+
1071
+ function set_booking_currency( $currency_code = false ){
1072
+
1073
+ if( !isset( $_COOKIE [ '_wcml_booking_currency' ]) && !headers_sent()) {
1074
+ global $woocommerce_wpml;
1075
+
1076
+ $currency_code = get_woocommerce_currency();
1077
+
1078
+ if ( $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
1079
+ $order_currencies = $woocommerce_wpml->multi_currency->orders->get_orders_currencies();
1080
+
1081
+ if (!isset($order_currencies[$currency_code])) {
1082
+ foreach ($order_currencies as $currency_code => $count) {
1083
+ $currency_code = $currency_code;
1084
+ break;
1085
+ }
1086
+ }
1087
+ }
1088
+ }
1089
+
1090
+ if( $currency_code ){
1091
+ setcookie('_wcml_booking_currency', $currency_code , time() + 86400, COOKIEPATH, COOKIE_DOMAIN);
1092
+ }
1093
+
1094
+ }
1095
+
1096
+ function get_cookie_booking_currency(){
1097
+
1098
+ if( isset( $_COOKIE [ '_wcml_booking_currency' ] ) ){
1099
+ $currency = $_COOKIE[ '_wcml_booking_currency' ];
1100
+ }else{
1101
+ $currency = get_woocommerce_currency();
1102
+ }
1103
+
1104
+ return $currency;
1105
+ }
1106
+
1107
+ function filter_booking_currency_symbol( $currency ){
1108
+ global $pagenow;
1109
+
1110
+ remove_filter( 'woocommerce_currency_symbol', array( $this, 'filter_booking_currency_symbol' ) );
1111
+ if( isset( $_COOKIE [ '_wcml_booking_currency' ] ) && $pagenow == 'edit.php' && isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'create_booking' ){
1112
+ $currency = get_woocommerce_currency_symbol( $_COOKIE [ '_wcml_booking_currency' ] );
1113
+ }
1114
+ add_filter( 'woocommerce_currency_symbol', array( $this, 'filter_booking_currency_symbol' ) );
1115
+
1116
+ return $currency;
1117
+ }
1118
+
1119
+ function create_booking_page_client_currency( $currency ){
1120
+ global $pagenow;
1121
+
1122
+ if( wpml_is_ajax() && isset( $_POST[ 'form' ] ) ){
1123
+ parse_str( $_POST[ 'form' ], $posted );
1124
+ }
1125
+
1126
+ if( ( $pagenow == 'edit.php' && isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'create_booking' ) || ( isset( $posted[ '_wp_http_referer' ] ) && strpos( $posted[ '_wp_http_referer' ], 'page=create_booking' ) !== false ) ){
1127
+ $currency = $this->get_cookie_booking_currency();
1128
+ }
1129
+
1130
+ return $currency;
1131
+ }
1132
+
1133
+ function set_order_currency_on_create_booking_page( $order_id ){
1134
+ global $sitepress;
1135
+
1136
+ update_post_meta( $order_id, '_order_currency', $this->get_cookie_booking_currency() );
1137
+
1138
+ update_post_meta( $order_id, 'wpml_language', $sitepress->get_current_language() );
1139
+
1140
+ }
1141
+
1142
+ function filter_get_booking_products_args( $args ){
1143
+ if( isset( $args['suppress_filters'] ) ){
1144
+ $args['suppress_filters'] = false;
1145
+ }
1146
+ return $args;
1147
+ }
1148
+
1149
+ function custom_box_html( $obj, $product_id, $data ){
1150
+ global $wpdb;
1151
+
1152
+ if( wc_get_product($product_id)->product_type != 'booking' ){
1153
+ return;
1154
+ }
1155
+
1156
+ $bookings_section = new WPML_Editor_UI_Field_Section( __( 'Bookings', 'woocommerce-multilingual' ) );
1157
+
1158
+ if( get_post_meta( $product_id,'_wc_booking_has_resources',true) == 'yes' ){
1159
+ $group = new WPML_Editor_UI_Field_Group( '', true );
1160
+ $booking_field = new WPML_Editor_UI_Single_Line_Field( '_wc_booking_resouce_label', __( 'Resources Label', 'woocommerce-multilingual' ), $data, true );
1161
+ $group->add_field( $booking_field );
1162
+ $bookings_section->add_field( $group );
1163
+ }
1164
+
1165
+ $orig_resources = maybe_unserialize( get_post_meta( $product_id, '_resource_base_costs', true ) );
1166
+
1167
+ if( $orig_resources ){
1168
+ $group = new WPML_Editor_UI_Field_Group( __( 'Resources', 'woocommerce-multilingual' ) );
1169
+ $group_title = __( 'Resources', 'woocommerce-multilingual' );
1170
+ foreach ( $orig_resources as $resource_id => $cost) {
1171
+
1172
+ if ($resource_id == 'custom_costs') continue;
1173
+
1174
+ $group = new WPML_Editor_UI_Field_Group( $group_title );
1175
+ $group_title = '';
1176
+
1177
+ $resource_field = new WPML_Editor_UI_Single_Line_Field( 'bookings-resource_'.$resource_id.'_title', __( 'Title', 'woocommerce-multilingual' ), $data, true );
1178
+ $group->add_field( $resource_field );
1179
+ $bookings_section->add_field( $group );
1180
+ }
1181
+
1182
+ }
1183
+
1184
+ $original_persons = $this->get_original_persons( $product_id );
1185
+ end( $original_persons );
1186
+ $last_key = key( $original_persons );
1187
+ $divider = true;
1188
+ $group_title = __( 'Person Types', 'woocommerce-multilingual' );
1189
+ foreach( $original_persons as $person_id ){
1190
+ if( $person_id == $last_key ){
1191
+ $divider = false;
1192
+ }
1193
+ $group = new WPML_Editor_UI_Field_Group( $group_title , $divider );
1194
+ $group_title = '';
1195
+
1196
+ $person_field = new WPML_Editor_UI_Single_Line_Field( 'bookings-person_'.$person_id.'_title', __( 'Person Type Name', 'woocommerce-multilingual' ), $data, false );
1197
+ $group->add_field( $person_field );
1198
+ $person_field = new WPML_Editor_UI_Single_Line_Field( 'bookings-person_'.$person_id.'_description', __( 'Description', 'woocommerce-multilingual' ), $data, false );
1199
+ $group->add_field( $person_field );
1200
+ $bookings_section->add_field( $group );
1201
+
1202
+ }
1203
+
1204
+ if( $orig_resources || $original_persons ){
1205
+ $obj->add_field( $bookings_section );
1206
+ }
1207
+
1208
+ }
1209
+
1210
+
1211
+ function custom_box_html_data( $data, $product_id, $translation, $lang ){
1212
+
1213
+ if( wc_get_product($product_id)->product_type != 'booking' ){
1214
+ return $data;
1215
+ }
1216
+
1217
+ if( get_post_meta( $product_id,'_wc_booking_has_resources',true) == 'yes' ){
1218
+
1219
+ $data[ '_wc_booking_resouce_label' ] = array( 'original' => get_post_meta( $product_id,'_wc_booking_resouce_label',true) );
1220
+ $data[ '_wc_booking_resouce_label' ][ 'translation' ] = $translation ? get_post_meta( $translation->ID,'_wc_booking_resouce_label',true) : '';
1221
+ }
1222
+
1223
+ $orig_resources = $this->get_original_resources( $product_id );
1224
+
1225
+ if( $orig_resources ){
1226
+
1227
+ foreach ( $orig_resources as $resource_id => $cost) {
1228
+
1229
+ if ($resource_id == 'custom_costs') continue;
1230
+ $data[ 'bookings-resource_'.$resource_id.'_title' ] = array( 'original' => get_the_title( $resource_id ) );
1231
+
1232
+ $trns_resource_id = apply_filters('translate_object_id', $resource_id, 'bookable_resource', false, $lang);
1233
+ $data[ 'bookings-resource_'.$resource_id.'_title' ][ 'translation' ] = $trns_resource_id ? get_the_title( $trns_resource_id ) : '';
1234
+ }
1235
+ }
1236
+
1237
+ $original_persons = $this->get_original_persons( $product_id );
1238
+
1239
+ foreach( $original_persons as $person_id ){
1240
+
1241
+ $data[ 'bookings-person_'.$person_id.'_title' ] = array( 'original' => get_the_title( $person_id ) );
1242
+ $data[ 'bookings-person_'.$person_id.'_description' ] = array( 'original' => get_post( $person_id )->post_excerpt );
1243
+
1244
+ $trnsl_person_id = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $lang );
1245
+ $data[ 'bookings-person_'.$person_id.'_title' ][ 'translation' ] = $trnsl_person_id ? get_the_title( $trnsl_person_id ) : '';
1246
+ $data[ 'bookings-person_'.$person_id.'_description' ][ 'translation' ] = $trnsl_person_id ? get_post( $trnsl_person_id )->post_excerpt : '';
1247
+
1248
+ }
1249
+
1250
+ return $data;
1251
+ }
1252
+
1253
+
1254
+ function get_original_resources( $product_id ){
1255
+ $orig_resources = maybe_unserialize( get_post_meta( $product_id, '_resource_base_costs', true ) );
1256
+ return $orig_resources;
1257
+ }
1258
+
1259
+ function get_original_persons( $product_id ){
1260
+ global $wpdb;
1261
+ $original_persons = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'bookable_person' AND post_status = 'publish'", $product_id ) );
1262
+ return $original_persons;
1263
+ }
1264
+
1265
+ function show_custom_blocks_for_resources_and_persons( $check, $product_id, $product_content ){
1266
+ if( in_array( $product_content, array( 'wc_booking_resources', 'wc_booking_persons' ) ) ){
1267
+ return false;
1268
+ }
1269
+ return $check;
1270
+ }
1271
+
1272
+ function remove_custom_fields_to_translate( $exception, $product_id, $meta_key ){
1273
+ if( in_array( $meta_key, array( '_resource_base_costs', '_resource_block_costs' ) ) ){
1274
+ $exception = true;
1275
+ }
1276
+ return $exception;
1277
+ }
1278
+
1279
+ function remove_single_custom_fields_to_translate( $fields ){
1280
+ $fields[] = '_wc_booking_resouce_label';
1281
+
1282
+ return $fields;
1283
+ }
1284
+
1285
+ function product_content_resource_label( $meta_key, $product_id ){
1286
+ if ($meta_key == '_wc_booking_resouce_label'){
1287
+ return __( 'Resources label', 'woocommerce-multilingual' );
1288
+ }
1289
+ return $meta_key;
1290
+ }
1291
+
1292
+ function wcml_products_tab_sync_resources_and_persons( $original_product_id, $tr_product_id, $data, $language ){
1293
+ global $wpdb, $woocommerce_wpml, $wpml_post_translations;
1294
+
1295
+ remove_action ( 'save_post', array( $wpml_post_translations, 'save_post_actions' ), 100, 2 );
1296
+
1297
+ $orig_resources = $orig_resources = $this->get_original_resources( $original_product_id );;
1298
+
1299
+ if( $orig_resources ){
1300
+
1301
+ foreach( $orig_resources as $orig_resource_id => $cost ){
1302
+
1303
+ $resource_id = apply_filters( 'translate_object_id', $orig_resource_id, 'bookable_resource', false, $language );
1304
+ $orig_resource = $wpdb->get_row( $wpdb->prepare( "SELECT resource_id, sort_order FROM {$wpdb->prefix}wc_booking_relationships WHERE resource_id = %d AND product_id = %d", $orig_resource_id, $original_product_id ), OBJECT );
1305
+
1306
+ if( is_null( $resource_id ) ){
1307
+
1308
+ if( $orig_resource ) {
1309
+ $resource_id = $this->duplicate_resource( $tr_product_id, $orig_resource, $language);
1310
+ }else{
1311
+ continue;
1312
+ }
1313
+
1314
+ }else{
1315
+ //update_relationship
1316
+
1317
+ $exist = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->prefix}wc_booking_relationships WHERE resource_id = %d AND product_id = %d", $resource_id, $tr_product_id ) );
1318
+
1319
+ if( !$exist ){
1320
+
1321
+ $wpdb->insert(
1322
+ $wpdb->prefix . 'wc_booking_relationships',
1323
+ array(
1324
+ 'product_id' => $tr_product_id,
1325
+ 'resource_id' => $resource_id,
1326
+ 'sort_order' => $orig_resource->sort_order
1327
+ )
1328
+ );
1329
+
1330
+ }
1331
+
1332
+ }
1333
+
1334
+
1335
+
1336
+ $wpdb->update(
1337
+ $wpdb->posts,
1338
+ array(
1339
+ 'post_title' => $data[ md5( 'bookings-resource_'.$orig_resource_id.'_title') ]
1340
+ ),
1341
+ array(
1342
+ 'ID' => $resource_id
1343
+ )
1344
+ );
1345
+
1346
+ update_post_meta( $resource_id, 'wcml_is_translated', true );
1347
+
1348
+ }
1349
+
1350
+ //sync resources data
1351
+ $this->sync_resources( $original_product_id, $tr_product_id, $language, false );
1352
+
1353
+ }
1354
+
1355
+ $original_persons = $this->get_original_persons( $original_product_id );
1356
+
1357
+ //sync persons
1358
+ if( $original_persons ){
1359
+
1360
+ foreach( $original_persons as $original_person_id ){
1361
+
1362
+ $person_id = apply_filters( 'translate_object_id', $original_person_id, 'bookable_person', false, $language );
1363
+
1364
+ if( is_null( $person_id ) ){
1365
+
1366
+ $person_id = $this->duplicate_person( $tr_product_id, $original_person_id, $language);
1367
+
1368
+ }else{
1369
+
1370
+ $wpdb->update(
1371
+ $wpdb->posts,
1372
+ array(
1373
+ 'post_parent' => $tr_product_id
1374
+ ),
1375
+ array(
1376
+ 'ID' => $person_id
1377
+ )
1378
+ );
1379
+
1380
+ }
1381
+
1382
+ $wpdb->update(
1383
+ $wpdb->posts,
1384
+ array(
1385
+ 'post_title' => $data[ md5 ( 'bookings-person_'.$original_person_id.'_title' ) ],
1386
+ 'post_excerpt' => $data[ md5( 'bookings-person_'.$original_person_id.'_description' ) ],
1387
+ ),
1388
+ array(
1389
+ 'ID' => $person_id
1390
+ )
1391
+ );
1392
+
1393
+ update_post_meta( $person_id, 'wcml_is_translated', true );
1394
+
1395
+ }
1396
+
1397
+ //sync persons data
1398
+ $this->sync_persons( $original_product_id, $tr_product_id, $language, false );
1399
+
1400
+ }
1401
+
1402
+ add_action ( 'save_post', array( $wpml_post_translations, 'save_post_actions' ), 100, 2 );
1403
+
1404
+ }
1405
+
1406
+ function duplicate_booking_for_translations( $booking_id, $lang = false ){
1407
+ global $sitepress;
1408
+
1409
+ $booking_object = get_post( $booking_id );
1410
+
1411
+ $booking_data = array(
1412
+ 'post_type' => 'wc_booking',
1413
+ 'post_title' => $booking_object->post_title,
1414
+ 'post_status' => $booking_object->post_status,
1415
+ 'ping_status' => 'closed',
1416
+ 'post_parent' => $booking_object->post_parent,
1417
+ );
1418
+
1419
+ $active_languages = $sitepress->get_active_languages();
1420
+
1421
+ foreach( $active_languages as $language ){
1422
+
1423
+ $booking_product_id = get_post_meta( $booking_id, '_booking_product_id', true );
1424
+
1425
+ if( !$lang ){
1426
+ $booking_language = $sitepress->get_element_language_details( $booking_product_id, 'post_product' );
1427
+ if ( $booking_language->language_code == $language['code'] ) {
1428
+ continue;
1429
+ }
1430
+ }elseif( $lang != $language['code'] ){
1431
+ continue;
1432
+ }
1433
+
1434
+ $booking_persons = maybe_unserialize( get_post_meta( $booking_id, '_booking_persons', true ) );
1435
+ $trnsl_booking_persons = array();
1436
+
1437
+ foreach( $booking_persons as $person_id => $person_count ){
1438
+
1439
+ $trnsl_person_id = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $language['code'] );
1440
+
1441
+ if( is_null( $trnsl_person_id ) ){
1442
+ $trnsl_booking_persons[] = $person_count;
1443
+ }else{
1444
+ $trnsl_booking_persons[ $trnsl_person_id ] = $person_count;
1445
+ }
1446
+
1447
+ }
1448
+
1449
+ $trnsl_booking_id = wp_insert_post( $booking_data );
1450
+
1451
+ $meta_args = array(
1452
+ '_booking_order_item_id' => get_post_meta( $booking_id, '_booking_order_item_id', true ),
1453
+ '_booking_product_id' => $this->get_translated_booking_product_id( $booking_id, $language['code'] ),
1454
+ '_booking_resource_id' => $this->get_translated_booking_resource_id( $booking_id, $language['code'] ),
1455
+ '_booking_persons' => $this->get_translated_booking_persons_ids( $booking_id, $language['code'] ),
1456
+ '_booking_cost' => get_post_meta( $booking_id, '_booking_cost', true ),
1457
+ '_booking_start' => get_post_meta( $booking_id, '_booking_start', true ),
1458
+ '_booking_end' => get_post_meta( $booking_id, '_booking_end', true ),
1459
+ '_booking_all_day' => intval( get_post_meta( $booking_id, '_booking_all_day', true ) ),
1460
+ '_booking_parent_id' => get_post_meta( $booking_id, '_booking_parent_id', true ),
1461
+ '_booking_customer_id' => get_post_meta( $booking_id, '_booking_customer_id', true ),
1462
+ '_booking_duplicate_of' => $booking_id,
1463
+ '_language_code' => $language['code'],
1464
+ );
1465
+
1466
+ foreach ( $meta_args as $key => $value ) {
1467
+ update_post_meta( $trnsl_booking_id, $key, $value );
1468
+ }
1469
+
1470
+ WC_Cache_Helper::get_transient_version( 'bookings', true );
1471
+
1472
+ }
1473
+
1474
+
1475
+ }
1476
+
1477
+ function get_translated_booking_product_id( $booking_id, $language ){
1478
+
1479
+ $booking_product_id = get_post_meta( $booking_id, '_booking_product_id', true );
1480
+
1481
+ if( $booking_product_id ){
1482
+ $trnsl_booking_product_id = apply_filters( 'translate_object_id', $booking_product_id, 'product', false, $language );
1483
+ if( is_null( $trnsl_booking_product_id ) ){
1484
+ $trnsl_booking_product_id = '';
1485
+ }
1486
+ }
1487
+
1488
+ return $trnsl_booking_product_id;
1489
+
1490
+ }
1491
+
1492
+ function get_translated_booking_resource_id( $booking_id, $language ){
1493
+
1494
+ $booking_resource_id = get_post_meta( $booking_id, '_booking_resource_id', true );
1495
+ $trnsl_booking_resource_id = '';
1496
+
1497
+ if( $booking_resource_id ){
1498
+ $trnsl_booking_resource_id = apply_filters( 'translate_object_id', $booking_resource_id, 'bookable_resource', false, $language );
1499
+
1500
+ if( is_null( $trnsl_booking_resource_id ) ){
1501
+ $trnsl_booking_resource_id = '';
1502
+ }
1503
+ }
1504
+
1505
+ return $trnsl_booking_resource_id;
1506
+ }
1507
+
1508
+ function get_translated_booking_persons_ids( $booking_id, $language ){
1509
+
1510
+ $booking_persons = maybe_unserialize( get_post_meta( $booking_id, '_booking_persons', true ) );
1511
+ $trnsl_booking_persons = array();
1512
+
1513
+ foreach( $booking_persons as $person_id => $person_count ){
1514
+
1515
+ $trnsl_person_id = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $language );
1516
+
1517
+ if( is_null( $trnsl_person_id ) ){
1518
+ $trnsl_booking_persons[] = $person_count;
1519
+ }else{
1520
+ $trnsl_booking_persons[ $trnsl_person_id ] = $person_count;
1521
+ }
1522
+
1523
+ }
1524
+
1525
+ return $trnsl_booking_persons;
1526
+
1527
+ }
1528
+
1529
+ function update_status_for_translations( $booking_id ){
1530
+ global $wpdb;
1531
+
1532
+ $translated_bookings = $this->get_translated_bookings( $booking_id );
1533
+
1534
+ foreach( $translated_bookings as $booking ){
1535
+
1536
+ $status = $wpdb->get_var( $wpdb->prepare( "SELECT post_status FROM {$wpdb->posts} WHERE ID = %d", $booking_id ) ); //get_post_status( $booking_id );
1537
+ $language = get_post_meta( $booking->post_id, '_language_code', true );
1538
+
1539
+ $wpdb->update(
1540
+ $wpdb->posts,
1541
+ array(
1542
+ 'post_status' => $status,
1543
+ 'post_parent' => wp_get_post_parent_id( $booking_id ),
1544
+ ),
1545
+ array(
1546
+ 'ID' => $booking->post_id
1547
+ )
1548
+ );
1549
+
1550
+ update_post_meta( $booking->post_id, '_booking_product_id', $this->get_translated_booking_product_id( $booking_id, $language ) );
1551
+ update_post_meta( $booking->post_id, '_booking_resource_id', $this->get_translated_booking_resource_id( $booking_id, $language ) );
1552
+ update_post_meta( $booking->post_id, '_booking_persons', $this->get_translated_booking_persons_ids( $booking_id, $language ) );
1553
+
1554
+ }
1555
+
1556
+ }
1557
+
1558
+ function get_translated_bookings($booking_id){
1559
+ global $wpdb;
1560
+
1561
+ $translated_bookings = $wpdb->get_results( $wpdb->prepare( "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_booking_duplicate_of' AND meta_value = %d", $booking_id ) );
1562
+
1563
+ return $translated_bookings;
1564
+ }
1565
+
1566
+ public function booking_filters_query( $query ) {
1567
+ global $typenow, $sitepress, $wpdb;
1568
+
1569
+ if ( ( isset( $query->query_vars['post_type'] ) && $query->query_vars['post_type'] == 'wc_booking' ) ) {
1570
+
1571
+ $product_ids = $wpdb->get_col( $wpdb->prepare(
1572
+ "SELECT element_id
1573
+ FROM {$wpdb->prefix}icl_translations
1574
+ WHERE language_code = %s AND element_type = 'post_product'", $sitepress->get_current_language() ) );
1575
+
1576
+ $query->query_vars[ 'meta_query' ][] = array(
1577
+ array(
1578
+ 'key' => '_booking_product_id',
1579
+ 'value' => $product_ids,
1580
+ 'compare ' => 'IN'
1581
+ )
1582
+ );
1583
+ }
1584
+ }
1585
+
1586
+ function bookings_in_date_range_query($booking_ids){
1587
+ global $sitepress;
1588
+
1589
+ foreach ( $booking_ids as $key => $booking_id ) {
1590
+
1591
+ $language_code = $sitepress->get_language_for_element( get_post_meta( $booking_id, '_booking_product_id', true ) , 'post_product' );
1592
+ $current_language = $sitepress->get_current_language();
1593
+
1594
+ if( $language_code != $current_language ){
1595
+ unset( $booking_ids[$key] );
1596
+ }
1597
+
1598
+ }
1599
+
1600
+ return $booking_ids;
1601
+
1602
+ }
1603
+
1604
+ function clear_transient_fields(){
1605
+
1606
+ if ( isset( $_GET['post_type'] ) && $_GET['post_type'] == 'wc_booking' && isset( $_GET['page'] ) && $_GET['page'] == 'booking_calendar' ) {
1607
+
1608
+ global $wpdb;
1609
+ //delete transient fields
1610
+ $wpdb->query("
1611
+ DELETE FROM $wpdb->options
1612
+ WHERE option_name LIKE '%book_dr_%'
1613
+ ");
1614
+
1615
+ }
1616
+
1617
+ }
1618
+
1619
+ function delete_bookings( $booking_id ){
1620
+
1621
+ if( $booking_id > 0 && get_post_type( $booking_id ) == 'wc_booking' ){
1622
+
1623
+ $translated_bookings = $this->get_translated_bookings( $booking_id );
1624
+
1625
+ remove_action( 'before_delete_post', array( $this, 'delete_bookings' ) );
1626
+
1627
+ foreach( $translated_bookings as $booking ){
1628
+
1629
+ global $wpdb;
1630
+
1631
+ $wpdb->update(
1632
+ $wpdb->posts,
1633
+ array(
1634
+ 'post_parent' => 0
1635
+ ),
1636
+ array(
1637
+ 'ID' => $booking->post_id
1638
+ )
1639
+ );
1640
+
1641
+ wp_delete_post( $booking->post_id );
1642
+
1643
+ }
1644
+
1645
+ add_action( 'before_delete_post', array( $this, 'delete_bookings' ) );
1646
+ }
1647
+
1648
+ }
1649
+
1650
+ function trash_bookings( $booking_id ){
1651
+
1652
+ if( $booking_id > 0 && get_post_type( $booking_id ) == 'wc_booking' ){
1653
+
1654
+ $translated_bookings = $this->get_translated_bookings( $booking_id );
1655
+
1656
+ foreach( $translated_bookings as $booking ){
1657
+ global $wpdb;
1658
+
1659
+ $wpdb->update(
1660
+ $wpdb->posts,
1661
+ array(
1662
+ 'post_status' => 'trash'
1663
+ ),
1664
+ array(
1665
+ 'ID' => $booking->post_id
1666
+ )
1667
+ );
1668
+
1669
+ }
1670
+
1671
+ }
1672
+
1673
+ }
1674
+
1675
+ function append_persons_to_translation_package( $package, $post ){
1676
+
1677
+ if( $post->post_type == 'product' ){
1678
+ $product = wc_get_product( $post->ID );
1679
+
1680
+ //WC_Product::get_type() available from WooCommerce 2.4.0
1681
+ $product_type = method_exists($product, 'get_type') ? $product->get_type() : $product->product_type;
1682
+
1683
+ if( $product_type == 'booking' ){
1684
+
1685
+ $bookable_product = new WC_Product_Booking( $post->ID );
1686
+
1687
+ $person_types = $bookable_product->get_person_types();
1688
+
1689
+ foreach( $person_types as $person_type ) {
1690
+
1691
+ $package['contents']['wc_bookings:person:' . $person_type->ID . ':name'] = array(
1692
+ 'translate' => 1,
1693
+ 'data' => $this->tp->encode_field_data( $person_type->post_title, 'base64' ),
1694
+ 'format' => 'base64'
1695
+ );
1696
+
1697
+ $package['contents']['wc_bookings:person:' . $person_type->ID . ':description'] = array(
1698
+ 'translate' => 1,
1699
+ 'data' => $this->tp->encode_field_data( $person_type->post_excerpt, 'base64' ),
1700
+ 'format' => 'base64'
1701
+ );
1702
+
1703
+ }
1704
+
1705
+ }
1706
+
1707
+ }
1708
+
1709
+ return $package;
1710
+
1711
+ }
1712
+
1713
+ function save_person_translation($post_id, $data, $job ){
1714
+ global $sitepress;
1715
+
1716
+ $person_translations = array();
1717
+
1718
+ foreach($data as $value){
1719
+
1720
+ if( $value['finished'] && strpos( $value['field_type'], 'wc_bookings:person:' ) === 0 ) {
1721
+
1722
+ $exp = explode( ':', $value['field_type'] );
1723
+
1724
+ $person_id = $exp[2];
1725
+ $field = $exp[3];
1726
+
1727
+ $person_translations[$person_id][$field] = $value['data'];
1728
+
1729
+ }
1730
+
1731
+ }
1732
+
1733
+ if( $person_translations ){
1734
+
1735
+ foreach( $person_translations as $person_id => $pt ){
1736
+
1737
+ $person_trid = $sitepress->get_element_trid( $person_id, 'post_bookable_person');
1738
+
1739
+
1740
+ $person_id_translated = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $job->language_code );
1741
+
1742
+ if( empty($person_id_translated) ) {
1743
+
1744
+ $person_post = array(
1745
+
1746
+ 'post_type' => 'bookable_person',
1747
+ 'post_status' => 'publish',
1748
+ 'post_title' => $pt['name'],
1749
+ 'post_parent' => $post_id,
1750
+ 'post_excerpt' => isset($pt['description']) ? $pt['description'] : ''
1751
+
1752
+ );
1753
+
1754
+ $person_id_translated = wp_insert_post( $person_post );
1755
+
1756
+ $sitepress->set_element_language_details( $person_id_translated, 'post_bookable_person', $person_trid, $job->language_code );
1757
+
1758
+ } else {
1759
+
1760
+ $person_post = array(
1761
+ 'ID' => $person_id_translated,
1762
+ 'post_title' => $pt['name'],
1763
+ 'post_excerpt' => isset($pt['description']) ? $pt['description'] : ''
1764
+ );
1765
+
1766
+ wp_update_post( $person_post );
1767
+
1768
+ }
1769
+
1770
+ }
1771
+
1772
+ }
1773
+
1774
+ }
1775
+
1776
+ function append_resources_to_translation_package( $package, $post ){
1777
+
1778
+ if( $post->post_type == 'product' ){
1779
+ $product = wc_get_product( $post->ID );
1780
+
1781
+ //WC_Product::get_type() available from WooCommerce 2.4.0
1782
+ $product_type = method_exists($product, 'get_type') ? $product->get_type() : $product->product_type;
1783
+
1784
+ if( $product_type == 'booking' && $product->has_resources() ){
1785
+
1786
+ $resources = $product->get_resources();
1787
+
1788
+ foreach( $resources as $resource ) {
1789
+
1790
+ $package['contents']['wc_bookings:resource:' . $resource->ID . ':name'] = array(
1791
+ 'translate' => 1,
1792
+ 'data' => $this->tp->encode_field_data( $resource->post_title, 'base64' ),
1793
+ 'format' => 'base64'
1794
+ );
1795
+
1796
+ }
1797
+
1798
+ }
1799
+
1800
+ }
1801
+
1802
+ return $package;
1803
+
1804
+ }
1805
+
1806
+ function save_resource_translation( $post_id, $data, $job ){
1807
+ global $sitepress, $wpdb;
1808
+
1809
+ $resource_translations = array();
1810
+
1811
+ foreach($data as $value){
1812
+
1813
+ if( $value['finished'] && strpos( $value['field_type'], 'wc_bookings:resource:' ) === 0 ) {
1814
+
1815
+ $exp = explode( ':', $value['field_type'] );
1816
+
1817
+ $resource_id = $exp[2];
1818
+ $field = $exp[3];
1819
+
1820
+ $resource_translations[$resource_id][$field] = $value['data'];
1821
+
1822
+ }
1823
+
1824
+ }
1825
+
1826
+ if( $resource_translations ){
1827
+
1828
+ foreach( $resource_translations as $resource_id => $rt ){
1829
+
1830
+ $resource_trid = $sitepress->get_element_trid( $resource_id, 'post_bookable_resource');
1831
+
1832
+ $resource_id_translated = apply_filters( 'translate_object_id', $resource_id, 'bookable_resource', false, $job->language_code );
1833
+
1834
+ if( empty($resource_id_translated) ) {
1835
+
1836
+ $resource_post = array(
1837
+
1838
+ 'post_type' => 'bookable_resource',
1839
+ 'post_status' => 'publish',
1840
+ 'post_title' => $rt['name'],
1841
+ 'post_parent' => $post_id
1842
+ );
1843
+
1844
+ $resource_id_translated = wp_insert_post( $resource_post );
1845
+
1846
+ $sitepress->set_element_language_details( $resource_id_translated, 'post_bookable_resource', $resource_trid, $job->language_code );
1847
+
1848
+ $sort_order = $wpdb->get_var( $wpdb->prepare( "SELECT sort_order FROM {$wpdb->prefix}wc_booking_relationships WHERE resource_id=%d", $resource_id ) );
1849
+ $relationship = array(
1850
+ 'product_id' => $post_id,
1851
+ 'resource_id' => $resource_id_translated,
1852
+ 'sort_order' => $sort_order
1853
+ );
1854
+ $wpdb->insert( $wpdb->prefix . 'wc_booking_relationships', $relationship);
1855
+
1856
+ } else {
1857
+
1858
+ $resource_post = array(
1859
+ 'ID' => $resource_id_translated,
1860
+ 'post_title' => $rt['name']
1861
+ );
1862
+
1863
+ wp_update_post( $resource_post );
1864
+
1865
+ $sort_order = $wpdb->get_var( $wpdb->prepare( "SELECT sort_order FROM {$wpdb->prefix}wc_booking_relationships WHERE resource_id=%d", $resource_id ) );
1866
+ $wpdb->update( $wpdb->prefix . 'wc_booking_relationships', array( 'sort_order' => $sort_order ),
1867
+ array ( 'product_id' => $post_id, 'resource_id' => $resource_id_translated) );
1868
+
1869
+
1870
+ }
1871
+
1872
+
1873
+ }
1874
+
1875
+ }
1876
+
1877
+ }
1878
+
1879
+ function wcml_js_lock_fields_ids( $ids ){
1880
+
1881
+ $ids = array_merge( $ids, array(
1882
+ '_wc_booking_has_resources',
1883
+ '_wc_booking_has_persons',
1884
+ '_wc_booking_duration_type',
1885
+ '_wc_booking_duration',
1886
+ '_wc_booking_duration_unit',
1887
+ '_wc_booking_calendar_display_mode',
1888
+ '_wc_booking_requires_confirmation',
1889
+ '_wc_booking_user_can_cancel',
1890
+ '_wc_accommodation_booking_min_duration',
1891
+ '_wc_accommodation_booking_max_duration',
1892
+ '_wc_accommodation_booking_max_duration',
1893
+ '_wc_accommodation_booking_calendar_display_mode',
1894
+ '_wc_accommodation_booking_requires_confirmation',
1895
+ '_wc_accommodation_booking_user_can_cancel',
1896
+ '_wc_accommodation_booking_cancel_limit',
1897
+ '_wc_accommodation_booking_cancel_limit_unit',
1898
+ '_wc_accommodation_booking_qty',
1899
+ '_wc_accommodation_booking_min_date',
1900
+ '_wc_accommodation_booking_min_date_unit',
1901
+ '_wc_accommodation_booking_max_date',
1902
+ '_wc_accommodation_booking_max_date_unit',
1903
+ 'bookings_pricing select',
1904
+ 'bookings_resources select',
1905
+ 'bookings_availability select',
1906
+ 'bookings_persons input[type="checkbox"]'
1907
+ ) );
1908
+
1909
+ return $ids;
1910
+ }
1911
+
1912
  }
compatibility/class-wcml-bulk-stock-management.php CHANGED
@@ -1,45 +1,45 @@
1
- <?php
2
- /**
3
- * Compatibility class for plugin WooCommerce Bulk Stock Management
4
- * http://www.woothemes.com/products/bulk-stock-management/
5
- *
6
- * @author konrad
7
- */
8
- class WCML_Bulk_Stock_Management {
9
- function __construct() {
10
- if (is_admin() && isset($_GET['page']) && $_GET['page'] == 'woocommerce-bulk-stock-management') {
11
- global $sitepress;
12
- remove_action('admin_enqueue_scripts', array($sitepress, 'language_filter'));
13
- }
14
-
15
- add_action( 'wc_bulk_stock_after_process_qty', array($this, 'wc_bulk_stock_after_process_qty_action'), 10, 1 );
16
- }
17
-
18
- function wc_bulk_stock_after_process_qty_action($id) {
19
- global $sitepress;
20
-
21
- $new_quantity = get_post_meta($id, '_stock', true);
22
-
23
- if (is_numeric($new_quantity)) {
24
-
25
- $new_stock_status = ($new_quantity > 0) ? "instock" : "outofstock";
26
- wc_update_product_stock_status($id, $new_stock_status);
27
-
28
- $trid = $sitepress->get_element_trid( $id, 'post_product' );
29
- if (is_numeric($trid)) {
30
- $translations = $sitepress->get_element_translations( $trid, 'post_product' );
31
-
32
- if (is_array($translations)) {
33
- foreach ($translations as $translation) {
34
- if ( !isset($translation->element_id) || $translation->element_id == $id) {
35
- continue;
36
- }
37
- update_post_meta($translation->element_id, '_stock', $new_quantity);
38
- wc_update_product_stock_status($translation->element_id, $new_stock_status);
39
- }
40
- }
41
- }
42
- }
43
-
44
- }
45
- }
1
+ <?php
2
+ /**
3
+ * Compatibility class for plugin WooCommerce Bulk Stock Management
4
+ * http://www.woothemes.com/products/bulk-stock-management/
5
+ *
6
+ * @author konrad
7
+ */
8
+ class WCML_Bulk_Stock_Management {
9
+ function __construct() {
10
+ if (is_admin() && isset($_GET['page']) && $_GET['page'] == 'woocommerce-bulk-stock-management') {
11
+ global $sitepress;
12
+ remove_action('admin_enqueue_scripts', array($sitepress, 'language_filter'));
13
+ }
14
+
15
+ add_action( 'wc_bulk_stock_after_process_qty', array($this, 'wc_bulk_stock_after_process_qty_action'), 10, 1 );
16
+ }
17
+
18
+ function wc_bulk_stock_after_process_qty_action($id) {
19
+ global $sitepress;
20
+
21
+ $new_quantity = get_post_meta($id, '_stock', true);
22
+
23
+ if (is_numeric($new_quantity)) {
24
+
25
+ $new_stock_status = ($new_quantity > 0) ? "instock" : "outofstock";
26
+ wc_update_product_stock_status($id, $new_stock_status);
27
+
28
+ $trid = $sitepress->get_element_trid( $id, 'post_product' );
29
+ if (is_numeric($trid)) {
30
+ $translations = $sitepress->get_element_translations( $trid, 'post_product' );
31
+
32
+ if (is_array($translations)) {
33
+ foreach ($translations as $translation) {
34
+ if ( !isset($translation->element_id) || $translation->element_id == $id) {
35
+ continue;
36
+ }
37
+ update_post_meta($translation->element_id, '_stock', $new_quantity);
38
+ wc_update_product_stock_status($translation->element_id, $new_stock_status);
39
+ }
40
+ }
41
+ }
42
+ }
43
+
44
+ }
45
+ }
compatibility/class-wcml-checkout-addons.php CHANGED
@@ -1,20 +1,20 @@
1
- <?php
2
- /**
3
- * Description of wc_checkout_addons
4
- *
5
- * @author konrad
6
- */
7
- class WCML_Checkout_Addons {
8
- public function __construct() {
9
- add_filter( 'wc_checkout_add_ons_options', array( $this, 'wc_checkout_add_ons_options_wpml_multi_currency_support' ) );
10
- }
11
-
12
- public function wc_checkout_add_ons_options_wpml_multi_currency_support( $options ) {
13
-
14
- foreach ( $options as $i => $option ) {
15
- $options[ $i ]['cost'] = apply_filters( 'wcml_raw_price_amount', $options[ $i ]['cost'] );
16
- }
17
-
18
- return $options;
19
- }
20
- }
1
+ <?php
2
+ /**
3
+ * Description of wc_checkout_addons
4
+ *
5
+ * @author konrad
6
+ */
7
+ class WCML_Checkout_Addons {
8
+ public function __construct() {
9
+ add_filter( 'wc_checkout_add_ons_options', array( $this, 'wc_checkout_add_ons_options_wpml_multi_currency_support' ) );
10
+ }
11
+
12
+ public function wc_checkout_add_ons_options_wpml_multi_currency_support( $options ) {
13
+
14
+ foreach ( $options as $i => $option ) {
15
+ $options[ $i ]['cost'] = apply_filters( 'wcml_raw_price_amount', $options[ $i ]['cost'] );
16
+ }
17
+
18
+ return $options;
19
+ }
20
+ }
compatibility/class-wcml-checkout-field-editor.php CHANGED
@@ -1,125 +1,125 @@
1
- <?php
2
-
3
- class WCML_Checkout_Field_Editor {
4
-
5
- protected $package, $billing, $shipping, $additional;
6
-
7
- function __construct() {
8
- $this->package = (object) array(
9
- 'kind' => 'WooCommerce Add-On',
10
- 'kind_slug' => 'woocommerce-add-on',
11
- 'name' => 'checkout-field-editor',
12
- 'title' => 'WooCommerce Checkout Field Editor'
13
- );
14
- global $supress_field_modification;
15
- if ( !is_admin() && !$supress_field_modification ) {
16
- add_filter( 'pre_option_wc_fields_billing', array($this, 'get_billing') );
17
- add_filter( 'pre_option_wc_fields_shipping', array($this, 'get_shipping') );
18
- add_filter( 'pre_option_wc_fields_additional', array($this, 'get_additional') );
19
- }
20
- add_filter( 'pre_update_option_wc_fields_billing', array($this, 'register_fields') );
21
- add_filter( 'pre_update_option_wc_fields_shipping', array($this, 'register_fields') );
22
- add_filter( 'pre_update_option_wc_fields_additional', array($this, 'register_fields') );
23
- }
24
-
25
- public function register_fields( $fields ) {
26
- foreach ( $fields as $string_name => $field ) {
27
- // Translate label
28
- if ( !empty( $field['label'] ) ) {
29
- do_action( 'wpml_register_string',
30
- $field['label'],
31
- "{$string_name}_label",
32
- $this->package,
33
- "{$string_name} Label",
34
- $this->package->kind
35
- );
36
- }
37
- // Translate placeholder
38
- if ( !empty( $field['placeholder'] ) ) {
39
- do_action( 'wpml_register_string',
40
- $field['placeholder'],
41
- "{$string_name}_placeholder",
42
- $this->package,
43
- "{$string_name} Placeholder",
44
- $this->package->kind
45
- );
46
- }
47
- // Translate options
48
- if ( !empty( $field['options'] ) ) {
49
- $i = 1;
50
- foreach ( $field['options'] as $option ) {
51
- do_action( 'wpml_register_string',
52
- $option,
53
- "{$string_name}_option_{$i}",
54
- $this->package,
55
- "{$string_name} Option {$i}",
56
- $this->package->kind
57
- );
58
- $i++;
59
- }
60
- }
61
- }
62
- return $fields;
63
- }
64
-
65
- public function translate_fields( $fields ) {
66
- foreach ( $fields as $string_name => &$field ) {
67
- // Translate label
68
- if ( !empty( $field['label'] ) ) {
69
- $field['label'] = apply_filters( 'wpml_translate_string',
70
- $field['label'],
71
- "{$string_name}_label",
72
- $this->package
73
- );
74
- }
75
- // Translate placeholder
76
- if ( !empty( $field['placeholder'] ) ) {
77
- $field['placeholder'] = apply_filters( 'wpml_translate_string',
78
- $field['label'],
79
- "{$string_name}_placeholder",
80
- $this->package
81
- );
82
- }
83
- // Translate options
84
- if ( !empty( $field['options'] ) ) {
85
- $i = 1;
86
- foreach ( $field['options'] as $k => $option ) {
87
- $field['options'][$k] = apply_filters( 'wpml_translate_string',
88
- $option,
89
- "{$string_name}_option_{$i}",
90
- $this->package
91
- );
92
- $i++;
93
- }
94
- }
95
- }
96
- return $fields;
97
- }
98
-
99
- public function get_billing() {
100
- if ( is_null( $this->billing ) ) {
101
- remove_filter( 'pre_option_wc_fields_billing', array($this, 'get_billing') );
102
- $this->billing = $this->translate_fields( get_option( 'wc_fields_billing', array() ) );
103
- add_filter( 'pre_option_wc_fields_billing', array($this, 'get_billing') );
104
- }
105
- return $this->billing;
106
- }
107
-
108
- public function get_shipping() {
109
- if ( is_null( $this->shipping ) ) {
110
- remove_filter( 'pre_option_wc_fields_shipping', array($this, 'get_shipping') );
111
- $this->shipping = $this->translate_fields( get_option( 'wc_fields_shipping', array() ) );
112
- add_filter( 'pre_option_wc_fields_shipping', array($this, 'get_shipping') );
113
- }
114
- return $this->shipping;
115
- }
116
-
117
- public function get_additional() {
118
- if ( is_null( $this->additional ) ) {
119
- remove_filter( 'pre_option_wc_fields_additional', array($this, 'get_additional') );
120
- $this->additional = $this->translate_fields( get_option( 'wc_fields_additional', array() ) );
121
- add_filter( 'pre_option_wc_fields_additional', array($this, 'get_additional') );
122
- }
123
- return $this->additional;
124
- }
125
- }
1
+ <?php
2
+
3
+ class WCML_Checkout_Field_Editor {
4
+
5
+ protected $package, $billing, $shipping, $additional;
6
+
7
+ function __construct() {
8
+ $this->package = (object) array(
9
+ 'kind' => 'WooCommerce Add-On',
10
+ 'kind_slug' => 'woocommerce-add-on',
11
+ 'name' => 'checkout-field-editor',
12
+ 'title' => 'WooCommerce Checkout Field Editor'
13
+ );
14
+ global $supress_field_modification;
15
+ if ( !is_admin() && !$supress_field_modification ) {
16
+ add_filter( 'pre_option_wc_fields_billing', array($this, 'get_billing') );
17
+ add_filter( 'pre_option_wc_fields_shipping', array($this, 'get_shipping') );
18
+ add_filter( 'pre_option_wc_fields_additional', array($this, 'get_additional') );
19
+ }
20
+ add_filter( 'pre_update_option_wc_fields_billing', array($this, 'register_fields') );
21
+ add_filter( 'pre_update_option_wc_fields_shipping', array($this, 'register_fields') );
22
+ add_filter( 'pre_update_option_wc_fields_additional', array($this, 'register_fields') );
23
+ }
24
+
25
+ public function register_fields( $fields ) {
26
+ foreach ( $fields as $string_name => $field ) {
27
+ // Translate label
28
+ if ( !empty( $field['label'] ) ) {
29
+ do_action( 'wpml_register_string',
30
+ $field['label'],
31
+ "{$string_name}_label",
32
+ $this->package,
33
+ "{$string_name} Label",
34
+ $this->package->kind
35
+ );
36
+ }
37
+ // Translate placeholder
38
+ if ( !empty( $field['placeholder'] ) ) {
39
+ do_action( 'wpml_register_string',
40
+ $field['placeholder'],
41
+ "{$string_name}_placeholder",
42
+ $this->package,
43
+ "{$string_name} Placeholder",
44
+ $this->package->kind
45
+ );
46
+ }
47
+ // Translate options
48
+ if ( !empty( $field['options'] ) ) {
49
+ $i = 1;
50
+ foreach ( $field['options'] as $option ) {
51
+ do_action( 'wpml_register_string',
52
+ $option,
53
+ "{$string_name}_option_{$i}",
54
+ $this->package,
55
+ "{$string_name} Option {$i}",
56
+ $this->package->kind
57
+ );
58
+ $i++;
59
+ }
60
+ }
61
+ }
62
+ return $fields;
63
+ }
64
+
65
+ public function translate_fields( $fields ) {
66
+ foreach ( $fields as $string_name => &$field ) {
67
+ // Translate label
68
+ if ( !empty( $field['label'] ) ) {
69
+ $field['label'] = apply_filters( 'wpml_translate_string',
70
+ $field['label'],
71
+ "{$string_name}_label",
72
+ $this->package
73
+ );
74
+ }
75
+ // Translate placeholder
76
+ if ( !empty( $field['placeholder'] ) ) {
77
+ $field['placeholder'] = apply_filters( 'wpml_translate_string',
78
+ $field['label'],
79
+ "{$string_name}_placeholder",
80
+ $this->package
81
+ );
82
+ }
83
+ // Translate options
84
+ if ( !empty( $field['options'] ) ) {
85
+ $i = 1;
86
+ foreach ( $field['options'] as $k => $option ) {
87
+ $field['options'][$k] = apply_filters( 'wpml_translate_string',
88
+ $option,
89
+ "{$string_name}_option_{$i}",
90
+ $this->package
91
+ );
92
+ $i++;
93
+ }
94
+ }
95
+ }
96
+ return $fields;
97
+ }
98
+
99
+ public function get_billing() {
100
+ if ( is_null( $this->billing ) ) {
101
+ remove_filter( 'pre_option_wc_fields_billing', array($this, 'get_billing') );
102
+ $this->billing = $this->translate_fields( get_option( 'wc_fields_billing', array() ) );
103
+ add_filter( 'pre_option_wc_fields_billing', array($this, 'get_billing') );
104
+ }
105
+ return $this->billing;
106
+ }
107
+
108
+ public function get_shipping() {
109
+ if ( is_null( $this->shipping ) ) {
110
+ remove_filter( 'pre_option_wc_fields_shipping', array($this, 'get_shipping') );
111
+ $this->shipping = $this->translate_fields( get_option( 'wc_fields_shipping', array() ) );
112
+ add_filter( 'pre_option_wc_fields_shipping', array($this, 'get_shipping') );
113
+ }
114
+ return $this->shipping;
115
+ }
116
+
117
+ public function get_additional() {
118
+ if ( is_null( $this->additional ) ) {
119
+ remove_filter( 'pre_option_wc_fields_additional', array($this, 'get_additional') );
120
+ $this->additional = $this->translate_fields( get_option( 'wc_fields_additional', array() ) );
121
+ add_filter( 'pre_option_wc_fields_additional', array($this, 'get_additional') );
122
+ }
123
+ return $this->additional;
124
+ }
125
+ }
compatibility/class-wcml-compatibility-helper.php CHANGED
@@ -1,19 +1,19 @@
1
- <?php
2
-
3
- class WCML_Compatibility_Helper{
4
-
5
- function get_product_type($product_id){
6
-
7
- if ( $terms = wp_get_object_terms( $product_id, 'product_type' ) ) {
8
- $product_type = sanitize_title( current( $terms )->name );
9
- } else {
10
- $product_type = apply_filters( 'default_product_type', 'simple' );
11
- }
12
-
13
- return $product_type;
14
-
15
- }
16
-
17
- }
18
-
19
  ?>
1
+ <?php
2
+
3
+ class WCML_Compatibility_Helper{
4
+
5
+ function get_product_type($product_id){
6
+
7
+ if ( $terms = wp_get_object_terms( $product_id, 'product_type' ) ) {
8
+ $product_type = sanitize_title( current( $terms )->name );
9
+ } else {
10
+ $product_type = apply_filters( 'default_product_type', 'simple' );
11
+ }
12
+
13
+ return $product_type;
14
+
15
+ }
16
+
17
+ }
18
+
19
  ?>
compatibility/class-wcml-composite-products.php CHANGED
@@ -1,319 +1,342 @@
1
- <?php
2
-
3
-
4
- class WCML_Composite_Products extends WCML_Compatibility_Helper{
5
-
6
- private $tp;
7
-
8
- function __construct() {
9
- add_filter( 'woocommerce_composite_component_default_option', array($this, 'woocommerce_composite_component_default_option'), 10, 3 );
10
- add_filter( 'wcml_cart_contents', array($this, 'wpml_composites_compat'), 11, 4 );
11
- add_filter( 'woocommerce_composite_component_options_query_args', array($this, 'wpml_composites_transients_cache_per_language'), 10, 3 );
12
- add_action( 'updated_post_meta', array( $this, 'sync_composite_data_across_translations'), 10, 4 );
13
-
14
- if( is_admin() ){
15
- add_filter( 'wcml_gui_additional_box', array( $this, 'custom_box_html'), 10, 3 );
16
- add_action('wcml_extra_titles',array($this,'product_editor_title'),10,1);
17
- add_action('wcml_update_extra_fields',array($this,'components_update'),10,2);
18
-
19
- $this->tp = new WPML_Element_Translation_Package();
20
-
21
- add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_composite_data_translation_package' ), 10, 2 );
22
- add_action( 'wpml_translation_job_saved', array( $this, 'save_composite_data_translation' ), 10, 3 );
23
-
24
- }
25
- }
26
-
27
- function woocommerce_composite_component_default_option($selected_value, $component_id, $object) {
28
-
29
- if( !empty( $selected_value ) )
30
- $selected_value = apply_filters( 'wpml_object_id', $selected_value, 'product', true );
31
-
32
-
33
- return $selected_value;
34
- }
35
-
36
- function wpml_composites_compat( $new_cart_data, $cart_contents, $key, $new_key ) {
37
-
38
- if ( isset( $cart_contents[ $key ][ 'composite_children' ] ) || isset( $cart_contents[ $key ][ 'composite_parent' ] ) ) {
39
-
40
- $buff = $new_cart_data[ $new_key ];
41
-
42
- unset( $new_cart_data[ $new_key ] );
43
-
44
- $new_cart_data[ $key ] = $buff;
45
- }
46
-
47
- return $new_cart_data;
48
- }
49
-
50
- function wpml_composites_transients_cache_per_language( $args, $query_args, $component_data ) {
51
-
52
- $args[ 'wpml_lang' ] = apply_filters( 'wpml_current_language', NULL );
53
-
54
- return $args;
55
- }
56
-
57
- function sync_composite_data_across_translations( $meta_id, $post_id, $meta_key, $composite_data ){
58
-
59
-
60
- if( $meta_key != '_bto_data' )
61
- return false;
62
-
63
-
64
- global $sitepress, $woocommerce_wpml;
65
-
66
- $post = get_post( $post_id );
67
-
68
- // skip auto-drafts // skip autosave
69
- if ( $post->post_status == 'auto-draft' || isset( $_POST[ 'autosave' ] ) ) {
70
- return;
71
- }
72
-
73
- if( $post->post_type == 'product' ) {
74
-
75
- if( $this->get_product_type( $post_id ) == 'composite' ) {
76
-
77
- remove_action( 'updated_post_meta', array( $this, 'sync_composite_data_across_translations'), 10, 4 );
78
-
79
- if ( $woocommerce_wpml->products->is_original_product( $post_id ) ) {
80
-
81
- $original_product_id = $post_id;
82
-
83
- } else {
84
-
85
- $original_product_language = $woocommerce_wpml->products->get_original_product_language( $post_id );
86
- $original_product_id = apply_filters( 'translate_object_id', $post_id, 'product', true, $original_product_language );
87
-
88
- }
89
-
90
- $product = new WC_Product_Composite( $original_product_id );
91
-
92
- $product_trid = $sitepress->get_element_trid( $original_product_id, 'post_product' );
93
- $product_translations = $sitepress->get_element_translations( $product_trid, 'post_product' );
94
-
95
- foreach ( $product_translations as $product_translation ) {
96
-
97
- if ( empty($product_translation->original) ) {
98
-
99
- $translated_product = new WC_Product_Composite( $product_translation->element_id );
100
- $translated_composite_data = $translated_product->get_composite_data();
101
-
102
- foreach ( $composite_data as $component_id => $component ) {
103
-
104
- if( isset( $translated_composite_data[$component_id]['title'] ) ){
105
- $composite_data[$component_id]['title'] = $translated_composite_data[$component_id]['title'];
106
- }
107
-
108
- if( isset( $translated_composite_data[$component_id]['description'] ) ){
109
- $composite_data[$component_id]['description'] = $translated_composite_data[$component_id]['description'];
110
- }
111
-
112
- if ( $component['query_type'] == 'product_ids' ) {
113
-
114
- foreach ( $component['assigned_ids'] as $idx => $assigned_id ) {
115
- $composite_data[$component_id]['assigned_ids'][$idx] =
116
- apply_filters( 'translate_object_id', $assigned_id, 'product', true, $product_translation->language_code );
117
- }
118
-
119
- } elseif( $component['query_type'] == 'category_ids' ){
120
-
121
- foreach ( $component['assigned_category_ids'] as $idx => $assigned_id ) {
122
- $composite_data[$component_id]['assigned_category_ids'][$idx] =
123
- apply_filters( 'translate_object_id', $assigned_id, 'product_cat', true, $product_translation->language_code );
124
-
125
- }
126
-
127
- }
128
-
129
- }
130
-
131
- update_post_meta( $product_translation->element_id, '_bto_data', $composite_data );
132
-
133
- }
134
-
135
- }
136
-
137
- add_action( 'updated_post_meta', array( $this, 'sync_composite_data_across_translations'), 10, 4 );
138
-
139
- }
140
-
141
- }
142
-
143
- }
144
-
145
- function custom_box_html($product_id,$lang, $is_duplicate_product = false){
146
- global $woocommerce_wpml, $sitepress;
147
-
148
- $original_product_language = $woocommerce_wpml->products->get_original_product_language( $product_id );
149
-
150
- if( $this->get_product_type( $product_id ) == 'composite' ){
151
-
152
- $product = new WC_Product_Composite( $product_id );
153
- $composite_data = $product->get_composite_data();
154
-
155
- if( $original_product_language != $lang ){
156
- $product_trid = $sitepress->get_element_trid( $product_id, 'post_product' );
157
- $product_translations = $sitepress->get_element_translations( $product_trid, 'post_product' );
158
- if( isset($product_translations[$lang]) ){
159
- $translated_product = new WC_Product_Composite( $product_translations[$lang]->element_id );
160
- $translated_composite_data = $translated_product->get_composite_data();
161
- }
162
-
163
- foreach( $composite_data as $component_id => $component ){
164
-
165
- $template_data['wc_composite_components']['components'][$component_id]['title'] =
166
- isset( $translated_composite_data[$component_id]['title'] ) ? $translated_composite_data[$component_id]['title'] : '';
167
-
168
- $template_data['wc_composite_components']['components'][$component_id]['description'] =
169
- isset( $translated_composite_data[$component_id]['description'] ) ? $translated_composite_data[$component_id]['description'] : '';
170
-
171
- }
172
-
173
- }else{
174
-
175
- foreach( $composite_data as $component_id => $component ) {
176
-
177
- $template_data['wc_composite_components']['components'][$component_id]['title'] =
178
- isset( $composite_data[$component_id]['title'] ) ? $composite_data[$component_id]['title'] : '';
179
-
180
- $template_data['wc_composite_components']['components'][$component_id]['description'] =
181
- isset( $composite_data[$component_id]['description'] ) ? $composite_data[$component_id]['description'] : '';
182
-
183
- }
184
-
185
- }
186
-
187
- $template_data['wc_composite_components']['_is_original'] = $original_product_language == $lang;
188
-
189
- include WCML_PLUGIN_PATH . '/compatibility/templates/woocommerce-composite-products.php';
190
- }
191
-
192
- }
193
-
194
- function product_editor_title( $product_id ){
195
-
196
- if( $this->get_product_type( $product_id ) == 'composite' ) {
197
- printf( '<th scope="col">%s</h>', __( 'Components', 'woocommerce-multilingual' ) );
198
- }
199
-
200
- }
201
-
202
- function components_update( $product_id, $data ){
203
-
204
- $this->sync_composite_data_across_translations( $product_id );
205
-
206
- $product = new WC_Product_Composite( $product_id );
207
-
208
- $composite_data = $product->get_composite_data();
209
-
210
- if(!empty($data['wc_composite_component'])){
211
- foreach($data['wc_composite_component'] as $component_id => $component){
212
-
213
- if(!empty($component['title'])){
214
- $composite_data[$component_id]['title'] = $component['title'];
215
- }
216
-
217
- if(!empty($component['description'])) {
218
- $composite_data[$component_id]['description'] = $component['description'];
219
- }
220
-
221
-
222
- }
223
-
224
- update_post_meta( $product_id, '_bto_data', $composite_data );
225
-
226
- }
227
- }
228
-
229
- function append_composite_data_translation_package( $package, $post ){
230
-
231
- if( $post->post_type == 'product' ) {
232
-
233
- $composite_data = get_post_meta( $post->ID, '_bto_data', true );
234
-
235
- if( $composite_data ){
236
-
237
- $fields = array( 'title', 'description' );
238
-
239
- foreach( $composite_data as $component_id => $component ){
240
-
241
- foreach( $fields as $field ) {
242
- if ( !empty($component[$field]) ) {
243
-
244
- $package['contents']['wc_composite:' . $component_id . ':' . $field] = array(
245
- 'translate' => 1,
246
- 'data' => $this->tp->encode_field_data( $component[$field], 'base64' ),
247
- 'format' => 'base64'
248
- );
249
-
250
- }
251
- }
252
-
253
- }
254
-
255
- }
256
-
257
- }
258
-
259
- return $package;
260
-
261
- }
262
-
263
- function save_composite_data_translation( $post_id, $data, $job ){
264
-
265
-
266
- $translated_composite_data = array();
267
- foreach( $data as $value){
268
-
269
- if( preg_match( '/wc_composite:([0-9]+):(.+)/', $value['field_type'], $matches ) ){
270
-
271
- $component_id = $matches[1];
272
- $field = $matches[2];
273
-
274
- $translated_composite_data[$component_id][$field] = $value['data'];
275
-
276
- }
277
-
278
- }
279
-
280
- if( $translated_composite_data ){
281
-
282
- $composite_data = get_post_meta( $job->original_doc_id, '_bto_data', true );
283
-
284
-
285
- foreach ( $composite_data as $component_id => $component ) {
286
-
287
- if( isset( $translated_composite_data[$component_id]['title'] ) ){
288
- $composite_data[$component_id]['title'] = $translated_composite_data[$component_id]['title'];
289
- }
290
-
291
- if( isset( $translated_composite_data[$component_id]['description'] ) ){
292
- $composite_data[$component_id]['description'] = $translated_composite_data[$component_id]['description'];
293
- }
294
-
295
- if ( $component['query_type'] == 'product_ids' ) {
296
-
297
- foreach ( $component['assigned_ids'] as $idx => $assigned_id ) {
298
- $composite_data[$component_id]['assigned_ids'][$idx] =
299
- apply_filters( 'translate_object_id', $assigned_id, 'product', true, $job->language_code );
300
- }
301
-
302
- } elseif( $component['query_type'] == 'category_ids' ){
303
-
304
- foreach ( $component['assigned_category_ids'] as $idx => $assigned_id ) {
305
- $composite_data[$component_id]['assigned_category_ids'][$idx] =
306
- apply_filters( 'translate_object_id', $assigned_id, 'product_cat', true, $job->language_code );
307
-
308
- }
309
-
310
- }
311
-
312
- }
313
-
314
- }
315
-
316
- update_post_meta( $post_id, '_bto_data', $composite_data );
317
-
318
- }
319
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ class WCML_Composite_Products extends WCML_Compatibility_Helper{
5
+
6
+ private $tp;
7
+
8
+ function __construct() {
9
+ add_filter( 'woocommerce_composite_component_default_option', array($this, 'woocommerce_composite_component_default_option'), 10, 3 );
10
+ add_filter( 'wcml_cart_contents', array($this, 'wpml_composites_compat'), 11, 4 );
11
+ add_filter( 'woocommerce_composite_component_options_query_args', array($this, 'wpml_composites_transients_cache_per_language'), 10, 3 );
12
+ add_action( 'updated_post_meta', array( $this, 'sync_composite_data_across_translations'), 10, 4 );
13
+
14
+ if( is_admin() ){
15
+
16
+ add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
17
+ add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
18
+ add_action( 'wcml_update_extra_fields', array( $this, 'components_update' ), 10, 3 );
19
+
20
+ $this->tp = new WPML_Element_Translation_Package();
21
+
22
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_composite_data_translation_package' ), 10, 2 );
23
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_composite_data_translation' ), 10, 3 );
24
+ //lock fields on translations pages
25
+ add_filter( 'wcml_js_lock_fields_input_names', array( $this, 'wcml_js_lock_fields_input_names' ) );
26
+
27
+ }
28
+ }
29
+
30
+ function woocommerce_composite_component_default_option($selected_value, $component_id, $object) {
31
+
32
+ if( !empty( $selected_value ) )
33
+ $selected_value = apply_filters( 'wpml_object_id', $selected_value, 'product', true );
34
+
35
+
36
+ return $selected_value;
37
+ }
38
+
39
+ function wpml_composites_compat( $new_cart_data, $cart_contents, $key, $new_key ) {
40
+
41
+ if ( isset( $cart_contents[ $key ][ 'composite_children' ] ) || isset( $cart_contents[ $key ][ 'composite_parent' ] ) ) {
42
+
43
+ $buff = $new_cart_data[ $new_key ];
44
+
45
+ unset( $new_cart_data[ $new_key ] );
46
+
47
+ $new_cart_data[ $key ] = $buff;
48
+ }
49
+
50
+ return $new_cart_data;
51
+ }
52
+
53
+ function wpml_composites_transients_cache_per_language( $args, $query_args, $component_data ) {
54
+
55
+ $args[ 'wpml_lang' ] = apply_filters( 'wpml_current_language', NULL );
56
+
57
+ return $args;
58
+ }
59
+
60
+ function sync_composite_data_across_translations( $meta_id, $post_id, $meta_key, $composite_data ){
61
+
62
+
63
+ if( $meta_key != '_bto_data' )
64
+ return false;
65
+
66
+
67
+ global $sitepress, $woocommerce_wpml;
68
+
69
+ $post = get_post( $post_id );
70
+
71
+ // skip auto-drafts // skip autosave
72
+ if ( $post->post_status == 'auto-draft' || isset( $_POST[ 'autosave' ] ) ) {
73
+ return;
74
+ }
75
+
76
+ if( $post->post_type == 'product' ) {
77
+
78
+ if( $this->get_product_type( $post_id ) == 'composite' ) {
79
+
80
+ remove_action( 'updated_post_meta', array( $this, 'sync_composite_data_across_translations'), 10, 4 );
81
+
82
+ if ( $woocommerce_wpml->products->is_original_product( $post_id ) ) {
83
+
84
+ $original_product_id = $post_id;
85
+
86
+ } else {
87
+
88
+ $original_product_language = $woocommerce_wpml->products->get_original_product_language( $post_id );
89
+ $original_product_id = apply_filters( 'translate_object_id', $post_id, 'product', true, $original_product_language );
90
+
91
+ }
92
+
93
+ $product = new WC_Product_Composite( $original_product_id );
94
+
95
+ $product_trid = $sitepress->get_element_trid( $original_product_id, 'post_product' );
96
+ $product_translations = $sitepress->get_element_translations( $product_trid, 'post_product' );
97
+
98
+ foreach ( $product_translations as $product_translation ) {
99
+
100
+ if ( empty($product_translation->original) ) {
101
+
102
+ $translated_product = new WC_Product_Composite( $product_translation->element_id );
103
+ $translated_composite_data = $translated_product->get_composite_data();
104
+
105
+ foreach ( $composite_data as $component_id => $component ) {
106
+
107
+ if( isset( $translated_composite_data[$component_id]['title'] ) ){
108
+ $composite_data[$component_id]['title'] = $translated_composite_data[$component_id]['title'];
109
+ }
110
+
111
+ if( isset( $translated_composite_data[$component_id]['description'] ) ){
112
+ $composite_data[$component_id]['description'] = $translated_composite_data[$component_id]['description'];
113
+ }
114
+
115
+ if ( $component['query_type'] == 'product_ids' ) {
116
+
117
+ foreach ( $component['assigned_ids'] as $idx => $assigned_id ) {
118
+ $composite_data[$component_id]['assigned_ids'][$idx] =
119
+ apply_filters( 'translate_object_id', $assigned_id, 'product', true, $product_translation->language_code );
120
+ }
121
+
122
+ } elseif( $component['query_type'] == 'category_ids' ){
123
+
124
+ foreach ( $component['assigned_category_ids'] as $idx => $assigned_id ) {
125
+ $composite_data[$component_id]['assigned_category_ids'][$idx] =
126
+ apply_filters( 'translate_object_id', $assigned_id, 'product_cat', true, $product_translation->language_code );
127
+
128
+ }
129
+
130
+ }
131
+
132
+ }
133
+
134
+ update_post_meta( $product_translation->element_id, '_bto_data', $composite_data );
135
+
136
+ }
137
+
138
+ }
139
+
140
+ add_action( 'updated_post_meta', array( $this, 'sync_composite_data_across_translations'), 10, 4 );
141
+
142
+ }
143
+
144
+ }
145
+
146
+ }
147
+
148
+ function custom_box_html( $obj, $product_id, $data ){
149
+
150
+ if( $this->get_product_type( $product_id ) == 'composite' ){
151
+
152
+ $product = new WC_Product_Composite( $product_id );
153
+ $composite_data = $product->get_composite_data();
154
+
155
+ $composite_section = new WPML_Editor_UI_Field_Section( __( 'Composite Products', 'woocommerce-multilingual' ) );
156
+ end( $composite_data );
157
+ $last_key = key( $composite_data );
158
+ $divider = true;
159
+ foreach( $composite_data as $component_id => $component ) {
160
+ if( $component_id == $last_key ){
161
+ $divider = false;
162
+ }
163
+ $group = new WPML_Editor_UI_Field_Group( '', $divider );
164
+ $composite_field = new WPML_Editor_UI_Single_Line_Field( 'composite_'.$component_id.'_title', __( 'Name', 'woocommerce-multilingual' ), $data, false );
165
+ $group->add_field( $composite_field );
166
+ $composite_field = new WPML_Editor_UI_Single_Line_Field( 'composite_'.$component_id.'_description' , __( 'Description', 'woocommerce-multilingual' ), $data, false );
167
+ $group->add_field( $composite_field );
168
+ $composite_section->add_field( $group );
169
+
170
+ }
171
+
172
+ if( $composite_data ){
173
+ $obj->add_field( $composite_section );
174
+ }
175
+
176
+ }
177
+
178
+ }
179
+
180
+ function custom_box_html_data( $data, $product_id, $translation, $lang ){
181
+
182
+ if( $this->get_product_type( $product_id ) == 'composite' ){
183
+
184
+ $product = new WC_Product_Composite( $product_id );
185
+ $composite_data = $product->get_composite_data();
186
+
187
+ foreach( $composite_data as $component_id => $component ) {
188
+
189
+ $data['composite_'.$component_id.'_title'] = array( 'original' =>
190
+ isset( $composite_data[$component_id]['title'] ) ? $composite_data[$component_id]['title'] : '' );
191
+
192
+ $data['composite_'.$component_id.'_description'] = array( 'original' =>
193
+ isset( $composite_data[$component_id]['description'] ) ? $composite_data[$component_id]['description'] : '' );
194
+
195
+ }
196
+
197
+ if( $translation ){
198
+ $translated_product = new WC_Product_Composite( $translation->ID );
199
+ $translated_composite_data = $translated_product->get_composite_data();
200
+
201
+ foreach( $composite_data as $component_id => $component ){
202
+
203
+ $data['composite_'.$component_id.'_title'][ 'translation' ] =
204
+ isset( $translated_composite_data[$component_id]['title'] ) ? $translated_composite_data[$component_id]['title'] : '';
205
+
206
+ $data['composite_'.$component_id.'_description'][ 'translation' ] =
207
+ isset( $translated_composite_data[$component_id]['description'] ) ? $translated_composite_data[$component_id]['description'] : '';
208
+
209
+ }
210
+ }
211
+
212
+ }
213
+
214
+ return $data;
215
+ }
216
+
217
+ function components_update( $original_product_id, $product_id, $data ){
218
+
219
+ $product = new WC_Product_Composite( $product_id );
220
+
221
+ $composite_data = $product->get_composite_data();
222
+
223
+ foreach( $composite_data as $component_id => $component ) {
224
+
225
+ if(!empty($data[ md5( 'composite_'.$component_id.'_title' ) ] ) ){
226
+ $composite_data[$component_id]['title'] = $data[ md5( 'composite_'.$component_id.'_title' ) ];
227
+ }
228
+
229
+ if(!empty($data[ md5( 'composite_'.$component_id.'_description' ) ])) {
230
+ $composite_data[$component_id]['description'] = $data[ md5( 'composite_'.$component_id.'_description' ) ];
231
+ }
232
+
233
+ }
234
+
235
+ update_post_meta( $product_id, '_bto_data', $composite_data );
236
+
237
+
238
+ }
239
+
240
+ function append_composite_data_translation_package( $package, $post ){
241
+
242
+ if( $post->post_type == 'product' ) {
243
+
244
+ $composite_data = get_post_meta( $post->ID, '_bto_data', true );
245
+
246
+ if( $composite_data ){
247
+
248
+ $fields = array( 'title', 'description' );
249
+
250
+ foreach( $composite_data as $component_id => $component ){
251
+
252
+ foreach( $fields as $field ) {
253
+ if ( !empty($component[$field]) ) {
254
+
255
+ $package['contents']['wc_composite:' . $component_id . ':' . $field] = array(
256
+ 'translate' => 1,
257
+ 'data' => $this->tp->encode_field_data( $component[$field], 'base64' ),
258
+ 'format' => 'base64'
259
+ );
260
+
261
+ }
262
+ }
263
+
264
+ }
265
+
266
+ }
267
+
268
+ }
269
+
270
+ return $package;
271
+
272
+ }
273
+
274
+ function save_composite_data_translation( $post_id, $data, $job ){
275
+
276
+
277
+ $translated_composite_data = array();
278
+ foreach( $data as $value){
279
+
280
+ if( preg_match( '/wc_composite:([0-9]+):(.+)/', $value['field_type'], $matches ) ){
281
+
282
+ $component_id = $matches[1];
283
+ $field = $matches[2];
284
+
285
+ $translated_composite_data[$component_id][$field] = $value['data'];
286
+
287
+ }
288
+
289
+ }
290
+
291
+ if( $translated_composite_data ){
292
+
293
+ $composite_data = get_post_meta( $job->original_doc_id, '_bto_data', true );
294
+
295
+
296
+ foreach ( $composite_data as $component_id => $component ) {
297
+
298
+ if( isset( $translated_composite_data[$component_id]['title'] ) ){
299
+ $composite_data[$component_id]['title'] = $translated_composite_data[$component_id]['title'];
300
+ }
301
+
302
+ if( isset( $translated_composite_data[$component_id]['description'] ) ){
303
+ $composite_data[$component_id]['description'] = $translated_composite_data[$component_id]['description'];
304
+ }
305
+
306
+ if ( $component['query_type'] == 'product_ids' ) {
307
+
308
+ foreach ( $component['assigned_ids'] as $idx => $assigned_id ) {
309
+ $composite_data[$component_id]['assigned_ids'][$idx] =
310
+ apply_filters( 'translate_object_id', $assigned_id, 'product', true, $job->language_code );
311
+ }
312
+
313
+ } elseif( $component['query_type'] == 'category_ids' ){
314
+
315
+ foreach ( $component['assigned_category_ids'] as $idx => $assigned_id ) {
316
+ $composite_data[$component_id]['assigned_category_ids'][$idx] =
317
+ apply_filters( 'translate_object_id', $assigned_id, 'product_cat', true, $job->language_code );
318
+
319
+ }
320
+
321
+ }
322
+
323
+ }
324
+
325
+ }
326
+
327
+ update_post_meta( $post_id, '_bto_data', $composite_data );
328
+
329
+ }
330
+
331
+ function wcml_js_lock_fields_input_names( $names ){
332
+
333
+ $names[] = '_per_product_pricing_bto';
334
+ $names[] = '_per_product_shipping_bto';
335
+ $names[] = '_base_regular_price';
336
+ $names[] = '_base_sale_price';
337
+ $names[] = '_bto_hide_shop_price';
338
+
339
+ return $names;
340
+ }
341
+
342
+ }
compatibility/class-wcml-dynamic-pricing.php CHANGED
@@ -1,95 +1,81 @@
1
- <?php
2
-
3
- class WCML_Dynamic_Pricing{
4
-
5
- function __construct(){
6
- if(!is_admin()){
7
- add_filter('wc_dynamic_pricing_load_modules', array($this, 'filter_price'));
8
- add_filter('woocommerce_dynamic_pricing_is_applied_to', array($this, 'woocommerce_dynamic_pricing_is_applied_to'),10,5);
9
- add_filter('woocommerce_dynamic_pricing_get_rule_amount',array($this,'woocommerce_dynamic_pricing_get_rule_amount'),10,4);
10
- add_filter('dynamic_pricing_product_rules',array($this,'dynamic_pricing_product_rules'));
11
- add_filter('translate_cart_subtotal_exception',array($this,'translate_cart_subtotal_exception'),10,2);
12
-
13
- }
14
- }
15
-
16
- function filter_price($modules){
17
-
18
- foreach($modules as $mod_key=>$module){
19
- if(isset($module->available_rulesets)){
20
- $available_rulesets = $module->available_rulesets;
21
- foreach($available_rulesets as $rule_key=>$available_ruleset){
22
- $rules = $available_ruleset['rules'];
23
-
24
- if($rules){
25
- foreach($rules as $r_key=>$rule){
26
- if($rule['type'] == 'fixed_product'){
27
- $rules[$r_key]['amount'] = apply_filters('wcml_raw_price_amount', $rule['amount']);
28
- }
29
- }
30
- $modules[$mod_key]->available_rulesets[$rule_key]['rules'] = $rules;
31
-
32
- }
33
- }
34
-
35
- }
36
- }
37
-
38
- return $modules;
39
- }
40
-
41
-
42
- function woocommerce_dynamic_pricing_is_applied_to($process_discounts, $_product, $module_id, $obj,$cat_id){
43
-
44
- if (is_numeric($cat_id)) {
45
- $cat_id = array($cat_id);
46
- }
47
-
48
- foreach ($cat_id as $cid) {
49
-
50
- if ($process_discounts) {
51
- continue;
52
- }
53
-
54
- if($cid && isset($obj->available_rulesets) && count($obj->available_rulesets) > 0){
55
- global $sitepress;
56
- $cid = apply_filters( 'translate_object_id',$cid,'product_cat',true,$sitepress->get_current_language());
57
- $process_discounts = is_object_in_term($_product->id, 'product_cat', $cid);
58
- }
59
- }
60
-
61
-
62
-
63
- return $process_discounts;
64
- }
65
-
66
-
67
- function woocommerce_dynamic_pricing_get_rule_amount($amount, $rule, $cart_item, $obj){
68
-
69
- if($rule['type'] == 'price_discount' || $rule['type'] == 'fixed_price'){
70
- $amount = apply_filters('wcml_raw_price_amount',$amount);
71
- }
72
-
73
- return $amount;
74
-
75
- }
76
-
77
-
78
- function dynamic_pricing_product_rules($rules){
79
- if(is_array($rules)){
80
- foreach($rules as $r_key=>$rule){
81
- foreach($rule['rules'] as $key=>$product_rule){
82
- if($product_rule['type'] == 'price_discount' || $product_rule['type'] == 'fixed_price'){
83
- $rules[$r_key]['rules'][$key]['amount'] = apply_filters('wcml_raw_price_amount', $product_rule['amount']);
84
- }
85
- }
86
- }
87
- }
88
- return $rules;
89
- }
90
-
91
- function translate_cart_subtotal_exception( $value, $cart ){
92
- return true;
93
- }
94
-
95
- }
1
+ <?php
2
+
3
+ class WCML_Dynamic_Pricing{
4
+
5
+ function __construct(){
6
+ if(!is_admin()){
7
+ add_filter('wc_dynamic_pricing_load_modules', array($this, 'filter_price'));
8
+ add_filter('woocommerce_dynamic_pricing_is_applied_to', array($this, 'woocommerce_dynamic_pricing_is_applied_to'),10,5);
9
+ add_filter('woocommerce_dynamic_pricing_get_rule_amount',array($this,'woocommerce_dynamic_pricing_get_rule_amount'),10,4);
10
+ add_filter('dynamic_pricing_product_rules',array($this,'dynamic_pricing_product_rules'));
11
+ add_filter('translate_cart_subtotal_exception',array($this,'translate_cart_subtotal_exception'),10,2);
12
+
13
+ }
14
+ }
15
+
16
+ function filter_price($modules){
17
+
18
+ foreach($modules as $mod_key=>$module){
19
+ if(isset($module->available_rulesets)){
20
+ $available_rulesets = $module->available_rulesets;
21
+ foreach($available_rulesets as $rule_key=>$available_ruleset){
22
+ $rules = $available_ruleset['rules'];
23
+
24
+ if($rules){
25
+ foreach($rules as $r_key=>$rule){
26
+ if($rule['type'] == 'fixed_product'){
27
+ $rules[$r_key]['amount'] = apply_filters('wcml_raw_price_amount', $rule['amount']);
28
+ }
29
+ }
30
+ $modules[$mod_key]->available_rulesets[$rule_key]['rules'] = $rules;
31
+
32
+ }
33
+ }
34
+
35
+ }
36
+ }
37
+
38
+ return $modules;
39
+ }
40
+
41
+
42
+ function woocommerce_dynamic_pricing_is_applied_to($process_discounts, $_product, $module_id, $obj,$cat_id){
43
+ if($cat_id && isset($obj->available_rulesets) && count($obj->available_rulesets) > 0){
44
+ global $sitepress;
45
+ $cat_id = apply_filters( 'translate_object_id',$cat_id,'product_cat',true,$sitepress->get_current_language());
46
+ $process_discounts = is_object_in_term($_product->id, 'product_cat', $cat_id);
47
+ }
48
+
49
+ return $process_discounts;
50
+ }
51
+
52
+
53
+ function woocommerce_dynamic_pricing_get_rule_amount($amount, $rule, $cart_item, $obj){
54
+
55
+ if($rule['type'] == 'price_discount' || $rule['type'] == 'fixed_price'){
56
+ $amount = apply_filters('wcml_raw_price_amount',$amount);
57
+ }
58
+
59
+ return $amount;
60
+
61
+ }
62
+
63
+
64
+ function dynamic_pricing_product_rules($rules){
65
+ if(is_array($rules)){
66
+ foreach($rules as $r_key=>$rule){
67
+ foreach($rule['rules'] as $key=>$product_rule){
68
+ if($product_rule['type'] == 'price_discount' || $product_rule['type'] == 'fixed_price'){
69
+ $rules[$r_key]['rules'][$key]['amount'] = apply_filters('wcml_raw_price_amount', $product_rule['amount']);
70
+ }
71
+ }
72
+ }
73
+ }
74
+ return $rules;
75
+ }
76
+
77
+ function translate_cart_subtotal_exception( $value, $cart ){
78
+ return true;
79
+ }
80
+
81
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
compatibility/class-wcml-extra-product-options.php CHANGED
@@ -1,122 +1,107 @@
1
- <?php
2
-
3
- class WCML_Extra_Product_Options{
4
-
5
- function __construct(){
6
-
7
- add_filter( 'get_tm_product_terms', array( $this, 'filter_product_terms' ) );
8
-
9
- add_filter( 'get_post_metadata', array( $this, 'product_options_filter'), 100, 4 );
10
-
11
- add_action( 'updated_post_meta', array( $this, 'register_options_strings' ), 10, 4 );
12
-
13
- add_action( 'tm_before_extra_product_options', array( $this, 'inf_translate_product_page_strings' ) );
14
- add_action( 'tm_before_price_rules', array( $this, 'inf_translate_strings' ) );
15
- }
16
-
17
- function register_options_strings( $meta_id, $id, $meta_key, $options ){
18
- if( $meta_key != 'tm_meta' )
19
- return false;
20
-
21
- $this->filter_options( $options, $id, 'register' );
22
-
23
- }
24
-
25
- function product_options_filter( $null, $object_id, $meta_key, $single ){
26
- static $no_filter = false;
27
-
28
- if( empty($no_filter) && $meta_key == 'tm_meta' && !is_admin() ){
29
- $no_filter = true;
30
-
31
- $options = maybe_unserialize( get_post_meta( $object_id, $meta_key, $single ) );
32
-
33
- $options = $this->filter_options( $options, $object_id, 'translate' );
34
-
35
- $no_filter = false;
36
- }
37
-
38
- return isset( $options ) ? array( $options ) : $null;
39
- }
40
-
41
- function filter_options( $options, $id, $action ){
42
-
43
- if( !isset( $options[ 'tmfbuilder' ] ) ){
44
- return $options;
45
- }
46
-
47
- global $sitepress,$woocommerce_wpml;
48
- $keys_to_translate = array( 'header_title', 'header_subtitle', 'text_after_price', 'placeholder' );
49
-
50
- $id = apply_filters( 'translate_object_id', $id, get_post_type( $id ), true, $woocommerce_wpml->products->get_original_product_language( $id ) );
51
-
52
- foreach( $options[ 'tmfbuilder' ] as $key => $values ){
53
- foreach( $keys_to_translate as $key_text ){
54
- if ( preg_match('/.*'.$key_text.'$/', $key ) ) {
55
- foreach( $values as $value_key => $value ){
56
- if( $value ){
57
- if( $action == 'register'){
58
- do_action('wpml_register_single_string', 'wc_extra_product_options', $id.'_option_'.$value_key.'_'.$key, $value );
59
- }else{
60
- $options[ 'tmfbuilder' ][ $key ][ $value_key ] = apply_filters( 'wpml_translate_single_string', $value, 'wc_extra_product_options', $id.'_option_'.$value_key.'_'.$key);
61
- }
62
- }
63
-
64
- }
65
- }
66
- }
67
-
68
- //convert prices
69
- if( $action == 'translate' && preg_match('/.*price$/', $key ) && !preg_match('/.*text_after_price/', $key )){
70
- foreach( $values as $value_key => $value ){
71
- if( $value ){
72
- if( is_array( $value ) ){
73
- foreach( $value as $key_price => $price ){
74
- $options[ 'tmfbuilder' ][ $key ][ $value_key ][ $key_price ] = apply_filters( 'wcml_raw_price_amount', $price );
75
- }
76
- }else{
77
- $options[ 'tmfbuilder' ][ $key ][ $value_key ] = apply_filters( 'wcml_raw_price_amount', $value );
78
- }
79
- }
80
- }
81
- }
82
-
83
- }
84
-
85
- return $options;
86
- }
87
-
88
-
89
- function filter_product_terms( $product_terms ){
90
- global $sitepress,$wpdb;
91
-
92
- $translated_terms = array();
93
-
94
- foreach($product_terms as $key => $product_term){
95
- $tr_id = apply_filters( 'translate_object_id', $key, 'product_cat', true, $sitepress->get_default_language() );
96
-
97
- $translated_terms[$tr_id] = $wpdb->get_row( $wpdb->prepare("
98
- SELECT * FROM {$wpdb->terms} t JOIN {$wpdb->term_taxonomy} x ON x.term_id = t.term_id WHERE t.term_id = %d AND x.taxonomy = %s", $tr_id, 'product_cat' ) );
99
-
100
- }
101
-
102
-
103
- return $translated_terms;
104
- }
105
-
106
- function inf_translate_strings(){
107
- if( isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'tm-global-epo' )
108
- $this->inf_message( 'Options Form' );
109
- }
110
-
111
- function inf_translate_product_page_strings(){
112
- $this->inf_message( 'Product' );
113
- }
114
-
115
- function inf_message( $text ){
116
- $message = '<div><p class="icl_cyan_box">';
117
- $message .= sprintf(__('To translate Extra Options strings please save %s and go to the <b><a href="%s">String Translation interface</a></b>', 'woocommerce-multilingual'), $text, admin_url('admin.php?page='.WPML_ST_FOLDER.'/menu/string-translation.php&context=wc_extra_product_options'));
118
- $message .= '</p></div>';
119
-
120
- echo $message;
121
- }
122
- }
1
+ <?php
2
+
3
+ class WCML_Extra_Product_Options{
4
+
5
+ function __construct(){
6
+
7
+ // commented out because of wcml-1218
8
+ // add_filter( 'get_post_metadata', array( $this, 'product_options_filter'), 100, 4 );
9
+ // add_action( 'updated_post_meta', array( $this, 'register_options_strings' ), 10, 4 );
10
+
11
+ add_action( 'tm_before_extra_product_options', array( $this, 'inf_translate_product_page_strings' ) );
12
+ add_action( 'tm_before_price_rules', array( $this, 'inf_translate_strings' ) );
13
+ }
14
+
15
+ // commented out because of wcml-1218
16
+ /*
17
+
18
+ function register_options_strings( $meta_id, $id, $meta_key, $options ){
19
+ if( $meta_key != 'tm_meta' )
20
+ return false;
21
+
22
+ $this->filter_options( $options, $id, 'register' );
23
+
24
+ }
25
+
26
+ function product_options_filter( $null, $object_id, $meta_key, $single ){
27
+ static $no_filter = false;
28
+
29
+ if( empty($no_filter) && $meta_key == 'tm_meta' && !is_admin() ){
30
+ $no_filter = true;
31
+
32
+ $options = maybe_unserialize( get_post_meta( $object_id, $meta_key, $single ) );
33
+
34
+ $options = $this->filter_options( $options, $object_id, 'translate' );
35
+
36
+ $no_filter = false;
37
+ }
38
+
39
+ return isset( $options ) ? array( $options ) : $null;
40
+ }
41
+
42
+ function filter_options( $options, $id, $action ){
43
+
44
+ if( !isset( $options[ 'tmfbuilder' ] ) ){
45
+ return $options;
46
+ }
47
+
48
+ global $sitepress,$woocommerce_wpml;
49
+ $keys_to_translate = array( 'header_title', 'header_subtitle', 'text_after_price', 'placeholder' );
50
+
51
+ $id = apply_filters( 'translate_object_id', $id, get_post_type( $id ), true, $woocommerce_wpml->products->get_original_product_language( $id ) );
52
+
53
+ foreach( $options[ 'tmfbuilder' ] as $key => $values ){
54
+ foreach( $keys_to_translate as $key_text ){
55
+ if ( preg_match('/.*'.$key_text.'$/', $key ) ) {
56
+ foreach( $values as $value_key => $value ){
57
+ if( $value ){
58
+ if( $action == 'register'){
59
+ do_action('wpml_register_single_string', 'wc_extra_product_options', $id.'_option_'.$value_key.'_'.$key, $value );
60
+ }else{
61
+ $options[ 'tmfbuilder' ][ $key ][ $value_key ] = apply_filters( 'wpml_translate_single_string', $value, 'wc_extra_product_options', $id.'_option_'.$value_key.'_'.$key);
62
+ }
63
+ }
64
+
65
+ }
66
+ }
67
+ }
68
+
69
+ //convert prices
70
+ if( $action == 'translate' && preg_match('/.*price$/', $key ) && !preg_match('/.*text_after_price/', $key )){
71
+ foreach( $values as $value_key => $value ){
72
+ if( $value ){
73
+ if( is_array( $value ) ){
74
+ foreach( $value as $key_price => $price ){
75
+ $options[ 'tmfbuilder' ][ $key ][ $value_key ][ $key_price ] = apply_filters( 'wcml_raw_price_amount', $price );
76
+ }
77
+ }else{
78
+ $options[ 'tmfbuilder' ][ $key ][ $value_key ] = apply_filters( 'wcml_raw_price_amount', $value );
79
+ }
80
+ }
81
+ }
82
+ }
83
+
84
+ }
85
+
86
+ return $options;
87
+ }
88
+
89
+ */
90
+
91
+ function inf_translate_strings(){
92
+ if( isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'tm-global-epo' )
93
+ $this->inf_message( 'Options Form' );
94
+ }
95
+
96
+ function inf_translate_product_page_strings(){
97
+ $this->inf_message( 'Product' );
98
+ }
99
+
100
+ function inf_message( $text ){
101
+ $message = '<div><p class="icl_cyan_box">';
102
+ $message .= sprintf(__('To translate Extra Options strings please save %s and go to the <b><a href="%s">String Translation interface</a></b>', 'woocommerce-multilingual'), $text, admin_url('admin.php?page='.WPML_ST_FOLDER.'/menu/string-translation.php&context=wc_extra_product_options'));
103
+ $message .= '</p></div>';
104
+
105
+ echo $message;
106
+ }
107
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
compatibility/class-wcml-flatsome.php CHANGED
@@ -1,16 +1,16 @@
1
- <?php
2
-
3
- class WCML_Flatsome{
4
-
5
- function __construct(){
6
- add_filter( 'wcml_multi_currency_is_ajax', array( $this, 'add_action_to_multi_currency_ajax' ) );
7
- }
8
-
9
- function add_action_to_multi_currency_ajax($actions){
10
- $actions[] = 'ux_quickview';
11
- return $actions;
12
- }
13
-
14
-
15
- }
16
-
1
+ <?php
2
+
3
+ class WCML_Flatsome{
4
+
5
+ function __construct(){
6
+ add_filter( 'wcml_multi_currency_is_ajax', array( $this, 'add_action_to_multi_currency_ajax' ) );
7
+ }
8
+
9
+ function add_action_to_multi_currency_ajax($actions){
10
+ $actions[] = 'ux_quickview';
11
+ return $actions;
12
+ }
13
+
14
+
15
+ }
16
+
compatibility/class-wcml-gravityforms.php CHANGED
@@ -1,47 +1,47 @@
1
- <?php
2
-
3
- class WCML_gravityforms{
4
-
5
- function __construct(){
6
- add_filter('gform_formatted_money',array($this,'wcml_convert_price'),10,2);
7
- add_filter('wcml_multi_currency_is_ajax',array($this,'add_ajax_action'));
8
-
9
- add_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_gf_data'), 10, 3 );
10
- }
11
-
12
- function wcml_convert_price($formatted, $unformatted){
13
- if ( ! is_admin() ) {
14
- $currency = apply_filters('wcml_price_currency', get_woocommerce_currency());
15
- $formatted = strip_tags(wc_price(apply_filters('wcml_raw_price_amount', $unformatted), array('currency'=>$currency)));
16
- }
17
- return $formatted;
18
- }
19
-
20
-
21
- function add_ajax_action($actions){
22
- $actions[] = 'get_updated_price';
23
- return $actions;
24
- }
25
-
26
- function sync_gf_data($original_product_id, $trnsl_product_id, $data){
27
- $orig_gf = maybe_unserialize( get_post_meta( $original_product_id, '_gravity_form_data' , true ) );
28
- $trnsl_gf = maybe_unserialize( get_post_meta( $trnsl_product_id, '_gravity_form_data' , true ) );
29
-
30
- if( !$trnsl_gf ){
31
- update_post_meta( $trnsl_product_id, '_gravity_form_data', $orig_gf );
32
- }else{
33
- $trnsl_gf['id'] = $orig_gf['id'];
34
- $trnsl_gf['display_title'] = $orig_gf['display_title'];
35
- $trnsl_gf['display_description'] = $orig_gf['display_description'];
36
- $trnsl_gf['disable_woocommerce_price'] = $orig_gf['disable_woocommerce_price'];
37
- $trnsl_gf['disable_calculations'] = $orig_gf['disable_calculations'];
38
- $trnsl_gf['disable_label_subtotal'] = $orig_gf['disable_label_subtotal'];
39
- $trnsl_gf['disable_label_options'] = $orig_gf['disable_label_options'];
40
- $trnsl_gf['disable_label_total'] = $orig_gf['disable_label_total'];
41
- $trnsl_gf['disable_anchor'] = $orig_gf['disable_anchor'];
42
-
43
- update_post_meta( $trnsl_product_id, '_gravity_form_data', $trnsl_gf );
44
- }
45
- }
46
-
47
- }
1
+ <?php
2
+
3
+ class WCML_gravityforms{
4
+
5
+ function __construct(){
6
+ add_filter('gform_formatted_money',array($this,'wcml_convert_price'),10,2);
7
+ add_filter('wcml_multi_currency_is_ajax',array($this,'add_ajax_action'));
8
+
9
+ add_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_gf_data'), 10, 3 );
10
+ }
11
+
12
+ function wcml_convert_price($formatted, $unformatted){
13
+ if ( ! is_admin() ) {
14
+ $currency = apply_filters('wcml_price_currency', get_woocommerce_currency());
15
+ $formatted = strip_tags(wc_price(apply_filters('wcml_raw_price_amount', $unformatted), array('currency'=>$currency)));
16
+ }
17
+ return $formatted;
18
+ }
19
+
20
+
21
+ function add_ajax_action($actions){
22
+ $actions[] = 'get_updated_price';
23
+ return $actions;
24
+ }
25
+
26
+ function sync_gf_data($original_product_id, $trnsl_product_id, $data){
27
+ $orig_gf = maybe_unserialize( get_post_meta( $original_product_id, '_gravity_form_data' , true ) );
28
+ $trnsl_gf = maybe_unserialize( get_post_meta( $trnsl_product_id, '_gravity_form_data' , true ) );
29
+
30
+ if( !$trnsl_gf ){
31
+ update_post_meta( $trnsl_product_id, '_gravity_form_data', $orig_gf );
32
+ }else{
33
+ $trnsl_gf['id'] = $orig_gf['id'];
34
+ $trnsl_gf['display_title'] = $orig_gf['display_title'];
35
+ $trnsl_gf['display_description'] = $orig_gf['display_description'];
36
+ $trnsl_gf['disable_woocommerce_price'] = $orig_gf['disable_woocommerce_price'];
37
+ $trnsl_gf['disable_calculations'] = $orig_gf['disable_calculations'];
38
+ $trnsl_gf['disable_label_subtotal'] = $orig_gf['disable_label_subtotal'];
39
+ $trnsl_gf['disable_label_options'] = $orig_gf['disable_label_options'];
40
+ $trnsl_gf['disable_label_total'] = $orig_gf['disable_label_total'];
41
+ $trnsl_gf['disable_anchor'] = $orig_gf['disable_anchor'];
42
+
43
+ update_post_meta( $trnsl_product_id, '_gravity_form_data', $trnsl_gf );
44
+ }
45
+ }
46
+
47
+ }
compatibility/class-wcml-mix-and-match-products.php CHANGED
@@ -1,78 +1,67 @@
1
- <?php
2
-
3
- class WCML_Mix_and_Match_Products{
4
-
5
- function __construct(){
6
- add_action( 'updated_post_meta', array( $this, 'sync_mnm_data'), 10, 4 );
7
- add_filter('woocommerce_product_object', array($this, 'woocommerce_product_object'), 10, 1 );
8
- }
9
-
10
- function sync_mnm_data( $meta_id, $post_id, $meta_key, $meta_value ){
11
-
12
- if( $meta_key != '_mnm_data' )
13
- return false;
14
-
15
- global $sitepress, $woocommerce_wpml;
16
-
17
- $post = get_post( $post_id );
18
-
19
- // skip auto-drafts // skip autosave
20
- if ( $post->post_status == 'auto-draft' || isset( $_POST[ 'autosave' ] ) ) {
21
- return;
22
- }
23
-
24
- if( $post->post_type == 'product' ) {
25
-
26
- remove_action( 'updated_post_meta', array( $this, 'sync_mnm_data'), 10, 4 );
27
-
28
- if ( $woocommerce_wpml->products->is_original_product( $post_id ) ) {
29
-
30
- $original_product_id = $post_id;
31
-
32
- } else {
33
-
34
- $original_product_language = $woocommerce_wpml->products->get_original_product_language( $post_id );
35
- $original_product_id = apply_filters( 'translate_object_id', $post_id, 'product', true, $original_product_language );
36
-
37
- }
38
-
39
- $mnm_data = maybe_unserialize( get_post_meta( $original_product_id, '_mnm_data', true ) );
40
- $product_trid = $sitepress->get_element_trid( $original_product_id, 'post_product' );
41
- $product_translations = $sitepress->get_element_translations( $product_trid, 'post_product' );
42
-
43
- foreach ( $product_translations as $product_translation ) {
44
-
45
- if (empty($product_translation->original)) {
46
-
47
- foreach ($mnm_data as $key => $mnm_element) {
48
-
49
- $trnsl_prod = apply_filters( 'translate_object_id', $key, 'product', true, $product_translation->language_code );
50
- $mnm_element['product_id'] = $trnsl_prod;
51
- $mnm_data[ $trnsl_prod ] = $mnm_element;
52
- unset( $mnm_data[$key]);
53
- }
54
-
55
- update_post_meta($product_translation->element_id, '_mnm_data', $mnm_data);
56
-
57
- }
58
-
59
- }
60
-
61
- add_action( 'updated_post_meta', array( $this, 'sync_mnm_data'), 10, 4 );
62
-
63
- }
64
-
65
- }
66
-
67
- function woocommerce_product_object ($the_product) {
68
-
69
- $translated_product_id = apply_filters('wpml_object_id', $the_product->ID, 'product', True);
70
-
71
- if ($translated_product_id != $the_product->ID) {
72
- $the_product = wc_get_product($translated_product_id);
73
- }
74
-
75
- return $the_product;
76
- }
77
-
78
- }
1
+ <?php
2
+
3
+ class WCML_Mix_and_Match_Products{
4
+
5
+ function __construct(){
6
+ add_action( 'updated_post_meta', array( $this, 'sync_mnm_data'), 10, 4 );
7
+ }
8
+
9
+ function sync_mnm_data( $meta_id, $post_id, $meta_key, $meta_value ){
10
+
11
+ if( $meta_key != '_mnm_data' )
12
+ return false;
13
+
14
+ global $sitepress, $woocommerce_wpml;
15
+
16
+ $post = get_post( $post_id );
17
+
18
+ // skip auto-drafts // skip autosave
19
+ if ( $post->post_status == 'auto-draft' || isset( $_POST[ 'autosave' ] ) ) {
20
+ return;
21
+ }
22
+
23
+ if( $post->post_type == 'product' ) {
24
+
25
+ remove_action( 'updated_post_meta', array( $this, 'sync_mnm_data'), 10, 4 );
26
+
27
+ if ( $woocommerce_wpml->products->is_original_product( $post_id ) ) {
28
+
29
+ $original_product_id = $post_id;
30
+
31
+ } else {
32
+
33
+ $original_product_language = $woocommerce_wpml->products->get_original_product_language( $post_id );
34
+ $original_product_id = apply_filters( 'translate_object_id', $post_id, 'product', true, $original_product_language );
35
+
36
+ }
37
+
38
+ $mnm_data = maybe_unserialize( get_post_meta( $original_product_id, '_mnm_data', true ) );
39
+ $product_trid = $sitepress->get_element_trid( $original_product_id, 'post_product' );
40
+ $product_translations = $sitepress->get_element_translations( $product_trid, 'post_product' );
41
+
42
+ foreach ( $product_translations as $product_translation ) {
43
+
44
+ if (empty($product_translation->original)) {
45
+
46
+ foreach ($mnm_data as $key => $mnm_element) {
47
+
48
+ $trnsl_prod = apply_filters( 'translate_object_id', $key, 'product', true, $product_translation->language_code );
49
+ $mnm_element['product_id'] = $trnsl_prod;
50
+ $mnm_data[ $trnsl_prod ] = $mnm_element;
51
+ unset( $mnm_data[$key]);
52
+ }
53
+
54
+ update_post_meta($product_translation->element_id, '_mnm_data', $mnm_data);
55
+
56
+ }
57
+
58
+ }
59
+
60
+ add_action( 'updated_post_meta', array( $this, 'sync_mnm_data'), 10, 4 );
61
+
62
+ }
63
+
64
+ }
65
+
66
+
67
+ }
 
 
 
 
 
 
 
 
 
 
 
compatibility/class-wcml-per-product-shipping.php CHANGED
@@ -1,30 +1,30 @@
1
- <?php
2
-
3
- class WCML_Per_Product_Shipping{
4
-
5
- function __construct(){
6
-
7
- if(!is_admin()){
8
-
9
- add_filter('woocommerce_per_product_shipping_get_matching_rule_product_id', array( $this, 'original_product_id' ) );
10
-
11
- }
12
-
13
-
14
- }
15
-
16
- function original_product_id( $product_id ){
17
- global $sitepress;
18
-
19
- $trid = $sitepress->get_element_trid($product_id, 'post_product');
20
- $translations = $sitepress->get_element_translations($trid, 'post_product');
21
- foreach($translations as $language_code =>$translation){
22
- if($translation->original){
23
- $product_id = $translation->element_id;
24
- }
25
- }
26
-
27
- return $product_id;
28
- }
29
-
30
- }
1
+ <?php
2
+
3
+ class WCML_Per_Product_Shipping{
4
+
5
+ function __construct(){
6
+
7
+ if(!is_admin()){
8
+
9
+ add_filter('woocommerce_per_product_shipping_get_matching_rule_product_id', array( $this, 'original_product_id' ) );
10
+
11
+ }
12
+
13
+
14
+ }
15
+
16
+ function original_product_id( $product_id ){
17
+ global $sitepress;
18
+
19
+ $trid = $sitepress->get_element_trid($product_id, 'post_product');
20
+ $translations = $sitepress->get_element_translations($trid, 'post_product');
21
+ foreach($translations as $language_code =>$translation){
22
+ if($translation->original){
23
+ $product_id = $translation->element_id;
24
+ }
25
+ }
26
+
27
+ return $product_id;
28
+ }
29
+
30
+ }
compatibility/class-wcml-product-addons.php CHANGED
@@ -1,76 +1,175 @@
1
- <?php
2
-
3
- class WCML_Product_Addons{
4
-
5
- function __construct(){
6
-
7
- add_filter('get_product_addons_product_terms',array($this,'addons_product_terms'));
8
- add_filter('get_product_addons_fields',array($this,'product_addons_filter'),10,2);
9
-
10
- add_action('updated_post_meta',array($this,'register_addons_strings'),10,4);
11
-
12
- global $pagenow;
13
- if($pagenow == 'edit.php' && isset($_GET['post_type']) && $_GET['post_type']=='product' && isset($_GET['page']) && $_GET['page']=='global_addons' && !isset($_GET['edit'])){
14
- add_action('admin_notices', array($this, 'inf_translate_strings'));
15
- }
16
-
17
- add_action( 'addons_panel_start', array( $this, 'inf_translate_strings' ) );
18
- }
19
-
20
- function register_addons_strings( $meta_id, $id, $meta_key, $addons){
21
- if( $meta_key != '_product_addons' )
22
- return false;
23
-
24
- foreach($addons as $addon){
25
- //register name
26
- do_action('wpml_register_single_string', 'wc_product_addons_strings', $id.'_addon_'.$addon['type'].'_'.$addon['position'].'_name', $addon['name']);
27
- //register description
28
- do_action('wpml_register_single_string', 'wc_product_addons_strings', $id.'_addon_'.$addon['type'].'_'.$addon['position'].'_description', $addon['description']);
29
- //register options labels
30
- foreach($addon['options'] as $key=>$option){
31
- do_action('wpml_register_single_string', 'wc_product_addons_strings', $id.'_addon_'.$addon['type'].'_'.$addon['position'].'_option_label_'.$key, $option['label']);
32
- }
33
- }
34
- }
35
-
36
- function product_addons_filter($addons, $object_id){
37
- global $sitepress;
38
-
39
- $addon_type = get_post_type($object_id);
40
- if( $addon_type != 'global_product_addon' )
41
- $object_id = $sitepress->get_original_element_id( $object_id , 'post_'.$addon_type );
42
-
43
- foreach($addons as $add_id => $addon){
44
- $addons[$add_id]['name'] = apply_filters( 'wpml_translate_single_string', $addon['name'], 'wc_product_addons_strings', $object_id.'_addon_'.$addon['type'].'_'.$addon['position'].'_name' );
45
- $addons[$add_id]['description'] = apply_filters( 'wpml_translate_single_string', $addon['description'], 'wc_product_addons_strings', $object_id.'_addon_'.$addon['type'].'_'.$addon['position'].'_description');
46
- foreach($addon['options'] as $key=>$option){
47
- $addons[$add_id]['options'][$key]['label'] = apply_filters( 'wpml_translate_single_string', $option['label'], 'wc_product_addons_strings', $object_id.'_addon_'.$addon['type'].'_'.$addon['position'].'_option_label_'.$key);
48
-
49
- //price filter
50
- $addons[$add_id]['options'][$key]['price'] = apply_filters('wcml_raw_price_amount', $option['price']);
51
- }
52
- }
53
-
54
- return $addons;
55
- }
56
-
57
-
58
- function addons_product_terms($product_terms){
59
- global $sitepress;
60
-
61
- foreach($product_terms as $key => $product_term){
62
- $product_terms[$key] = apply_filters( 'translate_object_id',$product_term,'product_cat',true,$sitepress->get_default_language());
63
- }
64
-
65
- return $product_terms;
66
- }
67
-
68
- function inf_translate_strings(){
69
- $message = '<div><p class="icl_cyan_box">';
70
- $message .= sprintf(__('To translate Add-ons strings please save Add-ons and go to the <b><a href="%s">String Translation interface</a></b>', 'woocommerce-multilingual'), admin_url('admin.php?page='.WPML_ST_FOLDER.'/menu/string-translation.php&context=wc_product_addons_strings'));
71
- $message .= '</p></div>';
72
-
73
- echo $message;
74
- }
75
-
76
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_Product_Addons{
4
+
5
+ function __construct(){
6
+
7
+ add_filter('get_product_addons_product_terms',array($this,'addons_product_terms'));
8
+ add_filter('get_product_addons_fields',array($this,'product_addons_filter'),10,2);
9
+
10
+ add_action('updated_post_meta',array($this,'register_addons_strings'),10,4);
11
+ add_action('added_post_meta',array($this,'register_addons_strings'),10,4);
12
+
13
+ global $pagenow;
14
+ if($pagenow == 'edit.php' && isset($_GET['post_type']) && $_GET['post_type']=='product' && isset($_GET['page']) && $_GET['page']=='global_addons' && !isset($_GET['edit'])){
15
+ add_action('admin_notices', array($this, 'inf_translate_strings'));
16
+ }
17
+
18
+ add_action( 'addons_panel_start', array( $this, 'inf_translate_strings' ) );
19
+
20
+ if( is_admin() ) {
21
+
22
+ add_action('wcml_gui_additional_box_html', array($this, 'custom_box_html'), 10, 3);
23
+ add_filter('wcml_gui_additional_box_data', array($this, 'custom_box_html_data'), 10, 4);
24
+ add_action('wcml_update_extra_fields',array($this,'addons_update'),10,3);
25
+ }
26
+ }
27
+
28
+ function register_addons_strings( $meta_id, $id, $meta_key, $addons){
29
+ if( $meta_key == '_product_addons' && get_post_type( $id ) == 'global_product_addon') {
30
+ foreach ($addons as $addon) {
31
+ //register name
32
+ do_action('wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_name', $addon['name']);
33
+ //register description
34
+ do_action('wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_description', $addon['description']);
35
+ //register options labels
36
+ foreach ($addon['options'] as $key => $option) {
37
+ do_action('wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_option_label_' . $key, $option['label']);
38
+ }
39
+ }
40
+ }
41
+ }
42
+
43
+ function product_addons_filter($addons, $object_id){
44
+
45
+ foreach($addons as $add_id => $addon){
46
+ foreach($addon['options'] as $key=>$option){
47
+ //price filter
48
+ $addons[$add_id]['options'][$key]['price'] = apply_filters('wcml_raw_price_amount', $option['price']);
49
+ }
50
+ }
51
+
52
+ return $addons;
53
+ }
54
+
55
+
56
+ function addons_product_terms($product_terms){
57
+ global $sitepress;
58
+
59
+ foreach($product_terms as $key => $product_term){
60
+ $product_terms[$key] = apply_filters( 'translate_object_id',$product_term,'product_cat',true,$sitepress->get_default_language());
61
+ }
62
+
63
+ return $product_terms;
64
+ }
65
+
66
+ function inf_translate_strings(){
67
+ $message = '<div><p class="icl_cyan_box">';
68
+ $message .= sprintf(__('To translate Add-ons strings please save Add-ons and go to the <b><a href="%s">String Translation interface</a></b>', 'woocommerce-multilingual'), admin_url('admin.php?page='.WPML_ST_FOLDER.'/menu/string-translation.php&context=wc_product_addons_strings'));
69
+ $message .= '</p></div>';
70
+
71
+ echo $message;
72
+ }
73
+
74
+ function custom_box_html( $obj, $product_id, $data ){
75
+
76
+ $product_addons = maybe_unserialize( get_post_meta( $product_id, '_product_addons', true ) );
77
+
78
+ if( !empty( $product_addons ) ){
79
+
80
+ foreach( $product_addons as $addon_id => $product_addon ) {
81
+
82
+ $addons_section = new WPML_Editor_UI_Field_Section( sprintf( __( 'Product Add-ons Group "%s"', 'woocommerce-multilingual' ), $product_addon['name'] ) );
83
+
84
+ $group = new WPML_Editor_UI_Field_Group( '' , true );
85
+ $addon_field = new WPML_Editor_UI_Single_Line_Field( 'addon_'.$addon_id.'_name', __( 'Name', 'woocommerce-multilingual' ), $data, false );
86
+ $group->add_field( $addon_field );
87
+ $addon_field = new WPML_Editor_UI_Single_Line_Field( 'addon_'.$addon_id.'_description' , __( 'Description', 'woocommerce-multilingual' ), $data, false );
88
+ $group->add_field( $addon_field );
89
+
90
+ $addons_section->add_field( $group );
91
+
92
+ if( !empty( $product_addon['options'] ) ){
93
+
94
+ $labels_group = new WPML_Editor_UI_Field_Group( __( 'Options', 'woocommerce-multilingual' ) , true );
95
+
96
+ foreach( $product_addon['options'] as $option_id => $option ){
97
+
98
+ $option_label_field = new WPML_Editor_UI_Single_Line_Field( 'addon_'.$addon_id.'_option_'.$option_id.'_label', __( 'Label', 'woocommerce-multilingual' ), $data, false );
99
+ $labels_group->add_field( $option_label_field );
100
+
101
+ }
102
+
103
+ $addons_section->add_field( $labels_group );
104
+ }
105
+
106
+ $obj->add_field( $addons_section );
107
+
108
+ }
109
+
110
+ }
111
+
112
+ }
113
+
114
+ function custom_box_html_data( $data, $product_id, $translation, $lang ){
115
+
116
+ $product_addons = maybe_unserialize( get_post_meta( $product_id, '_product_addons', true ) );
117
+
118
+ if( !empty( $product_addons ) ){
119
+ foreach( $product_addons as $addon_id => $product_addon ) {
120
+ $data[ 'addon_'.$addon_id.'_name' ] = array( 'original' => $product_addon[ 'name' ] );
121
+ $data[ 'addon_'.$addon_id.'_description' ] = array( 'original' => $product_addon['description'] );
122
+ if( !empty( $product_addon['options'] ) ){
123
+ foreach( $product_addon['options'] as $option_id => $option ){
124
+ $data[ 'addon_'.$addon_id.'_option_'.$option_id.'_label' ] = array( 'original' => $option[ 'label' ] );
125
+ }
126
+ }
127
+ }
128
+
129
+ if( $translation ){
130
+ $transalted_product_addons = maybe_unserialize( get_post_meta( $translation->ID, '_product_addons', true ) );
131
+ if( !empty( $transalted_product_addons ) ){
132
+ foreach( $transalted_product_addons as $addon_id => $transalted_product_addon ) {
133
+ $data[ 'addon_'.$addon_id.'_name' ][ 'translation' ] = $transalted_product_addon[ 'name' ];
134
+ $data[ 'addon_'.$addon_id.'_description' ][ 'translation' ] = $transalted_product_addon['description'];
135
+ if( !empty( $transalted_product_addon['options'] ) ){
136
+ foreach( $transalted_product_addon['options'] as $option_id => $option ){
137
+ $data[ 'addon_'.$addon_id.'_option_'.$option_id.'_label' ][ 'translation' ] = $option[ 'label' ];
138
+ }
139
+ }
140
+ }
141
+ }
142
+ }
143
+ }
144
+
145
+ return $data;
146
+ }
147
+
148
+ function addons_update( $original_product_id, $product_id, $data ){
149
+
150
+ $product_addons = maybe_unserialize( get_post_meta( $product_id, '_product_addons', true ) );
151
+
152
+ if( !empty( $product_addons ) ){
153
+
154
+ foreach( $product_addons as $addon_id => $product_addon ) {
155
+
156
+ $product_addons[ $addon_id ][ 'name' ] = $data[ md5( 'addon_'.$addon_id.'_name' ) ];
157
+ $product_addons[ $addon_id ][ 'description' ] = $data[ md5( 'addon_'.$addon_id.'_description' ) ];
158
+
159
+ if( !empty( $product_addon['options'] ) ){
160
+
161
+ foreach( $product_addon['options'] as $option_id => $option ){
162
+ $product_addons[ $addon_id ]['options'][ $option_id ][ 'label' ] = $data[ md5( 'addon_'.$addon_id.'_option_'.$option_id.'_label' ) ];
163
+ }
164
+
165
+ }
166
+
167
+ }
168
+ }
169
+
170
+ update_post_meta( $product_id, '_product_addons', $product_addons );
171
+
172
+
173
+ }
174
+
175
+ }
compatibility/class-wcml-product-bundles.php CHANGED
@@ -1,345 +1,364 @@
1
- <?php
2
- class WCML_Product_Bundles{
3
-
4
- var $tp;
5
-
6
- function __construct(){
7
-
8
- add_action('wcml_gui_additional_box',array($this,'product_bundles_box'),10,3);
9
- add_action('wcml_after_duplicate_product_post_meta',array($this,'sync_bundled_ids'),10,3);
10
- add_action('wcml_extra_titles',array($this,'product_bundles_title'),10,1);
11
- add_action('wcml_update_extra_fields',array($this,'bundle_update'),10,2);
12
- add_action('woocommerce_get_cart_item_from_session', array( $this, 'resync_bundle'),5,3);
13
- add_filter('woocommerce_cart_loaded_from_session', array($this, 'resync_bundle_clean'),10);
14
-
15
- if( version_compare( WCML_VERSION, '3.7.2', '>') ){
16
- add_filter( 'option_wpml_config_files_arr', array($this, 'make__bundle_data_not_translatable_by_default'), 0 );
17
- }
18
-
19
- if( is_admin() ){
20
- $this->tp = new WPML_Element_Translation_Package();
21
-
22
- add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_bundle_data_translation_package' ), 10, 2 );
23
- add_action( 'wpml_translation_job_saved', array( $this, 'save_bundle_data_translation' ), 10, 3 );
24
-
25
- }
26
-
27
- }
28
-
29
- function make__bundle_data_not_translatable_by_default($wpml_config_array){
30
-
31
- if( isset( $wpml_config_array->plugins['WooCommerce Product Bundles'] ) ){
32
- $wpml_config_array->plugins['WooCommerce Product Bundles'] =
33
- str_replace('<custom-field action="translate">_bundle_data</custom-field>', '<custom-field action="nothing">_bundle_data</custom-field>', $wpml_config_array->plugins['WooCommerce Product Bundles']);
34
- }
35
-
36
- return $wpml_config_array;
37
- }
38
-
39
- // Sync Bundled product '_bundle_data' with translated values when the product is duplicated
40
- function sync_bundled_ids($original_product_id, $trnsl_product_id, $data = false){
41
- global $sitepress;
42
- $atts = maybe_unserialize(get_post_meta($original_product_id, '_bundle_data', true));
43
- if( $atts ){
44
- $lang = $sitepress->get_language_for_element($trnsl_product_id,'post_product');
45
- $tr_bundle_meta = maybe_unserialize(get_post_meta($trnsl_product_id, '_bundle_data', true));
46
- $tr_ids = array();
47
- $i = 2;
48
- foreach($atts as $id=>$bundle_data){
49
- $tr_id = apply_filters( 'translate_object_id',$id,get_post_type($id),true,$lang);
50
- if(isset($tr_bundle[$tr_id])){
51
- $bundle_key = $tr_id.'_'.$i;
52
- $i++;
53
- }else{
54
- $bundle_key = $tr_id;
55
- }
56
- $tr_bundle[$bundle_key] = $bundle_data;
57
- $tr_bundle[$bundle_key]['product_id'] = $tr_id;
58
- if(isset($bundle_data['product_title'])){
59
- if($bundle_data['override_title'] == 'yes'){
60
- $tr_bundle[$bundle_key]['product_title'] = isset( $tr_bundle_meta[$bundle_key]['product_title'] ) ? $tr_bundle_meta[$bundle_key]['product_title'] : '';
61
- }else{
62
- $tr_title= get_the_title($tr_id);
63
- $tr_bundle[$bundle_key]['product_title'] = $tr_title;
64
- }
65
- }
66
- if(isset($bundle_data['product_description'])){
67
- if($bundle_data['override_description']=='yes'){
68
- $tr_bundle[$bundle_key]['product_description'] = isset( $tr_bundle_meta[$bundle_key]['product_description'] ) ? $tr_bundle_meta[$bundle_key]['product_description'] : '';
69
- }else{
70
- $tr_prod = get_post($tr_id);
71
- $tr_desc = $tr_prod->post_excerpt;
72
- $tr_bundle[$bundle_key]['product_description'] = $tr_desc;
73
- }
74
- }
75
- if(isset($bundle_data['filter_variations']) && $bundle_data['filter_variations']=='yes'){
76
- $allowed_var = $bundle_data['allowed_variations'];
77
- foreach($allowed_var as $key=>$var_id){
78
- $tr_var_id = apply_filters( 'translate_object_id',$var_id,get_post_type($var_id),true,$lang);
79
- $tr_bundle[$bundle_key]['allowed_variations'][$key] = $tr_var_id;
80
- }
81
- }
82
- if(isset($bundle_data['bundle_defaults']) && !empty($bundle_data['bundle_defaults'])){
83
- foreach($bundle_data['bundle_defaults'] as $tax=>$term_slug){
84
- global $woocommerce_wpml;
85
- $term_id = $woocommerce_wpml->products->wcml_get_term_id_by_slug( $tax, $term_slug );
86
- if( $term_id ){
87
- // Global Attribute
88
- $tr_def_id = apply_filters( 'translate_object_id',$term_id,$tax,true,$lang);
89
- $tr_term = $woocommerce_wpml->products->wcml_get_term_by_id( $tr_def_id, $tax );
90
- $tr_bundle[$bundle_key]['bundle_defaults'][$tax] = $tr_term->slug;
91
- }else{
92
- // Custom Attribute
93
- $args = array( 'post_type' => 'product_variation', 'meta_key' => 'attribute_'.$tax, 'meta_value' => $term_slug, 'meta_compare' => '=');
94
- $variationloop = new WP_Query( $args );
95
- while ( $variationloop->have_posts() ) : $variationloop->the_post();
96
- $tr_var_id = apply_filters( 'translate_object_id',get_the_ID(),'product_variation',true,$lang);
97
- $tr_meta = get_post_meta($tr_var_id, 'attribute_'.$tax , true);
98
- $tr_bundle[$bundle_key]['bundle_defaults'][$tax] = $tr_meta;
99
- endwhile;
100
- }
101
- }
102
- }
103
- }
104
- update_post_meta($trnsl_product_id,'_bundle_data',$tr_bundle);
105
- }
106
- }
107
-
108
- // Update Bundled products title and descritpion after saving the translation
109
- function bundle_update($tr_id, $data){
110
- global $sitepress;
111
- $tr_bundle_data = array();
112
- $tr_bundle_data = maybe_unserialize(get_post_meta($tr_id,'_bundle_data', true));
113
- if(!empty($data['bundles'])){
114
- foreach($data['bundles'] as $bundle_id => $bundle_data){
115
- if(isset($tr_bundle_data[$bundle_id])){
116
- $tr_bundle_data[$bundle_id]['product_title'] = $bundle_data['bundle_title'];
117
- $tr_bundle_data[$bundle_id]['product_description'] = $bundle_data['bundle_desc'];
118
- }
119
- }
120
- update_post_meta( $tr_id, '_bundle_data', $tr_bundle_data );
121
- $tr_bundle_data = array();
122
- }
123
- }
124
-
125
- // Add 'Product Bundles' title to the WCML Product GUI if the current product is a bundled product
126
- function product_bundles_title($product_id){
127
- $bundle_data = maybe_unserialize(get_post_meta($product_id,'_bundle_data', true));
128
- if(!empty($bundle_data) && $bundle_data!=false){ ?>
129
- <th scope="col"><?php _e('Product Bundles', 'woocommerce-multilingual'); ?></th>
130
- <?php }
131
- }
132
-
133
- // Add Bundles Box to WCML Translation GUI
134
- function product_bundles_box($product_id,$lang, $is_duplicate_product = false ) {
135
- global $sitepress, $woocommerce_wpml;
136
- $isbundle = true;
137
- $translated = true;
138
- $template_data = array();
139
- $default_language = $woocommerce_wpml->products->get_original_product_language( $product_id );
140
- if($default_language != $lang){
141
- $tr_product_id = apply_filters( 'translate_object_id',$product_id, 'product', true, $lang);
142
- if($tr_product_id == $product_id){
143
- $translated = false;
144
- }else{
145
- $product_id = $tr_product_id;
146
- }
147
- }
148
- $bundle_data = maybe_unserialize(get_post_meta($product_id,'_bundle_data', true));
149
- if(empty($bundle_data) || $bundle_data==false){
150
- $isbundle = false;
151
- }
152
- if(!$isbundle){
153
- return;
154
- }
155
- if($default_language == $lang){
156
- $template_data['original'] = true;
157
- }else{
158
- $template_data['original'] = false;
159
- }
160
- if (!$translated ) {
161
- $template_data['empty_translation'] = true;
162
- $template_data['product_bundles'] = array();
163
- }else{
164
- $product_bundles = array_keys($bundle_data);
165
- $k = 0;
166
- foreach($product_bundles as $original_id){
167
- $tr_bundles_ids[$k] = apply_filters( 'translate_object_id',$original_id,'product',false,$lang);
168
- $k++;
169
- }
170
- $template_data['product_bundles'] = $tr_bundles_ids;
171
- $tr_bundles_ids = $template_data['product_bundles'];
172
- if (empty($tr_bundles_ids)) {
173
- $template_data['empty_bundles'] = true;
174
- $template_data['product_bundles'] = array();
175
- } else {
176
- if ($default_language == $lang) {
177
- $template_data['product_bundles'] = $tr_bundles_ids;
178
- }
179
- foreach ($product_bundles as $bundle_id) {
180
- $bundles_texts = array();
181
- $bundle_name = get_the_title($bundle_id);
182
- if(isset($bundle_data[$bundle_id]['override_title']) && $bundle_data[$bundle_id]['override_title']=='yes'){
183
- $bundle_title = $bundle_data[$bundle_id]['product_title'];
184
- $template_data['bundles_data'][$bundle_name]['override_bundle_title'] = 'yes';
185
- }else{
186
- $bundle_title = get_the_title($bundle_id);
187
- }
188
- if(isset($bundle_data[$bundle_id]['override_description']) && $bundle_data[$bundle_id]['override_description']=='yes'){
189
- $bundle_desc = $bundle_data[$bundle_id]['product_description'];
190
- $template_data['bundles_data'][$bundle_name]['override_bundle_desc'] = 'yes';
191
- }else{
192
- $bundle_prod = get_post($bundle_id);
193
- $bundle_desc = $bundle_prod->post_excerpt;
194
- }
195
- $template_data['bundles_data'][$bundle_name]['bundle_title'] = $bundle_title;
196
- $template_data['bundles_data'][$bundle_name]['bundle_desc'] = $bundle_desc;
197
- }
198
- }
199
- }
200
- include WCML_PLUGIN_PATH . '/compatibility/templates/bundles_box.php';
201
- }
202
-
203
- function resync_bundle( $cart_item, $session_values, $cart_item_key ) {
204
- if ( isset( $cart_item[ 'bundled_items' ] ) && $cart_item[ 'data' ]->product_type === 'bundle' ) {
205
- $current_bundle_id = apply_filters( 'translate_object_id', $cart_item[ 'product_id' ], 'product', true );
206
- if ( $cart_item[ 'product_id' ] != $current_bundle_id ) {
207
- $old_bundled_item_ids = array_keys( $cart_item[ 'data' ]->bundle_data );
208
- $cart_item[ 'data' ] = wc_get_product( $current_bundle_id );
209
- $new_bundled_item_ids = array_keys( $cart_item[ 'data' ]->bundle_data );
210
- $remapped_bundled_item_ids = array();
211
- foreach ( $old_bundled_item_ids as $old_item_id_index => $old_item_id ) {
212
- $remapped_bundled_item_ids[ $old_item_id ] = $new_bundled_item_ids[ $old_item_id_index ];
213
- }
214
- $cart_item[ 'remapped_bundled_item_ids' ] = $remapped_bundled_item_ids;
215
- if ( isset( $cart_item[ 'stamp' ] ) ) {
216
- $new_stamp = array();
217
- foreach ( $cart_item[ 'stamp' ] as $bundled_item_id => $stamp_data ) {
218
- $new_stamp[ $remapped_bundled_item_ids[ $bundled_item_id ] ] = $stamp_data;
219
- }
220
- $cart_item[ 'stamp' ] = $new_stamp;
221
- }
222
- }
223
- }
224
- if ( isset( $cart_item[ 'bundled_by' ] ) && isset( WC()->cart->cart_contents[ $cart_item[ 'bundled_by' ] ] ) ) {
225
- $bundle_cart_item = WC()->cart->cart_contents[ $cart_item[ 'bundled_by' ] ];
226
- if ( isset( $bundle_cart_item[ 'remapped_bundled_item_ids' ] ) && isset( $cart_item[ 'bundled_item_id' ] ) && isset( $bundle_cart_item[ 'remapped_bundled_item_ids' ][ $cart_item[ 'bundled_item_id' ] ] ) ) {
227
- $old_id = $cart_item[ 'bundled_item_id' ];
228
- $remapped_bundled_item_ids = $bundle_cart_item[ 'remapped_bundled_item_ids' ];
229
- $cart_item[ 'bundled_item_id' ] = $remapped_bundled_item_ids[ $cart_item[ 'bundled_item_id' ] ];
230
- if ( isset( $cart_item[ 'stamp' ] ) ) {
231
- $new_stamp = array();
232
- foreach ( $cart_item[ 'stamp' ] as $bundled_item_id => $stamp_data ) {
233
- $new_stamp[ $remapped_bundled_item_ids[ $bundled_item_id ] ] = $stamp_data;
234
- }
235
- $cart_item[ 'stamp' ] = $new_stamp;
236
- }
237
- }
238
- }
239
- return $cart_item;
240
- }
241
-
242
- function resync_bundle_clean( $cart ) {
243
- foreach ( $cart->cart_contents as $cart_item_key => $cart_item ) {
244
- if ( isset( $cart_item[ 'bundled_items' ] ) && $cart_item[ 'data' ]->product_type === 'bundle' ) {
245
- if ( isset( $cart_item[ 'remapped_bundled_item_ids' ] ) ) {
246
- unset( WC()->cart->cart_contents[ $cart_item_key ][ 'remapped_bundled_item_ids' ] );
247
- }
248
- }
249
- }
250
- }
251
-
252
- function append_bundle_data_translation_package( $package, $post ){
253
-
254
- if( $post->post_type == 'product' ) {
255
-
256
- $bundle_data = get_post_meta( $post->ID, '_bundle_data', true );
257
-
258
- if( $bundle_data ){
259
-
260
- $fields = array( 'title', 'description' );
261
-
262
- foreach( $bundle_data as $product ){
263
-
264
- foreach( $fields as $field ) {
265
- if ( $product['override_' . $field] == 'yes' && !empty($product['product_' . $field]) ) {
266
-
267
- $package['contents']['product_bundles:' . $product['product_id'] . ':' . $field] = array(
268
- 'translate' => 1,
269
- 'data' => $this->tp->encode_field_data( $product['product_' . $field], 'base64' ),
270
- 'format' => 'base64'
271
- );
272
-
273
- }
274
- }
275
-
276
- }
277
-
278
- }
279
-
280
- }
281
-
282
- return $package;
283
-
284
- }
285
-
286
- function save_bundle_data_translation( $post_id, $data, $job ){
287
-
288
- remove_action('wcml_after_duplicate_product_post_meta',array($this,'sync_bundled_ids'),10,3);
289
-
290
- $bundle_data = get_post_meta( $post_id, '_bundle_data', true );
291
-
292
- $bundle_data_original = get_post_meta($job->original_doc_id , '_bundle_data', true);
293
-
294
- $translated_bundle_pieces = array();
295
-
296
- foreach( $data as $value){
297
-
298
- if( preg_match( '/product_bundles:([0-9]+):(.+)/', $value['field_type'], $matches ) ){
299
-
300
- $product_id = $matches[1];
301
- $field = $matches[2];
302
-
303
- $translated_product_id = apply_filters( 'translate_object_id', $product_id, 'product', true, $job->language_code );
304
-
305
- $products_translation_map[$translated_product_id] = $product_id;
306
-
307
- if( $translated_product_id ){
308
-
309
- $translated_bundle_pieces[$translated_product_id][$field] = $value['data'];
310
-
311
- }
312
-
313
- }
314
-
315
- }
316
-
317
- if( $translated_bundle_pieces ){
318
- foreach( $translated_bundle_pieces as $product_id => $piece ){
319
-
320
- if( isset($products_translation_map[$product_id]) ) {
321
-
322
- $bundle_data[$product_id] = array(
323
-
324
- 'product_id' => $product_id,
325
- 'hide_thumbnail' => $bundle_data_original[$products_translation_map[$product_id]]['hide_thumbnail'],
326
- 'override_title' => $bundle_data_original[$products_translation_map[$product_id]]['override_title'],
327
- 'product_title' => isset( $piece['title'] ) ? $piece['title'] : '',
328
- 'override_description' => $bundle_data_original[$products_translation_map[$product_id]]['override_description'],
329
- 'product_description' => isset( $piece['description'] ) ? $piece['description'] : '',
330
- 'optional' => $bundle_data_original[$products_translation_map[$product_id]]['optional'],
331
- 'bundle_quantity' => $bundle_data_original[$products_translation_map[$product_id]]['bundle_quantity'],
332
- 'bundle_quantity_max' => $bundle_data_original[$products_translation_map[$product_id]]['bundle_quantity_max'],
333
- 'bundle_discount' => $bundle_data_original[$products_translation_map[$product_id]]['bundle_discount'],
334
- 'visibility' => $bundle_data_original[$products_translation_map[$product_id]]['visibility'],
335
-
336
- );
337
- }
338
-
339
- }
340
- }
341
-
342
- update_post_meta( $post_id, '_bundle_data', $bundle_data );
343
-
344
- }
345
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class WCML_Product_Bundles{
3
+
4
+ var $tp;
5
+
6
+ function __construct(){
7
+
8
+ add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html'), 10, 3 );
9
+ add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data'), 10, 4 );
10
+ add_action('wcml_after_duplicate_product_post_meta',array($this,'sync_bundled_ids'),10,3);
11
+ add_action('wcml_update_extra_fields',array($this,'bundle_update'),10,4);
12
+ add_action('woocommerce_get_cart_item_from_session', array( $this, 'resync_bundle'),5,3);
13
+ add_filter('woocommerce_cart_loaded_from_session', array($this, 'resync_bundle_clean'),10);
14
+
15
+ if( version_compare( WCML_VERSION, '3.7.2', '>') ){
16
+ add_filter( 'option_wpml_config_files_arr', array($this, 'make__bundle_data_not_translatable_by_default'), 0 );
17
+ }
18
+
19
+ if( is_admin() ){
20
+ $this->tp = new WPML_Element_Translation_Package();
21
+
22
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_bundle_data_translation_package' ), 10, 2 );
23
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_bundle_data_translation' ), 10, 3 );
24
+
25
+ }
26
+
27
+ }
28
+
29
+ function make__bundle_data_not_translatable_by_default($wpml_config_array){
30
+
31
+ if( isset( $wpml_config_array->plugins['WooCommerce Product Bundles'] ) ){
32
+ $wpml_config_array->plugins['WooCommerce Product Bundles'] =
33
+ str_replace('<custom-field action="translate">_bundle_data</custom-field>', '<custom-field action="nothing">_bundle_data</custom-field>', $wpml_config_array->plugins['WooCommerce Product Bundles']);
34
+ }
35
+
36
+ return $wpml_config_array;
37
+ }
38
+
39
+ // Sync Bundled product '_bundle_data' with translated values when the product is duplicated
40
+ function sync_bundled_ids($original_product_id, $trnsl_product_id, $data = false){
41
+ global $sitepress;
42
+ $atts = maybe_unserialize(get_post_meta($original_product_id, '_bundle_data', true));
43
+ if( $atts ){
44
+ $lang = $sitepress->get_language_for_element($trnsl_product_id,'post_product');
45
+ $tr_bundle_meta = maybe_unserialize(get_post_meta($trnsl_product_id, '_bundle_data', true));
46
+ $tr_ids = array();
47
+ $i = 2;
48
+ foreach($atts as $id=>$bundle_data){
49
+ $tr_id = apply_filters( 'translate_object_id',$id,get_post_type($id),true,$lang);
50
+ if(isset($tr_bundle[$tr_id])){
51
+ $bundle_key = $tr_id.'_'.$i;
52
+ $i++;
53
+ }else{
54
+ $bundle_key = $tr_id;
55
+ }
56
+ $tr_bundle[$bundle_key] = $bundle_data;
57
+ $tr_bundle[$bundle_key]['product_id'] = $tr_id;
58
+ if(isset($bundle_data['product_title'])){
59
+ if($bundle_data['override_title'] == 'yes'){
60
+ $tr_bundle[$bundle_key]['product_title'] = isset( $tr_bundle_meta[$bundle_key]['product_title'] ) ? $tr_bundle_meta[$bundle_key]['product_title'] : '';
61
+ }else{
62
+ $tr_title= get_the_title($tr_id);
63
+ $tr_bundle[$bundle_key]['product_title'] = $tr_title;
64
+ }
65
+ }
66
+ if(isset($bundle_data['product_description'])){
67
+ if($bundle_data['override_description']=='yes'){
68
+ $tr_bundle[$bundle_key]['product_description'] = isset( $tr_bundle_meta[$bundle_key]['product_description'] ) ? $tr_bundle_meta[$bundle_key]['product_description'] : '';
69
+ }else{
70
+ $tr_prod = get_post($tr_id);
71
+ $tr_desc = $tr_prod->post_excerpt;
72
+ $tr_bundle[$bundle_key]['product_description'] = $tr_desc;
73
+ }
74
+ }
75
+ if(isset($bundle_data['filter_variations']) && $bundle_data['filter_variations']=='yes'){
76
+ $allowed_var = $bundle_data['allowed_variations'];
77
+ foreach($allowed_var as $key=>$var_id){
78
+ $tr_var_id = apply_filters( 'translate_object_id',$var_id,get_post_type($var_id),true,$lang);
79
+ $tr_bundle[$bundle_key]['allowed_variations'][$key] = $tr_var_id;
80
+ }
81
+ }
82
+ if(isset($bundle_data['bundle_defaults']) && !empty($bundle_data['bundle_defaults'])){
83
+ foreach($bundle_data['bundle_defaults'] as $tax=>$term_slug){
84
+ global $woocommerce_wpml;
85
+ $term_id = $woocommerce_wpml->terms->wcml_get_term_id_by_slug( $tax, $term_slug );
86
+ if( $term_id ){
87
+ // Global Attribute
88
+ $tr_def_id = apply_filters( 'translate_object_id',$term_id,$tax,true,$lang);
89
+ $tr_term = $woocommerce_wpml->terms->wcml_get_term_by_id( $tr_def_id, $tax );
90
+ $tr_bundle[$bundle_key]['bundle_defaults'][$tax] = $tr_term->slug;
91
+ }else{
92
+ // Custom Attribute
93
+ $args = array( 'post_type' => 'product_variation', 'meta_key' => 'attribute_'.$tax, 'meta_value' => $term_slug, 'meta_compare' => '=');
94
+ $variationloop = new WP_Query( $args );
95
+ while ( $variationloop->have_posts() ) : $variationloop->the_post();
96
+ $tr_var_id = apply_filters( 'translate_object_id',get_the_ID(),'product_variation',true,$lang);
97
+ $tr_meta = get_post_meta($tr_var_id, 'attribute_'.$tax , true);
98
+ $tr_bundle[$bundle_key]['bundle_defaults'][$tax] = $tr_meta;
99
+ endwhile;
100
+ }
101
+ }
102
+ }
103
+ }
104
+ update_post_meta($trnsl_product_id,'_bundle_data',$tr_bundle);
105
+ }
106
+ }
107
+ // Update Bundled products title and descritpion after saving the translation
108
+ function bundle_update( $original_product_id, $tr_id, $data, $lang ){
109
+ global $sitepress;
110
+ $tr_bundle_data = array();
111
+ $tr_bundle_data = maybe_unserialize( get_post_meta($tr_id,'_bundle_data', true) );
112
+
113
+ $bundle_data = maybe_unserialize( get_post_meta( $original_product_id, '_bundle_data', true ) );
114
+
115
+ if( empty( $bundle_data ) ){
116
+ return;
117
+ }
118
+
119
+ $product_bundles = array_keys( $bundle_data );
120
+
121
+ foreach ( $product_bundles as $key => $bundle_id ) {
122
+ $bundle_product_tr_id = apply_filters( 'translate_object_id', $bundle_id, get_post_type( $bundle_id ), true, $lang );
123
+ if(isset($tr_bundle_data[$bundle_product_tr_id])){
124
+ $tr_bundle_data[$bundle_product_tr_id]['product_title'] = $data[ md5( 'bundle_'.$bundle_id.'_title' )];
125
+ $tr_bundle_data[$bundle_product_tr_id]['product_description'] = $data[ md5( 'bundle_'.$bundle_id.'_desc' )];
126
+ }
127
+ }
128
+ update_post_meta( $tr_id, '_bundle_data', $tr_bundle_data );
129
+
130
+ }
131
+
132
+ // Add Bundles Box to WCML Translation GUI
133
+ function custom_box_html( $obj, $product_id, $data ){
134
+
135
+ $product_bundles = maybe_unserialize( get_post_meta( $product_id, '_bundle_data', true ) );
136
+
137
+ if( empty( $product_bundles ) || $product_bundles == false ){
138
+ return false;
139
+ }
140
+
141
+ $bundles_section = new WPML_Editor_UI_Field_Section( __( 'Product Bundles', 'woocommerce-multilingual' ) );
142
+ end( $product_bundles );
143
+ $last_key = key( $product_bundles );
144
+ $divider = true;
145
+ $flag = false;
146
+
147
+ foreach ( $product_bundles as $bundle_id => $product_bundle ) {
148
+ $add_group = false;
149
+ if( $bundle_id == $last_key ){
150
+ $divider = false;
151
+ }
152
+
153
+ $group = new WPML_Editor_UI_Field_Group( get_the_title( $bundle_id ), $divider );
154
+
155
+ if( $product_bundle['override_title'] == 'yes') {
156
+ $bundle_field = new WPML_Editor_UI_Single_Line_Field('bundle_' . $bundle_id . '_title', __('Name', 'woocommerce-multilingual'), $data, false);
157
+ $group->add_field($bundle_field);
158
+ $add_group = true;
159
+ }
160
+
161
+ if( $product_bundle['override_description'] == 'yes'){
162
+ $bundle_field = new WPML_Editor_UI_Single_Line_Field( 'bundle_'.$bundle_id.'_desc' , __( 'Description', 'woocommerce-multilingual' ), $data, false );
163
+ $group->add_field( $bundle_field );
164
+ $add_group = true;
165
+ }
166
+
167
+ if( $add_group ){
168
+ $bundles_section->add_field( $group );
169
+ $flag = true;
170
+ }
171
+
172
+ }
173
+
174
+ if( $flag ){
175
+ $obj->add_field( $bundles_section );
176
+ }
177
+
178
+ }
179
+
180
+
181
+ function custom_box_html_data( $data, $product_id, $translation, $lang ){
182
+ $bundle_data = maybe_unserialize( get_post_meta( $product_id, '_bundle_data', true ) );
183
+
184
+ if( $translation ) {
185
+ $tr_product_id = $translation->ID;
186
+ $tr_bundle_data = maybe_unserialize( get_post_meta( $tr_product_id, '_bundle_data', true ) );
187
+ }
188
+
189
+ if( empty( $bundle_data ) || $bundle_data == false ){
190
+ return $data;
191
+ }
192
+
193
+ $product_bundles = array_keys( $bundle_data );
194
+
195
+
196
+ foreach ( $product_bundles as $bundle_id ) {
197
+
198
+ $bundles_texts = array();
199
+ $bundle_name = get_the_title( $bundle_id );
200
+
201
+ $data[ 'bundle_'.$bundle_id.'_title' ] = array( 'original' => $bundle_data[$bundle_id]['product_title'] );
202
+ $data[ 'bundle_'.$bundle_id.'_desc' ] = array( 'original' => $bundle_data[$bundle_id]['product_description'] );
203
+
204
+ $curr_bundle_id = apply_filters( 'translate_object_id', $bundle_id, 'product', false, $lang );
205
+
206
+ if( isset($tr_bundle_data[$curr_bundle_id]['override_title']) && $tr_bundle_data[$curr_bundle_id]['override_title']=='yes' ){
207
+ $data[ 'bundle_'.$bundle_id.'_title' ][ 'translation' ] = $tr_bundle_data[$curr_bundle_id]['product_title'];
208
+ }else {
209
+ $data[ 'bundle_'.$bundle_id.'_title' ][ 'translation' ] = '';
210
+ }
211
+
212
+ if( isset($tr_bundle_data[$curr_bundle_id]['override_description']) && $tr_bundle_data[$curr_bundle_id]['override_description']=='yes' ){
213
+ $data[ 'bundle_'.$bundle_id.'_desc' ][ 'translation' ] = $tr_bundle_data[$curr_bundle_id]['product_description'];
214
+ }else {
215
+ $data[ 'bundle_'.$bundle_id.'_desc' ][ 'translation' ] = '';
216
+ }
217
+ }
218
+
219
+ return $data;
220
+ }
221
+
222
+ function resync_bundle( $cart_item, $session_values, $cart_item_key ) {
223
+ if ( isset( $cart_item[ 'bundled_items' ] ) && $cart_item[ 'data' ]->product_type === 'bundle' ) {
224
+ $current_bundle_id = apply_filters( 'translate_object_id', $cart_item[ 'product_id' ], 'product', true );
225
+ if ( $cart_item[ 'product_id' ] != $current_bundle_id ) {
226
+ $old_bundled_item_ids = array_keys( $cart_item[ 'data' ]->bundle_data );
227
+ $cart_item[ 'data' ] = wc_get_product( $current_bundle_id );
228
+ $new_bundled_item_ids = array_keys( $cart_item[ 'data' ]->bundle_data );
229
+ $remapped_bundled_item_ids = array();
230
+ foreach ( $old_bundled_item_ids as $old_item_id_index => $old_item_id ) {
231
+ $remapped_bundled_item_ids[ $old_item_id ] = $new_bundled_item_ids[ $old_item_id_index ];
232
+ }
233
+ $cart_item[ 'remapped_bundled_item_ids' ] = $remapped_bundled_item_ids;
234
+ if ( isset( $cart_item[ 'stamp' ] ) ) {
235
+ $new_stamp = array();
236
+ foreach ( $cart_item[ 'stamp' ] as $bundled_item_id => $stamp_data ) {
237
+ $new_stamp[ $remapped_bundled_item_ids[ $bundled_item_id ] ] = $stamp_data;
238
+ }
239
+ $cart_item[ 'stamp' ] = $new_stamp;
240
+ }
241
+ }
242
+ }
243
+ if ( isset( $cart_item[ 'bundled_by' ] ) && isset( WC()->cart->cart_contents[ $cart_item[ 'bundled_by' ] ] ) ) {
244
+ $bundle_cart_item = WC()->cart->cart_contents[ $cart_item[ 'bundled_by' ] ];
245
+ if ( isset( $bundle_cart_item[ 'remapped_bundled_item_ids' ] ) && isset( $cart_item[ 'bundled_item_id' ] ) && isset( $bundle_cart_item[ 'remapped_bundled_item_ids' ][ $cart_item[ 'bundled_item_id' ] ] ) ) {
246
+ $old_id = $cart_item[ 'bundled_item_id' ];
247
+ $remapped_bundled_item_ids = $bundle_cart_item[ 'remapped_bundled_item_ids' ];
248
+ $cart_item[ 'bundled_item_id' ] = $remapped_bundled_item_ids[ $cart_item[ 'bundled_item_id' ] ];
249
+ if ( isset( $cart_item[ 'stamp' ] ) ) {
250
+ $new_stamp = array();
251
+ foreach ( $cart_item[ 'stamp' ] as $bundled_item_id => $stamp_data ) {
252
+ $new_stamp[ $remapped_bundled_item_ids[ $bundled_item_id ] ] = $stamp_data;
253
+ }
254
+ $cart_item[ 'stamp' ] = $new_stamp;
255
+ }
256
+ }
257
+ }
258
+ return $cart_item;
259
+ }
260
+
261
+ function resync_bundle_clean( $cart ) {
262
+ foreach ( $cart->cart_contents as $cart_item_key => $cart_item ) {
263
+ if ( isset( $cart_item[ 'bundled_items' ] ) && $cart_item[ 'data' ]->product_type === 'bundle' ) {
264
+ if ( isset( $cart_item[ 'remapped_bundled_item_ids' ] ) ) {
265
+ unset( WC()->cart->cart_contents[ $cart_item_key ][ 'remapped_bundled_item_ids' ] );
266
+ }
267
+ }
268
+ }
269
+ }
270
+
271
+ function append_bundle_data_translation_package( $package, $post ){
272
+
273
+ if( $post->post_type == 'product' ) {
274
+
275
+ $bundle_data = get_post_meta( $post->ID, '_bundle_data', true );
276
+
277
+ if( $bundle_data ){
278
+
279
+ $fields = array( 'title', 'description' );
280
+
281
+ foreach( $bundle_data as $product ){
282
+
283
+ foreach( $fields as $field ) {
284
+ if ( $product['override_' . $field] == 'yes' && !empty($product['product_' . $field]) ) {
285
+
286
+ $package['contents']['product_bundles:' . $product['product_id'] . ':' . $field] = array(
287
+ 'translate' => 1,
288
+ 'data' => $this->tp->encode_field_data( $product['product_' . $field], 'base64' ),
289
+ 'format' => 'base64'
290
+ );
291
+
292
+ }
293
+ }
294
+
295
+ }
296
+
297
+ }
298
+
299
+ }
300
+
301
+ return $package;
302
+
303
+ }
304
+
305
+ function save_bundle_data_translation( $post_id, $data, $job ){
306
+
307
+ remove_action('wcml_after_duplicate_product_post_meta',array($this,'sync_bundled_ids'),10,3);
308
+
309
+ $bundle_data = get_post_meta( $post_id, '_bundle_data', true );
310
+
311
+ $bundle_data_original = get_post_meta($job->original_doc_id , '_bundle_data', true);
312
+
313
+ $translated_bundle_pieces = array();
314
+
315
+ foreach( $data as $value){
316
+
317
+ if( preg_match( '/product_bundles:([0-9]+):(.+)/', $value['field_type'], $matches ) ){
318
+
319
+ $product_id = $matches[1];
320
+ $field = $matches[2];
321
+
322
+ $translated_product_id = apply_filters( 'translate_object_id', $product_id, 'product', true, $job->language_code );
323
+
324
+ $products_translation_map[$translated_product_id] = $product_id;
325
+
326
+ if( $translated_product_id ){
327
+
328
+ $translated_bundle_pieces[$translated_product_id][$field] = $value['data'];
329
+
330
+ }
331
+
332
+ }
333
+
334
+ }
335
+
336
+ if( $translated_bundle_pieces ){
337
+ foreach( $translated_bundle_pieces as $product_id => $piece ){
338
+
339
+ if( isset($products_translation_map[$product_id]) ) {
340
+
341
+ $bundle_data[$product_id] = array(
342
+
343
+ 'product_id' => $product_id,
344
+ 'hide_thumbnail' => $bundle_data_original[$products_translation_map[$product_id]]['hide_thumbnail'],
345
+ 'override_title' => $bundle_data_original[$products_translation_map[$product_id]]['override_title'],
346
+ 'product_title' => isset( $piece['title'] ) ? $piece['title'] : '',
347
+ 'override_description' => $bundle_data_original[$products_translation_map[$product_id]]['override_description'],
348
+ 'product_description' => isset( $piece['description'] ) ? $piece['description'] : '',
349
+ 'optional' => $bundle_data_original[$products_translation_map[$product_id]]['optional'],
350
+ 'bundle_quantity' => $bundle_data_original[$products_translation_map[$product_id]]['bundle_quantity'],
351
+ 'bundle_quantity_max' => $bundle_data_original[$products_translation_map[$product_id]]['bundle_quantity_max'],
352
+ 'bundle_discount' => $bundle_data_original[$products_translation_map[$product_id]]['bundle_discount'],
353
+ 'visibility' => $bundle_data_original[$products_translation_map[$product_id]]['visibility'],
354
+
355
+ );
356
+ }
357
+
358
+ }
359
+ }
360
+
361
+ update_post_meta( $post_id, '_bundle_data', $bundle_data );
362
+
363
+ }
364
+ }
compatibility/class-wcml-sensei.php CHANGED
@@ -1,231 +1,231 @@
1
- <?php
2
-
3
- class WCML_sensei{
4
-
5
- function __construct(){
6
- global $sitepress;
7
- add_action( 'manage_edit-lesson_columns', array( $sitepress, 'add_posts_management_column' ) );
8
- add_action( 'manage_edit-course_columns', array( $sitepress, 'add_posts_management_column' ) );
9
-
10
- add_action( 'save_post', array( $this, 'save_post_actions' ), 100, 2 );
11
- add_action( 'sensei_log_activity_after', array( $this, 'log_activity_after' ), 10, 3 );
12
- add_filter( 'sensei_bought_product_id', array( $this, 'filter_bought_product_id' ), 10, 2 );
13
- add_action( 'delete_comment', array( $this, 'delete_user_activity' ) );
14
-
15
- add_action( 'pre_get_comments', array( $this, 'pre_get_comments') );
16
-
17
- if( is_admin() &&
18
- (
19
- ( isset($_GET['post_type']) && $_GET['post_type'] == 'sensei_message' ) ||
20
- ( isset($_GET['page']) && $_GET['page'] == 'sensei_grading' )
21
- ) ){
22
- remove_action( 'wp_before_admin_bar_render', array($sitepress, 'admin_language_switcher') );
23
- }
24
-
25
- }
26
-
27
- function save_post_actions( $post_id, $post ){
28
- global $sitepress;
29
-
30
- // skip not related post types
31
- if ( !in_array( $post->post_type , array( 'lesson', 'course', 'quiz' ) ) ) {
32
- return;
33
- }
34
- // skip auto-drafts
35
- if ( $post->post_status == 'auto-draft' ) {
36
- return;
37
- }
38
- // skip autosave
39
- if ( isset( $_POST[ 'autosave' ] ) ) {
40
- return;
41
- }
42
-
43
- if( $post->post_type == 'quiz' && isset( $_POST[ 'ID' ] ) ){
44
- $this->save_post_actions( $_POST[ 'ID' ], get_post( $_POST[ 'ID' ] ) );
45
- }
46
-
47
-
48
- // sync fields from original
49
- $trid = $sitepress->get_element_trid( $post_id, 'post_' . $post->post_type );
50
- $translations = $sitepress->get_element_translations( $trid, 'post_' . $post->post_type );
51
-
52
- if ( !empty( $translations ) ) {
53
- $original_post_id = false;
54
- foreach ( $translations as $t ) {
55
- if ( $t->original ) {
56
- $original_post_id = $t->element_id;
57
- break;
58
- }
59
- }
60
-
61
- if ( $post_id != $original_post_id ) {
62
- $this->sync_custom_fields( $original_post_id, $post_id, $post->post_type );
63
- } else {
64
- foreach ( $translations as $t ) {
65
- if ( $original_post_id != $t->element_id ) {
66
- $this->sync_custom_fields( $original_post_id, $t->element_id, $post->post_type );
67
- }
68
- }
69
- }
70
- }
71
-
72
- }
73
-
74
-
75
- function sync_custom_fields ( $original_post_id, $post_id, $post_type ){
76
- global $sitepress;
77
-
78
- $language = $sitepress->get_language_for_element( $post_id, 'post_'.$post_type );
79
- if( $post_type == 'quiz' ){
80
-
81
- //sync quiz lesson
82
- $lesson_id = get_post_meta( $original_post_id, '_quiz_lesson', true );
83
-
84
- if( $lesson_id ){
85
- $tr_lesson_id = apply_filters( 'translate_object_id', $lesson_id, 'lesson', false, $language );
86
-
87
- if( !is_null( $tr_lesson_id ) ){
88
- update_post_meta( $post_id, '_quiz_lesson', $tr_lesson_id );
89
- }
90
- }else{
91
- delete_post_meta( $post_id, '_quiz_lesson' );
92
- }
93
-
94
- } elseif( $post_type == 'lesson' ){
95
- //sync lesson course
96
- $course_id = get_post_meta( $original_post_id, '_lesson_course', true );
97
-
98
- if( $course_id ){
99
- $tr_course_id = apply_filters( 'translate_object_id', $course_id, 'course', false, $language );
100
-
101
- if( !is_null( $tr_course_id ) ){
102
- update_post_meta( $post_id, '_lesson_course', $tr_course_id );
103
- }
104
- }else{
105
- delete_post_meta( $post_id, '_lesson_course' );
106
- }
107
-
108
- //sync lesson prerequisite
109
- $lesson_id = get_post_meta( $original_post_id, '_lesson_prerequisite', true );
110
-
111
- if( $lesson_id ){
112
- $tr_lesson_id = apply_filters( 'translate_object_id', $lesson_id, 'lesson', false, $language );
113
-
114
- if( !is_null( $tr_lesson_id ) ){
115
- update_post_meta( $post_id, '_lesson_prerequisite', $tr_lesson_id );
116
- }
117
- }else{
118
- delete_post_meta( $post_id, '_lesson_prerequisite' );
119
- }
120
-
121
- }else{
122
-
123
- //sync course woocommerce_product
124
- $product_id = get_post_meta( $original_post_id, '_course_woocommerce_product', true );
125
-
126
- if( $product_id ){
127
- $tr_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $language );
128
-
129
- if( !is_null( $tr_product_id ) ){
130
- update_post_meta( $post_id, '_course_woocommerce_product', $tr_product_id );
131
- }
132
- }else{
133
- delete_post_meta( $post_id, '_course_woocommerce_product' );
134
- }
135
-
136
- //sync course prerequisite
137
- $course_id = get_post_meta( $original_post_id, '_course_prerequisite', true );
138
-
139
- if( $course_id ){
140
- $tr_course_id = apply_filters( 'translate_object_id', $course_id, 'course', false, $language );
141
-
142
- if( !is_null( $tr_course_id ) ){
143
- update_post_meta( $post_id, '_course_prerequisite', $tr_course_id );
144
- }
145
- }else{
146
- delete_post_meta( $post_id, '_course_prerequisite' );
147
- }
148
-
149
- }
150
-
151
- }
152
-
153
- function log_activity_after ( $args, $data, $comment_id = false ){
154
- global $sitepress;
155
-
156
- if( !$comment_id ){
157
- return false;
158
- }
159
-
160
- $comment_post_id = $data['comment_post_ID'];
161
- $trid = $sitepress->get_element_trid( $comment_post_id, 'post_'.get_post_type( $comment_post_id ) );
162
- $translations = $sitepress->get_element_translations( $trid, 'post_'.get_post_type( $comment_post_id ) );
163
-
164
- foreach($translations as $translation){
165
-
166
- if( $comment_post_id != $translation->element_id ){
167
- $data['comment_post_ID'] = $translation->element_id;
168
-
169
- $trid = $sitepress->get_element_trid( $comment_id, 'comment' );
170
-
171
- $tr_comment_id = apply_filters( 'translate_object_id', $comment_id, 'comment', false, $translation->language_code );
172
- if ( isset( $args['action'] ) && 'update' == $args['action'] && !is_null( $tr_comment_id ) && get_comment( $tr_comment_id ) ) {
173
- $data['comment_ID'] = $tr_comment_id;
174
- $tr_comment_id = wp_update_comment( $data );
175
- }else{
176
- $tr_comment_id = wp_insert_comment( $data );
177
- $sitepress->set_element_language_details( $tr_comment_id, 'comment', $trid, $translation->language_code );
178
- }
179
- }
180
-
181
- }
182
-
183
- }
184
-
185
- function filter_bought_product_id( $product_id, $order ){
186
-
187
- $order_language = get_post_meta( $order->id, 'wpml_language', true );
188
-
189
- $tr_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $order_language );
190
-
191
- if( !is_null( $tr_product_id ) ){
192
- return $tr_product_id;
193
- }else{
194
- return $product_id;
195
- }
196
- }
197
-
198
- function delete_user_activity ( $comment_id ){
199
- global $sitepress;
200
-
201
- $comment_type = get_comment_type( $comment_id );
202
-
203
- if( strstr( $comment_type, "sensei" ) ){
204
-
205
- $trid = $sitepress->get_element_trid( $comment_id, 'comment' );
206
- $translations = $sitepress->get_element_translations( $trid, 'comment' );
207
-
208
- remove_action( 'delete_comment', array ( $this, 'delete_user_activity' ) );
209
- foreach ( $translations as $translation ){
210
- if( $comment_id != $translation->element_id ){
211
- wp_delete_comment( $translation->element_id, true );
212
- }
213
- }
214
-
215
- }
216
-
217
-
218
- }
219
-
220
- function pre_get_comments($obj){
221
- global $sitepress;
222
-
223
- if( $obj->query_vars[ 'type' ] == 'sensei_course_start' ){
224
-
225
- remove_filter( 'comments_clauses', array( $sitepress, 'comments_clauses' ), 10, 2 );
226
-
227
- }
228
-
229
- }
230
-
231
- }
1
+ <?php
2
+
3
+ class WCML_sensei{
4
+
5
+ function __construct(){
6
+ global $sitepress;
7
+ add_action( 'manage_edit-lesson_columns', array( $sitepress, 'add_posts_management_column' ) );
8
+ add_action( 'manage_edit-course_columns', array( $sitepress, 'add_posts_management_column' ) );
9
+
10
+ add_action( 'save_post', array( $this, 'save_post_actions' ), 100, 2 );
11
+ add_action( 'sensei_log_activity_after', array( $this, 'log_activity_after' ), 10, 3 );
12
+ add_filter( 'sensei_bought_product_id', array( $this, 'filter_bought_product_id' ), 10, 2 );
13
+ add_action( 'delete_comment', array( $this, 'delete_user_activity' ) );
14
+
15
+ add_action( 'pre_get_comments', array( $this, 'pre_get_comments') );
16
+
17
+ if( is_admin() &&
18
+ (
19
+ ( isset($_GET['post_type']) && $_GET['post_type'] == 'sensei_message' ) ||
20
+ ( isset($_GET['page']) && $_GET['page'] == 'sensei_grading' )
21
+ ) ){
22
+ remove_action( 'wp_before_admin_bar_render', array($sitepress, 'admin_language_switcher') );
23
+ }
24
+
25
+ }
26
+
27
+ function save_post_actions( $post_id, $post ){
28
+ global $sitepress;
29
+
30
+ // skip not related post types
31
+ if ( !in_array( $post->post_type , array( 'lesson', 'course', 'quiz' ) ) ) {
32
+ return;
33
+ }
34
+ // skip auto-drafts
35
+ if ( $post->post_status == 'auto-draft' ) {
36
+ return;
37
+ }
38
+ // skip autosave
39
+ if ( isset( $_POST[ 'autosave' ] ) ) {
40
+ return;
41
+ }
42
+
43
+ if( $post->post_type == 'quiz' && isset( $_POST[ 'ID' ] ) ){
44
+ $this->save_post_actions( $_POST[ 'ID' ], get_post( $_POST[ 'ID' ] ) );
45
+ }
46
+
47
+
48
+ // sync fields from original
49
+ $trid = $sitepress->get_element_trid( $post_id, 'post_' . $post->post_type );
50
+ $translations = $sitepress->get_element_translations( $trid, 'post_' . $post->post_type );
51
+
52
+ if ( !empty( $translations ) ) {
53
+ $original_post_id = false;
54
+ foreach ( $translations as $t ) {
55
+ if ( $t->original ) {
56
+ $original_post_id = $t->element_id;
57
+ break;
58
+ }
59
+ }
60
+
61
+ if ( $post_id != $original_post_id ) {
62
+ $this->sync_custom_fields( $original_post_id, $post_id, $post->post_type );
63
+ } else {
64
+ foreach ( $translations as $t ) {
65
+ if ( $original_post_id != $t->element_id ) {
66
+ $this->sync_custom_fields( $original_post_id, $t->element_id, $post->post_type );
67
+ }
68
+ }
69
+ }
70
+ }
71
+
72
+ }
73
+
74
+
75
+ function sync_custom_fields ( $original_post_id, $post_id, $post_type ){
76
+ global $sitepress;
77
+
78
+ $language = $sitepress->get_language_for_element( $post_id, 'post_'.$post_type );
79
+ if( $post_type == 'quiz' ){
80
+
81
+ //sync quiz lesson
82
+ $lesson_id = get_post_meta( $original_post_id, '_quiz_lesson', true );
83
+
84
+ if( $lesson_id ){
85
+ $tr_lesson_id = apply_filters( 'translate_object_id', $lesson_id, 'lesson', false, $language );
86
+
87
+ if( !is_null( $tr_lesson_id ) ){
88
+ update_post_meta( $post_id, '_quiz_lesson', $tr_lesson_id );
89
+ }
90
+ }else{
91
+ delete_post_meta( $post_id, '_quiz_lesson' );
92
+ }
93
+
94
+ } elseif( $post_type == 'lesson' ){
95
+ //sync lesson course
96
+ $course_id = get_post_meta( $original_post_id, '_lesson_course', true );
97
+
98
+ if( $course_id ){
99
+ $tr_course_id = apply_filters( 'translate_object_id', $course_id, 'course', false, $language );
100
+
101
+ if( !is_null( $tr_course_id ) ){
102
+ update_post_meta( $post_id, '_lesson_course', $tr_course_id );
103
+ }
104
+ }else{
105
+ delete_post_meta( $post_id, '_lesson_course' );
106
+ }
107
+
108
+ //sync lesson prerequisite
109
+ $lesson_id = get_post_meta( $original_post_id, '_lesson_prerequisite', true );
110
+
111
+ if( $lesson_id ){
112
+ $tr_lesson_id = apply_filters( 'translate_object_id', $lesson_id, 'lesson', false, $language );
113
+
114
+ if( !is_null( $tr_lesson_id ) ){
115
+ update_post_meta( $post_id, '_lesson_prerequisite', $tr_lesson_id );
116
+ }
117
+ }else{
118
+ delete_post_meta( $post_id, '_lesson_prerequisite' );
119
+ }
120
+
121
+ }else{
122
+
123
+ //sync course woocommerce_product
124
+ $product_id = get_post_meta( $original_post_id, '_course_woocommerce_product', true );
125
+
126
+ if( $product_id ){
127
+ $tr_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $language );
128
+
129
+ if( !is_null( $tr_product_id ) ){
130
+ update_post_meta( $post_id, '_course_woocommerce_product', $tr_product_id );
131
+ }
132
+ }else{
133
+ delete_post_meta( $post_id, '_course_woocommerce_product' );
134
+ }
135
+
136
+ //sync course prerequisite
137
+ $course_id = get_post_meta( $original_post_id, '_course_prerequisite', true );
138
+
139
+ if( $course_id ){
140
+ $tr_course_id = apply_filters( 'translate_object_id', $course_id, 'course', false, $language );
141
+
142
+ if( !is_null( $tr_course_id ) ){
143
+ update_post_meta( $post_id, '_course_prerequisite', $tr_course_id );
144
+ }
145
+ }else{
146
+ delete_post_meta( $post_id, '_course_prerequisite' );
147
+ }
148
+
149
+ }
150
+
151
+ }
152
+
153
+ function log_activity_after ( $args, $data, $comment_id = false ){
154
+ global $sitepress;
155
+
156
+ if( !$comment_id ){
157
+ return false;
158
+ }
159
+
160
+ $comment_post_id = $data['comment_post_ID'];
161
+ $trid = $sitepress->get_element_trid( $comment_post_id, 'post_'.get_post_type( $comment_post_id ) );
162
+ $translations = $sitepress->get_element_translations( $trid, 'post_'.get_post_type( $comment_post_id ) );
163
+
164
+ foreach($translations as $translation){
165
+
166
+ if( $comment_post_id != $translation->element_id ){
167
+ $data['comment_post_ID'] = $translation->element_id;
168
+
169
+ $trid = $sitepress->get_element_trid( $comment_id, 'comment' );
170
+
171
+ $tr_comment_id = apply_filters( 'translate_object_id', $comment_id, 'comment', false, $translation->language_code );
172
+ if ( isset( $args['action'] ) && 'update' == $args['action'] && !is_null( $tr_comment_id ) && get_comment( $tr_comment_id ) ) {
173
+ $data['comment_ID'] = $tr_comment_id;
174
+ $tr_comment_id = wp_update_comment( $data );
175
+ }else{
176
+ $tr_comment_id = wp_insert_comment( $data );
177
+ $sitepress->set_element_language_details( $tr_comment_id, 'comment', $trid, $translation->language_code );
178
+ }
179
+ }
180
+
181
+ }
182
+
183
+ }
184
+
185
+ function filter_bought_product_id( $product_id, $order ){
186
+
187
+ $order_language = get_post_meta( $order->id, 'wpml_language', true );
188
+
189
+ $tr_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $order_language );
190
+
191
+ if( !is_null( $tr_product_id ) ){
192
+ return $tr_product_id;
193
+ }else{
194
+ return $product_id;
195
+ }
196
+ }
197
+
198
+ function delete_user_activity ( $comment_id ){
199
+ global $sitepress;
200
+
201
+ $comment_type = get_comment_type( $comment_id );
202
+
203
+ if( strstr( $comment_type, "sensei" ) ){
204
+
205
+ $trid = $sitepress->get_element_trid( $comment_id, 'comment' );
206
+ $translations = $sitepress->get_element_translations( $trid, 'comment' );
207
+
208
+ remove_action( 'delete_comment', array ( $this, 'delete_user_activity' ) );
209
+ foreach ( $translations as $translation ){
210
+ if( $comment_id != $translation->element_id ){
211
+ wp_delete_comment( $translation->element_id, true );
212
+ }
213
+ }
214
+
215
+ }
216
+
217
+
218
+ }
219
+
220
+ function pre_get_comments($obj){
221
+ global $sitepress;
222
+
223
+ if( $obj->query_vars[ 'type' ] == 'sensei_course_start' ){
224
+
225
+ remove_filter( 'comments_clauses', array( $sitepress, 'comments_clauses' ), 10, 2 );
226
+
227
+ }
228
+
229
+ }
230
+
231
+ }
compatibility/class-wcml-tab-manager.php CHANGED
@@ -1,516 +1,535 @@
1
- <?php
2
-
3
- class WCML_Tab_Manager{
4
-
5
- public $tp;
6
-
7
- function __construct(){
8
- add_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_tabs' ), 10, 3 );
9
- add_filter( 'wcml_product_content_exception', array( $this, 'is_have_custom_product_tab' ), 10, 3 );
10
- add_filter( 'wcml_custom_box_html', array( $this, 'custom_box_html'), 10, 3 );
11
- add_filter( 'wcml_translatable_custom_fields', array( $this, 'add_translatable_custom_fields') );
12
- add_filter( 'wpml_duplicate_custom_fields_exceptions', array( $this, 'duplicate_custom_fields_exceptions' ) );
13
- add_action( 'wcml_after_duplicate_product', array( $this, 'duplicate_product_tabs') , 10, 2 );
14
-
15
- add_filter('wc_tab_manager_tab_id', array($this, 'wc_tab_manager_tab_id'), 10, 1);
16
-
17
- if( version_compare( WCML_VERSION, '3.7.2', '>') ){
18
- add_filter( 'option_wpml_config_files_arr', array($this, 'make__product_tabs_not_translatable_by_default'), 0 );
19
- }
20
-
21
- if( is_admin() ){
22
-
23
- $this->tp = new WPML_Element_Translation_Package;
24
-
25
- add_action( 'save_post', array($this, 'force_set_language_information_on_product_tabs'), 10, 2);
26
-
27
- add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_custom_tabs_to_translation_package' ), 10, 2 );
28
- add_action( 'wpml_translation_job_saved', array( $this, 'save_custom_tabs_translation' ), 10, 3 );
29
-
30
- }
31
-
32
- }
33
-
34
- function make__product_tabs_not_translatable_by_default($wpml_config_array){
35
-
36
- if( isset( $wpml_config_array->plugins['WooCommerce Tab Manager'] ) ){
37
- $wpml_config_array->plugins['WooCommerce Tab Manager'] =
38
- str_replace('<custom-field action="translate">_product_tabs</custom-field>',
39
- '<custom-field action="nothing">_product_tabs</custom-field>',
40
- $wpml_config_array->plugins['WooCommerce Tab Manager'] );
41
- }
42
-
43
- return $wpml_config_array;
44
-
45
- }
46
-
47
- function sync_tabs( $original_product_id, $trnsl_product_id, $data = false ){
48
- global $sitepress, $woocommerce, $woocommerce_wpml;
49
-
50
- $lang = $sitepress->get_language_for_element( $trnsl_product_id, 'post_product' );
51
-
52
- //check if "duplicate" product
53
- if( ( isset( $_POST['icl_ajx_action'] ) && ( $_POST['icl_ajx_action'] == 'make_duplicates' ) ) || ( get_post_meta( $trnsl_product_id , '_icl_lang_duplicate_of', true ) ) ){
54
- $this->duplicate_tabs( $original_product_id, $trnsl_product_id, $lang );
55
- }
56
-
57
- $orig_prod_tabs = $this->get_product_tabs( $original_product_id );
58
-
59
- if( $orig_prod_tabs ){
60
- $trnsl_product_tabs = array();
61
- $i = 0;
62
- foreach( $orig_prod_tabs as $key => $orig_prod_tab ){
63
- switch( $orig_prod_tab[ 'type' ] ){
64
- case 'core':
65
- $default_language = $woocommerce_wpml->products->get_original_product_language( $original_product_id );
66
- $current_language = $sitepress->get_current_language();
67
- $trnsl_product_tabs[ $key ] = $orig_prod_tabs[ $key ];
68
- $title = '';
69
- $heading = '';
70
- if( isset( $data[ '_product_tabs_'.$lang ] ) ){
71
- $title = $data[ '_product_tabs_'.$lang ][ 'core_title' ][ $orig_prod_tab[ 'id' ] ];
72
- $heading = $data[ '_product_tabs_'.$lang ][ 'core_heading' ][ $orig_prod_tab[ 'id' ] ];
73
- }
74
-
75
- if( $default_language != $lang ){
76
- $this->refresh_text_domain( $lang );
77
-
78
- if( !$title ){
79
- $title = isset( $_POST['product_tab_title'][ $orig_prod_tab['position'] ] ) ? $_POST['product_tab_title'][ $orig_prod_tab['position'] ] : $orig_prod_tabs[ $key ][ 'title' ];
80
- $title = __( $title, 'woocommerce' );
81
- }
82
-
83
- if( !$heading && isset( $orig_prod_tabs[ $key ][ 'heading' ] ) ){
84
- $heading = isset( $_POST['product_tab_heading'][ $orig_prod_tab['position'] ]) ? $_POST['product_tab_heading'][ $orig_prod_tab['position'] ] : $orig_prod_tabs[ $key ][ 'heading' ];
85
- $heading = __( $heading, 'woocommerce' );
86
- }
87
-
88
- $this->refresh_text_domain( $current_language );
89
- }
90
-
91
- $trnsl_product_tabs[ $key ][ 'title' ] = $title;
92
- $trnsl_product_tabs[ $key ][ 'heading' ] = $heading;
93
- break;
94
- case 'global':
95
- $trnsl_product_tabs = $this->set_global_tab( $orig_prod_tab, $trnsl_product_tabs, $lang );
96
- break;
97
- case 'product':
98
- $tab_id = false;
99
- if( isset( $data[ '_product_tabs_'.$lang ][ 'id' ][ $i ] ) ){
100
- if( get_post_type( $data[ '_product_tabs_'.$lang ][ 'id' ][ $i ] ) == 'wc_product_tab' ){
101
- $tab_id = $data[ '_product_tabs_'.$lang ][ 'id' ][ $i ];
102
- }
103
- $title = $data[ '_product_tabs_'.$lang ][ 'title' ][ $i ];
104
- $content = $data[ '_product_tabs_'.$lang ][ 'content' ][ $i ];
105
- }
106
-
107
- $trnsl_product_tabs = $this->set_product_tab( $orig_prod_tab, $trnsl_product_tabs, $lang, $trnsl_product_id, $tab_id, $title, $content );
108
-
109
- $i++;
110
- break;
111
- }
112
- }
113
- update_post_meta( $trnsl_product_id, '_product_tabs', $trnsl_product_tabs );
114
- }
115
- }
116
-
117
- function duplicate_tabs( $original_product_id, $trnsl_product_id, $lang ){
118
- global $sitepress;
119
- $orig_prod_tabs = maybe_unserialize( get_post_meta( $original_product_id, '_product_tabs', true ) );
120
- $prod_tabs = array();
121
- foreach( $orig_prod_tabs as $key => $orig_prod_tab ){
122
- switch( $orig_prod_tab[ 'type' ] ){
123
- case 'core':
124
- $prod_tabs[ $key ] = $orig_prod_tab;
125
- $this->refresh_text_domain( $lang );
126
- $prod_tabs[ $key ][ 'title' ] = __( $orig_prod_tab[ 'title' ], 'woocommerce' );
127
- if( isset( $orig_prod_tab[ 'heading' ] ) )
128
- $prod_tabs[ $key ][ 'heading' ] = __( $orig_prod_tab[ 'heading' ], 'woocommerce' );
129
- $orig_lang = $sitepress->get_language_for_element( $original_product_id, 'post_product' );
130
- $this->refresh_text_domain( $orig_lang );
131
- break;
132
- case 'global':
133
- $prod_tabs = $this->set_global_tab( $orig_prod_tab, $prod_tabs, $lang );
134
- break;
135
- case 'product':
136
- $original_tab = get_post( $orig_prod_tab[ 'id' ] );
137
- $prod_tabs = $this->set_product_tab( $orig_prod_tab, $prod_tabs, $lang, $trnsl_product_id, false, $original_tab->post_title , $original_tab->post_content );
138
- break;
139
- }
140
- }
141
-
142
- update_post_meta( $trnsl_product_id, '_product_tabs', $prod_tabs );
143
- }
144
-
145
- function refresh_text_domain( $lang ){
146
- global $sitepress, $woocommerce;
147
-
148
- unload_textdomain( 'woocommerce' );
149
- $sitepress->switch_lang( $lang );
150
- $woocommerce->load_plugin_textdomain();
151
- }
152
-
153
- function set_global_tab( $orig_prod_tab, $trnsl_product_tabs, $lang ){
154
- $tr_tab_id = apply_filters( 'translate_object_id', $orig_prod_tab[ 'id' ], 'wc_product_tab', true, $lang );
155
- $trnsl_product_tabs[ $orig_prod_tab[ 'type' ].'_tab_'.$tr_tab_id ] = array(
156
- 'position' => $orig_prod_tab[ 'position' ],
157
- 'type' => $orig_prod_tab[ 'type' ],
158
- 'id' => $tr_tab_id,
159
- 'name' => get_post( $tr_tab_id )->post_name
160
- );
161
- return $trnsl_product_tabs;
162
- }
163
-
164
- function set_product_tab( $orig_prod_tab, $trnsl_product_tabs, $lang, $trnsl_product_id, $tab_id, $title, $content ){
165
- global $wpdb, $sitepress;
166
-
167
- if( !$tab_id ){
168
- $tr_tab_id = apply_filters( 'translate_object_id', $orig_prod_tab[ 'id' ], 'wc_product_tab', false, $lang );
169
-
170
- if( !is_null( $tr_tab_id ) ){
171
- $tab_id = $tr_tab_id;
172
- }
173
- }
174
-
175
- if( $tab_id ){
176
- //update existing tab
177
- $args = array();
178
- $args[ 'post_title' ] = $title;
179
- $args[ 'post_content' ] = $content;
180
- $wpdb->update( $wpdb->posts, $args, array( 'ID' => $tab_id ) );
181
- }else{
182
- //tab not exist creating new
183
- $args = array();
184
- $args[ 'post_title' ] = $title;
185
- $args[ 'post_content' ] = $content;
186
- $args[ 'post_author' ] = get_current_user_id();
187
- $args[ 'post_name' ] = sanitize_title( $title );
188
- $args[ 'post_type' ] = 'wc_product_tab';
189
- $args[ 'post_parent' ] = $trnsl_product_id;
190
- $args[ 'post_status' ] = 'publish';
191
- $wpdb->insert( $wpdb->posts, $args );
192
-
193
- $tab_id = $wpdb->insert_id;
194
- $tab_trid = $sitepress->get_element_trid( $orig_prod_tab[ 'id' ], 'post_wc_product_tab' );
195
- if( !$tab_trid ){
196
- $sitepress->set_element_language_details( $orig_prod_tab[ 'id' ], 'post_wc_product_tab', false, $sitepress->get_default_language() );
197
- $tab_trid = $sitepress->get_element_trid( $orig_prod_tab[ 'id' ], 'post_wc_product_tab' );
198
- }
199
- $sitepress->set_element_language_details( $tab_id, 'post_wc_product_tab', $tab_trid, $lang );
200
- }
201
-
202
- $trnsl_product_tabs[ $orig_prod_tab[ 'type' ].'_tab_'.$tab_id ] = array(
203
- 'position' => $orig_prod_tab[ 'position' ],
204
- 'type' => $orig_prod_tab[ 'type' ],
205
- 'id' => $tab_id,
206
- 'name' => get_post( $tab_id )->post_name
207
- );
208
-
209
- return $trnsl_product_tabs;
210
- }
211
-
212
- function duplicate_custom_fields_exceptions( $exceptions ){
213
- $exceptions[] = '_product_tabs';
214
- return $exceptions;
215
- }
216
-
217
- function is_have_custom_product_tab( $exception, $product_id, $meta_key ){
218
-
219
- if( $meta_key == '_product_tabs'){
220
- $exception = get_post_meta( $product_id, '_override_tab_layout', true) != 'yes';
221
- }
222
-
223
- return $exception;
224
- }
225
-
226
- function custom_box_html($html, $template_data, $lang){
227
-
228
- if( $template_data['product_content'] == '_product_tabs' ){
229
- $orig_prod_tabs = $this->get_product_tabs($template_data['product_id']);
230
- if(!$orig_prod_tabs) return '';
231
- if($template_data['tr_product_id']){
232
- $tr_prod_tabs = $this->get_product_tabs($template_data['tr_product_id']);
233
-
234
- if(!is_array($tr_prod_tabs)){
235
- return __('Please update original product', 'woocommerce-multilingual');
236
- }
237
-
238
- foreach($tr_prod_tabs as $key=>$prod_tab){
239
- if(in_array($prod_tab['type'],array('product','core'))){
240
- if($prod_tab['type'] == 'core'){
241
- $template_data['tr_tabs'][$prod_tab['id']]['id'] = $prod_tab['id'];
242
- $template_data['tr_tabs'][$prod_tab['id']]['type'] = $prod_tab['type'];
243
- $template_data['tr_tabs'][$prod_tab['id']]['title'] = $prod_tab['title'];
244
- $template_data['tr_tabs'][$prod_tab['id']]['heading'] = isset ($prod_tab['heading']) ? $prod_tab['heading'] : '';
245
- }else{
246
- $template_data['tr_tabs'][$prod_tab['position']]['id'] = $prod_tab['id'];
247
- $template_data['tr_tabs'][$prod_tab['position']]['type'] = $prod_tab['type'];
248
- }
249
- }
250
- }
251
- }else{
252
- global $sitepress,$woocommerce;
253
- $current_language = $sitepress->get_current_language();
254
- foreach($orig_prod_tabs as $key=>$prod_tab){
255
- if($prod_tab['type'] == 'core'){
256
- unload_textdomain('woocommerce');
257
- $sitepress->switch_lang($lang);
258
- $woocommerce->load_plugin_textdomain();
259
- $title = __( $prod_tab['title'], 'woocommerce' );
260
- if($prod_tab['title'] != $title){
261
- $template_data['tr_tabs'][$prod_tab['id']]['title'] = $title;
262
-
263
- }
264
-
265
- if(!isset($prod_tab['heading'])){
266
- $template_data['tr_tabs'][$prod_tab['id']]['heading'] = '';
267
- }else{
268
- $heading = __( $prod_tab['heading'], 'woocommerce' );
269
- if($prod_tab['heading'] != $heading){
270
- $template_data['tr_tabs'][$prod_tab['id']]['heading'] = $heading;
271
- }
272
- }
273
-
274
- unload_textdomain('woocommerce');
275
- $sitepress->switch_lang($current_language);
276
- $woocommerce->load_plugin_textdomain();
277
- }
278
- }
279
- }
280
-
281
- foreach($orig_prod_tabs as $key=>$prod_tab){
282
- if(in_array($prod_tab['type'],array('product','core'))){
283
- if($prod_tab['type'] == 'core'){
284
- $template_data['orig_tabs'][$prod_tab['id']]['id'] = $prod_tab['id'];
285
- $template_data['orig_tabs'][$prod_tab['id']]['type'] = $prod_tab['type'];
286
- }else{
287
- $template_data['orig_tabs'][$prod_tab['position']]['id'] = $prod_tab['id'];
288
- $template_data['orig_tabs'][$prod_tab['position']]['type'] = $prod_tab['type'];
289
- }
290
-
291
- }
292
- }
293
-
294
- return include WCML_PLUGIN_PATH . '/compatibility/templates/wc_tab_manager_custom_box_html.php';
295
- }
296
-
297
- return $html;
298
- }
299
-
300
- function duplicate_product_tabs( $new_id, $original_post ){
301
-
302
- wc_tab_manager_duplicate_product( $new_id, $original_post );
303
-
304
- }
305
-
306
- function force_set_language_information_on_product_tabs($post_id, $post){
307
- global $sitepress;
308
-
309
- if( $post->post_type == 'wc_product_tab' ){
310
-
311
- $language = $sitepress->get_language_for_element($post->ID, 'post_wc_product_tab');
312
- if( empty ($language) && $post->post_parent ) {
313
- $parent_language = $sitepress->get_language_for_element($post->post_parent, 'post_product');
314
- if( $parent_language ){
315
- $sitepress->set_element_language_details($post->ID, 'post_wc_product_tab', null, $parent_language);
316
- }
317
- }
318
-
319
- }
320
-
321
- }
322
-
323
- function append_custom_tabs_to_translation_package($package, $post){
324
-
325
- if( $post->post_type == 'product' ) {
326
-
327
- $override_tab_layout = get_post_meta( $post->ID , '_override_tab_layout', true);
328
-
329
- if( $override_tab_layout == 'yes' ){
330
-
331
- $meta = get_post_meta( $post->ID, '_product_tabs', true );
332
-
333
- foreach ( (array)$meta as $key => $value ) {
334
-
335
- if ( preg_match( '/product_tab_([0-9]+)/', $key, $matches ) ) {
336
-
337
- $wc_product_tab_id = $matches[1];
338
- $wc_product_tab = get_post( $wc_product_tab_id );
339
-
340
- $package['contents']['product_tabs:product_tab:' . $wc_product_tab_id . ':title'] = array(
341
- 'translate' => 1,
342
- 'data' => $this->tp->encode_field_data( $wc_product_tab->post_title, 'base64' ),
343
- 'format' => 'base64'
344
- );
345
-
346
- $package['contents']['product_tabs:product_tab:' . $wc_product_tab_id . ':description'] = array(
347
- 'translate' => 1,
348
- 'data' => $this->tp->encode_field_data( $wc_product_tab->post_content, 'base64' ),
349
- 'format' => 'base64'
350
- );
351
-
352
-
353
- } elseif ( preg_match( '/^core_tab_(.+)$/', $key, $matches ) ){
354
-
355
- $package['contents']['product_tabs:core_tab_title:' . $matches[1]] = array(
356
- 'translate' => 1,
357
- 'data' => $this->tp->encode_field_data( $value['title'], 'base64' ),
358
- 'format' => 'base64'
359
- );
360
-
361
- if(isset( $value['heading'] )) {
362
- $package['contents']['product_tabs:core_tab_heading:' . $matches[1]] = array(
363
- 'translate' => 1,
364
- 'data' => $this->tp->encode_field_data( $value['heading'], 'base64' ),
365
- 'format' => 'base64'
366
- );
367
- }
368
-
369
-
370
- }
371
-
372
- }
373
- }
374
-
375
-
376
- }
377
-
378
- return $package;
379
- }
380
-
381
- function save_custom_tabs_translation( $post_id, $data, $job ){
382
- global $sitepress;
383
-
384
-
385
- $translated_product_tabs_updated = false;
386
-
387
- $original_product_tabs = get_post_meta($job->original_doc_id, '_product_tabs', true);
388
-
389
- if( $original_product_tabs ) {
390
-
391
- // custom tabs
392
- $product_tab_translations = array();
393
-
394
- foreach ( $data as $value ) {
395
-
396
- if ( preg_match( '/product_tabs:product_tab:([0-9]+):(.+)/', $value['field_type'], $matches ) ) {
397
-
398
- $wc_product_tab_id = $matches[1];
399
- $field = $matches[2];
400
-
401
- $product_tab_translations[$wc_product_tab_id][$field] = $value['data'];
402
- }
403
-
404
- }
405
-
406
- if ( $product_tab_translations ) {
407
-
408
- $translated_product_tabs = get_post_meta( $post_id, '_product_tabs', true );
409
-
410
- foreach ( $product_tab_translations as $wc_product_tab_id => $value ) {
411
-
412
- $new_wc_product_tab = array(
413
- 'post_type' => 'wp_product_tab',
414
- 'post_title' => $value['title'],
415
- 'post_content' => $value['description'],
416
- 'post_status' => 'publish'
417
- );
418
-
419
- $wc_product_tab_id_translated = wp_insert_post( $new_wc_product_tab );
420
-
421
- if ( $wc_product_tab_id_translated ) {
422
-
423
- $wc_product_tab_trid = $sitepress->get_element_trid( $wc_product_tab_id, 'post_wc_product_tab' );
424
- $sitepress->set_element_language_details( $wc_product_tab_id_translated, 'post_wc_product_tab', $wc_product_tab_trid, $job->language_code );
425
-
426
- $wc_product_tab_translated = get_post( $wc_product_tab_id_translated );
427
-
428
- $translated_product_tabs['product_tab_' . $wc_product_tab_id_translated] = array(
429
-
430
- 'position' => $original_product_tabs['product_tab_' . $wc_product_tab_id]['position'],
431
- 'type' => 'product',
432
- 'id' => $wc_product_tab_id_translated,
433
- 'name' => $wc_product_tab_translated->post_name
434
-
435
- );
436
-
437
- }
438
-
439
- }
440
-
441
-
442
- $translated_product_tabs_updated = true;
443
- }
444
-
445
- // the other tabs
446
- $product_tab_translations = array();
447
-
448
- foreach ( $data as $value ) {
449
-
450
- if ( preg_match( '/product_tabs:core_tab_(.+):(.+)/', $value['field_type'], $matches ) ) {
451
-
452
- $tab_field = $matches[1];
453
- $tab_id = $matches[2];
454
-
455
- $product_tab_translations[$tab_id][$tab_field] = $value['data'];
456
-
457
- }
458
-
459
- }
460
-
461
- if( $product_tab_translations){
462
- foreach( $product_tab_translations as $id => $tab ){
463
-
464
- $translated_product_tabs['core_tab_' . $id] = array(
465
- 'type' => 'core',
466
- 'position' => $original_product_tabs['core_tab_' . $id]['position'],
467
- 'id' => $id,
468
- 'title' => $tab['title']
469
- );
470
-
471
- if( isset( $tab['heading'] ) ){
472
- $translated_product_tabs['core_tab_' . $id]['heading'] = $tab['heading'];
473
- }
474
-
475
- }
476
-
477
- $translated_product_tabs_updated = true;
478
- }
479
-
480
- if ( $translated_product_tabs_updated ) {
481
- update_post_meta( $post_id, '_product_tabs', $translated_product_tabs );
482
- }
483
-
484
- }
485
- }
486
-
487
- public function get_product_tabs( $product_id ) {
488
-
489
- $override_tab_layout = get_post_meta( $product_id, '_override_tab_layout', true );
490
-
491
- if ( 'yes' == $override_tab_layout ) {
492
- // product defines its own tab layout?
493
- $product_tabs = get_post_meta( $product_id, '_product_tabs', true );
494
- } else {
495
- // otherwise, get the default layout if any
496
- $product_tabs = get_option( 'wc_tab_manager_default_layout', false );
497
- }
498
-
499
-
500
- return $product_tabs;
501
- }
502
-
503
-
504
- function wc_tab_manager_tab_id($tab_id) {
505
- $tab_id = apply_filters('wpml_object_id', $tab_id, 'wc_product_tab', true);
506
-
507
- return $tab_id;
508
- }
509
-
510
- function add_translatable_custom_fields( $post_custom_keys ){
511
- $post_custom_keys[] = '_product_tabs';
512
- return $post_custom_keys;
513
-
514
- }
515
-
516
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_Tab_Manager{
4
+
5
+ public $tp;
6
+
7
+ function __construct(){
8
+ add_action( 'wcml_update_extra_fields', array( $this, 'sync_tabs' ), 10, 4 );
9
+ add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html'), 10, 3 );
10
+ add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data'), 10, 4 );
11
+ add_filter( 'wpml_duplicate_custom_fields_exceptions', array( $this, 'duplicate_custom_fields_exceptions' ) );
12
+ add_action( 'wcml_after_duplicate_product', array( $this, 'duplicate_product_tabs') , 10, 2 );
13
+
14
+ add_filter('wc_tab_manager_tab_id', array($this, 'wc_tab_manager_tab_id'), 10, 1);
15
+
16
+ if( version_compare( WCML_VERSION, '3.7.2', '>') ){
17
+ add_filter( 'option_wpml_config_files_arr', array($this, 'make__product_tabs_not_translatable_by_default'), 0 );
18
+ }
19
+
20
+ if( is_admin() ){
21
+
22
+ $this->tp = new WPML_Element_Translation_Package;
23
+
24
+ add_action( 'save_post', array($this, 'force_set_language_information_on_product_tabs'), 10, 2);
25
+
26
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_custom_tabs_to_translation_package' ), 10, 2 );
27
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_custom_tabs_translation' ), 10, 3 );
28
+
29
+ }
30
+
31
+ }
32
+
33
+ function make__product_tabs_not_translatable_by_default($wpml_config_array){
34
+
35
+ if( isset( $wpml_config_array->plugins['WooCommerce Tab Manager'] ) ){
36
+ $wpml_config_array->plugins['WooCommerce Tab Manager'] =
37
+ str_replace('<custom-field action="translate">_product_tabs</custom-field>',
38
+ '<custom-field action="nothing">_product_tabs</custom-field>',
39
+ $wpml_config_array->plugins['WooCommerce Tab Manager'] );
40
+ }
41
+
42
+ return $wpml_config_array;
43
+
44
+ }
45
+
46
+ function sync_tabs( $original_product_id, $trnsl_product_id, $data, $lang ){
47
+ global $sitepress, $woocommerce, $woocommerce_wpml;
48
+
49
+ //check if "duplicate" product
50
+ if( ( isset( $_POST['icl_ajx_action'] ) && ( $_POST['icl_ajx_action'] == 'make_duplicates' ) ) || ( get_post_meta( $trnsl_product_id , '_icl_lang_duplicate_of', true ) ) ){
51
+ $this->duplicate_tabs( $original_product_id, $trnsl_product_id, $lang );
52
+ }
53
+
54
+ $orig_prod_tabs = $this->get_product_tabs( $original_product_id );
55
+
56
+ if( $orig_prod_tabs ){
57
+ $trnsl_product_tabs = array();
58
+ $i = 0;
59
+ foreach( $orig_prod_tabs as $key => $orig_prod_tab ){
60
+ switch( $orig_prod_tab[ 'type' ] ){
61
+ case 'core':
62
+ $default_language = $woocommerce_wpml->products->get_original_product_language( $original_product_id );
63
+ $current_language = $sitepress->get_current_language();
64
+ $trnsl_product_tabs[ $key ] = $orig_prod_tabs[ $key ];
65
+ $title = '';
66
+ $heading = '';
67
+
68
+ $title = $data[ md5( 'coretab_'.$orig_prod_tab['id'].'_title' ) ] ? $data[ md5( 'coretab_'.$orig_prod_tab['id'].'_title' ) ] : '';
69
+ $heading = $data[ md5( 'coretab_'.$orig_prod_tab['id'].'_heading' ) ] ? $data[ md5( 'coretab_'.$orig_prod_tab['id'].'_heading' ) ] : '';
70
+
71
+
72
+ if( $default_language != $lang ){
73
+
74
+ $this->refresh_text_domain( $lang );
75
+
76
+ if( !$title ){
77
+ $title = isset( $_POST['product_tab_title'][ $orig_prod_tab['position'] ] ) ? $_POST['product_tab_title'][ $orig_prod_tab['position'] ] : $orig_prod_tabs[ $key ][ 'title' ];
78
+ $title = __( $title, 'woocommerce' );
79
+ }
80
+
81
+ if( !$heading && ( isset( $orig_prod_tabs[ $key ][ 'heading' ] ) || isset( $_POST['product_tab_heading'][ $orig_prod_tab['position'] ] ) ) ){
82
+ $heading = isset( $_POST['product_tab_heading'][ $orig_prod_tab['position'] ] ) ? $_POST['product_tab_heading'][ $orig_prod_tab['position'] ] : $orig_prod_tabs[ $key ][ 'heading' ];
83
+ $heading = __( $heading, 'woocommerce' );
84
+ }
85
+
86
+ $this->refresh_text_domain( $current_language );
87
+ }
88
+
89
+ $trnsl_product_tabs[ $key ][ 'title' ] = $title;
90
+ $trnsl_product_tabs[ $key ][ 'heading' ] = $heading;
91
+ break;
92
+ case 'global':
93
+ $trnsl_product_tabs = $this->set_global_tab( $orig_prod_tab, $trnsl_product_tabs, $lang );
94
+ break;
95
+ case 'product':
96
+ $tab_id = false;
97
+
98
+ $title = $data[ md5( 'tab_'.$orig_prod_tab['position'].'_title' ) ];
99
+ $content = $data[ md5( 'tab_'.$orig_prod_tab['position'].'_heading' ) ];
100
+
101
+ $trnsl_product_tabs = $this->set_product_tab( $orig_prod_tab, $trnsl_product_tabs, $lang, $trnsl_product_id, $tab_id, $title, $content );
102
+
103
+ $i++;
104
+ break;
105
+ }
106
+ }
107
+ update_post_meta( $trnsl_product_id, '_product_tabs', $trnsl_product_tabs );
108
+ }
109
+ }
110
+
111
+ function duplicate_tabs( $original_product_id, $trnsl_product_id, $lang ){
112
+ global $sitepress;
113
+ $orig_prod_tabs = maybe_unserialize( get_post_meta( $original_product_id, '_product_tabs', true ) );
114
+ $prod_tabs = array();
115
+ foreach( $orig_prod_tabs as $key => $orig_prod_tab ){
116
+ switch( $orig_prod_tab[ 'type' ] ){
117
+ case 'core':
118
+ $prod_tabs[ $key ] = $orig_prod_tab;
119
+ $this->refresh_text_domain( $lang );
120
+ $prod_tabs[ $key ][ 'title' ] = __( $orig_prod_tab[ 'title' ], 'woocommerce' );
121
+ if( isset( $orig_prod_tab[ 'heading' ] ) )
122
+ $prod_tabs[ $key ][ 'heading' ] = __( $orig_prod_tab[ 'heading' ], 'woocommerce' );
123
+ $orig_lang = $sitepress->get_language_for_element( $original_product_id, 'post_product' );
124
+ $this->refresh_text_domain( $orig_lang );
125
+ break;
126
+ case 'global':
127
+ $prod_tabs = $this->set_global_tab( $orig_prod_tab, $prod_tabs, $lang );
128
+ break;
129
+ case 'product':
130
+ $original_tab = get_post( $orig_prod_tab[ 'id' ] );
131
+ $prod_tabs = $this->set_product_tab( $orig_prod_tab, $prod_tabs, $lang, $trnsl_product_id, false, $original_tab->post_title , $original_tab->post_content );
132
+ break;
133
+ }
134
+ }
135
+
136
+ update_post_meta( $trnsl_product_id, '_product_tabs', $prod_tabs );
137
+ }
138
+
139
+ function refresh_text_domain( $lang ){
140
+ global $sitepress, $woocommerce;
141
+
142
+ unload_textdomain( 'woocommerce' );
143
+ $sitepress->switch_lang( $lang );
144
+ $woocommerce->load_plugin_textdomain();
145
+ }
146
+
147
+ function set_global_tab( $orig_prod_tab, $trnsl_product_tabs, $lang ){
148
+ $tr_tab_id = apply_filters( 'translate_object_id', $orig_prod_tab[ 'id' ], 'wc_product_tab', true, $lang );
149
+ $trnsl_product_tabs[ $orig_prod_tab[ 'type' ].'_tab_'.$tr_tab_id ] = array(
150
+ 'position' => $orig_prod_tab[ 'position' ],
151
+ 'type' => $orig_prod_tab[ 'type' ],
152
+ 'id' => $tr_tab_id,
153
+ 'name' => get_post( $tr_tab_id )->post_name
154
+ );
155
+ return $trnsl_product_tabs;
156
+ }
157
+
158
+ function set_product_tab( $orig_prod_tab, $trnsl_product_tabs, $lang, $trnsl_product_id, $tab_id, $title, $content ){
159
+ global $wpdb, $sitepress;
160
+
161
+ if( !$tab_id ){
162
+ $tr_tab_id = apply_filters( 'translate_object_id', $orig_prod_tab[ 'id' ], 'wc_product_tab', false, $lang );
163
+
164
+ if( !is_null( $tr_tab_id ) ){
165
+ $tab_id = $tr_tab_id;
166
+ }
167
+ }
168
+
169
+ if( $tab_id ){
170
+ //update existing tab
171
+ $args = array();
172
+ $args[ 'post_title' ] = $title;
173
+ $args[ 'post_content' ] = $content;
174
+ $wpdb->update( $wpdb->posts, $args, array( 'ID' => $tab_id ) );
175
+ }else{
176
+ //tab not exist creating new
177
+ $args = array();
178
+ $args[ 'post_title' ] = $title;
179
+ $args[ 'post_content' ] = $content;
180
+ $args[ 'post_author' ] = get_current_user_id();
181
+ $args[ 'post_name' ] = sanitize_title( $title );
182
+ $args[ 'post_type' ] = 'wc_product_tab';
183
+ $args[ 'post_parent' ] = $trnsl_product_id;
184
+ $args[ 'post_status' ] = 'publish';
185
+ $wpdb->insert( $wpdb->posts, $args );
186
+
187
+ $tab_id = $wpdb->insert_id;
188
+ $tab_trid = $sitepress->get_element_trid( $orig_prod_tab[ 'id' ], 'post_wc_product_tab' );
189
+ if( !$tab_trid ){
190
+ $sitepress->set_element_language_details( $orig_prod_tab[ 'id' ], 'post_wc_product_tab', false, $sitepress->get_default_language() );
191
+ $tab_trid = $sitepress->get_element_trid( $orig_prod_tab[ 'id' ], 'post_wc_product_tab' );
192
+ }
193
+ $sitepress->set_element_language_details( $tab_id, 'post_wc_product_tab', $tab_trid, $lang );
194
+ }
195
+
196
+ $trnsl_product_tabs[ $orig_prod_tab[ 'type' ].'_tab_'.$tab_id ] = array(
197
+ 'position' => $orig_prod_tab[ 'position' ],
198
+ 'type' => $orig_prod_tab[ 'type' ],
199
+ 'id' => $tab_id,
200
+ 'name' => get_post( $tab_id )->post_name
201
+ );
202
+
203
+ return $trnsl_product_tabs;
204
+ }
205
+
206
+ function duplicate_custom_fields_exceptions( $exceptions ){
207
+ $exceptions[] = '_product_tabs';
208
+ return $exceptions;
209
+ }
210
+
211
+ function custom_box_html( $obj, $product_id, $data ){
212
+
213
+ if( get_post_meta( $product_id, '_override_tab_layout', true ) != 'yes' ){
214
+ return false;
215
+ }
216
+
217
+ $orig_prod_tabs = $this->get_product_tabs( $product_id );
218
+ if( !$orig_prod_tabs ) return false;
219
+
220
+ $tabs_section = new WPML_Editor_UI_Field_Section( __( 'Product tabs', 'woocommerce-multilingual' ) );
221
+ end( $orig_prod_tabs );
222
+ $last_key = key( $orig_prod_tabs );
223
+ $divider = true;
224
+ foreach( $orig_prod_tabs as $key => $prod_tab ) {
225
+ if( $key == $last_key ){
226
+ $divider = false;
227
+ }
228
+
229
+ if( in_array( $prod_tab['type'], array( 'product', 'core' ) ) ){
230
+ if( $prod_tab['type'] == 'core' ){
231
+ $group = new WPML_Editor_UI_Field_Group( $prod_tab[ 'title' ], $divider );
232
+ $tab_field = new WPML_Editor_UI_Single_Line_Field( 'coretab_'.$prod_tab['id'].'_title', __( 'Title', 'woocommerce-multilingual' ), $data, false );
233
+ $group->add_field( $tab_field );
234
+ $tab_field = new WPML_Editor_UI_Single_Line_Field( 'coretab_'.$prod_tab['id'].'_heading' , __( 'Heading', 'woocommerce-multilingual' ), $data, false );
235
+ $group->add_field( $tab_field );
236
+ $tabs_section->add_field( $group );
237
+ }else{
238
+ $group = new WPML_Editor_UI_Field_Group( ucfirst( str_replace( '-', ' ', $prod_tab[ 'name' ] ) ), $divider );
239
+ $tab_field = new WPML_Editor_UI_Single_Line_Field( 'tab_'.$prod_tab['position'].'_title', __( 'Title', 'woocommerce-multilingual' ), $data, false );
240
+ $group->add_field( $tab_field );
241
+ $tab_field = new WPML_Editor_UI_WYSIWYG_Field( 'tab_'.$prod_tab['position'].'_heading' , null, $data, false );
242
+ $group->add_field( $tab_field );
243
+ $tabs_section->add_field( $group );
244
+ }
245
+ }
246
+ }
247
+ $obj->add_field( $tabs_section );
248
+
249
+ }
250
+
251
+
252
+ function custom_box_html_data( $data, $product_id, $translation, $lang ){
253
+
254
+ $orig_prod_tabs = $this->get_product_tabs( $product_id );
255
+
256
+ if( empty($orig_prod_tabs) ){
257
+ return $data;
258
+ }
259
+
260
+ foreach( $orig_prod_tabs as $key => $prod_tab ){
261
+ if( in_array( $prod_tab['type'], array( 'product', 'core' ) ) ){
262
+ if( $prod_tab['type'] == 'core' ){
263
+ $data[ 'coretab_'.$prod_tab['id'].'_title' ] = array( 'original' => $prod_tab['title'] );
264
+ $data[ 'coretab_'.$prod_tab['id'].'_heading' ] = array( 'original' => isset ( $prod_tab['heading'] ) ? $prod_tab['heading'] : '' );
265
+ }else{
266
+ $data[ 'tab_'.$prod_tab['position'].'_title' ] = array( 'original' => get_the_title( $prod_tab['id'] ) );
267
+ $data[ 'tab_'.$prod_tab['position'].'_heading' ] = array( 'original' => get_post( $prod_tab['id'] )->post_content );
268
+ }
269
+ }
270
+ }
271
+
272
+ if( $translation ){
273
+ $tr_product_id = $translation->ID;
274
+
275
+ $tr_prod_tabs = $this->get_product_tabs( $translation->ID );
276
+
277
+ if( !is_array( $tr_prod_tabs ) ){
278
+ return $data; // __('Please update original product','woocommerce-multilingual');
279
+ }
280
+
281
+ foreach( $tr_prod_tabs as $key => $prod_tab ){
282
+ if( in_array( $prod_tab['type'], array( 'product','core' ) ) ){
283
+ if($prod_tab['type'] == 'core'){
284
+ $data[ 'coretab_'.$prod_tab['id'].'_title' ][ 'translation' ] = $prod_tab['title'];
285
+ $data[ 'coretab_'.$prod_tab['id'].'_heading' ][ 'translation' ] = isset ( $prod_tab['heading'] ) ? $prod_tab['heading'] : '';
286
+ }else{
287
+ $data[ 'tab_'.$prod_tab['position'].'_title' ][ 'translation' ] = get_the_title( $prod_tab['id'] );
288
+ $data[ 'tab_'.$prod_tab['position'].'_heading' ][ 'translation' ] = get_post( $prod_tab['id'] )->post_content;
289
+ }
290
+ }
291
+ }
292
+ }else{
293
+ global $sitepress,$woocommerce;
294
+ $current_language = $sitepress->get_current_language();
295
+ foreach($orig_prod_tabs as $key=>$prod_tab){
296
+ if($prod_tab['type'] == 'core'){
297
+ unload_textdomain('woocommerce');
298
+ $sitepress->switch_lang($lang);
299
+ $woocommerce->load_plugin_textdomain();
300
+ $title = __( $prod_tab['title'], 'woocommerce' );
301
+ if($prod_tab['title'] != $title){
302
+ $data[ 'coretab_'.$prod_tab['id'].'_title' ][ 'translation' ] = $title;
303
+
304
+ }
305
+
306
+ if(!isset($prod_tab['heading'])){
307
+ $data[ 'coretab_'.$prod_tab['id'].'_heading' ][ 'translation' ] = '';
308
+ }else{
309
+ $heading = __( $prod_tab['heading'], 'woocommerce' );
310
+ if($prod_tab['heading'] != $heading){
311
+ $data[ 'coretab_'.$prod_tab['id'].'_heading' ][ 'translation' ] = $heading;
312
+ }
313
+ }
314
+
315
+ unload_textdomain('woocommerce');
316
+ $sitepress->switch_lang($current_language);
317
+ $woocommerce->load_plugin_textdomain();
318
+ }
319
+ }
320
+ }
321
+
322
+ return $data;
323
+
324
+ }
325
+
326
+ function duplicate_product_tabs( $new_id, $original_post ){
327
+
328
+ wc_tab_manager_duplicate_product( $new_id, $original_post );
329
+
330
+ }
331
+
332
+ function force_set_language_information_on_product_tabs($post_id, $post){
333
+ global $sitepress;
334
+
335
+ if( $post->post_type == 'wc_product_tab' ){
336
+
337
+ $language = $sitepress->get_language_for_element($post->ID, 'post_wc_product_tab');
338
+ if( empty ($language) && $post->post_parent ) {
339
+ $parent_language = $sitepress->get_language_for_element($post->post_parent, 'post_product');
340
+ if( $parent_language ){
341
+ $sitepress->set_element_language_details($post->ID, 'post_wc_product_tab', null, $parent_language);
342
+ }
343
+ }
344
+
345
+ }
346
+
347
+ }
348
+
349
+ function append_custom_tabs_to_translation_package($package, $post){
350
+
351
+ if( $post->post_type == 'product' ) {
352
+
353
+ $override_tab_layout = get_post_meta( $post->ID , '_override_tab_layout', true);
354
+
355
+ if( $override_tab_layout == 'yes' ){
356
+
357
+ $meta = get_post_meta( $post->ID, '_product_tabs', true );
358
+
359
+ foreach ( (array)$meta as $key => $value ) {
360
+
361
+ if ( preg_match( '/product_tab_([0-9]+)/', $key, $matches ) ) {
362
+
363
+ $wc_product_tab_id = $matches[1];
364
+ $wc_product_tab = get_post( $wc_product_tab_id );
365
+
366
+ $package['contents']['product_tabs:product_tab:' . $wc_product_tab_id . ':title'] = array(
367
+ 'translate' => 1,
368
+ 'data' => $this->tp->encode_field_data( $wc_product_tab->post_title, 'base64' ),
369
+ 'format' => 'base64'
370
+ );
371
+
372
+ $package['contents']['product_tabs:product_tab:' . $wc_product_tab_id . ':description'] = array(
373
+ 'translate' => 1,
374
+ 'data' => $this->tp->encode_field_data( $wc_product_tab->post_content, 'base64' ),
375
+ 'format' => 'base64'
376
+ );
377
+
378
+
379
+ } elseif ( preg_match( '/^core_tab_(.+)$/', $key, $matches ) ){
380
+
381
+ $package['contents']['product_tabs:core_tab_title:' . $matches[1]] = array(
382
+ 'translate' => 1,
383
+ 'data' => $this->tp->encode_field_data( $value['title'], 'base64' ),
384
+ 'format' => 'base64'
385
+ );
386
+
387
+ if(isset( $value['heading'] )) {
388
+ $package['contents']['product_tabs:core_tab_heading:' . $matches[1]] = array(
389
+ 'translate' => 1,
390
+ 'data' => $this->tp->encode_field_data( $value['heading'], 'base64' ),
391
+ 'format' => 'base64'
392
+ );
393
+ }
394
+
395
+
396
+ }
397
+
398
+ }
399
+ }
400
+
401
+
402
+ }
403
+
404
+ return $package;
405
+ }
406
+
407
+ function save_custom_tabs_translation( $post_id, $data, $job ){
408
+ global $sitepress;
409
+
410
+
411
+ $translated_product_tabs_updated = false;
412
+
413
+ $original_product_tabs = get_post_meta($job->original_doc_id, '_product_tabs', true);
414
+
415
+ if( $original_product_tabs ) {
416
+
417
+ // custom tabs
418
+ $product_tab_translations = array();
419
+
420
+ foreach ( $data as $value ) {
421
+
422
+ if ( preg_match( '/product_tabs:product_tab:([0-9]+):(.+)/', $value['field_type'], $matches ) ) {
423
+
424
+ $wc_product_tab_id = $matches[1];
425
+ $field = $matches[2];
426
+
427
+ $product_tab_translations[$wc_product_tab_id][$field] = $value['data'];
428
+ }
429
+
430
+ }
431
+
432
+ if ( $product_tab_translations ) {
433
+
434
+ $translated_product_tabs = get_post_meta( $post_id, '_product_tabs', true );
435
+
436
+ foreach ( $product_tab_translations as $wc_product_tab_id => $value ) {
437
+
438
+ $new_wc_product_tab = array(
439
+ 'post_type' => 'wp_product_tab',
440
+ 'post_title' => $value['title'],
441
+ 'post_content' => $value['description'],
442
+ 'post_status' => 'publish'
443
+ );
444
+
445
+ $wc_product_tab_id_translated = wp_insert_post( $new_wc_product_tab );
446
+
447
+ if ( $wc_product_tab_id_translated ) {
448
+
449
+ $wc_product_tab_trid = $sitepress->get_element_trid( $wc_product_tab_id, 'post_wc_product_tab' );
450
+ $sitepress->set_element_language_details( $wc_product_tab_id_translated, 'post_wc_product_tab', $wc_product_tab_trid, $job->language_code );
451
+
452
+ $wc_product_tab_translated = get_post( $wc_product_tab_id_translated );
453
+
454
+ $translated_product_tabs['product_tab_' . $wc_product_tab_id_translated] = array(
455
+
456
+ 'position' => $original_product_tabs['product_tab_' . $wc_product_tab_id]['position'],
457
+ 'type' => 'product',
458
+ 'id' => $wc_product_tab_id_translated,
459
+ 'name' => $wc_product_tab_translated->post_name
460
+
461
+ );
462
+
463
+ }
464
+
465
+ }
466
+
467
+
468
+ $translated_product_tabs_updated = true;
469
+ }
470
+
471
+ // the other tabs
472
+ $product_tab_translations = array();
473
+
474
+ foreach ( $data as $value ) {
475
+
476
+ if ( preg_match( '/product_tabs:core_tab_(.+):(.+)/', $value['field_type'], $matches ) ) {
477
+
478
+ $tab_field = $matches[1];
479
+ $tab_id = $matches[2];
480
+
481
+ $product_tab_translations[$tab_id][$tab_field] = $value['data'];
482
+
483
+ }
484
+
485
+ }
486
+
487
+ if( $product_tab_translations){
488
+ foreach( $product_tab_translations as $id => $tab ){
489
+
490
+ $translated_product_tabs['core_tab_' . $id] = array(
491
+ 'type' => 'core',
492
+ 'position' => $original_product_tabs['core_tab_' . $id]['position'],
493
+ 'id' => $id,
494
+ 'title' => $tab['title']
495
+ );
496
+
497
+ if( isset( $tab['heading'] ) ){
498
+ $translated_product_tabs['core_tab_' . $id]['heading'] = $tab['heading'];
499
+ }
500
+
501
+ }
502
+
503
+ $translated_product_tabs_updated = true;
504
+ }
505
+
506
+ if ( $translated_product_tabs_updated ) {
507
+ update_post_meta( $post_id, '_product_tabs', $translated_product_tabs );
508
+ }
509
+
510
+ }
511
+ }
512
+
513
+ public function get_product_tabs( $product_id ) {
514
+
515
+ $override_tab_layout = get_post_meta( $product_id, '_override_tab_layout', true );
516
+
517
+ if ( 'yes' == $override_tab_layout ) {
518
+ // product defines its own tab layout?
519
+ $product_tabs = get_post_meta( $product_id, '_product_tabs', true );
520
+ } else {
521
+ // otherwise, get the default layout if any
522
+ $product_tabs = get_option( 'wc_tab_manager_default_layout', false );
523
+ }
524
+
525
+ return $product_tabs;
526
+ }
527
+
528
+
529
+ function wc_tab_manager_tab_id($tab_id) {
530
+ $tab_id = apply_filters('wpml_object_id', $tab_id, 'wc_product_tab', true);
531
+
532
+ return $tab_id;
533
+ }
534
+
535
+ }
compatibility/class-wcml-table-rate-shipping.php CHANGED
@@ -1,66 +1,65 @@
1
- <?php
2
-
3
- class WCML_Table_Rate_Shipping{
4
-
5
- function __construct(){
6
-
7
- add_action('init', array($this, 'init'),9);
8
- }
9
-
10
- public function init(){
11
- global $pagenow;
12
-
13
- add_filter('woocommerce_table_rate_query_rates_args', array($this, 'default_shipping_class_id'));
14
- add_filter('get_the_terms',array( $this, 'shipping_class_id_in_default_language'), 10, 3 );
15
-
16
- //register shipping label
17
- if($pagenow == 'admin.php' && isset($_GET['page']) && $_GET['page']=='shipping_zones' && isset( $_POST['shipping_label'] ) && isset( $_POST['woocommerce_table_rate_title'] )){
18
- do_action('wpml_register_single_string', 'woocommerce', $_POST['woocommerce_table_rate_title'] .'_shipping_method_title', $_POST['woocommerce_table_rate_title']);
19
- $shipping_labels = array_map( 'woocommerce_clean', $_POST['shipping_label'] );
20
- foreach($shipping_labels as $shipping_label){
21
- do_action('wpml_register_single_string', 'woocommerce', $shipping_label .'_shipping_method_title', $shipping_label);
22
- }
23
- }
24
-
25
- }
26
-
27
- public function default_shipping_class_id($args){
28
- global $sitepress, $woocommerce_wpml;
29
- if($sitepress->get_current_language() != $sitepress->get_default_language() && !empty($args['shipping_class_id'])){
30
-
31
- $args['shipping_class_id'] = apply_filters( 'translate_object_id',$args['shipping_class_id'], 'product_shipping_class', false, $sitepress->get_default_language());
32
-
33
- if($woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT){
34
- // use unfiltred cart price to compare against limits of different shipping methods
35
- $args['price'] = $woocommerce_wpml->multi_currency->unconvert_price_amount($args['price']);
36
- }
37
-
38
- }
39
-
40
- return $args;
41
- }
42
-
43
- public function shipping_class_id_in_default_language( $terms, $post_id, $taxonomy ) {
44
- global $sitepress, $icl_adjust_id_url_filter_off;
45
- if ( isset( $_POST['calc_shipping'] ) && $taxonomy == 'product_shipping_class' ) {
46
-
47
- foreach( $terms as $k => $term ){
48
- $shipping_class_id = apply_filters( 'translate_object_id', $term->term_id, 'product_shipping_class', false, $sitepress->get_default_language());
49
-
50
- $icl_adjust_id_url_filter = $icl_adjust_id_url_filter_off;
51
- $icl_adjust_id_url_filter_off = true;
52
-
53
- $terms[$k] = get_term( $shipping_class_id, 'product_shipping_class');
54
-
55
- $icl_adjust_id_url_filter_off = $icl_adjust_id_url_filter;
56
-
57
- }
58
-
59
- }
60
-
61
- return $terms;
62
-
63
- }
64
-
65
-
66
- }
1
+ <?php
2
+
3
+ class WCML_Table_Rate_Shipping{
4
+
5
+ function __construct(){
6
+
7
+ add_action('init', array($this, 'init'),9);
8
+
9
+ add_filter('woocommerce_table_rate_query_rates_args', array($this, 'default_shipping_class_id'));
10
+ add_filter('get_the_terms',array( $this, 'shipping_class_id_in_default_language'), 10, 3 );
11
+ }
12
+
13
+ public function init(){
14
+ global $pagenow;
15
+
16
+ //register shipping label
17
+ if($pagenow == 'admin.php' && isset($_GET['page']) && $_GET['page']=='shipping_zones' && isset( $_POST['shipping_label'] ) && isset( $_POST['woocommerce_table_rate_title'] )){
18
+ do_action('wpml_register_single_string', 'woocommerce', $_POST['woocommerce_table_rate_title'] .'_shipping_method_title', $_POST['woocommerce_table_rate_title']);
19
+ $shipping_labels = array_map( 'woocommerce_clean', $_POST['shipping_label'] );
20
+ foreach($shipping_labels as $shipping_label){
21
+ do_action('wpml_register_single_string', 'woocommerce', $shipping_label .'_shipping_method_title', $shipping_label);
22
+ }
23
+ }
24
+
25
+ }
26
+
27
+ public function default_shipping_class_id($args){
28
+ global $sitepress, $woocommerce_wpml;
29
+ if($sitepress->get_current_language() != $sitepress->get_default_language() && !empty($args['shipping_class_id'])){
30
+
31
+ $args['shipping_class_id'] = apply_filters( 'translate_object_id',$args['shipping_class_id'], 'product_shipping_class', false, $sitepress->get_default_language());
32
+
33
+ if($woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT){
34
+ // use unfiltred cart price to compare against limits of different shipping methods
35
+ $args['price'] = $woocommerce_wpml->multi_currency->prices->unconvert_price_amount($args['price']);
36
+ }
37
+
38
+ }
39
+
40
+ return $args;
41
+ }
42
+
43
+ public function shipping_class_id_in_default_language( $terms, $post_id, $taxonomy ) {
44
+ global $sitepress, $icl_adjust_id_url_filter_off;
45
+ if ( isset( $_POST['calc_shipping'] ) && $taxonomy == 'product_shipping_class' ) {
46
+
47
+ foreach( $terms as $k => $term ){
48
+ $shipping_class_id = apply_filters( 'translate_object_id', $term->term_id, 'product_shipping_class', false, $sitepress->get_default_language());
49
+
50
+ $icl_adjust_id_url_filter = $icl_adjust_id_url_filter_off;
51
+ $icl_adjust_id_url_filter_off = true;
52
+
53
+ $terms[$k] = get_term( $shipping_class_id, 'product_shipping_class');
54
+
55
+ $icl_adjust_id_url_filter_off = $icl_adjust_id_url_filter;
56
+
57
+ }
58
+
59
+ }
60
+
61
+ return $terms;
62
+
63
+ }
64
+
65
+ }
 
compatibility/class-wcml-variation-swatches-and-photos.php CHANGED
@@ -1,62 +1,62 @@
1
- <?php
2
-
3
- class WCML_Variation_Swatches_and_Photos{
4
-
5
- function __construct(){
6
- add_action('wcml_after_duplicate_product_post_meta',array($this,'sync_variation_swatches_and_photos'),10,3);
7
- }
8
-
9
- function sync_variation_swatches_and_photos($original_product_id, $trnsl_product_id, $data = false){
10
- global $sitepress, $wpdb;
11
-
12
- $atts = maybe_unserialize(get_post_meta($original_product_id, '_swatch_type_options', true));
13
-
14
- if (!is_array($atts)) {
15
- return;
16
- }
17
-
18
- $lang = $sitepress->get_language_for_element($trnsl_product_id,'post_product');
19
- $tr_atts = $atts;
20
-
21
- $original_product_post = get_post($original_product_id);
22
-
23
- $original_product_taxonomies = get_object_taxonomies($original_product_post);
24
-
25
- $original_product_terms = get_terms($original_product_taxonomies);
26
-
27
- if (is_array($original_product_terms)) {
28
-
29
- foreach ($atts as $att_name=>$att_opts) {
30
-
31
- $attributes_hashed_names = array_keys($att_opts['attributes']);
32
-
33
- foreach($original_product_terms as $original_product_term) {
34
- $original_product_term_slug_md5 = md5($original_product_term->slug);
35
-
36
- if (in_array($original_product_term_slug_md5, $attributes_hashed_names)) {
37
-
38
- $translated_product_term_id = apply_filters('wpml_object_id', $original_product_term->term_id, $original_product_term->taxonomy, false, $lang);
39
-
40
- $translated_product_term = get_term($translated_product_term_id, $original_product_term->taxonomy);
41
-
42
- if (is_object($translated_product_term)) {
43
-
44
- $translated_product_term_slug_md5 = md5($translated_product_term->slug);
45
-
46
- $tr_atts[$att_name]['attributes'][$translated_product_term_slug_md5] = $tr_atts[$att_name]['attributes'][$original_product_term_slug_md5];
47
-
48
- unset( $tr_atts[$att_name]['attributes'][$original_product_term_slug_md5] );
49
- }
50
-
51
- }
52
-
53
- }
54
-
55
- }
56
-
57
- }
58
-
59
- update_post_meta($trnsl_product_id,'_swatch_type_options',$tr_atts); // Meta gets overwritten
60
- }
61
-
62
- }
1
+ <?php
2
+
3
+ class WCML_Variation_Swatches_and_Photos{
4
+
5
+ function __construct(){
6
+ add_action('wcml_after_duplicate_product_post_meta',array($this,'sync_variation_swatches_and_photos'),10,3);
7
+ }
8
+
9
+ function sync_variation_swatches_and_photos($original_product_id, $trnsl_product_id, $data = false){
10
+ global $sitepress, $wpdb;
11
+
12
+ $atts = maybe_unserialize(get_post_meta($original_product_id, '_swatch_type_options', true));
13
+
14
+ if (!is_array($atts)) {
15
+ return;
16
+ }
17
+
18
+ $lang = $sitepress->get_language_for_element($trnsl_product_id,'post_product');
19
+ $tr_atts = $atts;
20
+
21
+ $original_product_post = get_post($original_product_id);
22
+
23
+ $original_product_taxonomies = get_object_taxonomies($original_product_post);
24
+
25
+ $original_product_terms = get_terms($original_product_taxonomies);
26
+
27
+ if (is_array($original_product_terms)) {
28
+
29
+ foreach ($atts as $att_name=>$att_opts) {
30
+
31
+ $attributes_hashed_names = array_keys($att_opts['attributes']);
32
+
33
+ foreach($original_product_terms as $original_product_term) {
34
+ $original_product_term_slug_md5 = md5($original_product_term->slug);
35
+
36
+ if (in_array($original_product_term_slug_md5, $attributes_hashed_names)) {
37
+
38
+ $translated_product_term_id = apply_filters('wpml_object_id', $original_product_term->term_id, $original_product_term->taxonomy, false, $lang);
39
+
40
+ $translated_product_term = get_term($translated_product_term_id, $original_product_term->taxonomy);
41
+
42
+ if (is_object($translated_product_term)) {
43
+
44
+ $translated_product_term_slug_md5 = md5($translated_product_term->slug);
45
+
46
+ $tr_atts[$att_name]['attributes'][$translated_product_term_slug_md5] = $tr_atts[$att_name]['attributes'][$original_product_term_slug_md5];
47
+
48
+ unset( $tr_atts[$att_name]['attributes'][$original_product_term_slug_md5] );
49
+ }
50
+
51
+ }
52
+
53
+ }
54
+
55
+ }
56
+
57
+ }
58
+
59
+ update_post_meta($trnsl_product_id,'_swatch_type_options',$tr_atts); // Meta gets overwritten
60
+ }
61
+
62
+ }
compatibility/class-wcml-wc-name-your-price.php CHANGED
@@ -1,24 +1,24 @@
1
- <?php
2
-
3
- class WCML_WC_Name_Your_Price{
4
-
5
- function __construct(){
6
-
7
- add_action('init', array($this, 'init'),9);
8
-
9
- }
10
-
11
- function init(){
12
- if( !is_admin() ){
13
- add_filter('woocommerce_raw_suggested_price', array($this, 'product_price_filter'), 10, 2);
14
- add_filter('woocommerce_raw_minimum_price', array($this, 'product_price_filter'), 10, 2);
15
- }
16
- }
17
-
18
- function product_price_filter($price, $product){
19
-
20
- return apply_filters('wcml_raw_price_amount', $price );
21
-
22
- }
23
-
24
- }
1
+ <?php
2
+
3
+ class WCML_WC_Name_Your_Price{
4
+
5
+ function __construct(){
6
+
7
+ add_action('init', array($this, 'init'),9);
8
+
9
+ }
10
+
11
+ function init(){
12
+ if( !is_admin() ){
13
+ add_filter('woocommerce_raw_suggested_price', array($this, 'product_price_filter'), 10, 2);
14
+ add_filter('woocommerce_raw_minimum_price', array($this, 'product_price_filter'), 10, 2);
15
+ }
16
+ }
17
+
18
+ function product_price_filter($price, $product){
19
+
20
+ return apply_filters('wcml_raw_price_amount', $price );
21
+
22
+ }
23
+
24
+ }
compatibility/class-wcml-wc-subscriptions.php CHANGED
@@ -1,65 +1,185 @@
1
- <?php
2
-
3
- class WCML_WC_Subscriptions{
4
-
5
- function __construct(){
6
-
7
- add_action('init', array($this, 'init'),9);
8
- add_filter('wcml_variation_term_taxonomy_ids',array($this,'wcml_variation_term_taxonomy_ids'));
9
- add_filter('woocommerce_subscription_lengths', array($this, 'woocommerce_subscription_lengths'), 10, 2);
10
-
11
- // reenable coupons for subscriptions when multicurrency is on
12
- add_action('woocommerce_subscription_cart_after_grouping', array($this, 'woocommerce_subscription_cart_after_grouping'));
13
- }
14
-
15
- function init(){
16
- if( !is_admin() ){
17
- add_filter('woocommerce_subscriptions_product_sign_up_fee', array($this, 'product_price_filter'), 10, 2);
18
- }
19
- }
20
-
21
- function product_price_filter($subscription_sign_up_fee, $product){
22
-
23
- $subscription_sign_up_fee = apply_filters('wcml_raw_price_amount', $subscription_sign_up_fee );
24
-
25
- return $subscription_sign_up_fee;
26
- }
27
-
28
- function wcml_variation_term_taxonomy_ids($get_variation_term_taxonomy_ids){
29
- global $wpdb;
30
- $get_variation_term_taxonomy_id = $wpdb->get_var("SELECT tt.term_taxonomy_id FROM $wpdb->terms AS t LEFT JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE t.slug = 'variable-subscription'");
31
-
32
- if(!empty($get_variation_term_taxonomy_id)){
33
- $get_variation_term_taxonomy_ids[] = $get_variation_term_taxonomy_id;
34
- }
35
-
36
- return $get_variation_term_taxonomy_ids;
37
- }
38
-
39
- public function woocommerce_subscription_lengths($subscription_ranges, $subscription_period) {
40
-
41
- if (is_array($subscription_ranges)) {
42
- foreach ($subscription_ranges as $period => $ranges) {
43
- if (is_array($ranges)) {
44
- foreach ($ranges as $range) {
45
- if ($range == "9 months") {
46
- $breakpoint = true;
47
- }
48
- $new_subscription_ranges[$period][] = apply_filters( 'wpml_translate_single_string', $range, 'wc_subscription_ranges', $range);
49
- }
50
- }
51
- }
52
- }
53
-
54
- return isset($new_subscription_ranges) ? $new_subscription_ranges : $subscription_ranges;
55
- }
56
-
57
- public function woocommerce_subscription_cart_after_grouping() {
58
- global $woocommerce_wpml;
59
-
60
- if( $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
61
- remove_action('woocommerce_before_calculate_totals', 'WC_Subscriptions_Coupon::remove_coupons', 10);
62
- }
63
-
64
- }
65
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_WC_Subscriptions{
4
+
5
+ private $new_subscription = false;
6
+
7
+ function __construct(){
8
+
9
+ add_action('init', array($this, 'init'),9);
10
+ add_filter('wcml_variation_term_taxonomy_ids',array($this,'wcml_variation_term_taxonomy_ids'));
11
+ add_filter('woocommerce_subscription_lengths', array($this, 'woocommerce_subscription_lengths'), 10, 2);
12
+
13
+ add_filter('wcml_register_endpoints_query_vars', array($this, 'register_endpoint' ), 10, 3 );
14
+ add_filter('wcml_endpoint_permalink_filter', array($this, 'endpoint_permalink_filter'), 10, 2);
15
+
16
+ //custom prices
17
+ add_filter( 'wcml_custom_prices_fields', array( $this, 'set_prices_fields' ), 10, 2 );
18
+ add_filter( 'wcml_custom_prices_strings', array( $this, 'set_labels_for_prices_fields' ), 10, 2 );
19
+ add_filter( 'wcml_custom_prices_fields_labels', array( $this, 'set_labels_for_prices_fields' ), 10, 2 );
20
+ add_filter( 'wcml_update_custom_prices_values', array( $this, 'update_custom_prices_values' ), 10 ,3 );
21
+ add_action( 'wcml_after_custom_prices_block', array( $this, 'new_subscription_prices_block') );
22
+
23
+ // reenable coupons for subscriptions when multicurrency is on
24
+ add_action('woocommerce_subscription_cart_after_grouping', array($this, 'woocommerce_subscription_cart_after_grouping'));
25
+ }
26
+
27
+ function init(){
28
+ if( !is_admin() ){
29
+ add_filter('woocommerce_subscriptions_product_sign_up_fee', array($this, 'product_price_filter'), 10, 2);
30
+ }
31
+ }
32
+
33
+ function product_price_filter($subscription_sign_up_fee, $product){
34
+
35
+ $subscription_sign_up_fee = apply_filters('wcml_raw_price_amount', $subscription_sign_up_fee );
36
+
37
+ return $subscription_sign_up_fee;
38
+ }
39
+
40
+ function wcml_variation_term_taxonomy_ids($get_variation_term_taxonomy_ids){
41
+ global $wpdb;
42
+ $get_variation_term_taxonomy_id = $wpdb->get_var("SELECT tt.term_taxonomy_id FROM $wpdb->terms AS t LEFT JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE t.slug = 'variable-subscription'");
43
+
44
+ if(!empty($get_variation_term_taxonomy_id)){
45
+ $get_variation_term_taxonomy_ids[] = $get_variation_term_taxonomy_id;
46
+ }
47
+
48
+ return $get_variation_term_taxonomy_ids;
49
+ }
50
+
51
+ public function woocommerce_subscription_lengths($subscription_ranges, $subscription_period) {
52
+
53
+ if (is_array($subscription_ranges)) {
54
+ foreach ($subscription_ranges as $period => $ranges) {
55
+ if (is_array($ranges)) {
56
+ foreach ($ranges as $range) {
57
+ if ($range == "9 months") {
58
+ $breakpoint = true;
59
+ }
60
+ $new_subscription_ranges[$period][] = apply_filters( 'wpml_translate_single_string', $range, 'wc_subscription_ranges', $range);
61
+ }
62
+ }
63
+ }
64
+ }
65
+
66
+ return isset($new_subscription_ranges) ? $new_subscription_ranges : $subscription_ranges;
67
+ }
68
+
69
+ public function woocommerce_subscription_cart_after_grouping() {
70
+ global $woocommerce_wpml;
71
+
72
+ if( $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
73
+ remove_action('woocommerce_before_calculate_totals', 'WC_Subscriptions_Coupon::remove_coupons', 10);
74
+ }
75
+
76
+ }
77
+
78
+ function set_prices_fields( $fields, $product_id ){
79
+ if( $this->is_subscriptions_product( $product_id ) || $this->new_subscription ){
80
+ $fields[] = '_subscription_sign_up_fee';
81
+ }
82
+
83
+ return $fields;
84
+
85
+ }
86
+
87
+ function set_labels_for_prices_fields( $labels, $product_id ){
88
+
89
+ if( $this->is_subscriptions_product( $product_id ) || $this->new_subscription ){
90
+ $labels[ '_regular_price' ] = __( 'Subscription Price', 'woocommerce-multilingual' );
91
+ $labels[ '_subscription_sign_up_fee' ] = __( 'Sign-up Fee', 'woocommerce-multilingual' );
92
+ }
93
+
94
+ return $labels;
95
+
96
+ }
97
+
98
+ function update_custom_prices_values( $prices, $code, $variation_id = false ){
99
+
100
+ if( isset( $_POST[ '_custom_subscription_sign_up_fee' ][ $code ] ) ){
101
+ $prices[ '_subscription_sign_up_fee' ] = wc_format_decimal( $_POST[ '_custom_subscription_sign_up_fee' ][ $code ] );
102
+ }
103
+
104
+ if( $variation_id && isset( $_POST[ '_custom_variation_subscription_sign_up_fee' ][ $code ][ $variation_id ] ) ){
105
+ $prices[ '_subscription_sign_up_fee' ] = wc_format_decimal( $_POST[ '_custom__custom_variation_subscription_sign_up_fee' ][ $code ][ $variation_id ] );
106
+ }
107
+
108
+ return $prices;
109
+
110
+ }
111
+
112
+ function is_subscriptions_product( $product_id ){
113
+ global $wpdb;
114
+ $get_variation_term_taxonomy_ids = $wpdb->get_col("SELECT tt.term_taxonomy_id FROM $wpdb->terms AS t LEFT JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE t.slug IN ( 'subscription', 'variable-subscription' ) AND tt.taxonomy = 'product_type'");
115
+
116
+ if( get_post_type( $product_id ) == 'product_variation' ){
117
+ $product_id = wp_get_post_parent_id( $product_id );
118
+ }
119
+
120
+ $is_subscriptions_product = $wpdb->get_var($wpdb->prepare("SELECT count(object_id) FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id IN (".join(',',$get_variation_term_taxonomy_ids).")",$product_id));
121
+ return $is_subscriptions_product;
122
+ }
123
+
124
+ function new_subscription_prices_block( $product_id ){
125
+ global $woocommerce_wpml;
126
+ if( $product_id == 'new' ){
127
+ $this->new_subscription = true;
128
+ echo '<div class="wcml_prices_if_subscription" style="display: none">';
129
+ $custom_prices_ui = new WCML_Custom_Prices_UI( $woocommerce_wpml, 'new' );
130
+ $custom_prices_ui->show();
131
+ echo '</div>';
132
+ ?>
133
+ <script>
134
+ jQuery(document).ready(function($) {
135
+ jQuery('.wcml_prices_if_subscription .wcml_custom_prices_input').attr('name', '_wcml_custom_prices[new_subscription]').attr( 'id', '_wcml_custom_prices[new_subscription]');
136
+ jQuery('.wcml_prices_if_subscription .wcml_custom_prices_options_block>label').attr('for', '_wcml_custom_prices[new_subscription]');
137
+ jQuery('.wcml_prices_if_subscription .wcml_schedule_input').each( function(){
138
+ jQuery(this).attr('name', jQuery(this).attr('name')+'_subscription');
139
+ });
140
+
141
+ jQuery('.options_group>.wcml_custom_prices_block .wcml_custom_prices_input:first-child').click();
142
+ jQuery('.options_group>.wcml_custom_prices_block .wcml_schedule_options .wcml_schedule_input:first-child').click();
143
+
144
+ jQuery(document).on('change', 'select#product-type', function () {
145
+ if (jQuery(this).val() == 'subscription') {
146
+ jQuery('.wcml_prices_if_subscription').show();
147
+ jQuery('.options_group>.wcml_custom_prices_block').hide();
148
+ } else if (jQuery(this).val() != 'variable-subscription') {
149
+ jQuery('.wcml_prices_if_subscription').hide();
150
+ jQuery('.options_group>.wcml_custom_prices_block').show();
151
+ }
152
+ });
153
+
154
+ jQuery(document).on('click', '#publish', function () {
155
+ if ( jQuery('.wcml_prices_if_subscription').is( ':visible' ) ) {
156
+ jQuery('.options_group>.wcml_custom_prices_block').remove();
157
+ jQuery('.wcml_prices_if_subscription .wcml_custom_prices_input').attr('name', '_wcml_custom_prices[new]');
158
+ jQuery('.wcml_prices_if_subscription .wcml_schedule_input').each( function(){
159
+ jQuery(this).attr('name', jQuery(this).attr('name').replace('_subscription','') );
160
+ });
161
+ }else{
162
+ jQuery('.wcml_prices_if_subscription').remove();
163
+ }
164
+ });
165
+ });
166
+ </script>
167
+ <?php
168
+ }
169
+ }
170
+
171
+ function register_endpoint( $query_vars, $wc_vars, $obj ){
172
+
173
+ $query_vars[ 'view-subscription' ] = $obj->get_endpoint_translation( 'view-subscription', isset( $wc_vars['view-subscription'] ) ? $wc_vars['view-subscription'] : 'view-subscription' );
174
+ return $query_vars;
175
+ }
176
+
177
+ function endpoint_permalink_filter( $endpoint, $key ){
178
+
179
+ if( $key == 'view-subscription' ){
180
+ return 'view-subscription';
181
+ }
182
+
183
+ return $endpoint;
184
+ }
185
+ }
compatibility/class-wcml-wcexporter.php CHANGED
@@ -1,70 +1,70 @@
1
- <?php
2
-
3
- class WCML_wcExporter{
4
-
5
- function __construct(){
6
-
7
- add_filter('woo_ce_product_fields',array($this,'woo_ce_fields'));
8
- add_filter('woo_ce_category_fields',array($this,'woo_ce_fields'));
9
- add_filter('woo_ce_tag_fields',array($this,'woo_ce_fields'));
10
- add_filter('woo_ce_order_fields',array($this,'woo_ce_order_fields'));
11
- add_filter('woo_ce_product_item',array($this,'woo_ce_product_item'),10,2);
12
- add_filter('woo_ce_category_item',array($this,'woo_ce_category_item'),10);
13
- add_filter('woo_ce_tags',array($this,'woo_ce_tags'),10);
14
-
15
- }
16
-
17
- function woo_ce_fields($fields){
18
- $fields[] = array(
19
- 'name' => 'language',
20
- 'label' => __( 'Language', 'woo_ce' ),
21
- 'default' => 1
22
- );
23
- $fields[] = array(
24
- 'name' => 'translation_of',
25
- 'label' => __( 'Translation of', 'woo_ce' ),
26
- 'default' => 1
27
- );
28
- return $fields;
29
- }
30
-
31
- function woo_ce_order_fields($fields){
32
- $fields[] = array(
33
- 'name' => 'language',
34
- 'label' => __( 'Language', 'woo_ce' ),
35
- 'default' => 1
36
- );
37
-
38
- return $fields;
39
- }
40
-
41
- function woo_ce_product_item($data, $product_id){
42
- global $sitepress,$woocommerce_wpml;
43
-
44
- $data->language = $sitepress->get_language_for_element($product_id,'post_'.get_post_type($product_id));
45
- $data->translation_of = apply_filters( 'translate_object_id',$product_id,get_post_type($product_id),true, $woocommerce_wpml->products->get_original_product_language( $product_id ) );
46
-
47
- return $data;
48
- }
49
-
50
- function woo_ce_category_item($data){
51
- global $sitepress;
52
-
53
- $data->language = $sitepress->get_language_for_element($data->term_taxonomy_id,'tax_product_cat');
54
- $data->translation_of = apply_filters( 'translate_object_id',$data->term_taxonomy_id,'tax_product_cat',true,$sitepress->get_default_language());
55
-
56
- return $data;
57
- }
58
-
59
- function woo_ce_tags($tags){
60
- global $sitepress;
61
-
62
- foreach($tags as $key=>$tag){
63
- $tags[$key]->language = $sitepress->get_language_for_element($tag->term_taxonomy_id,'tax_product_tag');
64
- $tags[$key]->translation_of = apply_filters( 'translate_object_id',$tag->term_taxonomy_id,'tax_product_tag',true,$sitepress->get_default_language());
65
- }
66
-
67
- return $tags;
68
- }
69
-
70
- }
1
+ <?php
2
+
3
+ class WCML_wcExporter{
4
+
5
+ function __construct(){
6
+
7
+ add_filter('woo_ce_product_fields',array($this,'woo_ce_fields'));
8
+ add_filter('woo_ce_category_fields',array($this,'woo_ce_fields'));
9
+ add_filter('woo_ce_tag_fields',array($this,'woo_ce_fields'));
10
+ add_filter('woo_ce_order_fields',array($this,'woo_ce_order_fields'));
11
+ add_filter('woo_ce_product_item',array($this,'woo_ce_product_item'),10,2);
12
+ add_filter('woo_ce_category_item',array($this,'woo_ce_category_item'),10);
13
+ add_filter('woo_ce_tags',array($this,'woo_ce_tags'),10);
14
+
15
+ }
16
+
17
+ function woo_ce_fields($fields){
18
+ $fields[] = array(
19
+ 'name' => 'language',
20
+ 'label' => __( 'Language', 'woo_ce' ),
21
+ 'default' => 1
22
+ );
23
+ $fields[] = array(
24
+ 'name' => 'translation_of',
25
+ 'label' => __( 'Translation of', 'woo_ce' ),
26
+ 'default' => 1
27
+ );
28
+ return $fields;
29
+ }
30
+
31
+ function woo_ce_order_fields($fields){
32
+ $fields[] = array(
33
+ 'name' => 'language',
34
+ 'label' => __( 'Language', 'woo_ce' ),
35
+ 'default' => 1
36
+ );
37
+
38
+ return $fields;
39
+ }
40
+
41
+ function woo_ce_product_item($data, $product_id){
42
+ global $sitepress,$woocommerce_wpml;
43
+
44
+ $data->language = $sitepress->get_language_for_element($product_id,'post_'.get_post_type($product_id));
45
+ $data->translation_of = apply_filters( 'translate_object_id',$product_id,get_post_type($product_id),true, $woocommerce_wpml->products->get_original_product_language( $product_id ) );
46
+
47
+ return $data;
48
+ }
49
+
50
+ function woo_ce_category_item($data){
51
+ global $sitepress;
52
+
53
+ $data->language = $sitepress->get_language_for_element($data->term_taxonomy_id,'tax_product_cat');
54
+ $data->translation_of = apply_filters( 'translate_object_id',$data->term_taxonomy_id,'tax_product_cat',true,$sitepress->get_default_language());
55
+
56
+ return $data;
57
+ }
58
+
59
+ function woo_ce_tags($tags){
60
+ global $sitepress;
61
+
62
+ foreach($tags as $key=>$tag){
63
+ $tags[$key]->language = $sitepress->get_language_for_element($tag->term_taxonomy_id,'tax_product_tag');
64
+ $tags[$key]->translation_of = apply_filters( 'translate_object_id',$tag->term_taxonomy_id,'tax_product_tag',true,$sitepress->get_default_language());
65
+ }
66
+
67
+ return $tags;
68
+ }
69
+
70
+ }
compatibility/class-wcml-wpseo.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_WPSEO{
4
+
5
+ function __construct(){
6
+
7
+ add_filter( 'wcml_product_content_label', array( $this, 'wpseo_custom_field_label' ), 10, 2 );
8
+
9
+ if( defined( 'WPSEO_VERSION') && defined( 'WPSEO_PATH' ) && isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'wpml-wcml' && isset( $_GET[ 'tab' ] ) && $_GET[ 'tab' ] == 'products' ){
10
+ if( version_compare( WPSEO_VERSION, '3', '<' ) ) {
11
+ require_once WPSEO_PATH . 'admin/class-metabox.php';
12
+ } elseif( file_exists( WPSEO_PATH . 'admin/metabox/class-metabox.php' ) ) {
13
+ require_once WPSEO_PATH . 'admin/metabox/class-metabox.php';
14
+ }
15
+ }
16
+
17
+ }
18
+
19
+ function wpseo_custom_field_label( $field, $product_id ){
20
+ global $woocommerce_wpml, $wpseo_metabox;
21
+
22
+ $yoast_seo_fields = array( '_yoast_wpseo_focuskw', '_yoast_wpseo_title', '_yoast_wpseo_metadesc' );
23
+
24
+ if ( !is_array( maybe_unserialize( get_post_meta( $product_id, $field, true ) ) ) ) {
25
+
26
+ if ( !is_null( $wpseo_metabox ) && in_array( $field, $yoast_seo_fields ) ) {
27
+
28
+ $wpseo_metabox_values = $wpseo_metabox->get_meta_boxes( 'product' );
29
+
30
+ $label = $wpseo_metabox_values[ str_replace( '_yoast_wpseo_', '', $field ) ][ 'title' ];
31
+
32
+ return $label;
33
+ }
34
+ }
35
+
36
+ return $field;
37
+ }
38
+
39
+
40
+ }
41
+
compatibility/{assets → res}/css/wcml-bookings.css RENAMED
@@ -1,53 +1,60 @@
1
- .wcml_custom_cost_field{
2
- display: none;
3
- clear: both;
4
- }
5
-
6
- .wcml_bookings_range_block,
7
- .wcml_bookings_person_block,
8
- .wcml_bookings_resource_block{
9
- padding: 5px 0;
10
- display: -webkit-flex;
11
- display: flex;
12
- display: -moz-box;
13
- -webkit-flex-direction: row;
14
- flex-direction: row;
15
- }
16
-
17
- .wcml_bookings_range_block label,
18
- .wcml_bookings_person_block label,
19
- .wcml_bookings_resource_block label{
20
- width: auto;
21
- margin: 0;
22
- padding: 6px 7px;
23
- }
24
-
25
- .wcml_wc_booking_cost_field label,
26
- .wcml_wc_booking_base_cost_field label,
27
- .wcml_wc_display_cost_field label{
28
- text-align: right;
29
- margin-left: -160px;
30
- }
31
-
32
- .wcml_custom_costs{
33
- padding: 9px 9px 0;
34
- display: inline-block;
35
- width: 100%;
36
- }
37
-
38
- .wcml_custom_costs label{
39
- width: auto;
40
- margin: 0;
41
- float: left;
42
- }
43
-
44
- .wcml_custom_costs input{
45
- width: 16px;
46
- clear: both;
47
- margin: 2px 5px 2px 0;
48
- float: left;
49
- }
50
- input.wcml_bookings_custom_price,
51
- #bookings_pricing .table_grid table td input.wcml_bookings_custom_price{
52
- background-color: #F5F2E1;
 
 
 
 
 
 
 
53
  }
1
+ .wcml_custom_cost_field{
2
+ display: none;
3
+ clear: both;
4
+ }
5
+
6
+ .wcml_bookings_range_block,
7
+ .wcml_bookings_person_block,
8
+ .wcml_bookings_resource_block{
9
+ padding: 5px 0;
10
+ display: -webkit-flex;
11
+ display: flex;
12
+ display: -moz-box;
13
+ -webkit-flex-direction: row;
14
+ flex-direction: row;
15
+ }
16
+
17
+ .wcml_bookings_range_block label,
18
+ .wcml_bookings_person_block label,
19
+ .wcml_bookings_resource_block label{
20
+ width: auto;
21
+ margin: 0;
22
+ padding: 6px 7px;
23
+ }
24
+
25
+ .wcml_wc_booking_cost_field label,
26
+ .wcml_wc_booking_base_cost_field label,
27
+ .wcml_wc_display_cost_field label{
28
+ text-align: right;
29
+ margin-left: -160px;
30
+ }
31
+
32
+ .wcml_custom_costs{
33
+ padding: 9px 9px 0;
34
+ display: inline-block;
35
+ width: 100%;
36
+ }
37
+
38
+ #bookings_pricing .wcml_custom_costs label{
39
+ width: auto;
40
+ margin: 0 5px;
41
+ float: left;
42
+ }
43
+
44
+ #bookings_pricing .wcml_custom_cost_field label,
45
+ #bookings_resources .woocommerce_booking_resource .wcml_bookings_resource_block label{
46
+ width: 20px;
47
+ margin: 0 5px;
48
+ float: left;
49
+ }
50
+
51
+ .wcml_custom_costs input{
52
+ width: 16px;
53
+ clear: both;
54
+ margin: 2px 5px 2px 0;
55
+ float: left;
56
+ }
57
+ input.wcml_bookings_custom_price,
58
+ #bookings_pricing .table_grid table td input.wcml_bookings_custom_price{
59
+ background-color: #F5F2E1;
60
  }
compatibility/res/js/wcml-adventure-tours.js ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery( document ).ready( function( $ ){
2
+
3
+
4
+ $( '.wcml_custom_cost_field').each( function(){
5
+
6
+ var tour_id = $(this).attr('data-tour');
7
+
8
+ $('input[name="tour-booking-row['+tour_id+'][spec_price]"]').after( $(this) );
9
+
10
+ if( $( '.wcml_custom_prices_input:checked' ).val() == 1 ){
11
+ $(this).show();
12
+ }
13
+
14
+ });
15
+
16
+ $(document).on( 'change', '.wcml_custom_prices_input', function(){
17
+
18
+ if( $(this).val() == 1 ){
19
+
20
+ $( '.wcml_custom_cost_field' ).show();
21
+
22
+ }else{
23
+
24
+ $( '.wcml_custom_cost_field' ).hide();
25
+
26
+ }
27
+
28
+ });
29
+
30
+ });
31
+
compatibility/res/js/wcml-bookings.js ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery( document ).ready( function( $ ){
2
+
3
+ if( $( '.wcml_custom_costs_input:checked' ).val() == 1 ){
4
+
5
+ $( '.wcml_custom_cost_field' ).show();
6
+
7
+ }
8
+
9
+ $(document).on( 'change', '.wcml_custom_costs_input', function(){
10
+
11
+ if( $(this).val() == 1 ){
12
+
13
+ $( '.wcml_custom_cost_field' ).show();
14
+
15
+ }else{
16
+
17
+ $( '.wcml_custom_cost_field' ).hide();
18
+
19
+ }
20
+
21
+ });
22
+
23
+ $(document).on( 'mouseout', '.add_row', function(){
24
+
25
+ if( $( '.wcml_custom_costs_input:checked' ).val() == 1 ) {
26
+
27
+ $( '.wcml_custom_cost_field' ).show();
28
+
29
+ }
30
+
31
+ });
32
+
33
+ $(document).on( 'mouseout', '.add_person', function(){
34
+
35
+ if( $( '.wcml_custom_costs_input:checked' ).val() == 1 ) {
36
+
37
+ setTimeout(
38
+ function() {
39
+ $( '.wcml_custom_cost_field' ).show();
40
+ }, 3000);
41
+
42
+ }
43
+
44
+ });
45
+
46
+
47
+ //lock fields
48
+ if( typeof lock_settings != 'undefined' && typeof lock_settings.lock_fields != 'undefined' && lock_settings.lock_fields == 1 ){
49
+
50
+ $('#bookings_pricing input[type="number"],' +
51
+ '#accommodation_bookings_rates input[type="number"], ' +
52
+ '#bookings_resources input[type="number"], ' +
53
+ '#bookings_availability input[type="number"], ' +
54
+ '#bookings_availability input[type="time"], ' +
55
+
56
+ '#bookings_persons input[type="number"]').each(function(){
57
+ $(this).attr('readonly','readonly');
58
+ $(this).after($('.wcml_lock_img').clone().removeClass('wcml_lock_img').show());
59
+ });
60
+
61
+ var buttons = [ 'add_resource', 'add_row','remove_booking_resource','remove_booking_person','add_person' ];
62
+
63
+ for (i = 0; i < buttons.length; i++) {
64
+ $('.'+buttons[i]).attr('disabled','disabled');
65
+ $('.'+buttons[i]).unbind('click');
66
+ $('.'+buttons[i]).after($('.wcml_lock_img').clone().removeClass('wcml_lock_img').show());
67
+ }
68
+ $('.add_row').removeAttr('data-row');
69
+
70
+ $('form#post input[type="submit"]').click(function(){
71
+
72
+ for (i = 0; i < non_standard_fields.ids.length; i++) {
73
+ $('#'+non_standard_fields.ids[i]).removeAttr('disabled');
74
+ }
75
+
76
+ $('#bookings_pricing select, #bookings_resources select, #bookings_availability select,#bookings_persons input[type="checkbox"]').each(function(){
77
+ $(this).removeAttr('disabled');
78
+ });
79
+
80
+ });
81
+
82
+
83
+ }
84
+ });
85
+
compatibility/templates/bundles_box.php DELETED
@@ -1,61 +0,0 @@
1
- <?php if(!isset($template_data['empty_bundles'])){ ?>
2
- <td>
3
- <button id="prod_bundles_link_<?php echo $lang ?>" class="button-secondary js-table-toggle prod_bundles_link<?php if($is_duplicate_product): ?> js-dup-disabled<?php endif;?>" data-text-opened="<?php _e('Collapse', 'woocommerce-multilingual'); ?>" data-text-closed="<?php _e('Expand', 'woocommerce-multilingual'); ?>"<?php if($is_duplicate_product): ?> disabled="disabled"<?php endif;?>>
4
- <span><?php _e('Expand', 'woocommerce-multilingual'); ?></span>
5
- <i class="icon-caret-down"></i>
6
- </button>
7
- <?php $bundles_ids = $template_data['product_bundles']; ?>
8
-
9
- <table id="prod_bundles_<?php echo $lang ?>" class="widefat prod_variations js-table">
10
- <tbody>
11
- <tr>
12
- <td></td>
13
- <?php if(!isset($template_data['empty_bundles']) && isset( $template_data['bundles_data'] )): ?>
14
- <?php foreach($template_data['bundles_data'] as $bundle_original_title=>$bundle_opts): ?>
15
- <td>
16
- <?php echo $bundle_original_title; ?>
17
- </td>
18
- <?php endforeach; ?>
19
- <?php endif; ?>
20
- </tr>
21
- <?php if(isset($template_data['empty_bundles'])): ?>
22
- <tr>
23
- <td><?php _e('Please set bundles for product', 'woocommerce-multilingual'); ?></td>
24
- </tr>
25
- <?php elseif(isset($template_data['empty_translation'])): ?>
26
- <tr>
27
- <td><?php _e('Please save translation before translate bundles texts', 'woocommerce-multilingual'); ?></td>
28
- </tr>
29
- <?php else: ?>
30
- <?php $texts = array('bundle_title','bundle_desc'); ?>
31
- <?php foreach($texts as $text): ?>
32
- <tr>
33
- <td>
34
- <?php if($text == 'bundle_title'): ?>
35
- <?php _e('Title', 'woocommerce-multilingual'); ?>
36
- <?php else: ?>
37
- <?php _e('Description', 'woocommerce-multilingual'); ?>
38
- <?php endif; ?>
39
- </td>
40
- <?php $i = 0; ?>
41
- <?php foreach($template_data['bundles_data'] as $bundle_id=>$bundle_opts): ?>
42
- <?php if(!empty($bundle_opts)): ?>
43
- <td>
44
- <?php if($template_data['original']): ?>
45
- <input type="text" value="<?php echo $bundle_opts[$text]?>" readonly="readonly"/>
46
- <?php else: ?>
47
- <input type="text" name="bundles[<?php echo $bundles_ids[$i] ?>][<?php echo $text; ?>]" value="<?php echo $bundle_opts[$text]?>" placeholder="<?php esc_attr_e('Enter translation', 'woocommerce-multilingual') ?>"/>
48
- <?php endif; ?>
49
- </td>
50
-
51
- <?php endif; ?>
52
- <?php $i++; ?>
53
- <?php endforeach; ?>
54
- </tr>
55
-
56
- <?php endforeach; ?>
57
- <?php endif; ?>
58
- </tbody>
59
- </table>
60
- </td>
61
- <?php } ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
compatibility/templates/wc_bookings_custom_box_html.php DELETED
@@ -1,30 +0,0 @@
1
- <?php if( isset( $template_data[ 'resources' ] ) ): ?>
2
- <?php foreach( $template_data[ 'resources' ] as $original_resource_id => $trnsl_resource_id ): ?>
3
- <tr>
4
- <td>
5
- <?php if( !$template_data[ 'original' ] ): ?>
6
- <input type="hidden" name="<?php echo $template_data[ 'product_content' ].'_'.$template_data['lang'].'[id][]'; ?>" value="<?php echo $trnsl_resource_id; ?>" />
7
- <?php if( empty( $trnsl_resource_id ) ): ?>
8
- <input type="hidden" name="<?php echo $template_data[ 'product_content' ].'_'.$template_data['lang'].'[orig_id][]'; ?>" value="<?php echo $original_resource_id; ?>" />
9
- <?php endif;?>
10
- <?php endif;?>
11
- <textarea rows="1" <?php if( !$template_data['original'] ): ?>name="<?php echo $template_data['product_content'].'_'.$template_data['lang'].'[title][]'; ?>"<?php endif;?> <?php if( $template_data['original'] ): ?> disabled="disabled"<?php endif;?>><?php echo $template_data[ 'original' ]? get_the_title( $original_resource_id ): get_the_title( $trnsl_resource_id ); ?></textarea>
12
- </td>
13
- </tr>
14
- <?php endforeach; ?>
15
- <?php elseif( isset( $template_data[ 'persons' ] ) ): ?>
16
- <?php foreach( $template_data[ 'persons' ] as $original_person_id => $trnsl_person_id ): ?>
17
- <tr>
18
- <td>
19
- <?php if( !$template_data[ 'original' ] ): ?>
20
- <input type="hidden" name="<?php echo $template_data[ 'product_content' ].'_'.$template_data['lang'].'[id][]'; ?>" value="<?php echo $trnsl_person_id; ?>" />
21
- <?php if( empty( $trnsl_person_id ) ): ?>
22
- <input type="hidden" name="<?php echo $template_data[ 'product_content' ].'_'.$template_data['lang'].'[orig_id][]'; ?>" value="<?php echo $original_person_id; ?>" />
23
- <?php endif;?>
24
- <?php endif;?>
25
- <textarea rows="1" <?php if( !$template_data['original'] ): ?>name="<?php echo $template_data['product_content'].'_'.$template_data['lang'].'[title][]'; ?>"<?php endif;?> <?php if( $template_data['original'] ): ?> disabled="disabled"<?php endif;?>><?php echo $template_data[ 'original' ]? get_the_title( $original_person_id ): get_the_title( $trnsl_person_id ); ?></textarea>
26
- <textarea rows="1" <?php if( !$template_data['original'] ): ?>name="<?php echo $template_data['product_content'].'_'.$template_data['lang'].'[description][]'; ?>"<?php endif;?> <?php if( $template_data['original'] ): ?> disabled="disabled"<?php endif;?>><?php echo $template_data[ 'original' ]? get_post( $original_person_id )->post_excerpt: $template_data[ 'translation_exist' ] ? get_post( $trnsl_person_id )->post_excerpt : ''; ?></textarea>
27
- </td>
28
- </tr>
29
- <?php endforeach; ?>
30
- <?php endif; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
compatibility/templates/wc_tab_manager_custom_box_html.php DELETED
@@ -1,60 +0,0 @@
1
- <?php if(isset($template_data['orig_tabs'])): ?>
2
- <?php foreach($template_data['orig_tabs'] as $key=>$values):
3
- $trnsl_tab_id = isset($template_data['tr_tabs'][$key]['id'])?$template_data['tr_tabs'][$key]['id']:'';
4
- $orig_tab_id = $template_data['orig_tabs'][$key]['id'];
5
- ?>
6
- <tr>
7
- <td>
8
- <?php if($values['type'] == 'product'): ?>
9
- <?php if(!$template_data['original']): ?>
10
- <input type="hidden" name="<?php echo $template_data['product_content'].'_'.$template_data['lang'].'[id][]'; ?>" value="<?php echo $trnsl_tab_id; ?>" />
11
- <?php endif;?>
12
- <textarea rows="1" <?php if(!$template_data['original']): ?>name="<?php echo $template_data['product_content'].'_'.$template_data['lang'].'[title][]'; ?>"<?php endif;?> <?php if($template_data['original']): ?> disabled="disabled"<?php endif;?>><?php echo $template_data['original']?get_the_title($orig_tab_id):get_the_title($trnsl_tab_id); ?></textarea>
13
- <?php else: ?>
14
- <textarea rows="1" <?php if(!$template_data['original']): ?>name="<?php echo $template_data['product_content'].'_'.$template_data['lang'].'[core_title]['.$key.']'; ?>"<?php endif;?> <?php if($template_data['original']): ?> disabled="disabled"<?php endif;?>><?php echo isset($template_data['tr_tabs'][$key]['title']) ? $template_data['tr_tabs'][$key]['title'] : ''; ?></textarea>
15
- <?php endif; ?>
16
- </td>
17
- <td>
18
- <?php if($values['type'] == 'core'): ?>
19
- <textarea rows="1" <?php if(!$template_data['original']): ?>name="<?php echo $template_data['product_content'].'_'.$template_data['lang'].'[core_heading]['.$key.']'; ?>"<?php endif;?> <?php if($template_data['original']): ?> disabled="disabled"<?php endif;?>><?php echo isset($template_data['tr_tabs'][$key]['heading']) ? $template_data['tr_tabs'][$key]['heading'] : ''; ?></textarea>
20
- <?php else: ?>
21
- <?php if($template_data['original']): ?>
22
- <button type="button" class="button-secondary wcml_edit_content origin_content"><?php _e('Show content', 'woocommerce-multilingual') ?></button>
23
- <?php else: ?>
24
- <button type="button" class="button-secondary wcml_edit_content<?php if($template_data['is_duplicate_product']): ?> js-dup-disabled<?php endif;?>"<?php if($template_data['is_duplicate_product']): ?> disabled="disabled"<?php endif;?>><?php _e('Edit translation', 'woocommerce-multilingual') ?></button>
25
- <?php endif;?>
26
- <div class="wcml_editor">
27
- <a class="media-modal-close wcml_close_cross" href="javascript:void(0);" title="<?php esc_attr_e('Close', 'woocommerce-multilingual') ?>"><span class="media-modal-icon"></span></a>
28
- <div class="wcml_editor_original">
29
- <h3><?php _e('Original content:', 'woocommerce-multilingual') ?></h3>
30
- <textarea class="wcml_original_content"><?php echo get_post($orig_tab_id)->post_content; ?></textarea>
31
- </div>
32
- <div class="wcml_line"></div>
33
- <div class="wcml_editor_translation">
34
- <?php if(!$template_data['original']): ?>
35
- <?php
36
- if($trnsl_tab_id){
37
- $content = get_post($trnsl_tab_id)->post_content;
38
- }else{
39
- $content = '';
40
- }
41
-
42
- wp_editor($content, 'wcmleditor'.$template_data['product_content'].$key.$template_data['lang'], array('textarea_name'=>$template_data['product_content'] .
43
- '_'.$template_data['lang'].'[content][]','textarea_rows'=>20,'editor_class'=>'wcml_content_tr')); ?>
44
- <?php endif; ?>
45
- </div>
46
- <div class="wcml_editor_buttons">
47
- <?php if($template_data['original']): ?>
48
- <button type="button" class="button-secondary wcml_popup_close"><?php _e('Close', 'woocommerce-multilingual') ?></button>
49
- <?php else: ?>
50
- <h3><?php printf(__('%s translation', 'woocommerce-multilingual'),$template_data['lang_name']); ?></h3>
51
- <button type="button" class="button-secondary wcml_popup_cancel"><?php _e('Cancel', 'woocommerce-multilingual') ?></button>
52
- <button type="button" class="button-secondary wcml_popup_ok"><?php _e('Ok', 'woocommerce-multilingual') ?></button>
53
- <?php endif; ?>
54
- </div>
55
- </div>
56
- <?php endif; ?>
57
- </td>
58
- </tr>
59
- <?php endforeach; ?>
60
- <?php endif; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
compatibility/templates/woocommerce-composite-products.php DELETED
@@ -1,35 +0,0 @@
1
- <td>
2
- <button id="wc_composite_link_<?php echo $lang ?>" class="button-secondary js-table-toggle wc_composite_link<?php if($is_duplicate_product): ?> js-dup-disabled<?php endif;?>" data-text-opened="<?php _e('Collapse', 'woocommerce-multilingual'); ?>" data-text-closed="<?php _e('Expand', 'woocommerce-multilingual'); ?>"<?php if($is_duplicate_product): ?> disabled="disabled"<?php endif;?>>
3
- <span><?php _e('Expand', 'woocommerce-multilingual'); ?></span>
4
- <i class="icon-caret-down"></i>
5
- </button>
6
-
7
- <table id="prod_wc_composite_<?php echo $lang ?>" class="widefat prod_variations js-table">
8
-
9
- <tbody>
10
-
11
- <?php $disabled = $template_data['wc_composite_components']['_is_original'] ? ' disabled="disabled"' : ''; ?>
12
- <?php foreach($template_data['wc_composite_components']['components'] as $key => $component): ?>
13
- <tr>
14
- <td>
15
- <label><?php _e('Title', 'woocommerce-multilingual'); ?>&nbsp;
16
- <textarea rows="1" name="wc_composite_component[<?php echo $key ?>][title]"<?php echo $disabled ?>><?php echo esc_attr( $component['title'] ) ?></textarea>
17
- </label>
18
- </td>
19
- <td>
20
- <label><?php _e('Description', 'woocommerce-multilingual'); ?>&nbsp;
21
- <textarea rows="1" name="wc_composite_component[<?php echo $key ?>][description]"<?php echo $disabled ?>><?php echo esc_attr( $component['description'] ) ?></textarea>
22
- </label>
23
- </td>
24
- </tr>
25
- <?php endforeach ?>
26
-
27
- </tbody>
28
-
29
- </table>
30
-
31
- </td>
32
-
33
-
34
-
35
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/installer/changelog.txt ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ = 1.7.8 =
2
+ * Small fix for hiding the WPML registration notice
3
+
4
+ = 1.7.7 =
5
+ * Fixed js error showing up during registration
6
+ * Styles update for unified WPML messages
7
+
8
+ = 1.7.6 =
9
+ * Updated error messages when validating site keys and stopped removing site keys in case of communication errors
10
+ * Added a note for users who renewed or purchased new subscriptions and who need to revalidate their subscription from their websites
11
+ * Fixed a problem with the registrations for multi-site setups when WordPress was installed in a separate folder
12
+
13
+ = 1.7.5 =
14
+ * Fixed a bug causing registration to not be recognized for the entire network in the multi-site mode
15
+
16
+ = 1.7.4 =
17
+ * Use https for wp-types API
18
+
19
+ = 1.7.3 =
20
+ * Added a dependencies class and check for the windows paths length exception
21
+ * Bug fix: all downloads showed up twice on the plugins list whe upgrading from WPML 3.3
22
+
23
+ = 1.7.2 =
24
+ * Added an exception to handle the case when Types embedded is installer from Toolset Installer and its included Installer version overrides the one running the Toolset setup wizard
25
+
26
+ = 1.7.1 =
27
+ * Added an exception for the case of Types 1.8.9 (Installer 1.7.0) together with older WPML (older Installer)
28
+
29
+ = 1.7.0 =
30
+ * New format for the products data file.
31
+ * Other fixes
32
+
33
+ = 1.6.8 =
34
+ * Sanitized an input that was a potential security issue
35
+
36
+ = 1.6.7 =
37
+ * Fixed a bug causing repeated calls to the Toolset api to validate the user subscription
38
+ * Use https for API urls
39
+
40
+ = 1.6.6 =
41
+ * Fixed the 'Call to undefined function get_plugins()' issue
42
+
43
+ = 1.6.5 =
44
+ * Added configuration file for composer
45
+ * Updated how free plugins are shown on the plugins list (commercial tab)
46
+ * API calls for manipulating translation service preferences
47
+ * Support for hosting custom Installer packages on wpml.org
48
+ * Fixed a warning that was showing when using the OTGS_DISABLE_AUTO_UPDATES constant before any product data was downloaded
49
+ * Changed the frequency with which product updates are checked automatically (24 hours)
50
+ * Improved reporting for version numbers
51
+
52
+ = 1.6.4 =
53
+ * Enabled the OTGS_DISABLE_AUTO_UPDATES constant for theme update checks
54
+ * Fixed a bug that was causing Register links to show for all installed plugins
55
+
56
+ = 1.6.3 =
57
+ * Fixed performance issue related to themes upgrade logic
58
+
59
+ = 1.6 =
60
+ * Improved the way plugins are matched: not just by the folder name (slug) but also by name
61
+ * Added support for installing and upgrading themes from repositories (currently: Toolset themes)
62
+ * Added support for 'alias' plugins on the toolset and wpml repositories (currently: Types)
63
+ * Enhanced the progress animation during plugins downloading
64
+
65
+ = 1.5.6 =
66
+ * Updated the translations
67
+ * Fix for WPML 3.2 conditional upgrade logic
68
+
69
+ = 1.5.5 =
70
+ * Fixed the logic for the high_priority parameter
71
+ * Fixed js bug causing a conflict with NextGen
72
+ * Fixed bug preventing users to install and upgrade Types when they didn't have a Toolset subscription
73
+ * Fixed bug preventing users to upgrade from the embedded Types to the full version
74
+
75
+ = 1.5.4 =
76
+ * Option to disable auto-updates
77
+ * Escaped urls generated with add_query_arg
78
+
79
+ = 1.5.3 =
80
+ * Fixed bug in WP_Installer::custom_plugins_api_call (filter for plugins_api) causing conflicts with other filters for plugins_api
81
+
82
+ = 1.5.2 =
83
+ * More meaningful errors when plugin downloads fail
84
+ * WordPress 4.2 compatibility
85
+ * Performance improvements (will not load in places where it's not needed and not make unnecessary requests to the CDN)
86
+ * Support putting deps.xml config file in the theme folder (root)
87
+ * Included code for importing data for toolset plugins
88
+ * Use CloudFront urls for products list files
89
+
90
+ = 1.5.1 =
91
+ * Fix for allowing embedded plugins to be updated
92
+ * Logic for the migration from embedded plugins to full plugins
93
+
94
+ = 1.5 =
95
+ * Support for embedded plugins
96
+ * Bug fix: When user registers site key with trailing slash, downloads might not work
97
+ * Tweak: Set a higher timeout limit for the http requests to CDN and API
98
+ * API function: link to specific repository
99
+ * API function: get product price
100
+ * New method for defining affiliate info (with backwards compatibility)
101
+
102
+ = 1.4 =
103
+ * Show explicit error in case of connectivity issues while validating a key.
104
+ * Bug fix: Downloading plugins in bulk was broken by plugin that had a redirect after activation
105
+ * Display friendly error message when WordPress does not have permissions to write to the plugins folder
106
+ * Added support for configuration files to auto-download required plugins and theme keys
107
+ * Changed the "Update this info" button to "Check for updates" (it refreshes the subscription info and checks for updates)
108
+ * Support for high_priority parameter that allows setting priority for an Installer instance when more with the same version number exist.
109
+ * Config files from different instances are combined (define repositories in different instances)
110
+ * Updated support for conditional updates display for ICL users
111
+ * More friendly error reporting and handling when using an invalid site key or the plugins archives are not valid.
112
+
113
+
114
+ = 1.3.1 =
115
+ * Support for conditional release notification (ICanLocalize)
116
+
117
+ = 1.3 =
118
+ * Added a new repository: Toolset
119
+ * The product packages can be displayed hierarchically and ordered
120
+ * The link to automatically create site keys will follow through login on the account site (e.g. wpml.org, wp-types.com)
121
+ * Fixed animation issues (not showing in most browsers) when downloading plugins.
122
+ * Created an admin screen on the repository end (icl-mpp) to sho registration stats (site keys, site keys usage, components usage etc..).
123
+ * Bug fix: Renew and Upgrade buttons were not entirely clickable
124
+ * Bug fix: Action buttons (buy, renew, upgrade) were not displayed correctly when WPML was not active (Installer embedded in theme)
125
+ * Support for site-wide registration. Products can be registered on the network instead of on each site separately.
126
+ * Users are able to add either http or https version for any site urls. There will be one site key that will work with both http and https versions.
127
+
128
+ = 1.2 =
129
+ * Added pagination for site keys list of Account -> My Sites
130
+ * Reversed the order in which the site keys are displayed.
131
+ * Fixed problem with WPML registration information (site key) not being saved when the option_value field in the wp_options table used a different charset than the default WordPress charset defined in wp-config.php
132
+ * Allow registering new sites by clicking a link in the WordPress admin instead of copying and pasting the site url in the Account -> My Sites section
133
+ * Display more detailed debug information related to connectivity issues with the WPML repository
embedded/installer/composer.json ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "otgs/installer",
3
+ "description": "Installs and updates WPML and Toolset dependencies automatically",
4
+ "keywords": ["plugins", "install", "utils", "update"],
5
+ "homepage": "https://git.onthegosystems.com/installer/installer",
6
+ "type": "wordpress-plugin",
7
+ "license": "GPL-2.0",
8
+ "authors": [
9
+ {
10
+ "name": "Mihai Grigori",
11
+ "email": "mihai@wpml.org",
12
+ "homepage": "http://www.wp-types.com"
13
+ }
14
+ ],
15
+ "require": {
16
+ "php": ">=5.2.0",
17
+ "composer/installers": "~1.0"
18
+ },
19
+ "require-dev": {
20
+ "phpunit/phpunit": "~4.5"
21
+ },
22
+ "extra": {
23
+ "branch-alias": {
24
+ "dev-master": "1.7.x-dev",
25
+ "dev-develop": "1.7.x-dev"
26
+ }
27
+ },
28
+ "scripts": {
29
+ "test": "phpunit"
30
+ }
31
+ }
embedded/installer/includes/class-installer-dependencies.php ADDED
@@ -0,0 +1,278 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Installer_Dependencies{
4
+
5
+ private $uploading_allowed = null;
6
+ private $is_win_paths_exception = array();
7
+
8
+
9
+ function __construct(){
10
+
11
+ add_action( 'admin_init', array( $this, 'prevent_plugins_update_on_plugins_page' ), 100);
12
+
13
+
14
+
15
+ global $pagenow;
16
+ if($pagenow == 'update.php'){
17
+ if(isset($_GET['action']) && $_GET['action'] == 'update-selected'){
18
+ add_action('admin_head', array($this, 'prevent_plugins_update_on_updates_screen')); //iframe/bulk
19
+ }else{
20
+ add_action('all_admin_notices', array($this, 'prevent_plugins_update_on_updates_screen')); //regular/singular
21
+ }
22
+ }
23
+ add_action('wp_ajax_update-plugin', array($this, 'prevent_plugins_update_on_updates_screen'), 0); // high priority, before WP
24
+
25
+ }
26
+
27
+ public function is_win_paths_exception($repository_id){
28
+
29
+ if(!isset($this->is_win_paths_exception[$repository_id])) {
30
+
31
+ $this->is_win_paths_exception[$repository_id] = false;
32
+
33
+ if ( strtoupper( substr( PHP_OS, 0, 3 ) ) === 'WIN' ) {
34
+
35
+ $windows_max_path_length = 256;
36
+ $longest_path['wpml'] = 109;
37
+ $longest_path['toolset'] = 99;
38
+
39
+ $margin = 15;
40
+
41
+ $upgrade_path_length = strlen( WP_CONTENT_DIR . '/upgrade' );
42
+
43
+ $installer_settings = WP_Installer()->settings;
44
+
45
+ if ( is_array( $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'] ) ) {
46
+ $a_plugin = current( $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'] );
47
+ $url = WP_Installer()->append_site_key_to_download_url( $a_plugin['url'], 'xxxxxx', $repository_id );
48
+ $tmpfname = wp_tempnam( $url );
49
+
50
+ $tmpname_length = strlen( basename( $tmpfname ) ) - 4; // -.tmp
51
+
52
+ if ( $upgrade_path_length + $tmpname_length + $longest_path[$repository_id] + $margin > $windows_max_path_length ) {
53
+
54
+ $this->is_win_paths_exception[$repository_id] = true;
55
+
56
+ }
57
+
58
+ }
59
+
60
+
61
+ }
62
+
63
+ }
64
+
65
+ return $this->is_win_paths_exception[$repository_id];
66
+
67
+ }
68
+
69
+ public function is_uploading_allowed(){
70
+
71
+ if(!isset($this->uploading_allowed)){
72
+ require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
73
+ require_once WP_Installer()->plugin_path() . '/includes/installer-upgrader-skins.php';
74
+
75
+ $upgrader_skins = new Installer_Upgrader_Skins(); //use our custom (mute) Skin
76
+ $upgrader = new Plugin_Upgrader($upgrader_skins);
77
+
78
+ ob_start();
79
+ $res = $upgrader->fs_connect( array(WP_CONTENT_DIR, WP_PLUGIN_DIR) );
80
+ ob_end_clean();
81
+
82
+ if ( ! $res || is_wp_error( $res ) ) {
83
+ $this->uploading_allowed = false;
84
+ }else{
85
+ $this->uploading_allowed = true;
86
+ }
87
+ }
88
+
89
+ return $this->uploading_allowed;
90
+
91
+ }
92
+
93
+ public function cant_download($repository_id){
94
+
95
+ return !$this->is_uploading_allowed() || $this->is_win_paths_exception($repository_id);
96
+
97
+ }
98
+
99
+ public function win_paths_exception_message(){
100
+ return __('Downloading is not possible. WordPress cannot create required folders because of the
101
+ 256 characters limitation of the current Windows environment.', 'installer');
102
+ }
103
+
104
+ public function prevent_plugins_update_on_plugins_page(){
105
+
106
+ $plugins = get_site_transient( 'update_plugins' );
107
+ if ( isset($plugins->response) && is_array($plugins->response) ) {
108
+ $plugins_with_updates = array_keys( $plugins->response );
109
+ }
110
+
111
+ if( !empty($plugins_with_updates) ) {
112
+
113
+ $plugins = get_plugins();
114
+
115
+ $installer_settings = WP_Installer()->settings;
116
+ foreach ($installer_settings['repositories'] as $repository_id => $repository) {
117
+
118
+ if ($this->is_win_paths_exception($repository_id)) {
119
+
120
+ $repositories_plugins = array();
121
+ foreach ($repository['data']['packages'] as $package) {
122
+ foreach ($package['products'] as $product) {
123
+ foreach ($product['plugins'] as $plugin_slug) {
124
+ $download = $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
125
+ if ( empty($download['free-on-wporg']) ) {
126
+ $repositories_plugins[$download['slug']] = $download['name'];
127
+ }
128
+ }
129
+ }
130
+ }
131
+
132
+ foreach ($plugins as $plugin_id => $plugin) {
133
+
134
+ if( in_array( $plugin_id, $plugins_with_updates ) ) {
135
+
136
+ $wp_plugin_slug = dirname($plugin_id);
137
+ if (empty($wp_plugin_slug)) {
138
+ $wp_plugin_slug = basename($plugin_id, '.php');
139
+ }
140
+
141
+ foreach ($repositories_plugins as $slug => $name) {
142
+ if ($wp_plugin_slug == $slug || $name == $plugin['Name'] || $name == $plugin['Title']) { //match order: slug, name, title
143
+
144
+ remove_action("after_plugin_row_$plugin_id", 'wp_plugin_update_row', 10, 2);
145
+ add_action("after_plugin_row_$plugin_id", array($this, 'wp_plugin_update_row_win_exception'), 10, 2);
146
+
147
+ }
148
+ }
149
+
150
+ }
151
+
152
+ }
153
+
154
+ }
155
+
156
+
157
+ }
158
+
159
+ }
160
+
161
+ }
162
+
163
+ public function wp_plugin_update_row_win_exception(){
164
+ $wp_list_table = _get_list_table('WP_Plugins_List_Table');
165
+ echo '<tr class="plugin-update-tr">';
166
+ echo '<td class="plugin-update colspanchange" colspan="' . esc_attr( $wp_list_table->get_column_count() ) .
167
+ '"><div class="update-message">' . $this->win_paths_exception_message() . '</div></td>';
168
+ echo '</tr>';
169
+ }
170
+
171
+ public function prevent_plugins_update_on_updates_screen(){
172
+
173
+ if ( isset($_REQUEST['action']) ) {
174
+
175
+ $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
176
+
177
+ $installer_settings = WP_Installer()->settings;
178
+
179
+ //bulk mode
180
+ if('update-selected' == $action) {
181
+
182
+ global $plugins;
183
+
184
+ if(isset($plugins) && is_array($plugins)) {
185
+
186
+ foreach ($plugins as $k => $plugin) {
187
+
188
+ $wp_plugin_slug = dirname($plugin);
189
+
190
+ foreach ($installer_settings['repositories'] as $repository_id => $repository) {
191
+
192
+ if( $this->is_win_paths_exception($repository_id) ){
193
+
194
+ foreach ($repository['data']['packages'] as $package) {
195
+
196
+ foreach ($package['products'] as $product) {
197
+
198
+ foreach ($product['plugins'] as $plugin_slug) {
199
+
200
+ $download = $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
201
+
202
+ if ($download['slug'] == $wp_plugin_slug && empty($download['free-on-wporg']) ) {
203
+
204
+ echo '<div class="updated error"><p>' . $this->win_paths_exception_message() .
205
+ ' <strong>(' . $download['name'] . ')</strong>' . '</p></div>';
206
+ unset($plugins[$k]);
207
+
208
+ break(3);
209
+
210
+ }
211
+
212
+ }
213
+
214
+ }
215
+
216
+ }
217
+
218
+
219
+ }
220
+
221
+ }
222
+
223
+ }
224
+
225
+ }
226
+
227
+ }
228
+
229
+
230
+ if( 'upgrade-plugin' == $action || 'update-plugin' == $action ) {
231
+
232
+ $plugin = isset($_REQUEST['plugin']) ? trim($_REQUEST['plugin']) : '';
233
+
234
+ $wp_plugin_slug = dirname($plugin);
235
+
236
+ foreach($installer_settings['repositories'] as $repository_id => $repository){
237
+
238
+ if( $this->is_win_paths_exception( $repository_id ) ) {
239
+ foreach ($repository['data']['packages'] as $package) {
240
+
241
+ foreach($package['products'] as $product) {
242
+
243
+ foreach($product['plugins'] as $plugin_slug) {
244
+ $download = $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
245
+
246
+ //match by folder, will change to match by name and folder
247
+ if ( $download['slug'] == $wp_plugin_slug && empty ($download['free-on-wporg'] ) ) {
248
+
249
+ echo '<div class="updated error"><p>' . $this->win_paths_exception_message() . '</p></div>';
250
+
251
+ echo '<div class="wrap">';
252
+ echo '<h2>' . __('Update Plugin') . '</h2>';
253
+ echo '<a href="' . admin_url('update-core.php') . '">' . __('Return to the updates page', 'installer') . '</a>';
254
+ echo '</div>';
255
+ require_once(ABSPATH . 'wp-admin/admin-footer.php');
256
+ exit;
257
+
258
+ }
259
+
260
+ }
261
+
262
+ }
263
+
264
+ }
265
+ }
266
+
267
+ }
268
+
269
+ }
270
+ }
271
+
272
+ }
273
+
274
+
275
+ }
276
+
277
+
278
+
embedded/installer/includes/class-installer-theme.php ADDED
@@ -0,0 +1,979 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Installer Class for Theme Support
4
+ *
5
+ * Supports automatic updates and installation of Toolset/WPML Themes
6
+ *
7
+ * @class Installer_Theme_Class
8
+ * @version 1.6
9
+ * @category Class
10
+ * @author OnTheGoSystems
11
+ */
12
+
13
+ if ( !defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ /**
18
+ * Installer_Theme_Class
19
+ */
20
+ class Installer_Theme_Class {
21
+
22
+ /** Theme Repository */
23
+ private $theme_repo;
24
+
25
+ /** Repository API */
26
+ private $repository_api;
27
+
28
+ /** Repository Theme Products */
29
+ private $repository_theme_products;
30
+
31
+ /** Site URL */
32
+ private $installer_site_url;
33
+
34
+ /** Site Key */
35
+ private $installer_site_key;
36
+
37
+ /** The Themes Option */
38
+ protected $installer_themes_option;
39
+
40
+ /** Update settings */
41
+ protected $installer_themes_available_updates;
42
+
43
+ /** The Themes */
44
+ protected $installer_themes = array();
45
+
46
+ /** Repository with themes */
47
+ protected $installer_repo_with_themes;
48
+
49
+ /** Active tab */
50
+ protected $installer_theme_active_tab;
51
+
52
+ /** Theme user registration */
53
+ protected $theme_user_registration;
54
+
55
+ /** Client active subscription */
56
+ protected $installer_theme_subscription_type;
57
+
58
+ public function __construct() {
59
+
60
+ /** Properties */
61
+
62
+ //Get installer repositories
63
+ $installer_repositories = WP_Installer()->get_repositories();
64
+
65
+ //Get repos with themes
66
+ $repos_with_themes = $this->installer_theme_reposities_that_has_themes( $installer_repositories );
67
+
68
+ if ( is_array( $repos_with_themes ) ) {
69
+ //Assign to property
70
+ $this->installer_repo_with_themes = $repos_with_themes;
71
+
72
+ //Let's looped through repos with themes
73
+ foreach ( $repos_with_themes as $k => $repo ) {
74
+
75
+ //$repo could be 'toolset' or 'wpml'
76
+ //Assign each repo with theme to property
77
+ $this->theme_repo[] = $repo;
78
+
79
+ if ( (isset($installer_repositories[$repo]['api-url'])) && (isset($installer_repositories[$repo]['products'])) ) {
80
+
81
+ //Define the rest of the properties based on the given repo
82
+ $this->repository_api[$repo] = $installer_repositories[$repo]['api-url'];
83
+ $this->repository_theme_products[$repo] = $installer_repositories[$repo]['products'];
84
+ $this->installer_site_url[$repo] = WP_Installer()->get_installer_site_url( $repo );
85
+ $this->installer_site_key[$repo] = WP_Installer()->get_site_key( $repo );
86
+ $this->theme_user_registration[$repo] = false;
87
+
88
+ if ( WP_Installer()->repository_has_valid_subscription( $repo ) ) {
89
+
90
+ $this->installer_theme_subscription_type = WP_Installer()->get_subscription_type_for_repository( $repo );
91
+ $this->installer_themes_option[$repo] = 'wp_installer_' . $repo . '_themes';
92
+ $this->installer_themes_available_updates[$repo] = 'wp_installer_' . $repo . '_updated_themes';
93
+ $this->installer_theme_active_tab = '';
94
+
95
+ //We only set themes available to this validated subscription
96
+ $this->installer_theme_available( $repo, $this->installer_theme_subscription_type );
97
+
98
+ add_action( 'installer_themes_support_set_up', array($this, 'installer_theme_sets_active_tab_on_init'), 10 );
99
+ $this->theme_user_registration[$repo] = true;
100
+ }
101
+
102
+ /** We are ready.. let's initialize .... */
103
+ $this->init();
104
+ }
105
+ }
106
+ add_action( 'installer_themes_support_set_up', array($this, 'installer_theme_loaded_hooks') );
107
+ }
108
+ }
109
+
110
+ /** Init */
111
+ public function init() {
112
+ add_action( 'admin_enqueue_scripts', array($this, 'installer_theme_enqueue_scripts') );
113
+ add_filter( 'themes_api', array($this, 'installer_theme_api_override'), 10, 3 );
114
+ add_filter( 'themes_api_result', array($this, 'installer_theme_api_override_response'), 10, 3 );
115
+ add_filter( 'site_transient_update_themes', array($this, 'installer_theme_upgrade_check'), 10, 1 );
116
+ add_action( 'http_api_debug', array($this, 'installer_theme_sync_native_wp_api'), 10, 5 );
117
+ add_filter( 'installer_theme_hook_response_theme', array($this, 'installer_theme_add_num_ratings'), 10, 1 );
118
+ add_filter( 'themes_update_check_locales', array($this, 'installer_theme_sync_call_wp_theme_api'), 10, 1 );
119
+ add_filter( 'admin_url', array($this, 'installer_theme_add_query_arg_tab'), 10, 3 );
120
+ add_filter( 'network_admin_url', array($this, 'installer_theme_add_query_arg_tab'), 10, 2 );
121
+ add_action( 'wp_ajax_installer_theme_frontend_selected_tab', array($this, 'installer_theme_frontend_selected_tab'), 0 );
122
+ add_action( 'wp_loaded', array($this, 'installer_themes_support_set_up_func') );
123
+ }
124
+
125
+ /** Enqueue scripts */
126
+ public function installer_theme_enqueue_scripts() {
127
+ $current_screen = $this->installer_theme_current_screen();
128
+ $commercial_plugin_screen = $this->installer_theme_is_commercial_plugin_screen( $current_screen );
129
+ if ( ('theme-install' == $current_screen) || ($commercial_plugin_screen) || ('theme-install-network' == $current_screen) ) {
130
+ $repo_with_themes = $this->installer_repo_with_themes;
131
+ $js_array = array();
132
+ if ( is_array( $repo_with_themes ) ) {
133
+ foreach ( $repo_with_themes as $k => $v ) {
134
+
135
+ //Hyperlink text
136
+ $theme_repo_name = $this->installer_theme_get_repo_product_name( $v );
137
+ $the_hyperlink_text = esc_js( $theme_repo_name );
138
+
139
+ if ( is_multisite() ) {
140
+ $admin_url_passed = network_admin_url();
141
+ } else {
142
+ $admin_url_passed = admin_url();
143
+ }
144
+
145
+ //Define
146
+ $js_array[$v] = array(
147
+ 'the_hyperlink_text' => $the_hyperlink_text,
148
+ 'registration_status' => $this->theme_user_registration[$v],
149
+ 'is_commercial_plugin_tab' => $commercial_plugin_screen,
150
+ 'registration_url' => $admin_url_passed . 'plugin-install.php?tab=commercial#installer_repo_' . $v
151
+ );
152
+
153
+ }
154
+ }
155
+
156
+ if ( !(empty($js_array)) ) {
157
+ wp_enqueue_script( 'installer-theme-install', WP_Installer()->res_url() . '/res/js/installer_theme_install.js', array('jquery', 'installer-admin'), WP_Installer()->version() );
158
+ $installer_ajax_url = admin_url( 'admin-ajax.php' );
159
+
160
+ if ( is_ssl() ) {
161
+ $installer_ajax_url = str_replace( 'http://', 'https://', $installer_ajax_url );
162
+ } else {
163
+ $installer_ajax_url = str_replace( 'https://', 'http://', $installer_ajax_url );
164
+ }
165
+
166
+ //Case where user is subscribed to a subscription that does not have themes
167
+ $subscription_js_check = $this->installer_theme_subscription_does_not_have_theme( $js_array );
168
+
169
+ wp_localize_script( 'installer-theme-install', 'installer_theme_install_localize',
170
+ array(
171
+ 'js_array_installer' => $js_array,
172
+ 'ajaxurl' => $installer_ajax_url,
173
+ 'no_associated_themes' => $subscription_js_check,
174
+ 'installer_theme_frontend_selected_tab_nonce' => wp_create_nonce( 'installer_theme_frontend_selected_tab' )
175
+ )
176
+ );
177
+ }
178
+ }
179
+ }
180
+
181
+ /** Case where user is subscribed to a subscription that does not have themes */
182
+ protected function installer_theme_subscription_does_not_have_theme( $js_array ) {
183
+
184
+ $any_subscription_has_theme = array();
185
+ $number_of_registrations = array();
186
+
187
+ //Step1, we looped through JS array
188
+ foreach ( $js_array as $repo_slug => $js_details ) {
189
+
190
+ //Step2, checked if user is registered
191
+ if ( isset($this->theme_user_registration[$repo_slug]) ) {
192
+ $registration_status = $this->theme_user_registration[$repo_slug];
193
+ if ( $registration_status ) {
194
+
195
+ //Registered
196
+ $number_of_registrations[] = $repo_slug;
197
+
198
+ //Step3, we checked if the $repo_slug has available theme
199
+ $themes_available = false;
200
+ if ( isset($this->installer_themes[$repo_slug]) ) {
201
+ $themes_available = $this->installer_themes[$repo_slug];
202
+ if ( !(empty($themes_available)) ) {
203
+ //This subscription has theme
204
+ $themes_available = true;
205
+ }
206
+ }
207
+
208
+ if ( $themes_available ) {
209
+ $any_subscription_has_theme[] = $repo_slug;
210
+ }
211
+ }
212
+ }
213
+
214
+ }
215
+
216
+ //Step4, we are done looping, check if there are any repos that have themes
217
+ if ( empty($registration_status) ) {
218
+
219
+ //No registration on any repos
220
+ return FALSE;
221
+
222
+ } elseif ( !(empty($registration_status)) ) {
223
+
224
+ //Has some registration on some repos
225
+ //We then checked if this user has any active subscriptions
226
+ if ( empty($any_subscription_has_theme) ) {
227
+ //No subscription
228
+ return TRUE;
229
+ } else {
230
+ //Has subscription found
231
+ return FALSE;
232
+ }
233
+ }
234
+ }
235
+
236
+ /** Check if its the commercial plugin screen */
237
+ private function installer_theme_is_commercial_plugin_screen( $current_screen ) {
238
+ $commercial = false;
239
+ if ( ('plugin-install' == $current_screen) || ('plugin-install-network' == $current_screen) ) {
240
+ if ( isset($_GET['tab']) ) {
241
+ $tab = $_GET['tab'];
242
+ if ( 'commercial' == $tab ) {
243
+ $commercial = true;
244
+ }
245
+ }
246
+ }
247
+ return $commercial;
248
+ }
249
+
250
+ /** Current screen */
251
+ private function installer_theme_current_screen() {
252
+
253
+ $current_screen_loaded = false;
254
+
255
+ if ( function_exists( 'get_current_screen' ) ) {
256
+
257
+ $screen_output = get_current_screen();
258
+ $current_screen_loaded = $screen_output->id;
259
+
260
+ }
261
+
262
+ return $current_screen_loaded;
263
+
264
+ }
265
+
266
+ /** Override WordPress Themes API */
267
+ public function installer_theme_api_override( $api_boolean, $action, $args ) {
268
+
269
+ //Let's checked if user is browsing our themes
270
+ if ( isset($args->browse) ) {
271
+ $browse = $args->browse;
272
+ if ( in_array( $browse, $this->theme_repo ) ) {
273
+ //Uniquely validated for our Themes
274
+ if ( 'query_themes' == $action ) {
275
+ //User is querying or asking information about our themes, let's override
276
+ $api_boolean = true;
277
+ }
278
+ }
279
+ } elseif ( isset($args->slug) ) {
280
+ //We are installing our themes
281
+ $theme_to_install = $args->slug;
282
+
283
+ //Lets uniquely validate if this belongs to us
284
+ //Check if this is OTGS theme
285
+ $validate_check = $this->installer_themes_belong_to_us( $theme_to_install );
286
+ if ( $validate_check ) {
287
+ //Belongs to us
288
+ if ( !(empty($theme_to_install)) ) {
289
+ $api_boolean = true;
290
+ }
291
+ }
292
+ }
293
+
294
+ return $api_boolean;
295
+ }
296
+
297
+ /** Override WordPress Themes API response with our own themes API*/
298
+ public function installer_theme_api_override_response( $res, $action, $args ) {
299
+
300
+ if ( true === $res ) {
301
+ if ( isset($args->browse) ) {
302
+ $browse = $args->browse;
303
+ if ( in_array( $browse, $this->theme_repo ) ) {
304
+ //Uniquely validated for our themes
305
+ if ( 'query_themes' == $action ) {
306
+ //Client querying OTGS themes
307
+ //Check for registration status
308
+ if ( isset($this->theme_user_registration[$browse]) ) {
309
+ //Set
310
+ if ( !($this->theme_user_registration[$browse]) ) {
311
+ //Not registered yet
312
+ $res = new stdClass();
313
+ $res->info = array();
314
+ $res->themes = array();
315
+ return $res;
316
+ } else {
317
+ //Registered
318
+ $themes = $this->installer_theme_get_themes( '', $browse );
319
+ $res = $this->installer_theme_format_response( $themes, $action );
320
+ }
321
+ }
322
+ }
323
+ }
324
+ } elseif ( isset($args->slug) ) {
325
+ //We are installing theme
326
+ //Lets uniquely validate if this belongs to our theme
327
+ $theme_to_install = $args->slug;
328
+
329
+ //Lets uniquely validate if this belongs to us
330
+ //Check if this is OTGS theme
331
+ $validate_check = $this->installer_themes_belong_to_us( $theme_to_install );
332
+ if ( $validate_check ) {
333
+ //Belongs to us
334
+ if ( ($res) && ('theme_information' == $action) ) {
335
+ $themes = $this->installer_theme_get_themes( '', $this->installer_theme_active_tab );
336
+ $res = $this->installer_theme_format_response( $themes, $action, $args->slug );
337
+ }
338
+ }
339
+ }
340
+ return $res;
341
+ } else {
342
+ //Default WP Themes here
343
+ $client_side_active_tab = get_option( 'wp_installer_clientside_active_tab' );
344
+ if ( $client_side_active_tab ) {
345
+ if ( !(in_array( $client_side_active_tab, $this->theme_repo )) ) {
346
+ //Not OTGS tab
347
+ return $res;
348
+ }
349
+ }
350
+
351
+ }
352
+ }
353
+
354
+ /** Get Themes */
355
+ private function installer_theme_get_themes( $product_url = '', $repo_source = '' ) {
356
+
357
+ //Query API
358
+ if ( empty($product_url) ) {
359
+ //Not set
360
+ if ( isset($this->repository_theme_products[$this->installer_theme_active_tab]) ) {
361
+ $query_remote_url = $this->repository_theme_products[$this->installer_theme_active_tab];
362
+ }
363
+
364
+ } else {
365
+ $query_remote_url = $product_url;
366
+ }
367
+
368
+ //Let's retrieved current installer settings so we won't be querying all the time
369
+ $current_installer_settings = WP_Installer()->get_settings();
370
+
371
+ //Set $themes to FALSE by default
372
+ $themes = false;
373
+
374
+ if ( (is_array( $current_installer_settings )) && (!(empty($current_installer_settings))) ) {
375
+
376
+ //Set and already defined, retrieved $products
377
+ if ( isset($current_installer_settings['repositories'][$repo_source]['data']) ) {
378
+ $products = $current_installer_settings['repositories'][$repo_source]['data'];
379
+ if ( isset($products['downloads']['themes']) ) {
380
+ $themes = $products['downloads']['themes'];
381
+ }
382
+ }
383
+
384
+ } else {
385
+
386
+ //Call API
387
+ $response = wp_remote_get( $query_remote_url );
388
+
389
+ if ( is_wp_error( $response ) ) {
390
+ //Error detected: http fallback
391
+ $query_remote_url = preg_replace( "@^https://@", 'http://', $query_remote_url );
392
+ $response = wp_remote_get( $query_remote_url );
393
+ }
394
+
395
+ if ( !(is_wp_error( $response )) ) {
396
+ //Not WP error
397
+ //Evaluate response
398
+ if ( $response && isset($response['response']['code']) && $response['response']['code'] == 200 ) {
399
+ //In this case, response is set and defined, proceed...
400
+ $body = wp_remote_retrieve_body( $response );
401
+ if ( $body ) {
402
+ $products = json_decode( $body, true );
403
+ if ( isset($products['downloads']['themes']) ) {
404
+ $themes = $products['downloads']['themes'];
405
+ }
406
+ }
407
+
408
+ }
409
+ }
410
+ }
411
+
412
+ //Return themes, can be filtered by user subscription type
413
+ return apply_filters( 'installer_theme_get_themes', $themes, $this->installer_theme_active_tab );
414
+ }
415
+
416
+ /** Format response in compatibility with WordPress Theme API response */
417
+ private function installer_theme_format_response( $themes, $action, $slug = '' ) {
418
+
419
+ //Let's append download link only when retrieving theme information for installation
420
+ if ( ('theme_information' == $action) && (!(empty($slug))) ) {
421
+
422
+ //Only return one result -> the theme to be installed
423
+ foreach ( $themes as $k => $theme ) {
424
+ if ( $slug == $theme['basename'] ) {
425
+ $theme['download_link'] = WP_Installer()->append_site_key_to_download_url( $theme['url'], $this->installer_site_key[$this->installer_theme_active_tab], $this->installer_theme_active_tab );
426
+ $theme = json_decode( json_encode( $theme ), FALSE );
427
+ return $theme;
428
+ }
429
+ }
430
+
431
+ } else {
432
+
433
+ $res = new stdClass();
434
+ $res->info = array();
435
+ $res->themes = array();
436
+
437
+ //Define info
438
+ $res->info['page'] = 1;
439
+ $res->info['pages'] = 10;
440
+
441
+ //Let's count available themes ;
442
+ $res->info['results'] = count( $themes );
443
+
444
+ //Let's saved themes for easy access later on
445
+ $this->installer_theme_savethemes_by_slug( $themes );
446
+
447
+ //Let's defined available themes
448
+ if ( isset($this->installer_theme_subscription_type) ) {
449
+ //Has subscription type defined, let's saved what is associated with this subscription
450
+ $this->installer_theme_available( $this->installer_theme_active_tab, $this->installer_theme_subscription_type );
451
+ } else {
452
+ $this->installer_theme_available( $this->installer_theme_active_tab );
453
+ }
454
+
455
+ //Let's add themes to the overriden WordPress API Theme response
456
+ /** Installer 1.7.6: Update to compatible data format response from WP Theme API */
457
+ $theme_compatible_array=array();
458
+ if ((is_array($themes))) {
459
+ foreach ($themes as $k=>$v) {
460
+ $theme_compatible_array[]=(object)($v);
461
+ }
462
+ }
463
+ $res->themes = $theme_compatible_array;
464
+ $res->themes = apply_filters( 'installer_theme_hook_response_theme', $res->themes );
465
+ return $res;
466
+ }
467
+ }
468
+
469
+ /** Let's save all available themes by its slug after any latest API query */
470
+ private function installer_theme_savethemes_by_slug( $themes, $doing_query = false ) {
471
+
472
+ if ( !($doing_query) ) {
473
+ $this->installer_themes[$this->installer_theme_active_tab] = array();
474
+ }
475
+
476
+ if ( !(empty($themes)) ) {
477
+ $themes_for_saving = array();
478
+ foreach ( $themes as $k => $theme ) {
479
+ if ( !($doing_query) ) {
480
+ if ( isset($theme['slug']) ) {
481
+ $theme_slug = $theme['slug'];
482
+ if ( !(empty($theme_slug)) ) {
483
+ $themes_for_saving[] = $theme_slug;
484
+ }
485
+ }
486
+ } else {
487
+
488
+ if ( ((isset($theme['slug'])) && (isset($theme['version'])) &&
489
+ (isset($theme['theme_page_url']))) && (isset($theme['url']))
490
+ ) {
491
+ $theme_slug = $theme['slug'];
492
+ $theme_version = $theme['version'];
493
+ $theme_page_url = $theme['theme_page_url'];
494
+ $theme_url = $theme['url'];
495
+ if ( (!(empty($theme_slug))) && (!(empty($theme_version))) &&
496
+ (!(empty($theme_page_url))) && (!(empty($theme_url)))
497
+ ) {
498
+ //$theme_slug is unique for every theme
499
+ $themes_for_saving[$theme_slug] = array(
500
+ 'version' => $theme_version,
501
+ 'theme_page_url' => $theme_page_url,
502
+ 'url' => $theme_url
503
+ );
504
+
505
+ }
506
+ }
507
+ }
508
+
509
+ }
510
+
511
+ if ( !(empty($themes_for_saving)) ) {
512
+ //Has themes for saving
513
+ if ( !($doing_query) ) {
514
+ //Not doing query
515
+ $existing_themes = get_option( $this->installer_themes_option[$this->installer_theme_active_tab] );
516
+ if ( !($existing_themes) ) {
517
+ //Does not yet exists
518
+ delete_option( $this->installer_themes_option[$this->installer_theme_active_tab] );
519
+ update_option( $this->installer_themes_option[$this->installer_theme_active_tab], $themes_for_saving );
520
+ } else {
521
+ //exists, check if we need to update
522
+ if ( $existing_themes == $themes_for_saving ) {
523
+ //Equal, no need to update here
524
+ } else {
525
+ //Update
526
+ delete_option( $this->installer_themes_option[$this->installer_theme_active_tab] );
527
+ update_option( $this->installer_themes_option[$this->installer_theme_active_tab], $themes_for_saving );
528
+ }
529
+ }
530
+ } else {
531
+ //Used for query purposes only, don't save anything
532
+ return $themes_for_saving;
533
+ }
534
+ }
535
+ }
536
+ }
537
+
538
+ /** Available themes */
539
+ private function installer_theme_available( $repo, $subscription_type = '' ) {
540
+
541
+ $subscription_type = intval( $subscription_type );
542
+ if ( $subscription_type > 0 ) {
543
+
544
+ //Here we have a case of validated subscription
545
+ //We need to set themes that is available to this subscription
546
+ $themes_associated_with_subscription = $this->installer_themes[$repo] = $this->installer_theme_get_themes_by_subscription( $subscription_type, $repo );
547
+ if ( !(empty($themes_associated_with_subscription)) ) {
548
+ //Has themes
549
+ $this->installer_themes[$repo] = $themes_associated_with_subscription;
550
+ }
551
+ } else {
552
+
553
+ //Get themes
554
+ $this->installer_themes[$repo] = get_option( $this->installer_themes_option[$repo] );
555
+ }
556
+ }
557
+
558
+ /** Theme upgrade check */
559
+ public function installer_theme_upgrade_check( $the_value ) {
560
+
561
+ //Step1: Let's looped through repos with themes and check if we have updates available for them.
562
+ if ( (is_array( $this->installer_repo_with_themes )) && (!(empty($this->installer_repo_with_themes))) ) {
563
+ foreach ( $this->installer_repo_with_themes as $k => $repo_slug ) {
564
+ //Step2: Let's checked if we have update for this theme
565
+ $update_available = get_option( $this->installer_themes_available_updates[$repo_slug] );
566
+ if ( $update_available ) {
567
+ if ( (is_array( $update_available )) && (!(empty($update_available))) ) {
568
+ //Has updates available coming from this specific theme repo
569
+ //Let's loop through the themes that needs update
570
+ foreach ( $update_available as $theme_slug => $v ) {
571
+ //Add to response API
572
+ $the_value->response [$theme_slug] = array(
573
+ 'theme' => $theme_slug,
574
+ 'new_version' => $v['new_version'],
575
+ 'url' => $v['url'],
576
+ 'package' => $v['package']
577
+ );
578
+ }
579
+ }
580
+ }
581
+ }
582
+ }
583
+ //Return
584
+ return $the_value;
585
+ }
586
+
587
+ /** Return repositories that has themes */
588
+ private function installer_theme_reposities_that_has_themes( $repositories, $ret_value = true, $doing_api_query = false ) {
589
+
590
+ $repositories_with_themes = array();
591
+
592
+ if ( (is_array( $repositories )) && (!(empty($repositories))) ) {
593
+
594
+ //Let's checked if we have something before
595
+ $themes = get_option( 'installer_repositories_with_theme' );
596
+
597
+ if ( (!($themes)) || ($doing_api_query) ) {
598
+ //Not yet defined
599
+ //Loop through each repositories and check whether they have themes
600
+ foreach ( $repositories as $k => $v ) {
601
+ if ( isset($v['products']) ) {
602
+ $products_url = $v['products'];
603
+ $themes = $this->installer_theme_get_themes( $products_url, $k );
604
+ if ( (is_array( $themes )) && (!(empty($themes))) ) {
605
+ //Repo has themes
606
+ $repositories_with_themes[] = $k;
607
+ }
608
+ }
609
+ }
610
+ } else {
611
+ //Already set
612
+ $repositories_with_themes = $themes;
613
+ }
614
+
615
+ if ( (((is_array( $repositories_with_themes )) && (!(empty($repositories_with_themes)))) && (!($themes))) || ($doing_api_query) ) {
616
+ //Save to db
617
+ update_option( 'installer_repositories_with_theme', $repositories_with_themes );
618
+ }
619
+ }
620
+
621
+ if ( $ret_value ) {
622
+ return $repositories_with_themes;
623
+ }
624
+
625
+ }
626
+
627
+ /** When WordPress queries its own Themes API, we sync with our own */
628
+ public function installer_theme_sync_native_wp_api( $response, $responsetext, $class, $args, $url ) {
629
+
630
+ $api_native_string = 'api.wordpress.org/themes/';
631
+ if ( (strpos( $url, $api_native_string ) !== false) ) {
632
+ //WordPress is querying its own themes API
633
+ $installer_repositories = WP_Installer()->get_repositories();
634
+
635
+ //Query our own API and update repository values too
636
+ $this->installer_theme_reposities_that_has_themes( $installer_repositories, false, true );
637
+ }
638
+ }
639
+
640
+ /** Returns product name by theme repo slug */
641
+ private function installer_theme_get_repo_product_name( $theme_repo ) {
642
+
643
+ $theme_repo_name = false;
644
+
645
+ if ( isset(WP_Installer()->settings['repositories'][$theme_repo]['data']['product-name']) ) {
646
+ //Set
647
+ $prod_name = WP_Installer()->settings['repositories'][$theme_repo]['data']['product-name'];
648
+ if ( !(empty($prod_name)) ) {
649
+ $theme_repo_name = $prod_name;
650
+ }
651
+ } else {
652
+ //Not yet
653
+ if ( $theme_repo == $this->theme_repo ) {
654
+ $result = $this->installer_theme_general_api_query();
655
+ if ( isset($result['product-name']) ) {
656
+ $product_name = $result['product-name'];
657
+ if ( !(empty($product_name)) ) {
658
+ $theme_repo_name = $product_name;
659
+ }
660
+ }
661
+ }
662
+ }
663
+
664
+ return $theme_repo_name;
665
+ }
666
+
667
+ /** General query API method, returns $products */
668
+ private function installer_theme_general_api_query() {
669
+ $products = false;
670
+ $response = wp_remote_get( $this->repository_theme_products );
671
+ if ( !(is_wp_error( $response )) ) {
672
+ //Not WP error
673
+ //Evaluate response
674
+ if ( $response && isset($response['response']['code']) && $response['response']['code'] == 200 ) {
675
+ //In this case, response is set and defined, proceed...
676
+ $body = wp_remote_retrieve_body( $response );
677
+ if ( $body ) {
678
+ $result = json_decode( $body, true );
679
+ if ( (is_array( $result )) && (!(empty($result))) ) {
680
+ $products = $result;
681
+ }
682
+ }
683
+
684
+ }
685
+ }
686
+
687
+ return $products;
688
+ }
689
+
690
+ /** General method to check if themes are OTGS themes based on its slug*/
691
+ private function installer_themes_belong_to_us( $theme_slug ) {
692
+
693
+ $found = false;
694
+ $theme_slug = trim( $theme_slug );
695
+
696
+ foreach ( $this->installer_themes as $repo_with_theme => $themes ) {
697
+ foreach ( $themes as $k => $otgs_theme_slug ) {
698
+ if ( $theme_slug == $otgs_theme_slug ) {
699
+ //match found! Theme belongs to otgs
700
+ return true;
701
+ }
702
+ }
703
+ }
704
+ return $found;
705
+
706
+ }
707
+
708
+ /** Sets active tab on init */
709
+ public function installer_theme_sets_active_tab_on_init() {
710
+
711
+ if ( isset ($_SERVER ['REQUEST_URI']) ) {
712
+ $request_uri = $_SERVER ['REQUEST_URI'];
713
+ if ( isset ($_GET ['browse']) ) {
714
+ $active_tab = trim( $_GET ['browse'] );
715
+ $this->installer_theme_active_tab = $active_tab;
716
+ } elseif ( isset ($_POST ['request'] ['browse']) ) {
717
+ $active_tab = trim( $_POST ['request'] ['browse'] );
718
+ $this->installer_theme_active_tab = $active_tab;
719
+ } elseif ( (isset ($_GET ['theme_repo'])) && (isset ($_GET ['action'])) ) {
720
+ $theme_repo = trim( $_GET ['theme_repo'] );
721
+ $the_action = trim( $_GET ['action'] );
722
+ if ( ('install-theme' == $the_action) && (!(empty($theme_repo))) ) {
723
+ $this->installer_theme_active_tab = $theme_repo;
724
+ }
725
+ } elseif ( wp_get_referer() ) {
726
+ $referer = wp_get_referer();
727
+ $parts = parse_url( $referer );
728
+ if ( isset($parts['query']) ) {
729
+ parse_str( $parts['query'], $query );
730
+ if ( isset($query['browse']) ) {
731
+ $this->installer_theme_active_tab = $query['browse'];
732
+ }
733
+ }
734
+ }
735
+ }
736
+ }
737
+
738
+ /** WP Theme API compatibility- added num ratings */
739
+ /** Installer 1.7.6+ Added updated 'rating' field */
740
+ public function installer_theme_add_num_ratings( $themes ) {
741
+
742
+ if ( (is_array( $themes )) && (!(empty($themes))) ) {
743
+ foreach ( $themes as $k => $v ) {
744
+ if ( !(isset($v->num_ratings)) ) {
745
+ $themes[$k]->num_ratings = 100;
746
+ }
747
+ if ( !(isset($v->rating)) ) {
748
+ $themes[$k]->rating = 100;
749
+ }
750
+ }
751
+ }
752
+
753
+ return $themes;
754
+ }
755
+
756
+ /** When WordPress.org makes a call to its repository, let's run our own upgrade checks too */
757
+ public function installer_theme_sync_call_wp_theme_api( $locales ) {
758
+
759
+ $this->installer_theme_upgrade_theme_check();
760
+
761
+ return $locales;
762
+ }
763
+
764
+ /** Upgrade theme check */
765
+ private function installer_theme_upgrade_theme_check() {
766
+
767
+ // Step1-> we get all installed themes in clients local themes directory
768
+ $installed_themes = wp_get_themes();
769
+
770
+ // Step2: We need to loop through each repository with themes
771
+ foreach ( $this->installer_repo_with_themes as $k => $repo_slug ) {
772
+
773
+ // We then need to retrieved the products URL for each of this repo
774
+ $products_url = $this->repository_theme_products [$repo_slug];
775
+
776
+ // Step3-> we get all available themes in our repository via API based on this URL
777
+ $available_themes = $this->installer_theme_get_themes( $products_url, $repo_slug );
778
+
779
+ if ( !($available_themes) ) {
780
+
781
+ // API is not available as of the moment, return..
782
+ return;
783
+ } else {
784
+
785
+ // We have available themes here...
786
+ // Step4->let's simplify available themes data by slugs
787
+ $simplified_available_themes = $this->installer_theme_savethemes_by_slug( $available_themes, true );
788
+
789
+ // Step5->Let's loop through installed themes
790
+ if ( (is_array( $installed_themes )) && (!(empty ($installed_themes))) ) {
791
+ $otgs_theme_updates_available = array();
792
+ foreach ( $installed_themes as $theme_slug => $theme_object ) {
793
+ if ( array_key_exists( $theme_slug, $simplified_available_themes ) ) {
794
+
795
+ // This is our theme
796
+ // Step6->Let's get version of the local theme installed
797
+ $local_version = $theme_object->get( 'Version' );
798
+
799
+ // Step7->Let's get the latest version of this theme, page URL and download URL from our repository
800
+ $repository_version = $simplified_available_themes [$theme_slug] ['version'];
801
+ $theme_page_url = $simplified_available_themes [$theme_slug] ['theme_page_url'];
802
+ $theme_download_url = $simplified_available_themes [$theme_slug] ['url'];
803
+
804
+ // Step8->Let's compare the version
805
+ if ( version_compare( $repository_version, $local_version, '>' ) ) {
806
+
807
+ // Update available for this theme
808
+ // Step9-> Define download URL with site key
809
+ $package_url = WP_Installer()->append_site_key_to_download_url( $theme_download_url, $this->installer_site_key [$repo_slug], $repo_slug );
810
+
811
+ //Step10-> Assign to updates array for later accessing.
812
+ $otgs_theme_updates_available[$theme_slug] = array(
813
+ 'theme' => $theme_slug,
814
+ 'new_version' => $repository_version,
815
+ 'url' => $theme_page_url,
816
+ 'package' => $package_url
817
+ );
818
+ }
819
+ }
820
+ }
821
+ //Exited the upgrade loop for this specific theme repository
822
+ if ( !(empty($otgs_theme_updates_available)) ) {
823
+ //Has updates
824
+ update_option( $this->installer_themes_available_updates[$repo_slug], $otgs_theme_updates_available );
825
+ } else {
826
+ //No updates
827
+ delete_option( $this->installer_themes_available_updates[$repo_slug] );
828
+ }
829
+
830
+ }
831
+ }
832
+ }
833
+ }
834
+
835
+ /** When the user is on Themes install page OTG themes repository, let's the currently selected tab */
836
+ public function installer_theme_add_query_arg_tab( $url, $path, $blog_id = null ) {
837
+
838
+ $wp_install_string = 'update.php?action=install-theme';
839
+ if ( $path == $wp_install_string ) {
840
+ if ( isset($this->installer_theme_active_tab) ) {
841
+ if ( !(empty($this->installer_theme_active_tab)) ) {
842
+ $url = add_query_arg( array(
843
+ 'theme_repo' => $this->installer_theme_active_tab
844
+ ), $url );
845
+ }
846
+ }
847
+ }
848
+ return $url;
849
+ }
850
+
851
+ /** Save frontend theme tab selected */
852
+ public function installer_theme_frontend_selected_tab() {
853
+ if ( isset($_POST["frontend_tab_selected"]) ) {
854
+ check_ajax_referer( 'installer_theme_frontend_selected_tab', 'installer_theme_frontend_selected_tab_nonce' );
855
+
856
+ //Client_side_active_tab
857
+ $frontend_tab_selected = filter_input( INPUT_POST, 'frontend_tab_selected', FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_NULL_ON_FAILURE );
858
+ if ( !(empty($frontend_tab_selected)) ) {
859
+ //Front end tab selected
860
+ update_option( 'wp_installer_clientside_active_tab', $frontend_tab_selected, false );
861
+
862
+ //Check for registration status
863
+ if ( isset($this->theme_user_registration[$frontend_tab_selected]) ) {
864
+ //Set
865
+ if ( !($this->theme_user_registration[$frontend_tab_selected]) ) {
866
+ //Not registered yet
867
+
868
+ if ( is_multisite() ) {
869
+ $admin_url_passed = network_admin_url();
870
+ } else {
871
+ $admin_url_passed = admin_url();
872
+ }
873
+
874
+ $registration_url = $admin_url_passed . 'plugin-install.php?tab=commercial#installer_repo_' . $frontend_tab_selected;
875
+
876
+ //Message and link
877
+ $theme_repo_name = $this->installer_theme_get_repo_product_name( $frontend_tab_selected );;
878
+ $response['unregistered_messages'] = sprintf( __( 'To install and update %s, please %sregister%s %s for this site.', 'installer' ),
879
+ $theme_repo_name, '<a href="' . $registration_url . '">', '</a>', $theme_repo_name );
880
+
881
+ }
882
+ }
883
+
884
+ $response['output'] = $frontend_tab_selected;
885
+ echo json_encode( $response );
886
+ }
887
+ die();
888
+ }
889
+ die();
890
+ }
891
+
892
+ /** Installer loaded aux hooks */
893
+ public function installer_theme_loaded_hooks() {
894
+
895
+ if ( isset($this->installer_theme_subscription_type) ) {
896
+ $subscription_type = intval( $this->installer_theme_subscription_type );
897
+ if ( $subscription_type > 0 ) {
898
+ //Client is subscribed
899
+ add_filter( 'installer_theme_get_themes', array($this, 'installer_theme_filter_themes_by_subscription'), 10, 2 );
900
+ }
901
+ }
902
+
903
+ }
904
+
905
+ /** Get themes by subscription type */
906
+ protected function installer_theme_get_themes_by_subscription( $subscription_type, $repo ) {
907
+
908
+ $themes_associated_with_subscription = array();
909
+ if ( isset(WP_Installer()->settings['repositories'][$repo]['data']['packages']) ) {
910
+ //Set
911
+ $packages = WP_Installer()->settings['repositories'][$repo]['data']['packages'];
912
+ $available_themes_subscription = array();
913
+ foreach ( $packages as $package_id => $package_details ) {
914
+ if ( isset($package_details['products']) ) {
915
+ $the_products = $package_details['products'];
916
+ foreach ( $the_products as $product_slug => $product_details ) {
917
+ if ( isset($product_details['subscription_type']) ) {
918
+ $subscription_type_from_settings = intval( $product_details['subscription_type'] );
919
+ if ( $subscription_type_from_settings == $subscription_type ) {
920
+ //We found the subscription
921
+ if ( isset($product_details['themes']) ) {
922
+ $themes_associated_with_subscription = $product_details['themes'];
923
+ return $themes_associated_with_subscription;
924
+ }
925
+ }
926
+ }
927
+
928
+ }
929
+ }
930
+ }
931
+ }
932
+ return $themes_associated_with_subscription;
933
+ }
934
+
935
+ /** Filter API theme response according to user subscription */
936
+ public function installer_theme_filter_themes_by_subscription( $themes, $active_tab ) {
937
+
938
+ //Step1, we only filter OTGS themes
939
+ $orig = count( $themes );
940
+ if ( in_array( $active_tab, $this->theme_repo ) ) {
941
+ //OTGS Theme
942
+ //Step2, we retrieved the available themes based on client subscription
943
+ if ( isset($this->installer_themes[$active_tab]) ) {
944
+ $available_themes = $this->installer_themes[$active_tab];
945
+ //Step3, we filter $themes based on this info
946
+ if ( (is_array( $themes )) && (!(empty($themes))) ) {
947
+ foreach ( $themes as $k => $theme ) {
948
+ //Step4, get theme slug
949
+ if ( isset($theme['slug']) ) {
950
+ $theme_slug = $theme['slug'];
951
+ if ( !(empty($theme_slug)) ) {
952
+ if ( !(in_array( $theme_slug, $available_themes )) ) {
953
+ //This theme is not in available themes
954
+ unset($themes[$k]);
955
+ }
956
+ }
957
+ }
958
+ }
959
+ }
960
+ }
961
+ }
962
+ $new = count( $themes );
963
+ if ( $orig != $new ) {
964
+ //It is filtered
965
+ $themes = array_values( $themes );
966
+ }
967
+
968
+ return $themes;
969
+ }
970
+
971
+ /** Hook to wp_loaded, fires when all Installer theme class is ready */
972
+ public function installer_themes_support_set_up_func() {
973
+ do_action( 'installer_themes_support_set_up' );
974
+ }
975
+
976
+ }
977
+
978
+ /** Instantiate Installer Theme Class */
979
+ new Installer_Theme_Class;
embedded/installer/includes/installer-api.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WP_Installer_API{
4
+
5
+ public static function get_product_installer_link($repository_id, $package_id = false){
6
+
7
+ $menu_url = WP_Installer()->menu_url();
8
+
9
+ $url = $menu_url . '#' . $repository_id;
10
+ if($package_id){
11
+ $url .= '/' . $package_id;
12
+ }
13
+
14
+ return $url;
15
+
16
+ }
17
+
18
+ public static function get_product_price($repository_id, $package_id, $product_id, $incl_discount = false){
19
+
20
+ $price = WP_Installer()->get_product_price($repository_id, $package_id, $product_id, $incl_discount);
21
+
22
+ return $price;
23
+ }
24
+
25
+ /**
26
+ * Retrieve the preferred translation service.
27
+ *
28
+ * @since 1.6.5
29
+ *
30
+ * @param string The repository id (e.g. wpml)
31
+ * @return string The translation service id
32
+ */
33
+ public static function get_preferred_ts($repository_id = 'wpml'){
34
+
35
+ if(isset(WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'])){
36
+ return WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'];
37
+ }
38
+
39
+ return false;
40
+
41
+ }
42
+
43
+ /**
44
+ * Set the preferred translation service.
45
+ *
46
+ * @since 1.6.5
47
+ *
48
+ * @param string The translation service id
49
+ * @param string The repository id (e.g. wpml)
50
+ */
51
+ public static function set_preferred_ts( $value, $repository_id = 'wpml' ){
52
+
53
+ if( isset( WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'] ) ){
54
+
55
+ WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'] = $value;
56
+
57
+ WP_Installer()->save_settings();
58
+
59
+ }
60
+
61
+ }
62
+
63
+ /**
64
+ * Retrieve the referring translation service (if any)
65
+ *
66
+ * @since 1.6.5
67
+ *
68
+ * @param string The repository id (e.g. wpml)
69
+ * @return string The translation service id or false
70
+ */
71
+ public static function get_ts_referal($repository_id = 'wpml'){
72
+
73
+ if(isset(WP_Installer()->settings['repositories'][$repository_id]['ts_info']['referal'])){
74
+ return WP_Installer()->settings['repositories'][$repository_id]['ts_info']['referal'];
75
+ }
76
+
77
+ return false;
78
+
79
+ }
80
+
81
+ }
embedded/installer/includes/installer-upgrader-skins.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Installer_Upgrader_Skins extends WP_Upgrader_Skin{
3
+
4
+ function __construct($args = array()){
5
+ $defaults = array( 'url' => '', 'nonce' => '', 'title' => '', 'context' => false );
6
+ $this->options = wp_parse_args($args, $defaults);
7
+ }
8
+
9
+ function header(){
10
+
11
+ }
12
+
13
+ function footer(){
14
+
15
+ }
16
+
17
+ function error($error){
18
+ $this->installer_error = $error;
19
+ }
20
+
21
+ function add_strings(){
22
+
23
+ }
24
+
25
+ function feedback($string){
26
+
27
+ }
28
+
29
+ function before(){
30
+
31
+ }
32
+
33
+ function after(){
34
+
35
+ }
36
+
37
+ }
embedded/installer/includes/installer.class.php ADDED
@@ -0,0 +1,2559 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ final class WP_Installer{
4
+ protected static $_instance = null;
5
+
6
+ public $settings = array();
7
+
8
+ private $repositories = array();
9
+
10
+ protected $api_debug = '';
11
+
12
+ private $config = array();
13
+
14
+ protected $_plugins_renew_warnings = array();
15
+
16
+ protected $_gz_on = false;
17
+
18
+ private $admin_messages = array();
19
+
20
+ private $_using_icl = false;
21
+ private $_wpml_version = false;
22
+
23
+ private $package_source = array();
24
+
25
+ const SITE_KEY_VALIDATION_SOURCE_OTHER = 0;
26
+ const SITE_KEY_VALIDATION_SOURCE_DOWNLOAD_SPECIFIC = 1;
27
+ const SITE_KEY_VALIDATION_SOURCE_DOWNLOAD_REPORT = 2;
28
+ const SITE_KEY_VALIDATION_SOURCE_REGISTRATION = 3;
29
+ const SITE_KEY_VALIDATION_SOURCE_REVALIDATION = 4;
30
+ const SITE_KEY_VALIDATION_SOURCE_UPDATES_CHECK = 5;
31
+
32
+ public $dependencies;
33
+
34
+ public static function instance() {
35
+
36
+ if ( is_null( self::$_instance ) ) {
37
+ self::$_instance = new self();
38
+ }
39
+
40
+ return self::$_instance;
41
+ }
42
+
43
+ public function __construct(){
44
+
45
+ if(!is_admin() || !is_user_logged_in()) return; //Only for admin
46
+
47
+ $this->_gz_on = function_exists('gzuncompress') && function_exists('gzcompress');
48
+ $this->settings = $this->get_settings();
49
+
50
+ add_action('admin_notices', array($this, 'show_site_key_nags'));
51
+
52
+ add_action('admin_notices', array($this, 'show_admin_messages'));
53
+
54
+ add_action('admin_init', array($this, 'load_embedded_plugins'), 0);
55
+
56
+ add_action('admin_menu', array($this, 'menu_setup'));
57
+ add_action('network_admin_menu', array($this, 'menu_setup'));
58
+
59
+ if(defined('DOING_AJAX') && isset($_POST['action']) && $_POST['action'] == 'installer_download_plugin'){
60
+ add_filter( 'site_transient_update_plugins', array( $this, 'plugins_upgrade_check') );
61
+ }
62
+ add_filter('plugins_api', array( $this, 'custom_plugins_api_call'), 10, 3);
63
+ add_filter('pre_set_site_transient_update_plugins', array( $this, 'plugins_upgrade_check'));
64
+
65
+ // register repositories
66
+ $this->load_repositories_list();
67
+
68
+ if( empty($this->settings['last_repositories_update']) || time() - $this->settings['last_repositories_update'] > 86400
69
+ || ( isset($_GET['force-check']) && $_GET['force-check'] == 1 ) ){
70
+ $this->refresh_repositories_data();
71
+ }
72
+
73
+ // default config
74
+ $this->config['plugins_install_tab'] = false;
75
+
76
+ add_action('init', array($this, 'init'));
77
+
78
+ //add_filter('wp_installer_buy_url', array($this, 'append_parameters_to_buy_url'));
79
+
80
+ add_action('init', array($this,'load_locale'));
81
+
82
+ }
83
+
84
+ public function get_repositories() {
85
+
86
+ return $this->repositories;
87
+
88
+ }
89
+
90
+ public function set_config($key, $value){
91
+
92
+ $this->config[$key] = $value;
93
+
94
+ }
95
+
96
+ public function init(){
97
+ global $pagenow;
98
+
99
+ $this->dependencies = new Installer_Dependencies;
100
+
101
+ if(empty($this->settings['_pre_1_0_clean_up'])) {
102
+ $this->_pre_1_0_clean_up();
103
+ }
104
+
105
+ $this->settings = $this->_old_products_format_backwards_compatibility($this->settings);
106
+
107
+ if ( !function_exists( 'get_plugins' ) ) {
108
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
109
+ }
110
+
111
+ $this->_using_icl = function_exists('wpml_site_uses_icl') && wpml_site_uses_icl();
112
+ $this->_wpml_version = defined('ICL_SITEPRESS_VERSION') ? ICL_SITEPRESS_VERSION : '';
113
+
114
+ wp_enqueue_script('installer-admin', $this->res_url() . '/res/js/admin.js', array('jquery'), $this->version());
115
+ wp_enqueue_style('installer-admin', $this->res_url() . '/res/css/admin.css', array(), $this->version());
116
+
117
+ $translation_array = array(
118
+ 'installing' => __( 'Installing %s', 'installer' ),
119
+ 'updating' => __( 'Updating %s', 'installer' ),
120
+ 'activating' => __( 'Activating %s', 'installer' )
121
+ );
122
+
123
+ wp_localize_script( 'installer-admin', 'installer_strings', $translation_array );
124
+
125
+ if($pagenow == 'plugins.php'){
126
+ add_action('admin_notices', array($this, 'setup_plugins_page_notices'));
127
+ add_action('admin_notices', array($this, 'setup_plugins_renew_warnings'), 10);
128
+ add_action('admin_notices', array($this, 'queue_plugins_renew_warnings'), 20);
129
+
130
+ add_action('admin_init', array($this, 'setup_plugins_action_links'));
131
+
132
+ }
133
+
134
+ if($this->is_repositories_page()){
135
+ add_action('admin_init', array($this, 'validate_repository_subscription'));
136
+ }
137
+
138
+ if(defined('DOING_AJAX')){
139
+ add_action('wp_ajax_save_site_key', array($this, 'save_site_key'));
140
+ add_action('wp_ajax_remove_site_key', array($this, 'remove_site_key'));
141
+ add_action('wp_ajax_update_site_key', array($this, 'update_site_key'));
142
+
143
+ add_action('wp_ajax_installer_download_plugin', array($this, 'download_plugin_ajax_handler'));
144
+ add_action('wp_ajax_installer_activate_plugin', array($this, 'activate_plugin'));
145
+
146
+ add_action('wp_ajax_installer_dismiss_nag', array($this, 'dismiss_nag'));
147
+ }
148
+
149
+ if($pagenow == 'update.php'){
150
+ if(isset($_GET['action']) && $_GET['action'] == 'update-selected'){
151
+ add_action('admin_head', array($this, 'plugin_upgrade_custom_errors')); //iframe/bulk
152
+ }else{
153
+ add_action('all_admin_notices', array($this, 'plugin_upgrade_custom_errors')); //regular/singular
154
+ }
155
+ }
156
+
157
+ // WP 4.2
158
+ if(defined('DOING_AJAX')){
159
+ add_action('wp_ajax_update-plugin', array($this, 'plugin_upgrade_custom_errors'), 0); // high priority, before WP
160
+ }
161
+
162
+ //Include theme support
163
+ include_once $this->plugin_path() . '/includes/class-installer-theme.php';
164
+
165
+ // Extra information about the source of Installer
166
+ $package_source_file = $this->plugin_path() . '/installer-source.json';
167
+ if( file_exists( $package_source_file ) ){
168
+ $this->package_source = json_decode( file_get_contents( $package_source_file ) );
169
+ }
170
+ }
171
+
172
+ protected function log($message){
173
+ if( defined('WPML_INSTALLER_LOGGING') && WPML_INSTALLER_LOGGING ){
174
+ if($fh = @fopen( $this->plugin_path() . '/installer.log', 'a' )){
175
+ fwrite($fh, current_time( 'mysql' ) . "\t" . $message . "\n");
176
+ }
177
+ }
178
+ }
179
+
180
+ public function register_admin_message($text, $type = 'updated'){
181
+ $this->admin_messages[] = array('text' => $text, 'type' => $type);
182
+ }
183
+
184
+ public function show_admin_messages(){
185
+ if(!empty($this->admin_messages)){
186
+ $types = array( 'error', 'updated', 'notice' );
187
+ foreach($this->admin_messages as $message){
188
+ $class = in_array( $message['type'], $types ) ? $message['type'] : 'updated';
189
+ ?>
190
+ <div class="<?php echo $class ?>">
191
+ <p>
192
+ <?php echo $message['text'] ?>
193
+ </p>
194
+ </div>
195
+ <?php
196
+ }
197
+ }
198
+ }
199
+
200
+ public function load_locale(){
201
+ $locale = get_locale();
202
+ $locale = apply_filters( 'plugin_locale', $locale, 'installer' );
203
+ $mo_file = $this->plugin_path() . '/locale/installer-' . $locale . '.mo';
204
+ if(file_exists($mo_file)){
205
+ load_textdomain( 'installer', $mo_file );
206
+ }
207
+ }
208
+
209
+ public function load_embedded_plugins(){
210
+ if(file_exists($this->plugin_path() . '/embedded-plugins' )) {
211
+ include_once $this->plugin_path() . '/embedded-plugins/embedded-plugins.class.php';
212
+ $this->installer_embedded_plugins = new Installer_Embedded_Plugins();
213
+ }
214
+ }
215
+
216
+ public function menu_setup(){
217
+ global $pagenow;
218
+
219
+ if(is_multisite() && !is_network_admin()){
220
+ $this->menu_multisite_redirect();
221
+ add_options_page(__('Installer', 'installer'), __('Installer', 'installer'), 'manage_options', 'installer', array($this, 'show_products')) ;
222
+ }else{
223
+ if($this->config['plugins_install_tab'] && is_admin() && $pagenow == 'plugin-install.php'){
224
+ // Default GUI, under Plugins -> Install
225
+ add_filter('install_plugins_tabs', array($this, 'add_install_plugins_tab'));
226
+ add_action('install_plugins_commercial', array($this, 'show_products'));
227
+ }
228
+ }
229
+
230
+ }
231
+
232
+ public function menu_url(){
233
+ if(is_multisite()){
234
+ if(is_network_admin()){
235
+ $url = network_admin_url('plugin-install.php?tab=commercial');
236
+ }else{
237
+ $url = admin_url('options-general.php?page=installer');
238
+ }
239
+ }else{
240
+ $url = admin_url('plugin-install.php?tab=commercial');
241
+ }
242
+ return $url;
243
+ }
244
+
245
+ private function menu_multisite_redirect(){
246
+ global $pagenow;
247
+
248
+ if($pagenow == 'plugin-install.php' && isset($_GET['tab']) && $_GET['tab'] == 'commercial'){
249
+ wp_redirect($this->menu_url());
250
+ exit;
251
+ }
252
+
253
+ }
254
+
255
+ private function _pre_1_0_clean_up(){
256
+ global $wpdb;
257
+
258
+ if(!defined('WPRC_VERSION')){
259
+ $old_tables = array(
260
+ $wpdb->prefix . 'wprc_cached_requests',
261
+ $wpdb->prefix . 'wprc_extension_types',
262
+ $wpdb->prefix . 'wprc_extensions',
263
+ $wpdb->prefix . 'wprc_repositories',
264
+ $wpdb->prefix . 'wprc_repositories_relationships',
265
+ );
266
+
267
+ foreach($old_tables as $table){
268
+ $wpdb->query(sprintf("DROP TABLE IF EXISTS %s", $table));
269
+ }
270
+
271
+ }
272
+
273
+ $this->settings['_pre_1_0_clean_up'] = true;
274
+ $this->save_settings();
275
+ }
276
+
277
+ public function setup_plugins_action_links(){
278
+
279
+ $plugins = get_plugins();
280
+
281
+ $repositories_plugins = array();
282
+
283
+ if( !empty($this->settings['repositories']) ) {
284
+
285
+ foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
286
+
287
+ foreach ( $repository['data']['packages'] as $package ) {
288
+
289
+ foreach ( $package['products'] as $product ) {
290
+
291
+ foreach ( $product['plugins'] as $plugin_slug ) {
292
+
293
+ $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
294
+
295
+ if ( !isset($repositories_plugins[$repository_id][$download['slug']]) ) {
296
+ $repositories_plugins[$repository_id][$download['slug']] = array(
297
+ 'name' => $download['name'],
298
+ 'registered' => $this->plugin_is_registered( $repository_id, $download['slug'] ) ? 1 : 0
299
+ );
300
+ }
301
+
302
+ }
303
+
304
+ }
305
+
306
+ }
307
+
308
+ foreach ( $plugins as $plugin_id => $plugin ) {
309
+
310
+ $wp_plugin_slug = dirname( $plugin_id );
311
+ if ( empty($wp_plugin_slug) ) {
312
+ $wp_plugin_slug = basename( $plugin_id, '.php' );
313
+ }
314
+
315
+ foreach ( $repositories_plugins as $repository_id => $r_plugins ) {
316
+
317
+ foreach ( $r_plugins as $slug => $r_plugin ) {
318
+
319
+ if ( $wp_plugin_slug == $slug || $r_plugin['name'] == $plugin['Name'] || $r_plugin['name'] == $plugin['Title'] ) { //match order: slug, name, title
320
+
321
+ if ( $r_plugin['registered'] ) {
322
+ add_filter( 'plugin_action_links_' . $plugin_id, array($this, 'plugins_action_links_registered') );
323
+ } else {
324
+ add_filter( 'plugin_action_links_' . $plugin_id, array($this, 'plugins_action_links_not_registered') );
325
+ }
326
+
327
+ }
328
+
329
+ }
330
+
331
+ }
332
+
333
+
334
+ }
335
+
336
+ }
337
+ }
338
+
339
+ }
340
+
341
+ public function plugins_action_links_registered($links){
342
+ $links[] = '<a href="' . $this->menu_url() . '">' . __('Registered', 'installer') . '</a>';
343
+ return $links;
344
+ }
345
+
346
+ public function plugins_action_links_not_registered($links){
347
+ $links[] = '<a href="' . $this->menu_url() . '">' . __('Register', 'installer') . '</a>';
348
+ return $links;
349
+ }
350
+
351
+ public function plugin_is_registered($repository_id, $slug){
352
+
353
+ $registered = false;
354
+
355
+ if( $this->repository_has_valid_subscription($repository_id) ){
356
+
357
+ $subscription_type = $this->get_subscription_type_for_repository($repository_id);
358
+ $r_plugins = array();
359
+
360
+ foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package){
361
+
362
+ foreach($package['products'] as $product){
363
+
364
+ if( $product['subscription_type'] == $subscription_type || $this->have_superior_subscription($subscription_type, $product) ) {
365
+
366
+ foreach ($product['plugins'] as $plugin_slug) {
367
+
368
+ $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
369
+
370
+ if (!isset($rep_plugins[$download['slug']])) {
371
+ $r_plugins[$download['slug']] = $download['slug'];
372
+ }
373
+
374
+ }
375
+
376
+ }
377
+
378
+ }
379
+
380
+ }
381
+
382
+ $registered = isset($r_plugins[$slug]);
383
+
384
+ }
385
+
386
+
387
+ return $registered;
388
+
389
+ }
390
+
391
+ public function version(){
392
+ return WP_INSTALLER_VERSION;
393
+ }
394
+
395
+ public function plugin_path() {
396
+ return untrailingslashit( plugin_dir_path( dirname(__FILE__) ) );
397
+ }
398
+
399
+ public function plugin_url() {
400
+ if(isset($this->config['in_theme_folder']) && !empty($this->config['in_theme_folder'])){
401
+ $url = untrailingslashit(get_template_directory_uri() . '/' . $this->config['in_theme_folder']);
402
+ }else{
403
+ $url = untrailingslashit( plugins_url( '/', dirname(__FILE__) ) );
404
+ }
405
+
406
+ return $url;
407
+ }
408
+
409
+ public function is_repositories_page(){
410
+ global $pagenow;
411
+
412
+ return $pagenow == 'plugin-install.php' && isset($_GET['tab']) && $_GET['tab'] == 'commercial';
413
+ }
414
+
415
+ public function res_url(){
416
+ if(isset($this->config['in_theme_folder']) && !empty($this->config['in_theme_folder'])){
417
+ $url = untrailingslashit(get_template_directory_uri() . '/' . $this->config['in_theme_folder']);
418
+ }else{
419
+ $url = $this->plugin_url();
420
+ }
421
+ return $url;
422
+ }
423
+
424
+ public function save_settings(){
425
+
426
+ $_settings = serialize($this->settings);
427
+ if($this->_gz_on){
428
+ $_settings = gzcompress($_settings);
429
+ }
430
+ $_settings = base64_encode($_settings);
431
+
432
+ update_option( 'wp_installer_settings', $_settings );
433
+
434
+ if( is_multisite() && is_main_site() && isset($this->settings['repositories']) ){
435
+ $network_settings = array();
436
+
437
+ foreach( $this->settings['repositories'] as $rep_id => $repository ){
438
+ if( isset($repository['subscription']) )
439
+ $network_settings[$rep_id] = $repository['subscription'];
440
+ }
441
+
442
+ update_site_option( 'wp_installer_network', $network_settings );
443
+
444
+
445
+ }
446
+
447
+ }
448
+
449
+ public function get_settings($refresh = false){
450
+
451
+ if($refresh || empty($this->settings)){
452
+
453
+ $_settings = get_option('wp_installer_settings');
454
+
455
+
456
+ if (is_array($_settings) || empty($_settings)) { //backward compatibility 1.1
457
+ $this->settings = $_settings;
458
+
459
+ } else {
460
+ $_settings = base64_decode($_settings);
461
+ if ($this->_gz_on) {
462
+ $_settings = gzuncompress($_settings);
463
+ }
464
+ $this->settings = unserialize($_settings);
465
+ }
466
+
467
+ if (is_multisite() && isset($this->settings['repositories'])) {
468
+ $network_settings = maybe_unserialize(get_site_option('wp_installer_network'));
469
+ if ($network_settings) {
470
+ foreach ($this->settings['repositories'] as $rep_id => $repository) {
471
+ if (isset($network_settings[$rep_id])) {
472
+ $this->settings['repositories'][$rep_id]['subscription'] = $network_settings[$rep_id];
473
+ }
474
+ }
475
+ }
476
+ }
477
+
478
+
479
+ $this->settings = $this->_pre_1_6_backwards_compatibility($this->settings);
480
+
481
+ $this->settings = $this->_old_products_format_backwards_compatibility($this->settings);
482
+
483
+ }
484
+
485
+
486
+ return $this->settings;
487
+ }
488
+
489
+ //backward compatibility, will remove 'basename' in version 1.8
490
+ private function _pre_1_6_backwards_compatibility($settings){
491
+
492
+ if( version_compare($this->version(), '1.8', '<') && !empty($settings['repositories']) ){
493
+
494
+ foreach ($settings['repositories'] as $repository_id => $repository) {
495
+
496
+ foreach ($repository['data']['downloads']['plugins'] as $slug => $download) {
497
+
498
+ $settings['repositories'][$repository_id]['data']['downloads']['plugins'][$slug]['slug'] = $download['basename'];
499
+
500
+ }
501
+ }
502
+
503
+ }
504
+
505
+ return $settings;
506
+
507
+ }
508
+
509
+ //backward compatibility - support old products list format (downloads under products instead of global downloads list)
510
+ private function _old_products_format_backwards_compatibility($settings){
511
+
512
+ if( version_compare($this->version(), '1.8', '<') && !empty($settings['repositories']) && empty($this->_old_products_format_backwards_compatibility) ) {
513
+
514
+ foreach ($settings['repositories'] as $repository_id => $repository) {
515
+
516
+ $populate_downloads = false;
517
+
518
+ foreach ($repository['data']['packages'] as $package_id => $package) {
519
+
520
+ foreach ($package['products'] as $product_id => $product) {
521
+
522
+ if (!isset($product['plugins'])) {
523
+
524
+ $populate_downloads = true;
525
+
526
+ foreach ($product['downloads'] as $download_id => $download) {
527
+
528
+ $settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['plugins'][] = $download['slug'];
529
+
530
+ }
531
+
532
+ }
533
+
534
+ }
535
+
536
+ }
537
+
538
+ if ($populate_downloads) {
539
+
540
+ // Add downloads branch
541
+ foreach ($repository['data']['packages'] as $package_id => $package) {
542
+
543
+ foreach ($package['products'] as $product_id => $product) {
544
+
545
+ foreach ($product['downloads'] as $download_id => $download) {
546
+
547
+ if (!isset($settings['repositories'][$repository_id]['data']['downloads']['plugins'][$download['slug']])) {
548
+ $settings['repositories'][$repository_id]['data']['downloads']['plugins'][$download['slug']] = $download;
549
+ }
550
+
551
+ $settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['plugins'][] = $download['slug'];
552
+ }
553
+
554
+ unset($settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['downloads']);
555
+
556
+ }
557
+
558
+ }
559
+
560
+ }
561
+
562
+ }
563
+
564
+ $this->_old_products_format_backwards_compatibility = true;
565
+
566
+ }
567
+
568
+ return $settings;
569
+
570
+ }
571
+
572
+ public function get_installer_site_url( $repository_id = false ){
573
+ global $current_site;
574
+
575
+ $site_url = get_site_url();
576
+
577
+ if( $repository_id && is_multisite() && isset( $this->settings['repositories'] ) ){
578
+ $network_settings = maybe_unserialize( get_site_option('wp_installer_network') );
579
+
580
+ if ( isset( $network_settings[$repository_id] ) ) {
581
+ $site_url = get_site_url( $current_site->blog_id );
582
+ }
583
+
584
+ }
585
+
586
+ return $site_url;
587
+ }
588
+
589
+ public function show_site_key_nags(){
590
+ $screen = get_current_screen();
591
+
592
+ if($screen->base == 'settings_page_installer' || ($screen->base == 'plugin-install' && isset($_GET['tab']) && $_GET['tab'] == 'commercial')){
593
+ return;
594
+ }
595
+
596
+ if(!empty($this->config['site_key_nags'])){
597
+
598
+ foreach($this->config['site_key_nags'] as $nag){
599
+
600
+ if(!$this->repository_has_subscription($nag['repository_id'] )){
601
+ $show = true;
602
+ if(!empty($nag['condition_cb'])){
603
+ $show = call_user_func($nag['condition_cb']);
604
+ }
605
+
606
+ if(empty($this->settings['dismissed_nags'][$nag['repository_id']]) && $show){
607
+ echo '<div class="updated error otgs-is-dismissible"><p>';
608
+ printf(__("To get automatic updates, you need to register %s for this site. %sRegister %s%s", 'sitepress'),
609
+ $nag['product_name'], '<a class="button-primary" href="' . $this->menu_url() . '">', $nag['product_name'], '</a>');
610
+
611
+ echo '</p>';
612
+ echo '<span class="installer-dismiss-nag notice-dismiss" data-repository="' . $nag['repository_id'] . '"><span class="screen-reader-text">' . __('Dismiss', 'sitepress') . '</span></span>';
613
+ echo '</div>';
614
+ }
615
+ }
616
+
617
+ }
618
+
619
+ }
620
+
621
+ }
622
+
623
+ public function dismiss_nag(){
624
+ $this->settings['dismissed_nags'][$_POST['repository']] = 1;
625
+
626
+ $this->save_settings();
627
+
628
+ echo json_encode(array());
629
+ exit;
630
+ }
631
+
632
+ public function add_install_plugins_tab($tabs){
633
+
634
+ $tabs['commercial'] = __('Commercial', 'installer');
635
+
636
+ return $tabs;
637
+ }
638
+
639
+ public function load_repositories_list(){
640
+ global $wp_installer_instances;
641
+
642
+ foreach ($wp_installer_instances as $instance) {
643
+
644
+ if (file_exists(dirname($instance['bootfile']) . '/repositories.xml')) {
645
+ $config_file = dirname($instance['bootfile']) . '/repositories.xml';
646
+
647
+ if (file_exists(dirname($instance['bootfile']) . '/repositories.sandbox.xml')) {
648
+ $config_file = dirname($instance['bootfile']) . '/repositories.sandbox.xml';
649
+ add_filter('https_ssl_verify', '__return_false');
650
+ }
651
+
652
+ $repos = simplexml_load_file($config_file);
653
+
654
+ if($repos) {
655
+ foreach ($repos as $repo) {
656
+ $id = strval($repo->id);
657
+
658
+ $data['api-url'] = strval($repo->apiurl);
659
+ $data['products'] = strval($repo->products);
660
+
661
+ // excludes rule;
662
+ if (isset($this->config['repositories_exclude']) && in_array($id, $this->config['repositories_exclude'])) {
663
+ continue;
664
+ }
665
+
666
+ // includes rule;
667
+ if (isset($this->config['repositories_include']) && !in_array($id, $this->config['repositories_include'])) {
668
+ continue;
669
+ }
670
+
671
+ $this->repositories[$id] = $data;
672
+
673
+ }
674
+ }
675
+
676
+ }
677
+ }
678
+
679
+ }
680
+
681
+ public function filter_repositories_list(){
682
+
683
+ if(!empty($this->settings['repositories'])) {
684
+ foreach ($this->settings['repositories'] as $id => $repo_data) {
685
+
686
+ // excludes rule;
687
+ if (isset($this->config['repositories_exclude']) && in_array($id, $this->config['repositories_exclude'])) {
688
+ unset($this->settings['repositories'][$id]);
689
+ }
690
+
691
+ // includes rule;
692
+ if (isset($this->config['repositories_include']) && !in_array($id, $this->config['repositories_include'])) {
693
+ unset($this->settings['repositories'][$id]);
694
+ }
695
+
696
+
697
+ }
698
+ }
699
+
700
+
701
+ }
702
+
703
+ public function refresh_repositories_data(){
704
+ static $checked = false;
705
+
706
+ if( defined('OTGS_DISABLE_AUTO_UPDATES') && OTGS_DISABLE_AUTO_UPDATES && empty($_GET['force-check']) || $checked ){
707
+
708
+ if(empty($this->settings['repositories']) && $this->is_repositories_page()){
709
+
710
+ foreach($this->repositories as $id => $data) {
711
+ $repository_names[] = $id;
712
+
713
+ }
714
+
715
+ $error = sprintf(__("Installer cannot display the products information because the automatic updating for %s was explicitly disabled with the configuration below (usually in wp-config.php):", 'installer'), strtoupper( join(', ', $repository_names) ));
716
+ $error .= '<br /><br /><code>define("OTGS_DISABLE_AUTO_UPDATES", true);</code><br /><br />';
717
+ $error .= sprintf(__("In order to see the products information, please run the %smanual updates check%s to initialize the products list or (temporarily) remove the above code.", 'installer'), '<a href="' . admin_url('update-core.php') . '">', '</a>');
718
+
719
+ $this->register_admin_message($error, 'error');
720
+
721
+
722
+ }
723
+
724
+ return;
725
+ }
726
+
727
+ $checked = true;
728
+
729
+ foreach($this->repositories as $id => $data){
730
+
731
+ $response = wp_remote_get($data['products']);
732
+
733
+ if(is_wp_error($response)){
734
+ // http fallback
735
+ $data['products'] = preg_replace("@^https://@", 'http://', $data['products']);
736
+ $response = wp_remote_get($data['products']);
737
+ }
738
+
739
+ if(is_wp_error($response)){
740
+
741
+ $error = sprintf(__("Installer cannot contact our updates server to get information about the available products and check for new versions. If you are seeing this message for the first time, you can ignore it, as it may be a temporary communication problem. If the problem persists and your WordPress admin is slowing down, you can disable automated version checks. Add the following line to your wp-config.php file:", 'installer'), strtoupper($id));
742
+ $error .= '<br /><br /><code>define("OTGS_DISABLE_AUTO_UPDATES", true);</code>';
743
+
744
+ $this->register_admin_message($error, 'error');
745
+
746
+ continue;
747
+ }
748
+
749
+ if($response && isset($response['response']['code']) && $response['response']['code'] == 200){
750
+ $body = wp_remote_retrieve_body($response);
751
+ if($body){
752
+ $products = json_decode($body, true);
753
+
754
+ if(is_array($products)){
755
+ $this->settings['repositories'][$id]['data'] = $products;
756
+ $this->settings = $this->_pre_1_6_backwards_compatibility($this->settings);
757
+ }
758
+ }
759
+
760
+ }
761
+
762
+ $this->log( sprintf("Checked for %s updates: %s", $id, $data['products']) );
763
+
764
+
765
+ }
766
+
767
+ // cleanup
768
+ if(empty($this->settings['repositories'])){
769
+ $this->settings['repositories'] = array();
770
+ }
771
+ foreach($this->settings['repositories'] as $id => $data){
772
+ if(!in_array($id, array_keys($this->repositories))){
773
+ unset($this->settings['repositories'][$id]);
774
+ }
775
+ }
776
+
777
+ $this->settings['last_repositories_update']= time();
778
+
779
+ $this->save_settings();
780
+
781
+ }
782
+
783
+ public function show_products($args = array()){
784
+
785
+ $screen = get_current_screen();
786
+
787
+ if($screen->base == 'settings_page_installer'){ // settings page
788
+ echo '<div class="wrap">';
789
+ echo '<h2>' . __('Installer', 'installer') . '</h2>';
790
+ echo '<br />';
791
+ }
792
+
793
+ if(!is_array($args)) $args = array();
794
+ if(empty($args['template'])) $args['template'] = 'default';
795
+
796
+ $this->filter_repositories_list();
797
+
798
+ if(!empty($this->settings['repositories'])){
799
+
800
+ $this->localize_strings();
801
+ $this->set_filtered_prices($args);
802
+ $this->set_hierarchy_and_order();
803
+
804
+ foreach($this->settings['repositories'] as $repository_id => $repository){
805
+
806
+ if($args['template'] == 'compact'){
807
+
808
+ if(isset($args['repository']) && $args['repository'] == $repository_id){
809
+ include $this->plugin_path() . '/templates/products-compact.php';
810
+ }
811
+
812
+ }else{
813
+
814
+ include $this->plugin_path() . '/templates/repository-listing.php';
815
+
816
+ }
817
+
818
+ unset($site_key, $subscription_type, $expired, $upgrade_options, $products_avaliable);
819
+
820
+ }
821
+
822
+ }else{
823
+
824
+ echo '<center>' . __('No repositories defined.', 'installer') . '</center>';
825
+
826
+ }
827
+
828
+ if($screen->base == 'settings_page_installer'){ // settings page
829
+ echo '</div>';
830
+ }
831
+
832
+
833
+ }
834
+
835
+ public function get_product_price($repository_id, $package_id, $product_id, $incl_discount = false){
836
+
837
+ $price = false;
838
+
839
+ foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package ){
840
+
841
+ if($package['id'] == $package_id){
842
+ if(isset($package['products'][$product_id])){
843
+ if($incl_discount && isset($package['products'][$product_id]['price_disc'])){
844
+ $price = $package['products'][$product_id]['price_disc'];
845
+ }elseif(isset($package['products'][$product_id]['price'])){
846
+ $price = $package['products'][$product_id]['price'];
847
+ }
848
+ }
849
+ break;
850
+ }
851
+ }
852
+
853
+ return $price;
854
+ }
855
+
856
+ private function _render_product_packages($packages, $subscription_type, $expired, $upgrade_options, $repository_id){
857
+
858
+ $data = array();
859
+
860
+ foreach($packages as $package_id => $package){
861
+
862
+ $row = array('products' => array(), 'downloads' => array());
863
+ foreach($package['products'] as $product){
864
+
865
+ // filter out free subscriptions from being displayed as buying options
866
+ if( empty($product['price']) && (empty($subscription_type) || $expired) ){
867
+ continue;
868
+ }
869
+
870
+ // buy base
871
+ if(empty($subscription_type) || $expired) {
872
+
873
+ $p['url'] = $this->append_parameters_to_buy_url($product['url'], $repository_id);
874
+ if (!empty($product['price_disc'])) {
875
+ $p['label'] = $product['call2action'] . ' - ' . sprintf('$%s %s$%d%s (USD)', $product['price_disc'], '&nbsp;&nbsp;<del>', $product['price'], '</del>');
876
+ } else {
877
+ $p['label'] = $product['call2action'] . ' - ' . sprintf('$%d (USD)', $product['price']);
878
+ }
879
+ $row['products'][] = $p;
880
+
881
+ // renew
882
+ } elseif(isset($subscription_type) && $product['subscription_type'] == $subscription_type){
883
+
884
+ if($product['renewals']) {
885
+ foreach ($product['renewals'] as $renewal) {
886
+ $p['url'] = $this->append_parameters_to_buy_url($renewal['url'], $repository_id);
887
+ $p['label'] = $renewal['call2action'] . ' - ' . sprintf('$%d (USD)', $renewal['price']);
888
+ }
889
+
890
+ $row['products'][] = $p;
891
+ }
892
+
893
+ }
894
+
895
+ // upgrades
896
+ if(!empty($upgrade_options[$product['subscription_type']])){
897
+
898
+ foreach($upgrade_options[$product['subscription_type']] as $stype => $upgrade){
899
+ if($stype != $subscription_type) continue;
900
+
901
+ $p['url'] = $this->append_parameters_to_buy_url($upgrade['url'], $repository_id);
902
+ if (!empty($upgrade['price_disc'])) {
903
+ $p['label'] = $upgrade['call2action'] . ' - ' . sprintf('$%s %s$%d%s (USD)', $upgrade['price_disc'], '&nbsp;&nbsp;<del>', $upgrade['price'], '</del>');
904
+ } else {
905
+ $p['label'] = $upgrade['call2action'] . ' - ' . sprintf('$%d (USD)', $upgrade['price']);
906
+ }
907
+ $row['products'][] = $p;
908
+
909
+ }
910
+
911
+ }
912
+
913
+ // downloads
914
+ if(isset($subscription_type) && !$expired && $product['subscription_type'] == $subscription_type){
915
+ foreach($product['plugins'] as $plugin_slug){
916
+
917
+ $row['downloads'][] = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
918
+
919
+ }
920
+
921
+ }
922
+
923
+ //subpackages
924
+ if(!empty($package['sub-packages'])){
925
+ $row['sub-packages'] = $package['sub-packages'];
926
+ }
927
+
928
+ }
929
+
930
+ $row['id'] = $package['id'];
931
+ $row['image_url'] = $package['image_url'];
932
+ $row['name'] = $package['name'];
933
+ $row['description'] = $package['description'];
934
+
935
+ if(!empty($row['products']) || !empty($row['downloads']) || !empty($row['sub-packages'])){
936
+ $data[] = $row;
937
+ }
938
+
939
+
940
+ }
941
+
942
+ return $data;
943
+
944
+ }
945
+
946
+ public function get_extra_url_parameters(){
947
+
948
+ $parameters = array();
949
+
950
+ if(!empty($this->package_source)){
951
+ foreach($this->package_source as $key => $val){
952
+ $parameters[$key] = $val;
953
+ }
954
+ }
955
+
956
+ $parameters['installer_version'] = WP_INSTALLER_VERSION;
957
+ $parameters['theme'] = wp_get_theme()->get( 'Name' );
958
+ $parameters['site_name'] = get_bloginfo( 'name' );
959
+
960
+ return $parameters;
961
+ }
962
+
963
+ public function append_parameters_to_buy_url($url, $repository_id, $args = array()){
964
+
965
+ $url = add_query_arg( array('icl_site_url' => $this->get_installer_site_url( $repository_id ) ), $url );
966
+
967
+ $affiliate_id = false;
968
+ $affiliate_key = false;
969
+
970
+ // Add extra parameters for custom Installer packages
971
+ if( !empty($this->package_source) ){
972
+ $extra = $this->get_extra_url_parameters();
973
+
974
+ if( !empty($extra['repository']) && $extra['repository'] == $repository_id ) {
975
+
976
+ if( !empty($extra['affiliate_key']) && !empty($extra['user_id']) ){
977
+ $this->config['affiliate_id:' . $repository_id] = $extra['user_id'];
978
+ $this->config['affiliate_key:' . $repository_id] = $extra['affiliate_key'];
979
+ unset($extra['affiliate_key'], $extra['user_id'], $extra['repository']); // no need to include these ones
980
+ }
981
+
982
+ $url = add_query_arg($extra, $url);
983
+ }
984
+
985
+ }
986
+
987
+ if(isset($this->config['affiliate_id:' . $repository_id]) && isset($this->config['affiliate_key:' . $repository_id])){
988
+
989
+ $affiliate_id = $this->config['affiliate_id:' . $repository_id];
990
+ $affiliate_key = $this->config['affiliate_key:' . $repository_id];
991
+
992
+ }elseif(isset($args['affiliate_id:' . $repository_id]) && isset($args['affiliate_key:' . $repository_id])){
993
+
994
+ $affiliate_id = $args['affiliate_id:' . $repository_id];
995
+ $affiliate_key = $args['affiliate_key:' . $repository_id];
996
+
997
+ }elseif(defined('ICL_AFFILIATE_ID') && defined('ICL_AFFILIATE_KEY')){ //support for 1 repo
998
+
999
+ $affiliate_id = ICL_AFFILIATE_ID;
1000
+ $affiliate_key = ICL_AFFILIATE_KEY;
1001
+
1002
+ }elseif(isset($this->config['affiliate_id']) && isset($this->config['affiliate_key'])) {
1003
+ // BACKWARDS COMPATIBILITY
1004
+ $affiliate_id = $this->config['affiliate_id'];
1005
+ $affiliate_key = $this->config['affiliate_key'];
1006
+ }
1007
+
1008
+ if($affiliate_id && $affiliate_key){
1009
+ $url = add_query_arg(array('aid' => $affiliate_id, 'affiliate_key' => $affiliate_key), $url);
1010
+ }
1011
+
1012
+ if($repository_id == 'wpml'){
1013
+ $url = add_query_arg(array('using_icl' => $this->_using_icl, 'wpml_version' => $this->_wpml_version), $url);
1014
+ }
1015
+
1016
+ $url = apply_filters('wp_installer_buy_url', $url);
1017
+
1018
+ $url = esc_url($url);
1019
+
1020
+ return $url;
1021
+
1022
+ }
1023
+
1024
+ public function save_site_key($args = array()){
1025
+
1026
+ $error = '';
1027
+
1028
+ $repository_id = isset($args['repository_id']) ? $args['repository_id'] : (isset($_POST['repository_id']) ? $_POST['repository_id'] : false);
1029
+ $nonce = isset($args['nonce']) ? $args['nonce'] : (isset($_POST['nonce']) ? $_POST['nonce'] : '');
1030
+ $site_key = isset($args['site_key']) ? $args['site_key'] : $_POST['site_key_' . $repository_id];
1031
+
1032
+ $site_key = preg_replace("/[^A-Za-z0-9]/", '', $site_key);
1033
+
1034
+ if($repository_id && $nonce && wp_create_nonce('save_site_key_' . $repository_id) == $nonce){
1035
+
1036
+ try {
1037
+ $subscription_data = $this->fetch_subscription_data( $repository_id, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REGISTRATION );
1038
+
1039
+ if ( $subscription_data ) {
1040
+ $this->settings['repositories'][$repository_id]['subscription'] = array('key' => $site_key, 'data' => $subscription_data);
1041
+ $this->save_settings();
1042
+ } else {
1043
+ $error = __( 'Invalid site key for the current site.', 'installer' );
1044
+ }
1045
+
1046
+ } catch (Exception $e ){
1047
+ $error = $e->getMessage();
1048
+ if( preg_match('#Could not resolve host: (.*)#', $error, $matches) || preg_match('#Couldn\'t resolve host \'(.*)\'#', $error, $matches) ){
1049
+ $error = sprintf(__("%s cannot access %s to register. Try again to see if it's a temporary problem. If the problem continues, make sure that this site has access to the Internet. You can still use the plugin without registration, but you will not receive automated updates.", 'installer'),
1050
+ '<strong><i>' . $this->get_generic_product_name($repository_id) . '</i></strong>',
1051
+ '<strong><i>' . $matches[1]. '</i></strong>'
1052
+ ) ;
1053
+ }
1054
+ }
1055
+
1056
+ }
1057
+
1058
+ $return = array('error' => $error);
1059
+
1060
+ if($this->api_debug){
1061
+ $return['debug'] = $this->api_debug;
1062
+ }
1063
+
1064
+ if(!empty($args['return'])){
1065
+ return $return;
1066
+ }else{
1067
+ echo json_encode($return);
1068
+ exit;
1069
+ }
1070
+
1071
+ }
1072
+
1073
+ public function get_site_key($repository_id){
1074
+
1075
+ if(isset($this->settings['repositories'][$repository_id]['subscription'])){
1076
+ $site_key = $this->settings['repositories'][$repository_id]['subscription']['key'];
1077
+ }else{
1078
+ $site_key = false;
1079
+ }
1080
+
1081
+ return $site_key;
1082
+ }
1083
+
1084
+ public function remove_site_key(){
1085
+ if($_POST['nonce'] == wp_create_nonce('remove_site_key_' . $_POST['repository_id'])){
1086
+ unset($this->settings['repositories'][$_POST['repository_id']]['subscription']);
1087
+ $this->save_settings();
1088
+
1089
+ $this->refresh_repositories_data();
1090
+ }
1091
+ exit;
1092
+ }
1093
+
1094
+ public function validate_repository_subscription(){
1095
+ $repository_id = isset($_GET['validate_repository']) ? $_GET['validate_repository'] : false;
1096
+ if($repository_id){
1097
+
1098
+ $site_key = $this->get_site_key($repository_id);
1099
+ if($site_key) {
1100
+ $subscription_data = $this->fetch_subscription_data( $repository_id, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REVALIDATION);
1101
+ if(empty($subscription_data)){
1102
+ unset($this->settings['repositories'][$repository_id]['subscription']);
1103
+ delete_site_transient('update_plugins');
1104
+ $this->save_settings();
1105
+ }
1106
+ }
1107
+
1108
+ wp_redirect($this->menu_url() . '#repository-' . $repository_id);
1109
+ exit;
1110
+
1111
+ }
1112
+
1113
+ }
1114
+
1115
+ public function update_site_key(){
1116
+
1117
+ $error = '';
1118
+
1119
+ if($_POST['nonce'] == wp_create_nonce('update_site_key_' . $_POST['repository_id'])){
1120
+
1121
+ $repository_id = $_POST['repository_id'];
1122
+ $site_key = $this->get_site_key($_POST['repository_id']);
1123
+
1124
+ if($site_key){
1125
+ try {
1126
+ $subscription_data = $this->fetch_subscription_data( $repository_id, $site_key, self::SITE_KEY_VALIDATION_SOURCE_UPDATES_CHECK );
1127
+
1128
+ if ( $subscription_data ) {
1129
+ $this->settings['repositories'][$repository_id]['subscription'] = array('key' => $site_key, 'data' => $subscription_data);
1130
+
1131
+ //also refresh products information
1132
+ $this->refresh_repositories_data();
1133
+
1134
+ $this->save_settings();
1135
+
1136
+ } else {
1137
+ unset($this->settings['repositories'][$repository_id]['subscription']);
1138
+ $error = __( 'Invalid site key for the current site. If the error persists, try to unregister first and then register again with the same site key.', 'installer' );
1139
+ }
1140
+
1141
+
1142
+ } catch (Exception $e ){
1143
+ $error = $e->getMessage();
1144
+ if( preg_match('#Could not resolve host: (.*)#', $error, $matches) || preg_match('#Couldn\'t resolve host \'(.*)\'#', $error, $matches) ){
1145
+ $error = sprintf(__("%s cannot access %s to register. Try again to see if it's a temporary problem. If the problem continues, make sure that this site has access to the Internet. You can still use the plugin without registration, but you will not receive automated updates.", 'installer'),
1146
+ '<strong><i>' . $this->get_generic_product_name($repository_id) . '</i></strong>',
1147
+ '<strong><i>' . $matches[1]. '</i></strong>'
1148
+ ) ;
1149
+ }
1150
+ }
1151
+
1152
+ }
1153
+
1154
+ }
1155
+
1156
+ echo json_encode(array('error' => $error));
1157
+
1158
+ exit;
1159
+ }
1160
+
1161
+ public function api_debug_log($text){
1162
+
1163
+ if(defined('WPML_DEBUG_INSTALLER') && WPML_DEBUG_INSTALLER){
1164
+
1165
+ if(!is_scalar($text)){
1166
+ $text = print_r($text, 1);
1167
+ }
1168
+
1169
+ $this->api_debug .= $text . "\n";
1170
+
1171
+ }
1172
+
1173
+ }
1174
+
1175
+ public function fetch_subscription_data( $repository_id, $site_key, $source = self::SITE_KEY_VALIDATION_SOURCE_OTHER ){
1176
+
1177
+ $subscription_data = false;
1178
+
1179
+ $args['body'] = array(
1180
+ 'action' => 'site_key_validation',
1181
+ 'site_key' => $site_key,
1182
+ 'site_url' => $this->get_installer_site_url( $repository_id ),
1183
+ 'source' => $source
1184
+ );
1185
+
1186
+ if($repository_id == 'wpml'){
1187
+ $args['body']['using_icl'] = $this->_using_icl;
1188
+ $args['body']['wpml_version'] = $this->_wpml_version;
1189
+ }
1190
+
1191
+ $args['body']['installer_version'] = WP_INSTALLER_VERSION;
1192
+ $args['body']['theme'] = wp_get_theme()->get( 'Name' );
1193
+ $args['body']['site_name'] = get_bloginfo( 'name' );
1194
+
1195
+ $args['body']['versions'] = $this->get_local_product_versions( $repository_id );
1196
+
1197
+ $args['timeout'] = 45;
1198
+
1199
+ // Add extra parameters for custom Installer packages
1200
+ if( !empty($this->package_source) ){
1201
+ $extra = $this->get_extra_url_parameters();
1202
+ if( !empty($extra['repository']) && $extra['repository'] == $repository_id ) {
1203
+ unset($extra['repository']);
1204
+ foreach($extra as $key => $val){
1205
+ $args['body'][$key] = $val;
1206
+ }
1207
+ }
1208
+ }
1209
+
1210
+ $response = wp_remote_post($this->repositories[$repository_id]['api-url'], $args);
1211
+
1212
+ $this->api_debug_log("POST {$this->repositories[$repository_id]['api-url']}");
1213
+ $this->api_debug_log($args);
1214
+
1215
+ $this->log("POST {$this->repositories[$repository_id]['api-url']} - fetch subscription data");
1216
+
1217
+ if( !is_wp_error($response) ){
1218
+ $datas = wp_remote_retrieve_body($response);
1219
+
1220
+ if(is_serialized($datas)){
1221
+ $data = unserialize($datas);
1222
+ $this->api_debug_log($data);
1223
+ }else{
1224
+ $this->api_debug_log($datas);
1225
+ }
1226
+
1227
+ if(!empty($data->subscription_data)){
1228
+ $subscription_data = $data->subscription_data;
1229
+ }
1230
+
1231
+ do_action( 'installer_fetched_subscription_data', $data, $repository_id);
1232
+
1233
+ }else{
1234
+
1235
+ $this->api_debug_log($response);
1236
+ throw new Exception( $response->get_error_message() );
1237
+ }
1238
+
1239
+ return $subscription_data;
1240
+
1241
+ }
1242
+
1243
+ function get_local_product_versions( $repository_id ){
1244
+
1245
+ $versions = array();
1246
+
1247
+ foreach( $this->settings['repositories'][$repository_id]['data']['packages'] as $package_id => $package ){
1248
+
1249
+ foreach( $package['products'] as $product_id => $product ){
1250
+
1251
+ foreach( $product['plugins'] as $plugin_slug ){
1252
+
1253
+ $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
1254
+
1255
+ if( empty( $versions[$download['slug']] ) ) {
1256
+ $v = $this->get_plugin_installed_version($download['name'], $download['slug']);
1257
+ if($v){
1258
+ $versions[$download['slug']] = $v;
1259
+ }
1260
+ }
1261
+
1262
+ }
1263
+
1264
+ }
1265
+
1266
+ }
1267
+
1268
+ return $versions;
1269
+ }
1270
+
1271
+ public function get_repository_site_key($repository_id){
1272
+ $site_key = false;
1273
+
1274
+ if(!empty($this->settings['repositories'][$repository_id]['subscription']['key'])){
1275
+ $site_key = $this->settings['repositories'][$repository_id]['subscription']['key'];
1276
+ }
1277
+
1278
+ return $site_key;
1279
+ }
1280
+
1281
+ public function repository_has_valid_subscription($repository_id){
1282
+
1283
+ $valid = false;
1284
+
1285
+ if(!empty($this->settings['repositories'][$repository_id]['subscription'])){
1286
+
1287
+ $subscription = $this->settings['repositories'][$repository_id]['subscription']['data'];
1288
+ $valid = ( $subscription->status == 1 && (strtotime($subscription->expires) > time() || empty($subscription->expires)) ) || $subscription->status == 4;
1289
+
1290
+ }
1291
+ return $valid;
1292
+
1293
+ }
1294
+
1295
+ public function repository_has_subscription($repository_id){
1296
+ $key = false;
1297
+ if(!empty($this->settings['repositories'][$repository_id]['subscription']['key'])){
1298
+ $key = $this->settings['repositories'][$repository_id]['subscription']['key'];
1299
+ }
1300
+
1301
+ return $key;
1302
+
1303
+ }
1304
+
1305
+ public function repository_has_expired_subscription($repository_id){
1306
+
1307
+ return $this->repository_has_subscription($repository_id) && !$this->repository_has_valid_subscription($repository_id);
1308
+
1309
+ }
1310
+
1311
+ public function get_generic_product_name($repository_id){
1312
+
1313
+ return $this->settings['repositories'][$repository_id]['data']['product-name'];
1314
+
1315
+ }
1316
+
1317
+ public function show_subscription_renew_warning($repository_id, $subscription_id){
1318
+
1319
+ $show = false;
1320
+
1321
+ $data = $this->settings['repositories'][$repository_id]['data'];
1322
+ if(!empty($data['subscriptions_meta'])){
1323
+ if(isset($data['subscriptions_meta']['expiration'])){
1324
+
1325
+ if(!empty($data['subscriptions_meta']['expiration'][$subscription_id])){
1326
+
1327
+ $days = $data['subscriptions_meta']['expiration'][$subscription_id]['days_warning'];
1328
+ $message = $data['subscriptions_meta']['expiration'][$subscription_id]['warning_message'];
1329
+
1330
+ }else{
1331
+
1332
+ //defaults
1333
+ $days = 30;
1334
+ $message = __('You will have to renew your subscription in order to continue getting the updates and support.', 'installer');
1335
+
1336
+ }
1337
+
1338
+ if(!empty($this->settings['repositories'][$repository_id]['subscription'])){
1339
+ $subscription = $this->settings['repositories'][$repository_id]['subscription'];
1340
+
1341
+ if($subscription['data']->subscription_type == $subscription_id && !empty($subscription['data']->expires)){
1342
+
1343
+ if(strtotime($subscription['data']->expires) < strtotime(sprintf("+%d day", $days))){
1344
+
1345
+ $days_to_expiration = ceil((strtotime($subscription['data']->expires) - time()) / 86400);
1346
+
1347
+ echo '<div><p class="installer-warn-box">' .
1348
+ sprintf(_n('Your subscription expires in %d day.', 'Your subscription expires in %d days.', $days_to_expiration, 'installer'), $days_to_expiration) .
1349
+ '<br />' . $message .
1350
+ '</p></div>';
1351
+
1352
+ $show = true;
1353
+
1354
+ }
1355
+
1356
+ }
1357
+
1358
+ }
1359
+
1360
+
1361
+ }
1362
+ }
1363
+
1364
+
1365
+ return $show;
1366
+
1367
+ }
1368
+
1369
+ public function setup_plugins_renew_warnings(){
1370
+
1371
+ $plugins = get_plugins();
1372
+
1373
+ $subscriptions_with_warnings = array();
1374
+ foreach($this->settings['repositories'] as $repository_id => $repository){
1375
+
1376
+ if($this->repository_has_valid_subscription($repository_id)){
1377
+ $subscription_type = $this->settings['repositories'][$repository_id]['subscription']['data']->subscription_type;
1378
+ $expires = $this->settings['repositories'][$repository_id]['subscription']['data']->expires;
1379
+
1380
+ $never_expires = isset($this->settings['repositories'][$repository_id]['subscription'])
1381
+ && empty($this->settings['repositories'][$repository_id]['subscription']['data']->expires)
1382
+ && (
1383
+ $this->settings['repositories'][$repository_id]['subscription']['data']->status == 4 ||
1384
+ $this->settings['repositories'][$repository_id]['subscription']['data']->status == 1
1385
+ );
1386
+
1387
+ if(!$never_expires){
1388
+ if(isset($this->settings['repositories'][$repository_id]['data']['subscriptions_meta']['expiration'][$subscription_type])){
1389
+
1390
+ $days_warning = $this->settings['repositories'][$repository_id]['data']['subscriptions_meta']['expiration'][$subscription_type]['days_warning'];
1391
+ $custom_message = $this->settings['repositories'][$repository_id]['data']['subscriptions_meta']['expiration'][$subscription_type]['warning_message'];
1392
+
1393
+ }else{
1394
+ //defaults
1395
+ $days_warning = 30;
1396
+ $custom_message = __('You will have to renew your subscription in order to continue getting the updates and support.', 'installer');
1397
+ }
1398
+
1399
+ if(strtotime($expires) < strtotime(sprintf('+%d day', $days_warning)) ){
1400
+
1401
+ $days_to_expiration = ceil((strtotime($expires) - time()) / 86400);
1402
+
1403
+ $message = sprintf(_n('Your subscription expires in %d day.', 'Your subscription expires in %d days.', $days_to_expiration, 'installer'), $days_to_expiration);
1404
+ $subscriptions_with_warnings[$subscription_type] = $message . ' ' . $custom_message;
1405
+
1406
+ }
1407
+ }
1408
+
1409
+ }
1410
+
1411
+ }
1412
+
1413
+
1414
+
1415
+ foreach($plugins as $plugin_id => $plugin){
1416
+
1417
+ $slug = dirname($plugin_id);
1418
+ if(empty($slug)) continue;
1419
+
1420
+ foreach($this->settings['repositories'] as $repository_id => $repository){
1421
+
1422
+ if($this->repository_has_valid_subscription($repository_id)){
1423
+
1424
+ foreach($repository['data']['packages'] as $package){
1425
+
1426
+ foreach($package['products'] as $product){
1427
+
1428
+ foreach($product['plugins'] as $plugin_slug){
1429
+
1430
+ $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
1431
+
1432
+ if($download['slug'] == $slug || $download['name'] == $plugin['Name'] || $download['name'] == $plugin['Title']){ //match order: slug, name, title
1433
+
1434
+ if(isset($subscriptions_with_warnings[$product['subscription_type']])){
1435
+
1436
+ $this->_plugins_renew_warnings[$plugin_id] = $subscriptions_with_warnings[$product['subscription_type']];
1437
+
1438
+ }
1439
+
1440
+ }
1441
+
1442
+ }
1443
+
1444
+ }
1445
+
1446
+ }
1447
+
1448
+ }
1449
+
1450
+ }
1451
+
1452
+ }
1453
+
1454
+ }
1455
+
1456
+ public function queue_plugins_renew_warnings() {
1457
+
1458
+ if(!empty($this->_plugins_renew_warnings)){
1459
+
1460
+ foreach($this->_plugins_renew_warnings as $plugin_id => $message){
1461
+
1462
+ add_action( "after_plugin_row_" . $plugin_id, array($this, 'plugins_renew_warning'), 10, 3 );
1463
+ }
1464
+
1465
+ }
1466
+
1467
+ }
1468
+
1469
+ public function plugins_renew_warning($plugin_file, $plugin_data, $status){
1470
+
1471
+ if(empty($this->_plugins_renew_warnings[$plugin_file])) return;
1472
+
1473
+ $wp_list_table = _get_list_table('WP_Plugins_List_Table');
1474
+ ?>
1475
+
1476
+ <tr class="plugin-update-tr"><td colspan="<?php echo $wp_list_table->get_column_count(); ?>" class="plugin-update colspanchange">
1477
+ <div class="update-message">
1478
+ <?php
1479
+ echo $this->_plugins_renew_warnings[$plugin_file]. ' ';
1480
+ printf(__('%sRenew here%s.', 'installer'),
1481
+ '<a href="' . $this->menu_url() . '">', '</a>');
1482
+ ?>
1483
+ </div>
1484
+ </tr>
1485
+
1486
+ <?php
1487
+
1488
+ }
1489
+
1490
+ public function get_subscription_type_for_repository($repository_id){
1491
+
1492
+ $subscription_type = false;
1493
+
1494
+ if(!empty($this->settings['repositories'][$repository_id]['subscription'])){
1495
+ $subscription_type = $this->settings['repositories'][$repository_id]['subscription']['data']->subscription_type;
1496
+ }
1497
+
1498
+ return $subscription_type;
1499
+
1500
+ }
1501
+
1502
+ public function have_superior_subscription($subscription_type, $product){
1503
+
1504
+ $have = false;
1505
+
1506
+ if(is_array($product['upgrades'])){
1507
+ foreach($product['upgrades'] as $u){
1508
+ if($u['subscription_type'] == $subscription_type){
1509
+ $have = true;
1510
+ break;
1511
+ }
1512
+ }
1513
+ }
1514
+
1515
+ return $have;
1516
+ }
1517
+
1518
+ public function is_product_available_for_download($product_name, $repository_id){
1519
+
1520
+ $available = false;
1521
+
1522
+ $subscription_type = $this->get_subscription_type_for_repository($repository_id);
1523
+ $expired = $this->repository_has_expired_subscription($repository_id);
1524
+
1525
+ if($this->repository_has_subscription($repository_id) && !$expired){
1526
+
1527
+ $this->set_hierarchy_and_order();
1528
+
1529
+ foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package_id => $package){
1530
+
1531
+ $has_top_package = false;
1532
+
1533
+ foreach($package['products'] as $product){
1534
+
1535
+ if($subscription_type == $product['subscription_type']){
1536
+ $has_top_package = true;
1537
+ if($product['name'] == $product_name){
1538
+ return $available = true;
1539
+ }
1540
+ }
1541
+
1542
+ }
1543
+
1544
+ if(!empty($package['sub-packages'])){
1545
+ foreach($package['sub-packages'] as $sub_package){
1546
+ foreach($sub_package['products'] as $product){
1547
+ if($product['name'] == $product_name && ($subscription_type == $product['subscription_type'] || $has_top_package)){
1548
+ return $available = true;
1549
+ }
1550
+ }
1551
+ }
1552
+ }
1553
+
1554
+ }
1555
+ }
1556
+
1557
+ return $available;
1558
+
1559
+ }
1560
+
1561
+ public function get_upgrade_options($repository_id){
1562
+ $all_upgrades = array();
1563
+
1564
+ //get all products: packages and subpackages
1565
+ $all_products = array();
1566
+ foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package){
1567
+ foreach($package['products'] as $product) {
1568
+ $all_products[] = $product;
1569
+ }
1570
+ if(!empty($package['sub-packages'])){
1571
+ foreach($package['sub-packages'] as $subpackage){
1572
+ foreach($subpackage['products'] as $product) {
1573
+ $all_products[] = $product;
1574
+ }
1575
+
1576
+ }
1577
+
1578
+ }
1579
+
1580
+ }
1581
+
1582
+ foreach($all_products as $product) {
1583
+ if ($product['upgrades']) {
1584
+ foreach ($product['upgrades'] as $upgrade) {
1585
+ if ($this->repository_has_valid_subscription($repository_id) || ($this->repository_has_subscription($repository_id) && $upgrade['including_expired'])) {
1586
+ $all_upgrades[$upgrade['subscription_type']][$product['subscription_type']] = $upgrade;
1587
+ }
1588
+ }
1589
+ }
1590
+ }
1591
+
1592
+ return $all_upgrades;
1593
+
1594
+ }
1595
+
1596
+ public function append_site_key_to_download_url($url, $key, $repository_id){
1597
+
1598
+ $url_params['site_key'] = $key;
1599
+ $url_params['site_url'] = $this->get_installer_site_url( $repository_id );
1600
+
1601
+
1602
+ // Add extra parameters for custom Installer packages
1603
+ if( !empty($this->package_source) ){
1604
+ $extra = $this->get_extra_url_parameters();
1605
+ if( !empty($extra['repository']) && $extra['repository'] == $repository_id ) {
1606
+ unset($extra['repository']);
1607
+ foreach($extra as $key => $val){
1608
+ $url_params[$key] = $val;
1609
+ }
1610
+ }
1611
+ }
1612
+
1613
+ $url = add_query_arg($url_params, $url);
1614
+
1615
+ if($repository_id == 'wpml'){
1616
+ $url = add_query_arg(array('using_icl' => $this->_using_icl, 'wpml_version' => $this->_wpml_version), $url);
1617
+ }
1618
+
1619
+ return $url;
1620
+
1621
+ }
1622
+
1623
+ public function plugin_is_installed($name, $slug, $version = null){
1624
+
1625
+ $is = false;
1626
+
1627
+ $plugins = get_plugins();
1628
+
1629
+ foreach($plugins as $plugin_id => $plugin){
1630
+
1631
+ $wp_plugin_slug = dirname($plugin_id);
1632
+
1633
+ // Exception: embedded plugins
1634
+ if( $wp_plugin_slug == $slug || $plugin['Name'] == $name || $plugin['Title'] == $name || ( $wp_plugin_slug == $slug . '-embedded' || $plugin['Name'] == $name . ' Embedded' ) ){
1635
+ if($version){
1636
+ if(version_compare($plugin['Version'], $version, '>=')){
1637
+ $is = $plugin['Version'];
1638
+ }
1639
+ }else{
1640
+ $is = $plugin['Version'];
1641
+ }
1642
+
1643
+ break;
1644
+ }
1645
+
1646
+ }
1647
+
1648
+ //exception: Types name difference
1649
+ if(!$is && $name == 'Types'){
1650
+ return $this->plugin_is_installed('Types - Complete Solution for Custom Fields and Types', $slug, $version);
1651
+ }
1652
+
1653
+ return $is;
1654
+ }
1655
+
1656
+ public function plugin_is_embedded_version($name, $slug){
1657
+ $is = false;
1658
+
1659
+ $plugins = get_plugins();
1660
+
1661
+ //false if teh full version is also installed
1662
+ $is_full_installed = false;
1663
+ foreach($plugins as $plugin_id => $plugin){
1664
+
1665
+ if(($plugin['Name'] == $name && !preg_match("#-embedded$#", $slug)) ){
1666
+ $is_full_installed = true;
1667
+ break;
1668
+ }
1669
+
1670
+ }
1671
+
1672
+ if($is_full_installed){
1673
+ return false;
1674
+ }
1675
+
1676
+ foreach($plugins as $plugin_id => $plugin){
1677
+
1678
+ // TBD
1679
+ $wp_plugin_slug = dirname($plugin_id);
1680
+ if( $wp_plugin_slug == $slug . '-embedded' && $plugin['Name'] == $name . ' Embedded'){
1681
+ $is = true;
1682
+ break;
1683
+ }
1684
+
1685
+ }
1686
+
1687
+ return $is;
1688
+
1689
+ }
1690
+
1691
+ //Alias for plugin_is_installed
1692
+ public function get_plugin_installed_version($name, $slug){
1693
+
1694
+ return $this->plugin_is_installed($name, $slug);
1695
+
1696
+ }
1697
+
1698
+ public function get_plugin_repository_version($repository_id, $slug){
1699
+ $version = false;
1700
+
1701
+ if(!empty($this->settings['repositories'][$repository_id]['data']['packages'])){
1702
+ foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package){
1703
+ foreach($package['products'] as $product) {
1704
+
1705
+ foreach($product['plugins'] as $plugin_slug){
1706
+
1707
+ $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
1708
+
1709
+ if($download['slug'] == $slug){
1710
+ $version = $download['version'];
1711
+ break (3);
1712
+ }
1713
+
1714
+ }
1715
+
1716
+ }
1717
+ }
1718
+ }
1719
+
1720
+ return $version;
1721
+ }
1722
+
1723
+ public function is_uploading_allowed(){
1724
+
1725
+ //_deprecated_function ( __FUNCTION__, '1.7.3', 'Installer_Dependencies::' . __FUNCTION__ );
1726
+ return $this->dependencies->is_uploading_allowed();
1727
+
1728
+ }
1729
+
1730
+ public function download_plugin_ajax_handler(){
1731
+
1732
+ require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
1733
+ require_once $this->plugin_path() . '/includes/installer-upgrader-skins.php';
1734
+
1735
+ if(isset($_POST['data'])){
1736
+
1737
+ $data = json_decode( base64_decode( $_POST['data'] ), true );
1738
+
1739
+ }
1740
+
1741
+ $ret = false;
1742
+ $plugin_id = false;
1743
+ $message = '';
1744
+
1745
+ //validate subscription
1746
+ $site_key = $this->get_repository_site_key($data['repository_id']);
1747
+ $subscription_data = $this->fetch_subscription_data( $data['repository_id'], $site_key , self::SITE_KEY_VALIDATION_SOURCE_DOWNLOAD_REPORT);
1748
+
1749
+ if($subscription_data && !is_wp_error($subscription_data) && $this->repository_has_valid_subscription($data['repository_id'])){
1750
+
1751
+ if($data['nonce'] == wp_create_nonce('install_plugin_' . $data['url'])){
1752
+
1753
+ $upgrader_skins = new Installer_Upgrader_Skins(); //use our custom (mute) Skin
1754
+ $upgrader = new Plugin_Upgrader($upgrader_skins);
1755
+
1756
+ remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
1757
+
1758
+ $plugins = get_plugins();
1759
+
1760
+ //upgrade or install?
1761
+ foreach($plugins as $id => $plugin){
1762
+ $wp_plugin_slug = dirname($id);
1763
+ $is_embedded = $this->plugin_is_embedded_version(preg_replace('/ Embedded$/', '', $plugin['Name']), preg_replace('/-embedded$/', '', $wp_plugin_slug));
1764
+
1765
+ if($wp_plugin_slug == $data['slug'] || $is_embedded && preg_replace('/-embedded$/', '', $wp_plugin_slug) == $data['slug']){
1766
+ $plugin_id = $id;
1767
+ break;
1768
+ }
1769
+ }
1770
+
1771
+ if($plugin_id && empty($is_embedded)){ //upgrade
1772
+ $response['upgrade'] = 1;
1773
+
1774
+ $plugin_is_active = is_plugin_active($plugin_id);
1775
+
1776
+ $ret = $upgrader->upgrade($plugin_id);
1777
+
1778
+ if(!$ret && !empty($upgrader->skin->installer_error)){
1779
+ if(is_wp_error($upgrader->skin->installer_error)){
1780
+ $message = $upgrader->skin->installer_error->get_error_message() .
1781
+ ' (' . $upgrader->skin->installer_error->get_error_data() . ')';
1782
+ }
1783
+ }
1784
+
1785
+ if($plugin_is_active){
1786
+ //prevent redirects
1787
+ add_filter('wp_redirect', '__return_false');
1788
+ activate_plugin($plugin_id);
1789
+ }
1790
+
1791
+ }else{ //install
1792
+
1793
+ if($is_embedded){
1794
+ delete_plugins(array($plugin_id));
1795
+ }
1796
+
1797
+ $response['install'] = 1;
1798
+ $ret = $upgrader->install($data['url']);
1799
+ if(!$ret && !empty($upgrader->skin->installer_error)){
1800
+ if(is_wp_error($upgrader->skin->installer_error)){
1801
+ $message = $upgrader->skin->installer_error->get_error_message() .
1802
+ ' (' . $upgrader->skin->installer_error->get_error_data() . ')';
1803
+ }
1804
+ }
1805
+ }
1806
+
1807
+ $plugins = get_plugins(); //read again
1808
+
1809
+ if($ret && !empty($_POST['activate'])){
1810
+ foreach($plugins as $id => $plugin){
1811
+ $wp_plugin_slug = dirname($id);
1812
+ if($wp_plugin_slug == $data['slug']){
1813
+ $plugin_version = $plugin['Version'];
1814
+ $plugin_id = $id;
1815
+ break;
1816
+ }
1817
+ }
1818
+
1819
+ }
1820
+
1821
+ }
1822
+
1823
+ } else { //subscription not valid
1824
+
1825
+ $ret = false;
1826
+ $message = __('Your subscription appears to no longer be valid. Please try to register again using a valid site key.', 'installer');
1827
+ }
1828
+
1829
+ $response['version'] = isset($plugin_version) ? $plugin_version : 0;
1830
+ $response['plugin_id'] = $plugin_id;
1831
+ $response['nonce'] = wp_create_nonce('activate_' . $plugin_id);
1832
+ $response['success'] = $ret;
1833
+ $response['message'] = $message;
1834
+
1835
+ echo json_encode( $response );
1836
+ exit;
1837
+
1838
+ }
1839
+
1840
+ public function download_plugin($slug, $url){
1841
+
1842
+ require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
1843
+ require_once $this->plugin_path() . '/includes/installer-upgrader-skins.php';
1844
+
1845
+ $upgrader_skins = new Installer_Upgrader_Skins(); //use our custom (mute) Skin
1846
+ $upgrader = new Plugin_Upgrader($upgrader_skins);
1847
+
1848
+ remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
1849
+
1850
+ $plugins = get_plugins();
1851
+
1852
+ $plugin_id = false;
1853
+
1854
+ //upgrade or install?
1855
+ foreach($plugins as $id => $plugin){
1856
+ $wp_plugin_slug = dirname($id);
1857
+ if($wp_plugin_slug == $slug){
1858
+ $plugin_id = $id;
1859
+ break;
1860
+ }
1861
+ }
1862
+
1863
+ if($plugin_id){ //upgrade
1864
+
1865
+ $plugin_is_active = is_plugin_active($plugin_id);
1866
+
1867
+ $ret = $upgrader->upgrade($plugin_id);
1868
+
1869
+ if($plugin_is_active){
1870
+ activate_plugin($plugin_id);
1871
+ }
1872
+
1873
+ }else{ //install
1874
+ $ret = $upgrader->install($url);
1875
+ }
1876
+
1877
+ return $ret;
1878
+
1879
+ }
1880
+
1881
+ public function activate_plugin(){
1882
+
1883
+ $error = '';
1884
+
1885
+ if(isset($_POST['nonce']) && isset($_POST['plugin_id']) && $_POST['nonce'] == wp_create_nonce('activate_' . $_POST['plugin_id'])){
1886
+
1887
+ $plugin_id = $_POST['plugin_id'];
1888
+
1889
+ // Deactivate any embedded version
1890
+ $plugin_slug = dirname($plugin_id);
1891
+ $active_plugins = get_option('active_plugins');
1892
+ foreach($active_plugins as $plugin){
1893
+ $wp_plugin_slug = dirname($plugin);
1894
+ if($wp_plugin_slug == $plugin_slug . '-embedded'){
1895
+ deactivate_plugins(array($plugin));
1896
+ break;
1897
+ }
1898
+ }
1899
+
1900
+ //prevent redirects
1901
+ add_filter('wp_redirect', '__return_false', 10000);
1902
+
1903
+ $return = activate_plugin($plugin_id);
1904
+
1905
+ if(is_wp_error($return)){
1906
+ $error = $return->get_error_message();
1907
+ }
1908
+
1909
+ }else{
1910
+ $error = 'error';
1911
+ }
1912
+
1913
+ $ret = array('error' => $error);
1914
+
1915
+ echo json_encode($ret);
1916
+ exit;
1917
+
1918
+ }
1919
+
1920
+ public function custom_plugins_api_call($false, $action, $args){
1921
+
1922
+ if($action == 'plugin_information'){
1923
+
1924
+ $slug = $args->slug;
1925
+
1926
+ foreach($this->settings['repositories'] as $repository_id => $repository){
1927
+
1928
+ if(!$this->repository_has_valid_subscription($repository_id)){
1929
+ $site_key = false;
1930
+ }else{
1931
+ $site_key = $repository['subscription']['key'];
1932
+ }
1933
+
1934
+ foreach($repository['data']['packages'] as $package){
1935
+
1936
+ foreach($package['products'] as $product){
1937
+
1938
+ foreach($product['plugins'] as $plugin_slug){
1939
+
1940
+ $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
1941
+
1942
+ if($download['slug'] == $slug){
1943
+
1944
+ $res = new stdClass();
1945
+ $res->external = true;
1946
+
1947
+ $res->name = $download['name'];
1948
+ $res->slug = $slug;
1949
+ $res->version = $download['version'];
1950
+ $res->author = '';
1951
+ $res->author_profile = '';
1952
+ $res->last_updated = $download['date'];
1953
+ //$res->homepage = $download['url'];
1954
+
1955
+ if($site_key){
1956
+ $res->download_link = $this->append_site_key_to_download_url($download['url'], $site_key, $repository_id);
1957
+ }else{
1958
+ // if(!empty($download['free-on-wporg'])
1959
+ return false; //try somewhere else. e.g. wordpress.org
1960
+ }
1961
+
1962
+ $res->homepage = $repository['data']['url'];
1963
+ $res->sections = array('Description' => $download['description'], 'Changelog' => $download['changelog']);
1964
+
1965
+ return $res;
1966
+
1967
+ }
1968
+
1969
+ }
1970
+
1971
+ }
1972
+
1973
+ }
1974
+
1975
+ }
1976
+
1977
+ }
1978
+
1979
+ return $false;
1980
+
1981
+ }
1982
+
1983
+ public function plugins_upgrade_check($update_plugins){
1984
+
1985
+ if(!empty($this->settings['repositories'])){
1986
+
1987
+ $plugins = get_plugins();
1988
+
1989
+ foreach($plugins as $plugin_id => $plugin){
1990
+
1991
+ $slug = dirname($plugin_id);
1992
+ if(empty($slug)) continue;
1993
+
1994
+ $version = $plugin['Version'];
1995
+ $name = $plugin['Name'];
1996
+
1997
+ foreach($this->settings['repositories'] as $repository_id => $repository){
1998
+
1999
+
2000
+ if(!$this->repository_has_valid_subscription($repository_id)){
2001
+ $site_key = false;
2002
+ }else{
2003
+ $site_key = $repository['subscription']['key'];
2004
+ //$subscription_type = $this->get_subscription_type_for_repository($repository_id);
2005
+ }
2006
+
2007
+ foreach($repository['data']['packages'] as $package){
2008
+
2009
+ foreach($package['products'] as $product){
2010
+
2011
+ foreach($product['plugins'] as $plugin_slug){
2012
+
2013
+ $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
2014
+
2015
+ if(!empty($download['free-on-wporg'])) {
2016
+ continue;
2017
+ }
2018
+
2019
+ if(empty($update_plugins->response[$plugin_id]) && ($download['slug'] == $slug || $download['name'] == $name ) && version_compare($download['version'], $version, '>')){
2020
+
2021
+ $response = new stdClass();
2022
+ $response->id = 0;
2023
+ $response->slug = $slug;
2024
+ $response->plugin = $plugin_id;
2025
+ $response->new_version = $download['version'];
2026
+ $response->upgrade_notice = '';
2027
+ $response->url = $download['url'];
2028
+ if($site_key){
2029
+ $response->package = $this->append_site_key_to_download_url($download['url'], $site_key, $repository_id);
2030
+ }
2031
+ $update_plugins->checked[$plugin_id] = $version;
2032
+ $update_plugins->response[$plugin_id] = $response;
2033
+
2034
+ }
2035
+
2036
+ }
2037
+
2038
+ }
2039
+
2040
+ }
2041
+
2042
+ }
2043
+
2044
+ }
2045
+
2046
+ }
2047
+
2048
+ return $update_plugins;
2049
+
2050
+ }
2051
+
2052
+ public function setup_plugins_page_notices(){
2053
+
2054
+ $plugins = get_plugins();
2055
+
2056
+ foreach($plugins as $plugin_id => $plugin){
2057
+
2058
+ $slug = dirname($plugin_id);
2059
+ if(empty($slug)) continue;
2060
+
2061
+ $name = $plugin['Name'];
2062
+
2063
+ foreach($this->settings['repositories'] as $repository_id => $repository){
2064
+
2065
+ if(!$this->repository_has_valid_subscription($repository_id)){
2066
+ $site_key = false;
2067
+ }else{
2068
+ $site_key = $repository['subscription']['key'];
2069
+ }
2070
+
2071
+ foreach($repository['data']['packages'] as $package){
2072
+
2073
+ foreach($package['products'] as $product){
2074
+
2075
+ foreach($product['plugins'] as $plugin_slug){
2076
+
2077
+ $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
2078
+
2079
+ if(!empty($download['free-on-wporg'])) {
2080
+ continue;
2081
+ }
2082
+
2083
+ if( $download['slug'] == $slug || $download['name'] == $name ){
2084
+
2085
+ if( !$site_key || !$this->plugin_is_registered($repository_id, $download['slug']) ){
2086
+ add_action( "after_plugin_row_" . $plugin_id, array($this, 'show_purchase_notice_under_plugin'), 10, 3 );
2087
+ }
2088
+
2089
+ }
2090
+
2091
+ }
2092
+
2093
+ }
2094
+
2095
+ }
2096
+
2097
+ }
2098
+
2099
+ }
2100
+
2101
+ }
2102
+
2103
+ public function show_purchase_notice_under_plugin($plugin_file, $plugin_data, $status){
2104
+
2105
+ $wp_list_table = _get_list_table('WP_Plugins_List_Table');
2106
+ ?>
2107
+
2108
+ <tr class="plugin-update-tr"><td colspan="<?php echo $wp_list_table->get_column_count(); ?>" class="plugin-update colspanchange">
2109
+ <div class="update-message installer-q-icon">
2110
+ <?php
2111
+ printf(__('You need to have a valid subscription in order to get upgrades or support for this plugin. %sPurchase a subscription or enter an existing site key%s.', 'installer'),
2112
+ '<a href="' . $this->menu_url() . '">', '</a>');
2113
+ ?>
2114
+ </div>
2115
+ </tr>
2116
+
2117
+ <?php
2118
+
2119
+ }
2120
+
2121
+ public function localize_strings(){
2122
+
2123
+ if(!empty($this->settings['repositories'])){
2124
+ foreach($this->settings['repositories'] as $repository_id => $repository){
2125
+ //set name as call2action when don't have any
2126
+ //products
2127
+ foreach($repository['data']['packages'] as $package_id => $package){
2128
+ foreach($package['products'] as $product_id => $product){
2129
+ if(empty($product['call2action'])){
2130
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['call2action'] = $product['name'];
2131
+ }
2132
+
2133
+ foreach($product['upgrades'] as $idx => $upg){
2134
+ if(empty($upg['call2action'])){
2135
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['upgrades'][$idx]['call2action'] = $upg['name'];
2136
+ }
2137
+ }
2138
+
2139
+ foreach($product['renewals'] as $idx => $rnw){
2140
+ if(empty($rnw['call2action'])){
2141
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['renewals'][$idx]['call2action'] = $rnw['name'];
2142
+ }
2143
+
2144
+ }
2145
+
2146
+ }
2147
+ }
2148
+ }
2149
+ }
2150
+
2151
+ global $sitepress;
2152
+ if(is_null($sitepress)){
2153
+ return;
2154
+ }
2155
+
2156
+ // default strings are always in English
2157
+ $user_admin_language = $sitepress->get_admin_language();
2158
+
2159
+ if($user_admin_language != 'en'){
2160
+ foreach($this->settings['repositories'] as $repository_id => $repository){
2161
+
2162
+ $localization = $repository['data']['localization'];
2163
+
2164
+ //packages
2165
+ foreach($repository['data']['packages'] as $package_id => $package){
2166
+
2167
+ if( isset($localization['packages'][$package_id]['name'][$user_admin_language]) ){
2168
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['name'] = $localization['packages'][$package_id]['name'][$user_admin_language];
2169
+ }
2170
+ if( isset($localization['packages'][$package_id]['description'][$user_admin_language]) ){
2171
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['description'] = $localization['packages'][$package_id]['description'][$user_admin_language];
2172
+ }
2173
+
2174
+ }
2175
+
2176
+ //products
2177
+ foreach($repository['data']['packages'] as $package_id => $package){
2178
+ foreach($package['products'] as $product_id => $product){
2179
+
2180
+ if( isset($localization['products'][$product_id]['name'][$user_admin_language]) ){
2181
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['name']
2182
+ = $localization['products'][$product_id]['name'][$user_admin_language];
2183
+ }
2184
+ if( isset($localization['products'][$product_id]['description'][$user_admin_language]) ){
2185
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['description']
2186
+ = $localization['products'][$product_id]['description'][$user_admin_language];
2187
+ }
2188
+ if( isset($localization['products'][$product_id]['call2action'][$user_admin_language]) ){
2189
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['name']
2190
+ = $localization['products'][$product_id]['call2action'][$user_admin_language];
2191
+ }
2192
+
2193
+
2194
+ }
2195
+ }
2196
+
2197
+ //subscription info
2198
+ if(isset($repository['data']['subscriptions_meta']['expiration'])){
2199
+ foreach($repository['data']['subscriptions_meta']['expiration'] as $subscription_id => $note){
2200
+ if(isset($localization['subscriptions-notes'][$subscription_id]['expiration-warning'][$user_admin_language])){
2201
+ $this->settings['repositories'][$repository_id]['data']['subscriptions_meta']['expiration'][$subscription_id]['warning_message']
2202
+ = $localization['subscriptions-notes'][$subscription_id]['expiration-warning'][$user_admin_language];
2203
+ }
2204
+ }
2205
+ }
2206
+
2207
+ }
2208
+ }
2209
+
2210
+ }
2211
+
2212
+ public function get_matching_cp($repository, $args = array()){
2213
+ $match = false;
2214
+
2215
+
2216
+ $cp_name = $cp_author = false;
2217
+
2218
+ if(isset($this->config['src_name']) && isset($this->config['src_author'])){
2219
+
2220
+ $cp_name = $this->config['src_name'];
2221
+ $cp_author = $this->config['src_author'];
2222
+
2223
+ }elseif(isset($args['src_name']) && isset($args['src_author'])){
2224
+
2225
+ $cp_name = $args['src_name'];
2226
+ $cp_author = $args['src_author'];
2227
+
2228
+ }
2229
+
2230
+ if(isset($repository['data']['marketing_cp'])){
2231
+
2232
+ foreach($repository['data']['marketing_cp'] as $cp){
2233
+
2234
+ if(!empty($cp['exp']) && time() > $cp['exp']){
2235
+ continue;
2236
+ }
2237
+
2238
+ //Use theme_name for plugins too
2239
+ if(!empty($cp['theme_name'])){
2240
+ if($cp['author_name'] == $cp_author && $cp['theme_name'] == $cp_name){
2241
+ $match = $cp;
2242
+ continue;
2243
+ }
2244
+ }else{
2245
+ if($cp['author_name'] == $cp_author){
2246
+ $match = $cp;
2247
+ continue;
2248
+ }
2249
+ }
2250
+
2251
+ }
2252
+
2253
+ }
2254
+
2255
+ return $match;
2256
+ }
2257
+
2258
+ public function set_filtered_prices($args = array()){
2259
+
2260
+ foreach($this->settings['repositories'] as $repository_id => $repository){
2261
+
2262
+ $match = $this->get_matching_cp($repository, $args);
2263
+
2264
+ if(empty($match)) continue;
2265
+
2266
+ foreach($repository['data']['packages'] as $package_id => $package){
2267
+
2268
+ foreach($package['products'] as $product_id => $product){
2269
+
2270
+ if($match['dtp'] == '%'){
2271
+ $fprice = round( $product['price'] * (1 - $match['amt']/100), 2 );
2272
+ $fprice = $fprice != round($fprice) ? sprintf('%.2f', $fprice) : round($fprice, 0);
2273
+ }elseif($match['dtp'] == '-'){
2274
+ $fprice = $product['price'] - $match['amt'];
2275
+ }else{
2276
+ $fprice = $product['price'];
2277
+ }
2278
+
2279
+ if($fprice){
2280
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['price_disc'] = $fprice;
2281
+
2282
+ $url_glue = false !== strpos($this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['url'], '?') ? '&' : '?';
2283
+ $cpndata = base64_encode(json_encode(array('theme_author' => $match['author_name'], 'theme_name' => $match['theme_name'], 'vlc' => $match['vlc'])));
2284
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['url'] .= $url_glue . 'cpn=' . $cpndata;
2285
+
2286
+ foreach($product['upgrades'] as $upgrade_id => $upgrade){
2287
+
2288
+ $fprice = false;
2289
+ if($match['dtp'] == '%'){
2290
+ $fprice = round( $upgrade['price'] * (1 - $match['amt']/100), 2 );
2291
+ $fprice = $fprice != round($fprice) ? sprintf('%.2f', $fprice) : round($fprice, 0);
2292
+ }elseif($match['dtp'] == '-'){
2293
+ $fprice = $upgrade['price'] - $match['amt'];
2294
+ }
2295
+ if($fprice){
2296
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['upgrades'][$upgrade_id]['price_disc'] = $fprice;
2297
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['upgrades'][$upgrade_id]['url'] .= $url_glue . 'cpn=' . $cpndata;
2298
+ }
2299
+
2300
+
2301
+ }
2302
+
2303
+ }
2304
+
2305
+ }
2306
+
2307
+ }
2308
+
2309
+ }
2310
+
2311
+ }
2312
+
2313
+ public function set_hierarchy_and_order(){
2314
+
2315
+ //2 levels
2316
+ if(!empty($this->settings['repositories'])) {
2317
+ foreach ($this->settings['repositories'] as $repository_id => $repository) {
2318
+
2319
+ if( empty( $repository['data']['packages'] ) ) continue;
2320
+
2321
+ $all_packages = $repository['data']['packages'];
2322
+ $ordered_packages = array();
2323
+
2324
+ //backward compatibility - 'order'
2325
+ foreach($all_packages as $k => $v){
2326
+ if(!isset($v['order'])){
2327
+ $all_packages[$k]['order'] = 0;
2328
+ }
2329
+ }
2330
+
2331
+ //select parents
2332
+ foreach ($all_packages as $package_id => $package) {
2333
+ if(empty($package['parent'])){
2334
+ $ordered_packages[$package_id] = $package;
2335
+ }
2336
+ }
2337
+
2338
+ //add sub-packages
2339
+ foreach($all_packages as $package_id => $package){
2340
+ if(!empty($package['parent'])) {
2341
+ if(isset($ordered_packages[$package['parent']])){
2342
+ $ordered_packages[$package['parent']]['sub-packages'][$package_id] = $package;
2343
+ }
2344
+ }
2345
+ }
2346
+
2347
+ // order parents
2348
+ usort($ordered_packages, array($this, '_order_packages_callback'));
2349
+ //order sub-packages
2350
+ foreach($ordered_packages as $package_id => $package){
2351
+ if(!empty($package['sub-packages'])) {
2352
+ usort($ordered_packages[$package_id]['sub-packages'], create_function('$a, $b', 'return $a[\'order\'] > $b[\'order\'];'));
2353
+ }
2354
+ }
2355
+
2356
+ $this->settings['repositories'][$repository_id]['data']['packages'] = $ordered_packages;
2357
+
2358
+
2359
+ }
2360
+ }
2361
+
2362
+
2363
+ }
2364
+
2365
+ public function _order_packages_callback($a, $b){
2366
+ return $a['order'] > $b['order'];
2367
+ }
2368
+
2369
+ public function get_support_tag_by_name( $name, $repository ){
2370
+
2371
+ if( is_array($this->settings['repositories'][$repository]['data']['support_tags'] )){
2372
+ foreach( $this->settings['repositories'][$repository]['data']['support_tags'] as $support_tag){
2373
+ if( $support_tag['name'] == $name ){
2374
+ return $support_tag['url'];
2375
+ }
2376
+ }
2377
+ }
2378
+
2379
+ return false;
2380
+ }
2381
+
2382
+ public function plugin_upgrade_custom_errors(){
2383
+
2384
+ if ( isset($_REQUEST['action']) ) {
2385
+
2386
+ $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
2387
+
2388
+ //bulk mode
2389
+ if('update-selected' == $action) {
2390
+
2391
+ global $plugins;
2392
+
2393
+ if(isset($plugins) && is_array($plugins)) {
2394
+
2395
+ foreach ($plugins as $k => $plugin) {
2396
+ $plugin_repository = false;
2397
+
2398
+ $wp_plugin_slug = dirname($plugin);
2399
+
2400
+ foreach ($this->settings['repositories'] as $repository_id => $repository) {
2401
+
2402
+ foreach ($repository['data']['packages'] as $package) {
2403
+
2404
+ foreach ($package['products'] as $product) {
2405
+
2406
+ foreach ($product['plugins'] as $plugin_slug) {
2407
+
2408
+ $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
2409
+
2410
+ if ($download['slug'] == $wp_plugin_slug) {
2411
+ $plugin_repository = $repository_id;
2412
+ $product_name = $repository['data']['product-name'];
2413
+ $plugin_name = $download['name'];
2414
+ $free_on_wporg = !empty($download['free-on-wporg']);
2415
+ break;
2416
+ }
2417
+
2418
+ }
2419
+
2420
+ }
2421
+
2422
+ }
2423
+
2424
+ }
2425
+
2426
+ if ($plugin_repository) {
2427
+
2428
+ //validate subscription
2429
+ static $sub_cache = array();
2430
+
2431
+ if(empty($sub_cache[$plugin_repository])){
2432
+ $site_key = $this->get_repository_site_key($plugin_repository);
2433
+ if ($site_key) {
2434
+ $subscription_data = $this->fetch_subscription_data( $plugin_repository, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REVALIDATION );
2435
+ }
2436
+
2437
+ $sub_cache[$plugin_repository]['site_key'] = $site_key;
2438
+ $sub_cache[$plugin_repository]['subscription_data'] = isset($subscription_data) ? $subscription_data : false;
2439
+ }else{
2440
+
2441
+ $site_key = $sub_cache[$plugin_repository]['site_key'];
2442
+ $subscription_data = $sub_cache[$plugin_repository]['subscription_data'];
2443
+
2444
+ }
2445
+
2446
+ if(!$site_key && !empty($free_on_wporg)){ // allow the download from wp.org
2447
+ continue;
2448
+ }
2449
+
2450
+ if (empty($site_key) || empty($subscription_data)) {
2451
+
2452
+
2453
+ $error_message = sprintf(__("%s cannot update because your site's registration is not valid. Please %sregister %s%s again for this site first.", 'installer'),
2454
+ '<strong>' . $plugin_name . '</strong>', '<a target="_top" href="' . $this->menu_url() . '&validate_repository=' . $plugin_repository .
2455
+ '#repository-' . $plugin_repository . '">', $product_name, '</a>');
2456
+
2457
+ echo '<div class="updated error"><p>' . $error_message . '</p></div>';
2458
+
2459
+ unset($plugins[$k]);
2460
+
2461
+
2462
+ }
2463
+
2464
+ }
2465
+
2466
+ }
2467
+
2468
+ }
2469
+
2470
+ }
2471
+
2472
+
2473
+ if( 'upgrade-plugin' == $action || 'update-plugin' == $action ) {
2474
+
2475
+ $plugin = isset($_REQUEST['plugin']) ? trim($_REQUEST['plugin']) : '';
2476
+
2477
+ $wp_plugin_slug = dirname($plugin);
2478
+
2479
+ $plugin_repository = false;
2480
+
2481
+ foreach($this->settings['repositories'] as $repository_id => $repository){
2482
+
2483
+ foreach($repository['data']['packages'] as $package){
2484
+
2485
+ foreach($package['products'] as $product){
2486
+
2487
+ foreach($product['plugins'] as $plugin_slug){
2488
+ $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
2489
+
2490
+ //match by folder, will change to match by name and folder
2491
+ if($download['slug'] == $wp_plugin_slug) {
2492
+ $plugin_repository = $repository_id;
2493
+ $product_name = $repository['data']['product-name'];
2494
+ $plugin_name = $download['name'];
2495
+ $free_on_wporg = !empty($download['free-on-wporg']);
2496
+ break;
2497
+ }
2498
+
2499
+ }
2500
+
2501
+ }
2502
+
2503
+ }
2504
+
2505
+ }
2506
+
2507
+ if($plugin_repository) {
2508
+
2509
+ //validate subscription
2510
+ $site_key = $this->get_repository_site_key($plugin_repository);
2511
+ if ($site_key) {
2512
+ $subscription_data = $this->fetch_subscription_data( $plugin_repository, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REVALIDATION );
2513
+ }
2514
+
2515
+ if ( (empty($site_key) || empty($subscription_data)) && empty($free_on_wporg)) {
2516
+
2517
+ $error_message = sprintf(__("%s cannot update because your site's registration is not valid. Please %sregister %s%s again for this site first.", 'installer'),
2518
+ '<strong>'.$plugin_name . '</strong>', '<a href="' . $this->menu_url() . '&validate_repository=' . $plugin_repository .
2519
+ '#repository-' . $plugin_repository . '">', $product_name, '</a>');
2520
+
2521
+ if(defined('DOING_AJAX')){ //WP 4.2
2522
+
2523
+ $status = array(
2524
+ 'update' => 'plugin',
2525
+ 'plugin' => $plugin,
2526
+ 'slug' => sanitize_key( $_POST['slug'] ),
2527
+ 'oldVersion' => '',
2528
+ 'newVersion' => '',
2529
+ );
2530
+
2531
+ $status['errorCode'] = 'wp_installer_invalid_subscription';
2532
+ $status['error'] = $error_message;
2533
+
2534
+ wp_send_json_error( $status );
2535
+
2536
+ } else { // WP 4.1.1
2537
+ echo '<div class="updated error"><p>' . $error_message . '</p></div>';
2538
+
2539
+
2540
+ echo '<div class="wrap">';
2541
+ echo '<h2>' . __('Update Plugin') . '</h2>';
2542
+ echo '<a href="' . admin_url('plugins.php') . '">' . __('Return to the plugins page') . '</a>';
2543
+ echo '</div>';
2544
+ require_once(ABSPATH . 'wp-admin/admin-footer.php');
2545
+ exit;
2546
+
2547
+ }
2548
+
2549
+ }
2550
+
2551
+
2552
+ }
2553
+
2554
+ }
2555
+ }
2556
+
2557
+ }
2558
+
2559
+ }
embedded/installer/includes/translation-service-info.class.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class TranslationServiceInfo{
4
+
5
+ function __construct(){
6
+
7
+ add_action('installer_fetched_subscription_data',array($this, 'save_info'), 10, 2);
8
+
9
+ }
10
+
11
+ function save_info($data, $repository_id) {
12
+
13
+ $ts_info = isset( WP_Installer()->settings['repositories'][$repository_id]['ts_info'] ) ?
14
+ WP_Installer()->settings['repositories'][$repository_id]['ts_info'] : false;
15
+
16
+ $save_settings = false;
17
+ if(isset($data->ts_info['preferred']) && empty($ts_info['preferred'])){
18
+ WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'] = $data->ts_info['preferred'];
19
+ $save_settings = true;
20
+ }
21
+
22
+ if(isset($data->ts_info['referal']) && empty($ts_info['referal'])){
23
+ WP_Installer()->settings['repositories'][$repository_id]['ts_info']['referal'] = $data->ts_info['referal'];
24
+ $save_settings = true;
25
+ }
26
+
27
+ if($save_settings){
28
+ WP_Installer()->save_settings();
29
+ }
30
+
31
+ }
32
+
33
+ }
34
+
35
+ new TranslationServiceInfo();
embedded/installer/installer.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ define('WP_INSTALLER_VERSION', '1.7.8');
3
+
4
+ include_once dirname(__FILE__) . '/includes/installer.class.php';
5
+
6
+ function WP_Installer() {
7
+ return WP_Installer::instance();
8
+ }
9
+
10
+
11
+ WP_Installer();
12
+
13
+ include_once WP_Installer()->plugin_path() . '/includes/installer-api.php';
14
+ include_once WP_Installer()->plugin_path() . '/includes/translation-service-info.class.php';
15
+ include_once WP_Installer()->plugin_path() . '/includes/class-installer-dependencies.php';
16
+
17
+ // Ext function
18
+ function WP_Installer_Show_Products($args = array()){
19
+
20
+ WP_Installer()->show_products($args);
21
+
22
+ }
embedded/installer/loader.php ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( ! defined( 'ABSPATH' ) ) {
4
+ exit; // Exit if accessed directly
5
+ }
6
+
7
+ //It should only be loaded on the admin side
8
+ if( !is_admin() ){
9
+ if(!function_exists('WP_Installer_Setup')){ function WP_Installer_Setup(){} }
10
+ $wp_installer_instance = null;
11
+ return;
12
+ }
13
+
14
+
15
+ $wp_installer_instance = dirname(__FILE__) . '/installer.php';
16
+
17
+
18
+ // Global stack of instances
19
+ global $wp_installer_instances;
20
+ $wp_installer_instances[$wp_installer_instance] = array(
21
+ 'bootfile' => $wp_installer_instance,
22
+ 'version' => '1.7.8'
23
+ );
24
+
25
+
26
+ /* EXCEPTIONS ********************************************************************************************/
27
+ // Exception: When WPML prior 3.2 is used, that instance must be used regardless of another newer instance
28
+ // Case 1: WPML loaded before Types - eliminate other instances
29
+ if( defined('ICL_SITEPRESS_VERSION') && version_compare(ICL_SITEPRESS_VERSION, '3.2', '<') ) {
30
+ foreach($wp_installer_instances as $key => $instance) {
31
+ if(isset($instance['args']['site_key_nags'])){
32
+ $wp_installer_instances[$key]['version'] = '9.9';
33
+ }else{
34
+ $wp_installer_instances[$key]['version'] = '0';
35
+ }
36
+ }
37
+ }
38
+
39
+ // Exception: Types 1.8.9 (Installer 1.7.0) with WPML before 3.3 (Installer before 1.7.0)
40
+ // New products file http://d2salfytceyqoe.cloudfront.net/wpml-products33.json overrides the old one
41
+ // while the WPML's instance is being used
42
+ // => Force using the new Installer Instance
43
+ if( defined('ICL_SITEPRESS_VERSION') && version_compare(ICL_SITEPRESS_VERSION, '3.3.1', '<') ) {
44
+
45
+ // if Installer 1.7.0+ is present, unregister Installer from old WPML
46
+ // Force Installer 1.7.0+ being used over older Installer versions
47
+ $installer_171_plus_on = false;
48
+ foreach($wp_installer_instances as $key => $instance) {
49
+ if( version_compare( $instance['version'], '1.7.1', '>=' ) ){
50
+ $installer_171_plus_on = true;
51
+ break;
52
+ }
53
+ }
54
+
55
+ if( $installer_171_plus_on ){
56
+ foreach($wp_installer_instances as $key => $instance) {
57
+
58
+ if( version_compare( $instance['version'], '1.7.0', '<' ) ){
59
+ unset( $wp_installer_instances[$key] );
60
+ }
61
+
62
+ }
63
+ }
64
+
65
+ }
66
+
67
+ // Exception: When using the embedded plugins module allow the set up to run completely with the
68
+ // Installer instance that triggers it
69
+ if( isset( $_POST['installer_instance'] ) && isset( $wp_installer_instances[$_POST['installer_instance']] ) ){
70
+ $wp_installer_instances[$_POST['installer_instance']]['version'] = '999';
71
+ }
72
+ /* EXCEPTIONS ********************************************************************************************/
73
+
74
+
75
+ // Only one of these in the end
76
+ remove_action('after_setup_theme', 'wpml_installer_instance_delegator', 1);
77
+ add_action('after_setup_theme', 'wpml_installer_instance_delegator', 1);
78
+
79
+ // When all plugins load pick the newest version
80
+ if(!function_exists('wpml_installer_instance_delegator')){
81
+ function wpml_installer_instance_delegator(){
82
+ global $wp_installer_instances;
83
+
84
+ // version based election
85
+ foreach($wp_installer_instances as $instance){
86
+
87
+ if(!isset($delegate)){
88
+ $delegate = $instance;
89
+ continue;
90
+ }
91
+
92
+ if(version_compare($instance['version'], $delegate['version'], '>')){
93
+ $delegate = $instance;
94
+ }
95
+ }
96
+
97
+ // priority based election
98
+ $highest_priority = null;
99
+ foreach($wp_installer_instances as $instance) {
100
+ if(isset($instance['args']['high_priority'])){
101
+ if(is_null($highest_priority) || $instance['args']['high_priority'] <= $highest_priority){
102
+ $highest_priority = $instance['args']['high_priority'];
103
+ $delegate = $instance;
104
+ }
105
+ }
106
+ }
107
+
108
+ // Exception: When WPML prior 3.2 is used, that instance must be used regardless of another newer instance
109
+ // Case 2: WPML loaded after Types
110
+ if( defined('ICL_SITEPRESS_VERSION') && version_compare(ICL_SITEPRESS_VERSION, '3.2', '<') ) {
111
+ foreach($wp_installer_instances as $key => $instance) {
112
+ if(isset($instance['args']['site_key_nags'])){
113
+ $delegate = $instance;
114
+ $wp_installer_instances = array($key => $delegate); //Eliminate other instances
115
+ break;
116
+ }
117
+ }
118
+ }
119
+
120
+ include_once $delegate['bootfile'];
121
+
122
+ // set configuration
123
+ if(strpos(realpath($delegate['bootfile']), realpath(TEMPLATEPATH)) === 0){
124
+ $delegate['args']['in_theme_folder'] = dirname(ltrim(str_replace(realpath(TEMPLATEPATH), '', realpath($delegate['bootfile'])), '\\/'));
125
+ }
126
+ if(isset($delegate['args']) && is_array($delegate['args'])){
127
+ foreach($delegate['args'] as $key => $value){
128
+ WP_Installer()->set_config($key, $value);
129
+ }
130
+ }
131
+
132
+ }
133
+ }
134
+
135
+ if(!function_exists('WP_Installer_Setup')){
136
+
137
+ // $args:
138
+ // plugins_install_tab = true|false (default: true)
139
+ // repositories_include = array() (default: all)
140
+ // repositories_exclude = array() (default: none)
141
+ // template = name (default: default)
142
+ //
143
+ // Ext function
144
+ function WP_Installer_Setup($wp_installer_instance, $args = array()){
145
+ global $wp_installer_instances;
146
+
147
+ $wp_installer_instances[$wp_installer_instance]['args'] = $args;
148
+
149
+ }
150
+
151
+ }
embedded/installer/locale/installer-ar.mo ADDED
Binary file
embedded/installer/locale/installer-de_DE.mo ADDED
Binary file
embedded/installer/locale/installer-el.mo ADDED
Binary file
embedded/installer/locale/installer-es_ES.mo ADDED
Binary file
embedded/installer/locale/installer-fr_FR.mo ADDED
Binary file
embedded/installer/locale/installer-he_IL.mo ADDED
Binary file
embedded/installer/locale/installer-it_IT.mo ADDED
Binary file
embedded/installer/locale/installer-ja.mo ADDED
Binary file
embedded/installer/locale/installer-ko_KR.mo ADDED
Binary file
embedded/installer/locale/installer-nl_NL.mo ADDED
Binary file
embedded/installer/locale/installer-pl_PL.mo ADDED
Binary file
embedded/installer/locale/installer-pt_BR.mo ADDED
Binary file
embedded/installer/locale/installer-pt_PT.mo ADDED
Binary file
embedded/installer/locale/installer-ru_RU.mo ADDED
Binary file
embedded/installer/locale/installer-sv_SE.mo ADDED
Binary file
embedded/installer/locale/installer-uk_UA.mo ADDED
Binary file
embedded/installer/locale/installer-vi.mo ADDED
Binary file
embedded/installer/locale/installer-zh_CN.mo ADDED
Binary file
embedded/installer/locale/installer-zh_TW.mo ADDED
Binary file
embedded/installer/locale/orig/installer.po ADDED
@@ -0,0 +1,230 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file was generated by WPML
2
+ # WPML is a WordPress plugin that can turn any WordPress site into a full featured multilingual content management system.
3
+ # https://wpml.org
4
+ msgid ""
5
+ msgstr ""
6
+ "Content-Type: text/plain; charset=utf-8\n"
7
+ "Content-Transfer-Encoding: 8bit\n"
8
+ "Project-Id-Version:WPML_EXPORT\n"
9
+ "POT-Creation-Date: \n"
10
+ "PO-Revision-Date: \n"
11
+ "Last-Translator: \n"
12
+ "Language-Team: \n"
13
+ "Language:en\n"
14
+ "MIME-Version: 1.0\n"
15
+
16
+ msgid "Installer"
17
+ msgstr ""
18
+
19
+ msgid "Registered"
20
+ msgstr ""
21
+
22
+ msgid "Register"
23
+ msgstr ""
24
+
25
+ msgid "To get automatic updates, you need to register %s for this site. %sRegister %s%s"
26
+ msgstr ""
27
+
28
+ msgid "Dismiss"
29
+ msgstr ""
30
+
31
+ msgid "Commercial"
32
+ msgstr ""
33
+
34
+ msgid "Installer cannot contact our updates server to get information about the available products and check for new versions. If you are seeing this message for the first time, you can ignore it, as it may be a temporary communication problem. If the problem persists and your WordPress admin is slowing down, you can disable automated version checks. Add the following line to your wp-config.php file:"
35
+ msgstr ""
36
+
37
+ msgid "No repositories defined."
38
+ msgstr ""
39
+
40
+ msgid "%s cannot access %s to register. Try again to see if it's a temporary problem. If the problem continues, make sure that this site has access to the Internet. You can still use the plugin without registration, but you will not receive automated updates."
41
+ msgstr ""
42
+
43
+ msgid "Invalid site key for the current site."
44
+ msgstr ""
45
+
46
+ msgid "You will have to renew your subscription in order to continue getting the updates and support."
47
+ msgstr ""
48
+
49
+ msgid "%sRenew here%s."
50
+ msgstr ""
51
+
52
+ msgid "Your subscription appears to no longer be valid. Please try to register again using a valid site key."
53
+ msgstr ""
54
+
55
+ msgid "You need to have a valid subscription in order to get upgrades or support for this plugin. %sPurchase a subscription or enter an existing site key%s."
56
+ msgstr ""
57
+
58
+ msgid "%s cannot update because your site's registration is not valid. Please %sregister %s%s again for this site first."
59
+ msgstr ""
60
+
61
+ msgid "Update Plugin"
62
+ msgstr ""
63
+
64
+ msgid "Return to the plugins page"
65
+ msgstr ""
66
+
67
+ msgid "Your subscription expires in %d day."
68
+ msgstr ""
69
+
70
+ msgid "Your subscription expires in %d days."
71
+ msgstr ""
72
+
73
+ msgid "Downloading is not possible because WordPress cannot write into the plugins folder. %sHow to fix%s."
74
+ msgstr ""
75
+
76
+ msgid "Plugin"
77
+ msgstr ""
78
+
79
+ msgid "downloading..."
80
+ msgstr ""
81
+
82
+ msgid "failed!"
83
+ msgstr ""
84
+
85
+ msgid "downloaded"
86
+ msgstr ""
87
+
88
+ msgid "activating"
89
+ msgstr ""
90
+
91
+ msgid "activated"
92
+ msgstr ""
93
+
94
+ msgid "Activate after download"
95
+ msgstr ""
96
+
97
+ msgid "Operation complete!"
98
+ msgstr ""
99
+
100
+ msgid "Download failed!\n\nClick OK to revalidate your subscription or CANCEL to try again."
101
+ msgstr ""
102
+
103
+ msgid "Available"
104
+ msgstr ""
105
+
106
+ msgid "Installed"
107
+ msgstr ""
108
+
109
+ msgid "Downloading"
110
+ msgstr ""
111
+
112
+ msgid "Activate"
113
+ msgstr ""
114
+
115
+ msgid "Download"
116
+ msgstr ""
117
+
118
+ msgid "Downloads:"
119
+ msgstr ""
120
+
121
+ msgid "Current version"
122
+ msgstr ""
123
+
124
+ msgid "Released"
125
+ msgstr ""
126
+
127
+ msgid "Installed version"
128
+ msgstr ""
129
+
130
+ msgid "(embedded)"
131
+ msgstr ""
132
+
133
+ msgid "installing..."
134
+ msgstr ""
135
+
136
+ msgid "updating..."
137
+ msgstr ""
138
+
139
+ msgid "installed"
140
+ msgstr ""
141
+
142
+ msgid "updated"
143
+ msgstr ""
144
+
145
+ msgid "Download failed!\n\nPlease refresh the page and try again."
146
+ msgstr ""
147
+
148
+ msgid "Incorrect setup"
149
+ msgstr ""
150
+
151
+ msgid "Invalid product"
152
+ msgstr ""
153
+
154
+ msgid "Unknown repository"
155
+ msgstr ""
156
+
157
+ msgid " Your current site key (%s) does not match the selected product (%s)."
158
+ msgstr ""
159
+
160
+ msgid "Buy %s"
161
+ msgstr ""
162
+
163
+ msgid "Already bought %s?"
164
+ msgstr ""
165
+
166
+ msgid "Renew %s"
167
+ msgstr ""
168
+
169
+ msgid "Remove current site key (%s)"
170
+ msgstr ""
171
+
172
+ msgid "%s support on wpml.org"
173
+ msgstr ""
174
+
175
+ msgid "Enter site key"
176
+ msgstr ""
177
+
178
+ msgid "Subscription is expired."
179
+ msgstr ""
180
+
181
+ msgid "Add"
182
+ msgstr ""
183
+
184
+ msgid "Are you sure you want to remove this site key?"
185
+ msgstr ""
186
+
187
+ msgid "Register %s"
188
+ msgstr ""
189
+
190
+ msgid "1. Go to your %s%s account%s and add this site URL: %s"
191
+ msgstr ""
192
+
193
+ msgid "Unregister %s from this site"
194
+ msgstr ""
195
+
196
+ msgid "%s is registered on this site. You will receive automatic updates until %s"
197
+ msgstr ""
198
+
199
+ msgid "%s is registered on this site. Your Lifetime account gives you updates for life."
200
+ msgstr ""
201
+
202
+ msgid "This page lets you install plugins and update existing plugins. To remove any of these plugins, go to the %splugins%s page and if you have the permission to remove plugins you should be able to do this."
203
+ msgstr ""
204
+
205
+ msgid "Already bought?"
206
+ msgstr ""
207
+
208
+ msgid "2. Enter your site key"
209
+ msgstr ""
210
+
211
+ msgid "Subscription is expired. You need to either purchase a new subscription or upgrade if available."
212
+ msgstr ""
213
+
214
+ msgid "Check for updates"
215
+ msgstr ""
216
+
217
+ msgid "Individual components"
218
+ msgstr ""
219
+
220
+ msgid "OK"
221
+ msgstr ""
222
+
223
+ msgid "Cancel"
224
+ msgstr ""
225
+
226
+ msgid "Are you sure you want to unregister?"
227
+ msgstr ""
228
+
229
+ msgid "Click to see individual components options."
230
+ msgstr ""
embedded/installer/repositories.xml ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <repositories>
3
+ <repository>
4
+ <id>wpml</id>
5
+ <apiurl>https://api.wpml.org/</apiurl>
6
+ <products>http://d2salfytceyqoe.cloudfront.net/wpml33-products.json</products>
7
+ </repository>
8
+ <repository>
9
+ <id>toolset</id>
10
+ <apiurl>https://api.wp-types.com/</apiurl>
11
+ <products>http://d7j863fr5jhrr.cloudfront.net/toolset33-products.json</products>
12
+ </repository>
13
+ </repositories>
embedded/installer/res/css/admin.css ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .otgsi_site_key_form{
2
+ display:none;
3
+ /*display:inline;*/
4
+ }
5
+
6
+ .installer-status-installing, .installer-status-installed, .installer-status-updating, .installer-status-updated, .installer-status-activating, .installer-status-activated, .installer-status-success{
7
+ display: none;
8
+ }
9
+ .installer-status-installing{color: #FF9900; }
10
+ .installer-status-installed{color: #003300; font-weight: bold; }
11
+ .installer-status-updating{color: #FF9900; }
12
+ .installer-status-updated{color: #003300; font-weight: bold; }
13
+
14
+ .installer-status-activating{color: #996666 }
15
+ .installer-status-activated{color: #333366; font-weight: bold; }
16
+
17
+ .js-status-success p{
18
+ color: #FF9900;
19
+ padding: 4px;
20
+ }
21
+
22
+ .installer-green-text{
23
+ color:#006600;
24
+ font-weight:bold;
25
+ }
26
+
27
+ .installer-red-text{
28
+ color:#b22121;
29
+ font-weight:bold;
30
+ }
31
+
32
+ .installer-products-list li{
33
+ display: inline;
34
+ margin-right: 20px;
35
+ }
36
+
37
+ .otgs_wp_installer_table a.disabled{
38
+ color:#888;
39
+ }
40
+
41
+ .otgs_wp_installer_subtable{
42
+ clear: both;
43
+ margin-left:-20px;
44
+ }
45
+ .otgs_wp_installer_subtable td p{
46
+ font-size: 92%;
47
+ }
48
+
49
+ .installer-status-error{
50
+ color: #f00;
51
+ }
52
+
53
+ .installer-status-note{
54
+ color: #6F6E6D;
55
+ font-style: italic;
56
+ }
57
+
58
+ .installer-warn-box{
59
+ -webkit-border-radius: 5px;-moz-border-radius: 5px;border-radius: 5px;border:1px solid #962722;background-color:#F5C8C6;
60
+ color: #333;
61
+ padding: 5px;
62
+ }
63
+ .installer-warn-box span.details{
64
+ font-style: italic;
65
+ color:#777;
66
+ }
67
+
68
+ .installer-error-box{
69
+ color:#962722;
70
+ margin-top: 10px;
71
+ }
72
+ .installer-error-box p{
73
+ margin: 10px 0 10px 0;
74
+ -webkit-border-radius: 5px;-moz-border-radius: 5px;border-radius: 5px;border:1px solid #962722;background-color:#F5C8C6;
75
+ color: #333;
76
+ padding: 5px;
77
+ text-align: center;
78
+ }
79
+
80
+ .spinner-inline{
81
+ float: none;
82
+ display: inline-block;
83
+ visibility: visible;
84
+ }
85
+
86
+ .installer-q-icon:before{
87
+ content: '\f223' !important;
88
+ }
89
+
90
+ .otgsi_yellow_bg{
91
+ background-color: #f2f46b;
92
+ }
93
+
94
+ .otgs_wp_installer_table_compact{
95
+ width:480px;
96
+ border: solid 1px #999;
97
+ padding:10px;
98
+ border-radius: 5px;
99
+ }
100
+
101
+ .installer-plugins-list-compact{
102
+ background-color: #fff;
103
+ border-collapse: collapse;
104
+ border:solid 1px #C1DAD7;
105
+ width:100%;
106
+ }
107
+
108
+ .installer-plugins-list-compact tr th{
109
+ padding-top:3px;
110
+ background-color: #ccc;
111
+ }
112
+
113
+ .installer-plugins-list-compact tr{
114
+ background-color: #ddd;
115
+ }
116
+
117
+ .installer-plugins-list-compact tr.even{
118
+ background-color: #eee;
119
+ }
120
+
121
+ .installer-plugins-list-compact td{
122
+ padding:2px 5px 2px 5px;
123
+ border-right: 1px solid #C1DAD7;
124
+ border-bottom: 1px solid #C1DAD7;
125
+ }
126
+
127
+ .installer-plugins-list-compact td.twelve{
128
+ width:16px;
129
+ }
130
+
131
+ .otgs_wp_installer_table_compact .installer-status-downloading,
132
+ .otgs_wp_installer_table_compact .installer-status-downloaded,
133
+ .otgs_wp_installer_table_compact .installer-status-activating,
134
+ .otgs_wp_installer_table_compact .installer-status-activated{
135
+ display: none;
136
+ color:transparent; width: 12px; padding:2px;
137
+ }
138
+
139
+ .otgs_wp_installer_table_compact .installer-status-success,
140
+ .otgs_wp_installer_table_compact .installer-status-fail{
141
+ display: none;
142
+ }
143
+
144
+ .installer-status-success{
145
+ float: right;
146
+ color: #006600;
147
+ }
148
+
149
+ .otgs_wp_installer_table_compact .installer-status-downloading{background: url(../img/dn.gif) no-repeat center; }
150
+ .otgs_wp_installer_table_compact .installer-status-downloaded{background: url(../img/complete.png) no-repeat center;}
151
+ .otgs_wp_installer_table_compact .installer-status-activating{background: url(../img/dn.gif) no-repeat center; }
152
+ .otgs_wp_installer_table_compact .installer-status-activated{background: url(../img/complete.png) no-repeat center; }
153
+ .otgs_wp_installer_table_compact .installer-status-error{background: url(../img/icon_error.gif) no-repeat center; }
154
+
155
+ .installer_highlight{
156
+ color:#c5510b;
157
+ }
158
+
159
+ .installer_highlight_package{
160
+ background-color: #fff9c0;
161
+ }
162
+
163
+ .plugin_progress{
164
+ font-style: italic;
165
+ color: #777
166
+ }
167
+
168
+ .installer-download-progress-status{
169
+ display: none;
170
+ float:right;
171
+ color: #006600;
172
+ font-style: italic;
173
+ background: url('../img/spinner.gif') no-repeat;
174
+ padding-left:24px;
175
+ }
176
+
177
+ .otgs-is-dismissible {
178
+ position: relative;
179
+ padding-right: 38px;
180
+ }
181
+ .otgs-is-dismissible .notice-dismiss {
182
+ text-decoration: none;
183
+ }
184
+ .otgs-is-dismissible p [class*="button-"] {
185
+ margin: -5px 5px;
186
+ }
embedded/installer/res/img/complete.png ADDED
Binary file
embedded/installer/res/img/computer.png ADDED
Binary file
embedded/installer/res/img/dn.gif ADDED
Binary file
embedded/installer/res/img/dn2.gif ADDED
Binary file
embedded/installer/res/img/globe.png ADDED
Binary file
embedded/installer/res/img/icon_error.gif ADDED
Binary file
embedded/installer/res/img/on.png ADDED
Binary file
embedded/installer/res/img/spinner.gif ADDED
Binary file
embedded/installer/res/js/admin.js ADDED
@@ -0,0 +1,403 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var otgs_wp_installer = {
2
+
3
+ init: function(){
4
+
5
+ jQuery('.otgs_wp_installer_table').on('click', '.enter_site_key_js', otgs_wp_installer.show_site_key_form);
6
+ jQuery('.otgs_wp_installer_table').on('click', '.cancel_site_key_js', otgs_wp_installer.hide_site_key_form);
7
+
8
+ jQuery('.otgs_wp_installer_table').on('click', '.remove_site_key_js', otgs_wp_installer.remove_site_key);
9
+ jQuery('.otgs_wp_installer_table').on('click', '.update_site_key_js', otgs_wp_installer.update_site_key);
10
+
11
+ jQuery('.otgs_wp_installer_table').on('submit', '.otgsi_site_key_form', otgs_wp_installer.save_site_key);
12
+ jQuery('.otgs_wp_installer_table').on('submit', '.otgsi_downloads_form', otgs_wp_installer.download_downloads);
13
+ jQuery('.otgs_wp_installer_table').on('change', '.otgsi_downloads_form :checkbox[name="downloads[]"]', otgs_wp_installer.update_downloads_form);
14
+
15
+ jQuery('.installer-dismiss-nag').click(otgs_wp_installer.dismiss_nag);
16
+
17
+ jQuery('.otgs_wp_installer_table').on('click', '.installer_expand_button', otgs_wp_installer.toggle_subpackages);
18
+
19
+ otgs_wp_installer.scroll_to_repository();
20
+
21
+ if( typeof pagenow != 'undefined' && pagenow == 'plugins'){
22
+
23
+ jQuery(document).ajaxSuccess(function(event, xhr, settings) {
24
+ var data = otgs_wp_installer.getQueryParameters(settings.data);
25
+ if(typeof data.action != 'undefined' && data.action == 'update-plugin'){
26
+ response = xhr.responseJSON.data;
27
+ console.log(typeof response.error);
28
+ if(typeof response.error != 'undefined'){
29
+ var default_error = jQuery('#' + response.slug + '-update .update-message').html();
30
+ jQuery('#' + response.slug + '-update .update-message').html(default_error + ' &raquo;<span class="installer-red-text"> ' + response.error + '</span>');
31
+ }
32
+ }
33
+ return false;
34
+ });
35
+
36
+ }
37
+
38
+ },
39
+
40
+ getQueryParameters : function(str) {
41
+ return (str || document.location.search).replace(/(^\?)/,'').split("&").map(function(n){return n = n.split("="),this[n[0]] = n[1],this}.bind({}))[0];
42
+ },
43
+
44
+ reset_errors: function(){
45
+ jQuery('.installer-error-box').html('').hide();
46
+ },
47
+
48
+ show_error: function(repo, text){
49
+ jQuery('#installer_repo_' + repo).find('.installer-error-box').html(text).show();
50
+ },
51
+
52
+ show_site_key_form: function(){
53
+ otgs_wp_installer.reset_errors();
54
+
55
+ var form = jQuery(this).parent().find('form.otgsi_site_key_form');
56
+ jQuery(this).prev().hide();
57
+ jQuery(this).hide();
58
+ form.css('display', 'inline');
59
+ form.find('input[name^=site_key_]').focus().val('');
60
+ form.find('input').removeAttr('disabled');
61
+
62
+ form.closest('.otgsi_register_product_wrap').addClass('otgsi_yellow_bg');
63
+
64
+ return false;
65
+ },
66
+
67
+ hide_site_key_form: function(){
68
+ var form = jQuery(this).closest('form');
69
+ form.hide();
70
+ form.parent().find('.enter_site_key_js').show();
71
+ form.parent().find('.enter_site_key_js').prev().show();
72
+
73
+ form.closest('.otgsi_register_product_wrap').removeClass('otgsi_yellow_bg');
74
+ otgs_wp_installer.reset_errors();
75
+ return false;
76
+ },
77
+
78
+ save_site_key: function(){
79
+
80
+ var thisf = jQuery(this);
81
+ var data = jQuery(this).serialize();
82
+ jQuery(this).find('input').attr('disabled', 'disabled');
83
+
84
+ var spinner = jQuery('<span class="spinner"></span>');
85
+ spinner.css({display: 'inline-block', float: 'none'}).prependTo(jQuery(this));
86
+
87
+ otgs_wp_installer.reset_errors();
88
+
89
+ jQuery.ajax({url: ajaxurl, type: 'POST', dataType:'json', data: data, success:
90
+ function(ret){
91
+ if(!ret.error){
92
+ otgs_wp_installer.saved_site_key();
93
+ }else{
94
+ otgs_wp_installer.show_error(thisf.find('[name=repository_id]').val(), ret.error);
95
+ thisf.find('input').removeAttr('disabled');
96
+ }
97
+
98
+ if(typeof ret.debug != 'undefined'){
99
+ thisf.append('<textarea style="width:100%" rows="20">' + ret.debug + '</textarea>');
100
+ }
101
+
102
+ spinner.remove();
103
+ }
104
+ });
105
+
106
+ return false;
107
+
108
+ },
109
+
110
+ saved_site_key: function(){
111
+ location.reload();
112
+ },
113
+
114
+ remove_site_key: function(){
115
+
116
+ if(confirm(jQuery(this).data('confirmation'))){
117
+
118
+ jQuery('<span class="spinner"></span>').css({visibility: 'visible', float: 'none'}).prependTo(jQuery(this).parent());
119
+ data = {action: 'remove_site_key', repository_id: jQuery(this).data('repository'), nonce: jQuery(this).data('nonce')}
120
+ jQuery.ajax({url: ajaxurl, type: 'POST', data: data, success: otgs_wp_installer.removed_site_key});
121
+ }
122
+
123
+ return false;
124
+ },
125
+
126
+ removed_site_key: function(){
127
+ location.reload();
128
+ },
129
+
130
+ update_site_key: function(){
131
+ var error_wrap = jQuery(this).closest('.otgsi_register_product_wrap').find('.installer-error-box');
132
+ error_wrap.html('');
133
+
134
+ var spinner = jQuery('<span class="spinner"></span>');
135
+
136
+ spinner.css({visibility: 'visible', float: 'none'}).prependTo(jQuery(this).parent());
137
+ data = {action: 'update_site_key', repository_id: jQuery(this).data('repository'), nonce: jQuery(this).data('nonce')}
138
+ jQuery.ajax({
139
+ url: ajaxurl,
140
+ type: 'POST',
141
+ data: data,
142
+ dataType: 'json',
143
+ complete: function( event, xhr, settings ){
144
+ var error = '';
145
+ if(xhr == 'success') {
146
+ var ret = event.responseJSON;
147
+ if(ret.error){
148
+ error = ret.error;
149
+ }else{
150
+ otgs_wp_installer.updated_site_key(ret);
151
+ }
152
+ }else{
153
+ error = 'Error processing request (' + xhr + '). Please try again!';
154
+ }
155
+
156
+ if( error ){
157
+ error_wrap.html('<p>' + error + '</p>').show();
158
+ spinner.remove();
159
+ }
160
+
161
+ }
162
+ });
163
+
164
+ return false;
165
+
166
+ },
167
+
168
+ updated_site_key: function(ret){
169
+ location.reload();
170
+ },
171
+
172
+ update_downloads_form: function(){
173
+
174
+ var checked = jQuery('.otgsi_downloads_form :checkbox:checked[name="downloads[]"]').length;
175
+
176
+ if(checked){
177
+ jQuery(this).closest('form').find(':submit, :checkbox[name=activate]').removeAttr('disabled');
178
+ }else{
179
+ jQuery(this).closest('form').find(':submit, :checkbox[name=activate]').attr('disabled', 'disabled');
180
+ }
181
+
182
+
183
+ },
184
+
185
+ download_downloads: function(){
186
+
187
+ var activate = jQuery(this).find(":checkbox:checked[name=activate]").val(),
188
+ action_button = jQuery(this).find('input[type="submit"]');
189
+ downloads_form = jQuery(this),
190
+ idx = 0,
191
+ checkboxes = [];
192
+
193
+ jQuery(this).find(':checkbox:checked[name="downloads[]"]').each(function(){
194
+ if(jQuery(this).attr('disabled')) return;
195
+ checkboxes[idx] = jQuery(this);
196
+ idx++;
197
+ jQuery(this).attr('disabled', 'disabled');
198
+ });
199
+
200
+ idx = 0;
201
+
202
+ if( typeof checkboxes[idx] != 'undefined' ){
203
+ download_and_activate( checkboxes[idx] );
204
+ action_button.attr('disabled', 'disabled');
205
+ }
206
+
207
+ function download_and_activate( elem ){
208
+
209
+ var this_tr = elem.closest('tr');
210
+ var is_update = this_tr.find('.installer-red-text').length;
211
+ if(is_update){
212
+ var installing = this_tr.find('.installer-status-updating');
213
+ var installed = this_tr.find('.installer-status-updated');
214
+ }else{
215
+ var installing = this_tr.find('.installer-status-installing');
216
+ var installed = this_tr.find('.installer-status-installed');
217
+
218
+ }
219
+ if(activate){
220
+ var activating = this_tr.find('.installer-status-activating');
221
+ var activated = this_tr.find('.installer-status-activated');
222
+ }
223
+
224
+ if( this_tr.find('.for_spinner_js .spinner').length > 0 ){
225
+ var spinner = this_tr.find('.for_spinner_js .spinner');
226
+ }else{
227
+ var spinner = this_tr.find('.installer-status-downloading');
228
+ }
229
+
230
+ otgs_wp_installer.reset_errors();
231
+ downloads_form.find('div.installer-status-success').hide();
232
+ spinner.css('visibility', 'visible');
233
+ installing.show();
234
+
235
+ var plugin_name = this_tr.find('.installer_plugin_name').html();
236
+ if(is_update){
237
+ otgs_wp_installer.show_download_progress_status(downloads_form, installer_strings.updating.replace('%s', plugin_name));
238
+ }else{
239
+ otgs_wp_installer.show_download_progress_status(downloads_form, installer_strings.installing.replace('%s', plugin_name));
240
+ }
241
+
242
+
243
+ data = {action: 'installer_download_plugin', data: elem.val(), activate: activate}
244
+
245
+ jQuery.ajax({
246
+ url: ajaxurl,
247
+ type: 'POST',
248
+ dataType: 'json',
249
+ data: data,
250
+ success: function(ret){
251
+ installing.hide();
252
+
253
+ if(!ret.success){
254
+ installed.addClass('installer-status-error');
255
+ installed.html(installed.data('fail'));
256
+
257
+ if(ret.message){
258
+ installed.closest('.otgs_wp_installer_table').find('.installer-error-box').html('<p>' + ret.message + '</p>').show();
259
+ }else{
260
+ installed.closest('.otgs_wp_installer_table').find('.installer-error-box').html('<p>' + downloads_form.find('.installer-revalidate-message').html() + '</p>').show();
261
+ }
262
+
263
+
264
+ }
265
+
266
+ installed.show();
267
+ spinner.fadeOut();
268
+
269
+ if(ret.version){
270
+ this_tr.find('.installer_version_installed').html('<span class="installer-green-text">' + ret.version + '</span>');
271
+ }
272
+
273
+ if(ret.success && activate){
274
+
275
+ otgs_wp_installer.show_download_progress_status(downloads_form, installer_strings.activating.replace('%s', plugin_name));
276
+ activating.show();
277
+ spinner.show();
278
+ this_tr.find('.installer-red-text').removeClass('installer-red-text').addClass('installer-green-text').html(ret.version);
279
+
280
+ jQuery.ajax({
281
+ url: ajaxurl,
282
+ type: 'POST',
283
+ dataType: 'json',
284
+ data: {action: 'installer_activate_plugin', plugin_id: ret.plugin_id, nonce: ret.nonce},
285
+ success: function(ret){
286
+ activating.hide();
287
+ if(!ret.error ){
288
+ activated.show();
289
+ }
290
+
291
+ spinner.fadeOut();
292
+
293
+ idx++;
294
+ if( typeof checkboxes[idx] != 'undefined' ){
295
+ download_and_activate( checkboxes[idx] );
296
+ }else{
297
+ otgs_wp_installer.hide_download_progress_status(downloads_form);
298
+ downloads_form.find('div.installer-status-success').show();
299
+ action_button.removeAttr('disabled');
300
+ }
301
+ }
302
+ });
303
+ }else{
304
+ idx++;
305
+ if( typeof checkboxes[idx] != 'undefined' ){
306
+ download_and_activate( checkboxes[idx] );
307
+ }else{
308
+ otgs_wp_installer.hide_download_progress_status(downloads_form);
309
+ downloads_form.find('div.installer-status-success').show();
310
+ action_button.removeAttr('disabled');
311
+ }
312
+ }
313
+ }
314
+
315
+ });
316
+
317
+ };
318
+
319
+ return false;
320
+ },
321
+
322
+
323
+ show_download_progress_status: function(downloads_form, text){
324
+
325
+ downloads_form.find('.installer-download-progress-status').html(text).fadeIn();
326
+
327
+ },
328
+
329
+ hide_download_progress_status: function(downloads_form){
330
+
331
+ downloads_form.find('.installer-download-progress-status').html('').fadeOut();
332
+
333
+ },
334
+
335
+ dismiss_nag: function(){
336
+
337
+ var thisa = jQuery(this);
338
+
339
+ data = {action: 'installer_dismiss_nag', repository: jQuery(this).data('repository')}
340
+
341
+ jQuery.ajax({url: ajaxurl, type: 'POST', dataType:'json', data: data, success:
342
+ function(ret){
343
+ thisa.closest('.otgs-is-dismissible').remove();
344
+ }
345
+ });
346
+
347
+ return false;
348
+ },
349
+
350
+ toggle_subpackages: function(){
351
+ var list = jQuery(this).closest('td').find('.otgs_wp_installer_subtable');
352
+
353
+ if(list.is(':visible')){
354
+ list.slideUp('fast');
355
+ }else{
356
+ list.slideDown('fast');
357
+ }
358
+
359
+
360
+ return false;
361
+
362
+ },
363
+
364
+ scroll_to_repository: function(){
365
+
366
+ var ref = window.location.hash.replace('#', '');
367
+
368
+ if(ref) {
369
+ var split = ref.split('/');
370
+ var repo = split[0];
371
+
372
+ if(typeof split[1] != 'undefined'){
373
+ var package = split[1];
374
+ var repo_element = jQuery('#repository-' + repo);
375
+
376
+
377
+
378
+ if(repo_element.length){
379
+
380
+ jQuery('html, body').animate({
381
+ scrollTop: repo_element.offset().top
382
+ }, 1000);
383
+
384
+ var package_element = jQuery('#repository-' + repo +'_' + package);
385
+
386
+ if(package_element.length && !package_element.is(':visible')){
387
+ package_element.parents('.otgs_wp_installer_subtable').slideDown();
388
+ package_element.addClass('installer_highlight_package');
389
+ }
390
+
391
+ package_element.find('.button-secondary').removeClass('button-secondary').addClass('button-primary');
392
+ }
393
+ }
394
+
395
+ }
396
+
397
+ }
398
+
399
+
400
+ }
401
+
402
+
403
+ jQuery(document).ready(otgs_wp_installer.init);
embedded/installer/res/js/iframeResizer.min.js ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ /*! iFrame Resizer (iframeSizer.min.js ) - v2.6.1 - 2014-09-03
2
+ * Desc: Force cross domain iframes to size to content.
3
+ * Requires: iframeResizer.contentWindow.min.js to be loaded into the target frame.
4
+ * Copyright: (c) 2014 David J. Bradshaw - dave@bradshaw.net
5
+ * License: MIT
6
+ */
7
+
8
+ !function(){"use strict";function a(a,b,c){"addEventListener"in window?a.addEventListener(b,c,!1):"attachEvent"in window&&a.attachEvent("on"+b,c)}function b(){var a,b=["moz","webkit","o","ms"];for(a=0;a<b.length&&!w;a+=1)w=window[b[a]+"RequestAnimationFrame"];w||c(" RequestAnimationFrame not supported")}function c(a){y.log&&"object"==typeof console&&console.log(s+"[Host page"+u+"]"+a)}function d(a){function b(){function a(){h(z),f(),y.resizedCallback(z)}i(a,z,"resetPage")}function d(a){var b=a.id;c(" Removing iFrame: "+b),a.parentNode.removeChild(a),y.closedCallback(b),c(" --")}function e(){var a=x.substr(t).split(":");return{iframe:document.getElementById(a[0]),id:a[0],height:a[1],width:a[2],type:a[3]}}function j(a){var b=Number(y["max"+a]),d=Number(y["min"+a]),e=a.toLowerCase(),f=Number(z[e]);if(d>b)throw new Error("Value for min"+a+" can not be greater than max"+a);c(" Checking "+e+" is in range "+d+"-"+b),d>f&&(f=d,c(" Set "+e+" to min value")),f>b&&(f=b,c(" Set "+e+" to max value")),z[e]=""+f}function k(){var b=a.origin,d=z.iframe.src.split("/").slice(0,3).join("/");if(y.checkOrigin&&(c(" Checking connection is from: "+d),""+b!="null"&&b!==d))throw new Error("Unexpected message received from: "+b+" for "+z.iframe.id+". Message was: "+a.data+". This error can be disabled by adding the checkOrigin: false option.");return!0}function l(){return s===(""+x).substr(0,t)}function m(){var a=z.type in{"true":1,"false":1};return a&&c(" Ignoring init message from meta parent page"),a}function n(){var a=x.substr(x.indexOf(":")+r+6);c(" MessageCallback passed: {iframe: "+z.iframe.id+", message: "+a+"}"),y.messageCallback({iframe:z.iframe,message:a}),c(" --")}function o(){if(null===z.iframe)throw new Error("iFrame ("+z.id+") does not exist on "+u);return!0}function q(){c(" Reposition requested from iFrame"),v={x:z.width,y:z.height},f()}function w(){switch(z.type){case"close":d(z.iframe),y.resizedCallback(z);break;case"message":n();break;case"scrollTo":q();break;case"reset":g(z);break;case"init":b(),y.initCallback(z.iframe);break;default:b()}}var x=a.data,z={};l()&&(c(" Received: "+x),z=e(),j("Height"),j("Width"),!m()&&o()&&k()&&(w(),p=!1))}function e(){null===v&&(v={x:void 0!==window.pageXOffset?window.pageXOffset:document.documentElement.scrollLeft,y:void 0!==window.pageYOffset?window.pageYOffset:document.documentElement.scrollTop},c(" Get position: "+v.x+","+v.y))}function f(){null!==v&&(window.scrollTo(v.x,v.y),c(" Set position: "+v.x+","+v.y),v=null)}function g(a){function b(){h(a),j("reset","reset",a.iframe)}c(" Size reset requested by "+("init"===a.type?"host page":"iFrame")),e(),i(b,a,"init")}function h(a){function b(b){a.iframe.style[b]=a[b]+"px",c(" IFrame ("+a.iframe.id+") "+b+" set to "+a[b]+"px")}y.sizeHeight&&b("height"),y.sizeWidth&&b("width")}function i(a,b,d){d!==b.type&&w?(c(" Requesting animation frame"),w(a)):a()}function j(a,b,d){c("["+a+"] Sending msg to iframe ("+b+")"),d.contentWindow.postMessage(s+b,"*")}function k(){function b(){function a(a){1/0!==y[a]&&0!==y[a]&&(k.style[a]=y[a]+"px",c(" Set "+a+" = "+y[a]+"px"))}a("maxHeight"),a("minHeight"),a("maxWidth"),a("minWidth")}function d(a){return""===a&&(k.id=a="iFrameResizer"+o++,c(" Added missing iframe ID: "+a+" ("+k.src+")")),a}function e(){c(" IFrame scrolling "+(y.scrolling?"enabled":"disabled")+" for "+l),k.style.overflow=!1===y.scrolling?"hidden":"auto",k.scrolling=!1===y.scrolling?"no":"yes"}function f(){("number"==typeof y.bodyMargin||"0"===y.bodyMargin)&&(y.bodyMarginV1=y.bodyMargin,y.bodyMargin=""+y.bodyMargin+"px")}function h(){return l+":"+y.bodyMarginV1+":"+y.sizeWidth+":"+y.log+":"+y.interval+":"+y.enablePublicMethods+":"+y.autoResize+":"+y.bodyMargin+":"+y.heightCalculationMethod+":"+y.bodyBackground+":"+y.bodyPadding+":"+y.tolerance}function i(b){a(k,"load",function(){var a=p;j("iFrame.onload",b,k),!a&&y.heightCalculationMethod in x&&g({iframe:k,height:0,width:0,type:"init"})}),j("init",b,k)}var k=this,l=d(k.id);e(),b(),f(),i(h())}function l(a){if("object"!=typeof a)throw new TypeError("Options is not an object.")}function m(){function a(a){if("IFRAME"!==a.tagName.toUpperCase())throw new TypeError("Expected <IFRAME> tag, found <"+a.tagName+">.");k.call(a)}function b(a){a=a||{},l(a);for(var b in z)z.hasOwnProperty(b)&&(y[b]=a.hasOwnProperty(b)?a[b]:z[b])}return function(c,d){b(c),Array.prototype.forEach.call(document.querySelectorAll(d||"iframe"),a)}}function n(a){a.fn.iFrameResize=function(b){return b=b||{},l(b),y=a.extend({},z,b),this.filter("iframe").each(k).end()}}var o=0,p=!0,q="message",r=q.length,s="[iFrameSizer]",t=s.length,u="",v=null,w=window.requestAnimationFrame,x={max:1,scroll:1,bodyScroll:1,documentElementScroll:1},y={},z={autoResize:!0,bodyBackground:null,bodyMargin:null,bodyMarginV1:8,bodyPadding:null,checkOrigin:!0,enablePublicMethods:!1,heightCalculationMethod:"offset",interval:32,log:!1,maxHeight:1/0,maxWidth:1/0,minHeight:0,minWidth:0,scrolling:!1,sizeHeight:!0,sizeWidth:!1,tolerance:0,closedCallback:function(){},initCallback:function(){},messageCallback:function(){},resizedCallback:function(){}};b(),a(window,"message",d),"jQuery"in window&&n(jQuery),"function"==typeof define&&define.amd?define(function(){return m()}):window.iFrameResize=m()}();
9
+ //# sourceMappingURL=../src/iframeResizer.map
10
+
embedded/installer/res/js/installer_theme_install.js ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery( document ).ready( function( $ ) {
2
+
3
+ /** Append OTGS Theme tab */
4
+ var js_array= installer_theme_install_localize.js_array_installer;
5
+
6
+ if (!($.isEmptyObject(js_array))) {
7
+ //Unempty
8
+ for(var key in js_array) {
9
+ //Dont append if we are on commercial plugins tab page and if there are no themes
10
+ if ((!(js_array[key]['is_commercial_plugin_tab'])) && (!(installer_theme_install_localize.no_associated_themes))) {
11
+ $('div.wp-filter ul.filter-links').append('<li><a data-sort="'+key+'" href="#">'+ js_array[key]['the_hyperlink_text'] +'</a></li>');
12
+ }
13
+ }
14
+ }
15
+
16
+ /** Page load event tab selected identifier */
17
+ var loaded_browsing_tab=installer_theme_extended_object.getParameterByName('browse');
18
+ if (loaded_browsing_tab.length > 0) {
19
+
20
+ var frontend_tab_selected_tab = loaded_browsing_tab;
21
+
22
+ } else if (0 == loaded_browsing_tab.length){
23
+
24
+ //WordPress defaults to 'Featured' when theme install is loaded without the browse parameter
25
+ var frontend_tab_selected_tab = 'featured';
26
+ }
27
+
28
+ /** Prepare data on page load event for AJAX */
29
+ var data = {
30
+ action: 'installer_theme_frontend_selected_tab',
31
+ installer_theme_frontend_selected_tab_nonce: installer_theme_install_localize.installer_theme_frontend_selected_tab_nonce,
32
+ frontend_tab_selected :frontend_tab_selected_tab
33
+ };
34
+
35
+ //Call AJAX
36
+ installer_theme_extended_object.doAJAX(data,frontend_tab_selected_tab,js_array);
37
+
38
+ /** When user clicks on any tab */
39
+ $(document).on('click','.filter-links li > a',function () {
40
+
41
+ //Get data_sort
42
+ var data_sort =$(this).attr('data-sort');
43
+
44
+ if (data_sort) {
45
+ //data_sort is set, prepare data
46
+ var data = {
47
+ action: 'installer_theme_frontend_selected_tab',
48
+ installer_theme_frontend_selected_tab_nonce: installer_theme_install_localize.installer_theme_frontend_selected_tab_nonce,
49
+ frontend_tab_selected : data_sort
50
+ };
51
+
52
+ //Call AJAX
53
+ installer_theme_extended_object.doAJAX(data,data_sort,js_array);
54
+
55
+ }
56
+ });
57
+
58
+ var fullhash = window.location.hash;
59
+ if (fullhash.length > 0) {
60
+ var product_selector=fullhash+' '+'.enter_site_key_js';
61
+ if ($(product_selector).length ) {
62
+ $(product_selector).click();
63
+ }
64
+ }
65
+ });
66
+
67
+ //Installer theme extended JS object for methods
68
+ var installer_theme_extended_object = {
69
+
70
+ getParameterByName: function(name) {
71
+ name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
72
+ var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
73
+ results = regex.exec(location.search);
74
+ return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
75
+ },
76
+
77
+ doAJAX: function(data,data_sort,js_array) {
78
+
79
+ //We only want to post to AJAX if its an OTGS tab
80
+ jQuery.post(installer_theme_install_localize.ajaxurl, data, function(response) {
81
+ //AJAX response
82
+ var myObject = jQuery.parseJSON(response);
83
+ if (typeof myObject != "undefined") {
84
+ if(myObject.hasOwnProperty("output")){
85
+ var tab_selected= myObject.output;
86
+ if (data_sort in js_array) {
87
+ if (!(installer_theme_install_localize.js_array_installer[tab_selected]['registration_status'])) {
88
+ //Not registered, no theme response
89
+ var unregistered_message= myObject.unregistered_messages;
90
+ jQuery('.no-themes').html(unregistered_message);
91
+ }
92
+ }
93
+ }
94
+ }
95
+ });
96
+ }
97
+ };
embedded/installer/templates/downloads-list-compact.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ <form method="post" class="otgsi_downloads_form">
3
+
4
+ <table class="installer-plugins-list-compact">
5
+ <thead>
6
+ <tr>
7
+ <th>&nbsp;</th>
8
+ <th><?php _e('Plugin', 'installer') ?></th>
9
+ <th><img src="<?php echo $this->plugin_url() ?>/res/img/globe.png" alt="<?php esc_attr_e('Available', 'installer') ?>" width="16" height="16"></th>
10
+ <th><img src="<?php echo $this->plugin_url() ?>/res/img/computer.png" alt="<?php esc_attr_e('Installed', 'installer') ?>" width="16" height="16"></th>
11
+ <th><img src="<?php echo $this->plugin_url() ?>/res/img/dn2.gif" alt="<?php esc_attr_e('Downloading', 'installer') ?>" width="16" height="16"></th>
12
+ <th><img src="<?php echo $this->plugin_url() ?>/res/img/on.png" alt="<?php esc_attr_e('Activate', 'installer') ?>" width="16" height="16"></th>
13
+ </tr>
14
+ </thead>
15
+ <tbody>
16
+ <?php foreach($product['downloads'] as $download): ?>
17
+ <?php if(empty($tr_oddeven) || $tr_oddeven == 'even') $tr_oddeven = 'odd'; else $tr_oddeven = 'even'; ?>
18
+ <tr class="<?php echo $tr_oddeven ?>">
19
+ <td>
20
+ <label>
21
+ <?php
22
+ $url = $this->append_site_key_to_download_url($download['url'], $site_key, $repository_id );
23
+
24
+ $download_data = array(
25
+ 'url' => $url,
26
+ 'slug' => $download['slug'],
27
+ 'nonce' => wp_create_nonce('install_plugin_' . $url),
28
+ 'repository_id' => $repository_id
29
+ );
30
+
31
+ $disabled = $expired ||
32
+ (
33
+ $this->plugin_is_installed($download['name'], $download['slug'], $download['version']) &&
34
+ !$this->plugin_is_embedded_version($download['name'], $download['slug'])
35
+ ) || WP_Installer()->dependencies->cant_download( $repository_id );
36
+
37
+ ?>
38
+ <input type="checkbox" name="downloads[]" value="<?php echo base64_encode(json_encode($download_data)); ?>" <?php
39
+ if($disabled): ?>disabled="disabled"<?php endif; ?> />&nbsp;
40
+
41
+ </label>
42
+ </td>
43
+ <td class="installer_plugin_name"><?php echo $download['name'] ?></td>
44
+ <td><?php echo $download['version'] ?></td>
45
+ <td class="installer_version_installed">
46
+ <?php if($v = $this->plugin_is_installed($download['name'], $download['slug'])):
47
+ $class = version_compare($v, $download['version'], '>=') ? 'installer-green-text' : 'installer-red-text'; ?>
48
+ <span class="<?php echo $class ?>"><?php echo $v; ?></span>
49
+ <?php endif; ?>
50
+ </td>
51
+ <td class="twelve">
52
+ <div class="installer-status-downloading"><?php _e('downloading...', 'installer') ?></div>
53
+ <div class="installer-status-downloaded" data-fail="<?php _e('failed!', 'installer') ?>"><?php _e('downloaded', 'installer') ?></div>
54
+ </td>
55
+ <td class="twelve">
56
+ <div class="installer-status-activating"><?php _e('activating', 'installer') ?></div>
57
+ <div class="installer-status-activated"><?php _e('activated', 'installer') ?></div>
58
+ </td>
59
+ </tr>
60
+ <?php endforeach; ?>
61
+ </tbody>
62
+ </table>
63
+
64
+ <?php if( !WP_Installer()->dependencies->is_uploading_allowed() ): ?>
65
+ <p class="installer-error-box"><?php printf(__('Downloading is not possible because WordPress cannot write into the plugins folder. %sHow to fix%s.', 'installer'),
66
+ '<a href="http://codex.wordpress.org/Changing_File_Permissions">', '</a>') ?></p>
67
+ <?php elseif( WP_Installer()->dependencies->is_win_paths_exception($repository_id) ): ?>
68
+ <p><?php echo WP_Installer()->dependencies->win_paths_exception_message() ?></p>
69
+ <?php endif;?>
70
+
71
+ <br />
72
+ <input type="submit" class="button-secondary" value="<?php esc_attr_e('Download', 'installer') ?>" disabled="disabled" />
73
+ &nbsp;
74
+ <label><input name="activate" type="checkbox" value="1" disabled="disabled" />&nbsp;<?php _e('Activate after download', 'installer') ?></label>
75
+
76
+ <div class="installer-download-progress-status"></div>
77
+ <div class="installer-status-success"><?php _e('Operation complete!', 'installer') ?></div>
78
+
79
+ <span class="installer-revalidate-message hidden"><?php _e("Download failed!\n\nClick OK to revalidate your subscription or CANCEL to try again.", 'installer') ?></span>
80
+ </form>
embedded/installer/templates/downloads-list.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <br clear="all" /><br />
2
+ <strong><?php _e('Downloads:', 'installer') ?></strong>
3
+
4
+ <form method="post" class="otgsi_downloads_form">
5
+
6
+ <table class="widefat">
7
+ <thead>
8
+ <tr>
9
+ <th>&nbsp;</th>
10
+ <th><?php _e('Plugin', 'installer') ?></th>
11
+ <th><?php _e('Current version', 'installer') ?></th>
12
+ <th><?php _e('Released', 'installer') ?></th>
13
+ <th><?php _e('Installed version', 'installer') ?></th>
14
+ <th>&nbsp;</th>
15
+ <th>&nbsp;</th>
16
+ <th>&nbsp;</th>
17
+ </tr>
18
+ </thead>
19
+ <tbody>
20
+ <?php
21
+ foreach($package['downloads'] as $download): ?>
22
+ <tr>
23
+ <td>
24
+ <label>
25
+ <?php
26
+ $url = $this->append_site_key_to_download_url($download['url'], $site_key, $repository_id);
27
+
28
+ $download_data = array(
29
+ 'url' => $url,
30
+ 'slug' => $download['slug'],
31
+ 'nonce' => wp_create_nonce('install_plugin_' . $url),
32
+ 'repository_id' => $repository_id
33
+ );
34
+ ?>
35
+ <input type="checkbox" name="downloads[]" value="<?php echo base64_encode(json_encode($download_data)); ?>" <?php
36
+ if($this->plugin_is_installed($download['name'], $download['slug'], $download['version']) && !$this->plugin_is_embedded_version($download['name'], $download['slug']) || WP_Installer()->dependencies->cant_download($repository_id) ): ?>disabled="disabled"<?php endif; ?> />&nbsp;
37
+
38
+ </label>
39
+ </td>
40
+ <td class="installer_plugin_name"><?php echo $download['name'] ?></td>
41
+ <td><?php echo $download['version'] ?></td>
42
+ <td><?php echo date_i18n('F j, Y', strtotime($download['date'])) ?></td>
43
+ <td class="installer_version_installed">
44
+ <?php if($v = $this->plugin_is_installed($download['name'], $download['slug'])): $class = version_compare($v, $download['version'], '>=') ? 'installer-green-text' : 'installer-red-text'; ?>
45
+ <span class="<?php echo $class ?>"><?php echo $v; ?></span>
46
+ <?php if($this->plugin_is_embedded_version($download['name'], $download['slug'])): ?>&nbsp;<?php _e('(embedded)', 'installer'); ?><?php endif; ?>
47
+ <?php endif; ?>
48
+ </td>
49
+ <td>
50
+ <span class="installer-status-installing"><?php _e('installing...', 'installer') ?></span>
51
+ <span class="installer-status-updating"><?php _e('updating...', 'installer') ?></span>
52
+ <span class="installer-status-installed" data-fail="<?php _e('failed!', 'installer') ?>"><?php _e('installed', 'installer') ?></span>
53
+ <span class="installer-status-updated" data-fail="<?php _e('failed!', 'installer') ?>"><?php _e('updated', 'installer') ?></span>
54
+ </td>
55
+ <td>
56
+ <span class="installer-status-activating"><?php _e('activating', 'installer') ?></span>
57
+ <span class="installer-status-activated"><?php _e('activated', 'installer') ?></span>
58
+ </td>
59
+ <td class="for_spinner_js"><span class="spinner"></span></td>
60
+ </tr>
61
+ <?php endforeach; ?>
62
+ </tbody>
63
+ </table>
64
+
65
+ <br />
66
+
67
+ <div class="installer-error-box">
68
+ <?php if( !WP_Installer()->dependencies->is_uploading_allowed() ): ?>
69
+ <p><?php printf(__('Downloading is not possible because WordPress cannot write into the plugins folder. %sHow to fix%s.', 'installer'),
70
+ '<a href="http://codex.wordpress.org/Changing_File_Permissions">', '</a>') ?></p>
71
+ <?php elseif( WP_Installer()->dependencies->is_win_paths_exception($repository_id) ): ?>
72
+ <p><?php echo WP_Installer()->dependencies->win_paths_exception_message() ?></p>
73
+ <?php endif; ?>
74
+ </div>
75
+
76
+ <input type="submit" class="button-secondary" value="<?php esc_attr_e('Download', 'installer') ?>" disabled="disabled" />
77
+ &nbsp;
78
+ <label><input name="activate" type="checkbox" value="1" disabled="disabled" />&nbsp;<?php _e('Activate after download', 'installer') ?></label>
79
+
80
+ <div class="installer-download-progress-status"></div>
81
+
82
+ <div class="installer-status-success"><?php _e('Operation complete!', 'installer') ?></div>
83
+
84
+ <span class="installer-revalidate-message hidden"><?php _e("Download failed!\n\nPlease refresh the page and try again.", 'installer') ?></span>
85
+ </form>
embedded/installer/templates/products-compact.php ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <h3><?php echo $args['box_title'] ?></h3>
2
+
3
+ <?php
4
+ if(empty($args['repository']) || empty($args['package']) || empty($args['product'])){
5
+ echo __('Incorrect setup', 'installer');
6
+ return;
7
+ }
8
+
9
+ $product = false;
10
+ foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package_idx => $package){
11
+
12
+ //pre 1.3 backwardds compatibility
13
+ if(!isset($package['id'])){
14
+ $package['id'] = sanitize_title_with_dashes($package['name']);
15
+ }
16
+
17
+ if($package['id'] == $args['package']){
18
+ $product = $this->settings['repositories'][$repository_id]['data']['packages'][$package_idx]['products'][$args['product']];
19
+ break;
20
+ }
21
+ }
22
+
23
+
24
+ if(!$product){
25
+ echo __('Invalid product', 'installer');
26
+ return;
27
+ }
28
+
29
+ if(isset($this->settings['repositories'][$repository_id])){
30
+ if(isset($this->settings['repositories'][$repository_id]['subscription']['key'])){
31
+ $site_key = $this->settings['repositories'][$repository_id]['subscription']['key'];
32
+ }else{
33
+ $site_key = false;
34
+ }
35
+ }else{
36
+ echo __('Unknown repository', 'installer');
37
+ return;
38
+ }
39
+
40
+ $subscription_type = $this->get_subscription_type_for_repository($repository_id);
41
+ $expired = false;
42
+
43
+ if($subscription_type != $product['subscription_type'] && !$this->have_superior_subscription($subscription_type, $product) && $site_key){
44
+ $subscription_no_match = sprintf(__(' Your current site key (%s) does not match the selected product (%s).', 'installer'), $site_key, $product['name']);
45
+ }
46
+
47
+ if(!isset($args['product_name'])) $args['product_name'] = $product['name'];
48
+
49
+ ?>
50
+
51
+ <div class="otgs_wp_installer_table otgs_wp_installer_table_compact">
52
+
53
+ <p><?php echo $args['box_description'] ?></p>
54
+
55
+
56
+ <?php if(!$this->repository_has_subscription($repository_id) || !empty($subscription_no_match)): ?>
57
+
58
+ <?php if(!empty($subscription_no_match)): ?>
59
+ <div class="installer-warn-box">
60
+ <?php echo $subscription_no_match; ?>
61
+ </div>
62
+ <br />
63
+ <?php endif; ?>
64
+
65
+ <a class="button-primary" href="<?php echo $this->append_parameters_to_buy_url($product['url'], $repository_id, $args) ?>"><?php printf(__('Buy %s', 'installer'), $args['product_name']) ?></a>
66
+
67
+ <div>
68
+ <br />
69
+ <?php printf(__('Already bought %s?', 'installer'), $args['product_name']) ?>
70
+ <a class="enter_site_key_js" href="#"><?php _e('Enter site key', 'installer') ?></a>&nbsp;&nbsp;
71
+
72
+ <form class="otgsi_site_key_form" method="post">
73
+ <input type="hidden" name="action" value="save_site_key" />
74
+ <input type="hidden" name="nonce" value="<?php echo wp_create_nonce('save_site_key_' . $repository_id) ?>" />
75
+ <input type="hidden" name="repository_id" value="<?php echo $repository_id ?>">
76
+ <input type="text" size="10" name="site_key_<?php echo $repository_id ?>" />
77
+ <input class="button-secondary" type="submit" value="<?php esc_attr_e('Add', 'installer') ?>" />
78
+ </form>
79
+ <div class="installer-error-box hidden" style="margin-top:10px;"></div>
80
+ </div>
81
+
82
+ <?php else: ?>
83
+
84
+ <?php if($this->repository_has_expired_subscription($repository_id)): $expired = true; ?>
85
+
86
+ <div><p class="installer-warn-box"><?php _e('Subscription is expired.', 'installer') ?></p></div>
87
+
88
+ <?php else: ?>
89
+
90
+ <?php if($this->show_subscription_renew_warning($repository_id, $subscription_type)): ?>
91
+
92
+ <ul class="installer-products-list">
93
+ <?php foreach($product['renewals'] as $renewal): ?>
94
+ <li>
95
+ <a href="<?php echo $this->append_parameters_to_buy_url($renewal['url'], $repository_id, $args) ?>"><?php printf(__('Renew %s', 'installer'), $args['product_name']) ?></a>
96
+ </li>
97
+ <?php endforeach; ?>
98
+ </ul>
99
+
100
+ <?php endif; ?>
101
+
102
+ <?php endif; ?>
103
+
104
+ <center>
105
+ <a class="remove_site_key_js" href="#" data-repository=<?php echo $repository_id ?> data-confirmation="<?php esc_attr_e('Are you sure you want to remove this site key?', 'installer') ?>" data-nonce="<?php echo wp_create_nonce('remove_site_key_' . $repository_id) ?>"><?php printf(__("Remove current site key (%s)", 'installer'), $site_key) ?></a>
106
+ </center>
107
+ <br />
108
+
109
+ <?php include $this->plugin_path() . '/templates/downloads-list-compact.php'; ?>
110
+
111
+
112
+
113
+ <?php endif; ?>
114
+
115
+ <?php
116
+ if( isset( $args[ 'name' ] ) ):
117
+ $support_link = $this->get_support_tag_by_name($args['name'], $args['repository']); ?>
118
+
119
+ <?php if($support_link): ?>
120
+ <p><a href="<?php echo $support_link ?>" target="_blank"><?php printf(__('%s support on wpml.org', 'installer'), $args['name'] ) ?></a></p>
121
+
122
+ <?php endif; ?>
123
+ <?php
124
+ // compatibility for installer 1.1
125
+ elseif( isset( $args[ 'support_link' ] ) ): ?>
126
+ <p><?php echo $args[ 'support_link' ]; ?></p>
127
+ <?php endif; ?>
128
+
129
+ </div>
embedded/installer/templates/repository-listing.php ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if((!$this->repository_has_subscription($repository_id) && $match = $this->get_matching_cp($repository)) && $match['exp']): ?>
2
+ <p class="alignright installer_highlight"><strong><?php printf('Price offers available until %s', date_i18n(get_option( 'date_format' ), $match['exp'])) ?></strong></p>
3
+ <?php endif; ?>
4
+
5
+ <h3 id="repository-<?php echo $repository_id ?>"><?php echo $repository['data']['name'] ?></h3>
6
+ <?php
7
+ $generic_product_name = $this->settings['repositories'][$repository_id]['data']['product-name'];
8
+ ?>
9
+ <table class="widefat otgs_wp_installer_table" id="installer_repo_<?php echo $repository_id ?>">
10
+
11
+ <tr>
12
+ <td>&nbsp;</td>
13
+ <td class="otgsi_register_product_wrap" align="center" valign="top">
14
+ <?php // IF NO SUBSCRIPTION ?>
15
+ <?php if(!$this->repository_has_subscription($repository_id)): ?>
16
+
17
+ <div style="text-align: right;">
18
+ <span><?php _e('Already bought?', 'installer'); ?>&nbsp;</span>
19
+ <a class="enter_site_key_js button-primary" href="#"><?php printf(__('Register %s', 'installer'), $generic_product_name); ?></a>&nbsp;&nbsp;
20
+ <form class="otgsi_site_key_form" method="post">
21
+ <input type="hidden" name="action" value="save_site_key" />
22
+ <input type="hidden" name="nonce" value="<?php echo wp_create_nonce('save_site_key_' . $repository_id) ?>" />
23
+ <input type="hidden" name="repository_id" value="<?php echo $repository_id ?>">
24
+ <?php _e('2. Enter your site key', 'installer'); ?>
25
+ <input type="text" size="10" name="site_key_<?php echo $repository_id ?>" placeholder="<?php echo esc_attr('site key') ?>" />
26
+ <input class="button-primary" type="submit" value="<?php esc_attr_e('OK', 'installer') ?>" />
27
+ <input class="button-secondary cancel_site_key_js" type="button" value="<?php esc_attr_e('Cancel', 'installer') ?>" />
28
+
29
+ <div class="alignleft" style="margin-top:6px;"><?php printf(__('1. Go to your %s%s account%s and add this site URL: %s', 'installer'),
30
+ '<a href="' . $this->settings['repositories'][$repository_id]['data']['site_keys_management_url'] . '?add='.urlencode($this->get_installer_site_url( $repository_id )).'">',
31
+ $generic_product_name, '</a>', $this->get_installer_site_url( $repository_id )); ?></div>
32
+ </form>
33
+
34
+
35
+ </div>
36
+
37
+ <?php
38
+ $site_key = false;
39
+
40
+ // IF SUBSCRIPTION
41
+ else:
42
+
43
+ $site_key = $this->settings['repositories'][$repository_id]['subscription']['key'];
44
+ $subscription_type = $this->get_subscription_type_for_repository($repository_id);
45
+
46
+ $upgrade_options = $this->get_upgrade_options($repository_id);
47
+ $expired = false;
48
+
49
+ ?>
50
+
51
+ <?php if($this->repository_has_expired_subscription($repository_id)): $expired = true; ?>
52
+ <div>
53
+ <p class="installer-warn-box">
54
+ <?php _e('Subscription expired. You need to either purchase a new subscription or upgrade if available.', 'installer') ?>
55
+ <span class="alignright">
56
+ <a class="update_site_key_js button-secondary" href="#" data-repository=<?php echo $repository_id ?> data-nonce="<?php echo wp_create_nonce('update_site_key_' . $repository_id) ?>">
57
+ <?php _e('Revalidate subscription', 'installer'); ?>
58
+ </a>
59
+ </span>
60
+ <br />
61
+ <span class="details"><?php _e("If you have already purchased or renewed your subscription and you can still see this message, please revalidate your subscription", 'installer') ?></span>
62
+ </p>
63
+ </div>
64
+ <?php else: ?>
65
+ <?php $this->show_subscription_renew_warning($repository_id, $subscription_type); ?>
66
+ <?php endif; ?>
67
+
68
+ <div class="alignright">
69
+ <a class="remove_site_key_js button-secondary" href="#" data-repository=<?php echo $repository_id ?> data-confirmation="<?php esc_attr_e('Are you sure you want to unregister?', 'installer') ?>" data-nonce="<?php echo wp_create_nonce('remove_site_key_' . $repository_id) ?>"><?php printf(__("Unregister %s from this site", 'installer'), $generic_product_name) ?></a>&nbsp;
70
+ <a class="update_site_key_js button-secondary" href="#" data-repository=<?php echo $repository_id ?> data-nonce="<?php echo wp_create_nonce('update_site_key_' . $repository_id) ?>">
71
+ <?php _e('Check for updates', 'installer'); ?>
72
+ </a>
73
+ </div>
74
+
75
+ <?php if(empty($expired)): ?>
76
+ <div class="alignleft">
77
+ <?php if($expires = $this->settings['repositories'][$repository_id]['subscription']['data']->expires): ?>
78
+ <?php printf(__('%s is registered on this site. You will receive automatic updates until %s', 'installer'), $generic_product_name, date_i18n('F j, Y', strtotime($expires))); ?>
79
+ <?php else: ?>
80
+ <?php printf(__('%s is registered on this site. Your Lifetime account gives you updates for life.', 'installer'), $generic_product_name); ?>
81
+ <?php endif; ?>
82
+ </div>
83
+ <?php endif; //if(empty($expired)) ?>
84
+
85
+ <?php endif; // if(!repository_has_subscription) ?>
86
+ <br clear="all" />
87
+ <div class="installer-error-box hidden"></div>
88
+
89
+ </td>
90
+ </tr>
91
+
92
+ <?php
93
+
94
+ $subscription_type = isset($subscription_type) ? $subscription_type : null;
95
+ $expired = isset($expired) ? $expired : null;
96
+ $upgrade_options = isset($upgrade_options) ? $upgrade_options : null;
97
+ $packages = $this->_render_product_packages($repository['data']['packages'], $subscription_type, $expired, $upgrade_options, $repository_id);
98
+ if(empty($subscription_type) || $expired){
99
+ $subpackages_expandable = true;
100
+ }else{
101
+ $subpackages_expandable = false;
102
+ }
103
+
104
+ ?>
105
+
106
+ <?php foreach($packages as $package): ?>
107
+ <tr id="repository-<?php echo $repository_id ?>_<?php echo $package['id'] ?>">
108
+ <td><img width="140" height="140" src="<?php echo $package['image_url'] ?>" /></td>
109
+ <td>
110
+ <p><strong><?php echo $package['name'] ?></strong></p>
111
+ <p><?php echo $package['description'] ?></p>
112
+
113
+ <?php if($package['products']): ?>
114
+ <?php foreach($package['products'] as $product): ?>
115
+ <ul class="installer-products-list" style="display:inline">
116
+ <li>
117
+ <a class="button-secondary" href="<?php echo $product['url'] ?>"><?php echo $product['label'] ?></a>
118
+ </li>
119
+ </ul>
120
+ <?php endforeach; ?>
121
+ <?php endif; ?>
122
+
123
+ <?php if($package['downloads']): ?>
124
+ <?php include $this->plugin_path() . '/templates/downloads-list.php'; ?>
125
+ <?php endif; ?>
126
+
127
+ <?php if(!empty($package['sub-packages'])): ?>
128
+
129
+ <?php $subpackages = $this->_render_product_packages($package['sub-packages'], $subscription_type, $expired, $upgrade_options, $repository_id); ?>
130
+
131
+ <?php if($subpackages): ?>
132
+
133
+ <?php if($subpackages_expandable): ?>
134
+ <h5><a class="installer_expand_button" href="#" title="<?php esc_attr_e('Click to see individual components options.', 'installer') ?>"><?php _e('Individual components', 'installer') ?></a></h5>
135
+ <?php endif; ?>
136
+
137
+ <table class="otgs_wp_installer_subtable" style="<?php if($subpackages_expandable) echo 'display:none' ?>">
138
+ <?php foreach($subpackages as $package): ?>
139
+ <tr id="repository-<?php echo $repository_id ?>_<?php echo $package['id'] ?>">
140
+ <td><img width="70" height="70" src="<?php echo $package['image_url'] ?>" /></td>
141
+ <td>
142
+ <p><strong><?php echo $package['name'] ?></strong></p>
143
+ <p><?php echo $package['description'] ?></p>
144
+
145
+ <?php if($package['products']): ?>
146
+ <?php foreach($package['products'] as $product): ?>
147
+ <ul class="installer-products-list" style="display:inline">
148
+ <li>
149
+ <a class="button-secondary" href="<?php echo $product['url'] ?>"><?php echo $product['label'] ?></a>
150
+ </li>
151
+ </ul>
152
+ <?php endforeach; ?>
153
+ <?php endif; ?>
154
+
155
+ <?php if($package['downloads']): ?>
156
+ <?php include $this->plugin_path() . '/templates/downloads-list.php'; ?>
157
+ <?php endif; ?>
158
+ </td>
159
+ </tr>
160
+ <?php endforeach; ?>
161
+ </table>
162
+ <?php endif; ?>
163
+
164
+ <?php endif; ?>
165
+
166
+
167
+ </td>
168
+ </tr>
169
+
170
+ <?php endforeach; ?>
171
+
172
+ </table>
173
+
174
+
175
+ <p><i><?php printf(__('This page lets you install plugins and update existing plugins. To remove any of these plugins, go to the %splugins%s page and if you have the permission to remove plugins you should be able to do this.', 'installer'), '<a href="' . admin_url('plugins.php') . '">' , '</a>'); ?></i></p>
176
+
177
+
178
+
179
+ <br />
inc/admin-menus/class-wcml-admin-menus.php ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_Admin_Menus{
4
+
5
+ private static $woocommerce_wpml;
6
+ private static $sitepress;
7
+
8
+ public static function set_up_menus( &$woocommerce_wpml, &$sitepress, $check_dependencies ){
9
+ self::$woocommerce_wpml =& $woocommerce_wpml;
10
+ self::$sitepress =& $sitepress;
11
+
12
+ add_action('admin_menu', array(__CLASS__, 'register_menus'));
13
+
14
+ if( self::is_page_without_admin_language_switcher() ){
15
+ self::remove_wpml_admin_language_switcher();
16
+ }
17
+
18
+ if( is_admin() && !is_null( $sitepress ) && $check_dependencies ){
19
+ add_action('admin_footer', array(__CLASS__, 'documentation_links'));
20
+ add_action( 'admin_head', array( __CLASS__, 'hide_multilingual_content_setup_box' ) );
21
+ add_action( 'admin_init', array( __CLASS__, 'restrict_admin_with_redirect' ) );
22
+ }
23
+
24
+ }
25
+
26
+ public static function register_menus(){
27
+ if( self::$woocommerce_wpml->check_dependencies && self::$woocommerce_wpml->check_design_update){
28
+ $top_page = apply_filters('icl_menu_main_page', basename(ICL_PLUGIN_PATH) .'/menu/languages.php');
29
+
30
+ if(current_user_can('wpml_manage_woocommerce_multilingual')){
31
+ add_submenu_page($top_page, __('WooCommerce Multilingual', 'woocommerce-multilingual'),
32
+ __('WooCommerce Multilingual', 'woocommerce-multilingual'), 'wpml_manage_woocommerce_multilingual', 'wpml-wcml', array(__CLASS__, 'render_menus'));
33
+
34
+ }else{
35
+ global $wpdb, $sitepress;
36
+ $user_lang_pairs = get_user_meta(get_current_user_id(), $wpdb->prefix.'language_pairs', true);
37
+ if( !empty( $user_lang_pairs ) ){
38
+ add_menu_page(__('WooCommerce Multilingual', 'woocommerce-multilingual'),
39
+ __('WooCommerce Multilingual', 'woocommerce-multilingual'), 'translate',
40
+ 'wpml-wcml', array(__CLASS__, 'render_menus'), ICL_PLUGIN_URL . '/res/img/icon16.png');
41
+ }
42
+ }
43
+
44
+ }elseif( current_user_can('wpml_manage_woocommerce_multilingual') ){
45
+ if(!defined('ICL_SITEPRESS_VERSION')){
46
+ add_menu_page( __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ), __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ),
47
+ 'wpml_manage_woocommerce_multilingual', 'wpml-wcml', array(__CLASS__, 'render_menus'), WCML_PLUGIN_URL . '/res/images/icon16.png' );
48
+ }else{
49
+ $top_page = apply_filters('icl_menu_main_page', basename(ICL_PLUGIN_PATH) .'/menu/languages.php');
50
+ add_submenu_page($top_page, __('WooCommerce Multilingual', 'woocommerce-multilingual'),
51
+ __('WooCommerce Multilingual', 'woocommerce-multilingual'), 'wpml_manage_woocommerce_multilingual', 'wpml-wcml', array(__CLASS__, 'render_menus'));
52
+ }
53
+
54
+ }
55
+ }
56
+
57
+ public static function render_menus(){
58
+
59
+ if( self::$woocommerce_wpml->check_dependencies && self::$woocommerce_wpml->check_design_update ){
60
+ $menus_wrap = new WCML_Menus_Wrap( self::$woocommerce_wpml );
61
+ $menus_wrap->show();
62
+ }else{
63
+ global $sitepress;
64
+ $plugins_wrap = new WCML_Plugins_Wrap( self::$woocommerce_wpml, $sitepress );
65
+ $plugins_wrap->show();
66
+ }
67
+
68
+ }
69
+
70
+ private static function is_page_without_admin_language_switcher(){
71
+ global $pagenow;
72
+
73
+ $get_post_type = isset( $_GET['post_type'] ) ? $_GET['post_type'] : false;
74
+ $get_post = isset( $_GET['post'] ) ? $_GET['post'] : false;
75
+ $get_page = isset( $_GET['page'] ) ? $_GET['page'] : false;
76
+
77
+ $is_page_wpml_wcml = isset($_GET['page']) && $_GET['page'] == 'wpml-wcml';
78
+ $is_new_order_or_coupon = in_array( $pagenow, array( 'edit.php', 'post-new.php' ) ) &&
79
+ $get_post_type &&
80
+ in_array( $get_post_type, array( 'shop_coupon', 'shop_order' ) );
81
+ $is_edit_order_or_coupon = $pagenow == 'post.php' && $get_post &&
82
+ in_array( get_post_type( $get_post ), array( 'shop_coupon', 'shop_order' ) );
83
+ $is_shipping_zones = $get_page == 'shipping_zones';
84
+ $is_attributes_page = apply_filters( 'wcml_is_attributes_page', $get_page == 'product_attributes' );
85
+
86
+
87
+ return is_admin() && (
88
+ $is_page_wpml_wcml ||
89
+ $is_new_order_or_coupon ||
90
+ $is_edit_order_or_coupon ||
91
+ $is_shipping_zones ||
92
+ $is_attributes_page
93
+ );
94
+
95
+ }
96
+
97
+ public static function remove_wpml_admin_language_switcher(){
98
+
99
+ remove_action( 'wp_before_admin_bar_render', array(self::$sitepress, 'admin_language_switcher') );
100
+
101
+ }
102
+
103
+ public static function documentation_links() {
104
+ global $post, $pagenow;
105
+
106
+ if ( is_null( $post ) )
107
+ return;
108
+
109
+ $get_post_type = get_post_type( $post->ID );
110
+
111
+ if ( $get_post_type == 'product' && $pagenow == 'edit.php' ) {
112
+ $prot_link = '<span class="button"><img align="baseline" src="' . ICL_PLUGIN_URL . '/res/img/icon.png" width="16" height="16" style="margin-bottom:-4px" /> <a href="' . WCML_Links::generate_tracking_link( 'https://wpml.org/documentation/related-projects/woocommerce-multilingual/', 'woocommerce-multilingual', 'documentation', '#4' ) . '" target="_blank">' .
113
+ __( 'How to translate products', 'sitepress' ) . '<\/a>' . '<\/span>';
114
+ $quick_edit_notice = '<div id="quick_edit_notice" style="display:none;"><p>' .
115
+ sprintf( __( "Quick edit is disabled for product translations. It\'s recommended to use the %s for editing products translations. %s",
116
+ 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=wpml-wcml&tab=products' ) . '" >' .
117
+ __( 'WooCommerce Multilingual products editor', 'woocommerce-multilingual' ) . '</a>',
118
+ '<a href="" class="quick_product_trnsl_link" >' . __( 'Edit this product translation', 'woocommerce-multilingual' ) . '</a>'
119
+ ) . '</p></div>';
120
+ $quick_edit_notice_prod_link = '<input type="hidden" id="wcml_product_trnsl_link" value="' . admin_url( 'admin.php?page=wpml-wcml&tab=products&prid=' ) . '">';
121
+ ?>
122
+ <script type="text/javascript">
123
+ jQuery(".subsubsub").append('<?php echo $prot_link ?>');
124
+ jQuery(".subsubsub").append('<?php echo $quick_edit_notice ?>');
125
+ jQuery(".subsubsub").append('<?php echo $quick_edit_notice_prod_link ?>');
126
+ jQuery(".quick_hide a").on('click', function () {
127
+ jQuery(".quick_product_trnsl_link").attr('href', jQuery("#wcml_product_trnsl_link").val() + jQuery(this).closest('tr').attr('id').replace(/post-/, ''));
128
+ });
129
+
130
+ //lock feautured for translations
131
+ jQuery(document).on('click', '.featured a', function () {
132
+
133
+ if (jQuery(this).closest('tr').find('.quick_hide').size() > 0) {
134
+
135
+ return false;
136
+
137
+ }
138
+
139
+ });
140
+ </script>
141
+ <?php
142
+ }
143
+
144
+ if ( isset($_GET['taxonomy']) ) {
145
+ $pos = strpos( $_GET['taxonomy'], 'pa_' );
146
+
147
+ if ( $pos !== false && $pagenow == 'edit-tags.php' ) {
148
+ $prot_link = '<span class="button" style="padding:4px;margin-top:0px; float: left;"><img align="baseline" src="' . ICL_PLUGIN_URL . '/res/img/icon16.png" width="16" height="16" style="margin-bottom:-4px" /> <a href="' . WCML_Links::generate_tracking_link( 'https://wpml.org/documentation/related-projects/woocommerce-multilingual/', 'woocommerce-multilingual', 'documentation', '#3' ) . '" target="_blank" style="text-decoration: none;">' .
149
+ __( 'How to translate attributes', 'sitepress' ) . '<\/a>' . '<\/span><br \/><br \/>';
150
+ ?>
151
+ <script type="text/javascript">
152
+ jQuery("table.widefat").before('<?php echo $prot_link ?>');
153
+ </script>
154
+ <?php
155
+ }
156
+ }
157
+
158
+ if ( isset($_GET['taxonomy']) && $_GET['taxonomy'] == 'product_cat' ) {
159
+
160
+ $prot_link = '<span class="button" style="padding:4px;margin-top:0px; float: left;"><img align="baseline" src="' . ICL_PLUGIN_URL . '/res/img/icon16.png" width="16" height="16" style="margin-bottom:-4px" /> <a href="' . WCML_Links::generate_tracking_link( 'https://wpml.org/documentation/related-projects/woocommerce-multilingual/', 'woocommerce-multilingual', 'documentation', '#3' ) . '" target="_blank" style="text-decoration: none;">' .
161
+ __( 'How to translate product categories', 'sitepress' ) . '<\/a>' . '<\/span><br \/><br \/>';
162
+ ?>
163
+ <script type="text/javascript">
164
+ jQuery("table.widefat").before('<?php echo $prot_link ?>');
165
+ </script>
166
+ <?php
167
+ }
168
+ }
169
+
170
+ public static function hide_multilingual_content_setup_box(){
171
+ remove_meta_box('icl_div_config', convert_to_screen('shop_order'), 'normal');
172
+ remove_meta_box('icl_div_config', convert_to_screen('shop_coupon'), 'normal');
173
+ }
174
+
175
+ public static function restrict_admin_with_redirect() {
176
+ global $pagenow;
177
+
178
+ $default_lang = self::$sitepress->get_default_language();
179
+ $current_lang = self::$sitepress->get_current_language();
180
+
181
+ if(
182
+ ( $pagenow == 'post.php' && isset( $_GET[ 'post' ] ) ) ||
183
+ ( $pagenow == 'admin.php' &&
184
+ isset( $_GET[ 'action' ] ) &&
185
+ $_GET[ 'action'] == 'duplicate_product' &&
186
+ isset( $_GET[ 'post' ] )
187
+ )
188
+ ){
189
+ $prod_lang = self::$sitepress->get_language_for_element( $_GET[ 'post' ], 'post_product' );
190
+ }
191
+
192
+ if(
193
+ !self::$woocommerce_wpml->settings[ 'trnsl_interface' ] &&
194
+ $pagenow == 'post.php' &&
195
+ isset( $_GET[ 'post' ] )&&
196
+ get_post_type( $_GET[ 'post' ] ) == 'product' &&
197
+ !self::$woocommerce_wpml->products->is_original_product( $_GET[ 'post' ] ) )
198
+ {
199
+ add_action( 'admin_notices', array( __CLASS__, 'inf_editing_product_in_non_default_lang' ) );
200
+ }
201
+
202
+ if(
203
+ self::$woocommerce_wpml->settings[ 'trnsl_interface' ] &&
204
+ $pagenow == 'post.php' &&
205
+ !is_ajax() &&
206
+ isset( $_GET[ 'post' ] ) &&
207
+ !self::$woocommerce_wpml->products->is_original_product( $_GET[ 'post' ] ) &&
208
+ get_post_type( $_GET[ 'post' ] ) == 'product'
209
+ ) {
210
+ if(
211
+ !isset( $_GET[ 'action' ] ) ||
212
+ ( isset( $_GET[ 'action' ] ) && !in_array( $_GET[ 'action' ], array( 'trash', 'delete' ) ) )
213
+ ) {
214
+ wp_redirect( admin_url( 'admin.php?page=wpml-wcml&tab=products' ) );
215
+ exit;
216
+ }
217
+ }
218
+
219
+ if(
220
+ self::$woocommerce_wpml->settings[ 'trnsl_interface' ] &&
221
+ $pagenow == 'admin.php' &&
222
+ isset( $_GET[ 'action' ] ) &&
223
+ $_GET[ 'action' ] == 'duplicate_product' &&
224
+ $default_lang != $prod_lang )
225
+ {
226
+ wp_redirect( admin_url( 'admin.php?page=wpml-wcml&tab=products' ) );
227
+ exit;
228
+ }
229
+ }
230
+
231
+ public static function inf_editing_product_in_non_default_lang(){
232
+ $message = '<div class="message error"><p>';
233
+ $message .= sprintf(
234
+ __( 'The recommended way to translate WooCommerce products is using the
235
+ %sWooCommerce Multilingual products translation%s page.
236
+ Please use this page only for translating elements that are not available in the WooCommerce Multilingual products translation table.',
237
+ 'woocommerce-multilingual' ),
238
+ '<strong><a href="' .admin_url( 'admin.php?page=wpml-wcml&tab=products' ) . '">', '</a></strong>' );
239
+ $message .= '</p></div>';
240
+
241
+ echo $message;
242
+ }
243
+
244
+ }
inc/admin-menus/class-wcml-links.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_Links {
4
+
5
+ public static function generate_tracking_link( $link, $term = false, $content = false, $id = false ) {
6
+
7
+ $params = '?utm_source=wcml-admin&utm_medium=plugin&utm_term=';
8
+ $params .= $term ? $term : 'WPML';
9
+ $params .= '&utm_content=';
10
+ $params .= $content ? $content : 'required-plugins';
11
+ $params .= '&utm_campaign=WCML';
12
+
13
+ if ( $id ) {
14
+ $params .= $id;
15
+ }
16
+ return $link . $params;
17
+
18
+ }
19
+
20
+ public static function filter_woocommerce_redirect_location( $link ) {
21
+ global $sitepress;
22
+ return html_entity_decode( $sitepress->convert_url( $link ) );
23
+ }
24
+
25
+ }
inc/admin-menus/class-wcml-setup.php ADDED
@@ -0,0 +1,332 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_Setup {
4
+
5
+ private $step;
6
+ private $woocommerce_wpml;
7
+ private $sitepress;
8
+ private $next_step = false;
9
+
10
+
11
+ public function __construct( &$woocommerce_wpml, &$sitepress ){
12
+
13
+ $this->woocommerce_wpml =& $woocommerce_wpml;
14
+ $this->sitepress =& $sitepress;
15
+
16
+ $this->steps = array(
17
+ 'introduction' => array(
18
+ 'name' => __( 'Introduction', 'woocommerce-multilingual' ),
19
+ 'view' => array( $this, 'setup_introduction' ),
20
+ 'handler' => ''
21
+ ),
22
+ 'store-pages' => array(
23
+ 'name' => __( 'Store Pages', 'woocommerce-multilingual' ),
24
+ 'view' => array( $this, 'setup_store_pages' ),
25
+ 'handler' => array( $this, 'install_store_pages' ),
26
+ ),
27
+ 'attributes' => array(
28
+ 'name' => __( 'Global Attributes', 'woocommerce-multilingual' ),
29
+ 'view' => array( $this, 'setup_attributes' ),
30
+ 'handler' => array( $this, 'save_attributes' )
31
+ ),
32
+ 'multi-currency' => array(
33
+ 'name' => __( 'Multiple Currencies', 'woocommerce-multilingual' ),
34
+ 'view' => array( $this, 'setup_multi_currency' ),
35
+ 'handler' => array( $this, 'save_multi_currency' )
36
+ ),
37
+ 'translation-interface' => array(
38
+ 'name' => __( 'Translation Interface', 'woocommerce-multilingual' ),
39
+ 'view' => array( $this, 'setup_translation_interface' ),
40
+ 'handler' => array( $this, 'save_translation_interface' )
41
+ ),
42
+ 'ready' => array(
43
+ 'name' => __( 'Ready!', 'woocommerce-multilingual' ),
44
+ 'view' => array( $this, 'setup_ready' ),
45
+ 'handler' => ''
46
+ )
47
+ );
48
+
49
+ if( current_user_can( 'manage_options' ) ) {
50
+ add_action( 'admin_menu', array($this, 'admin_menus') );
51
+ add_action( 'admin_init', array($this, 'setup_wizard') );
52
+
53
+ add_action( 'admin_init', array($this, 'handle_steps'), 0 );
54
+ add_filter( 'wp_redirect', array($this, 'redirect_filters') );
55
+ }
56
+
57
+ if( !$this->has_completed()){
58
+ add_filter( 'admin_notices', array( $this, 'setup_wizard_notice') );
59
+ add_action( 'admin_init', array( $this, 'skip_setup' ), 1 );
60
+ }
61
+
62
+ }
63
+
64
+ public function admin_menus() {
65
+ add_dashboard_page( '', '', 'manage_options', 'wcml-setup', '' );
66
+ }
67
+
68
+ public function setup_wizard_notice(){
69
+ ?>
70
+ <div id="wcml-setup-wizard" class="updated message fade otgs-is-dismissible">
71
+ <p><?php printf( __('Welcome to %sWooCommerce Multilingual!%s Please take a moment to configure the main settings and then you are ready to start translating your products.', 'woocommerce-multilingual'), '<strong>', '</strong>') ?></p>
72
+ <p class="submit">
73
+ <a href="<?php echo esc_url( admin_url('admin.php?page=wcml-setup') ); ?>" class="button-primary"><?php _e('Run the Setup Wizard', 'woocommerce-multilingual') ?></a>
74
+ <a href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wcml-setup-skip', 1 ), 'wcml_setup_skip_nonce', '_wcml_setup_nonce' ) ); ?>" class="button-secondary skip"><?php _e('Skip Setup', 'woocommerce-multilingual') ?></a>
75
+ </p>
76
+ </div>
77
+ <?php
78
+ }
79
+
80
+ public function skip_setup(){
81
+
82
+ if ( isset( $_GET['wcml-setup-skip'] ) && isset( $_GET['_wcml_setup_nonce'] ) ) {
83
+ if ( ! wp_verify_nonce( $_GET['_wcml_setup_nonce'], 'wcml_setup_skip_nonce' ) ) {
84
+ wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce-multilingual' ) );
85
+ }
86
+
87
+ if ( ! current_user_can( 'manage_options' ) ) {
88
+ wp_die( __( 'Cheatin&#8217; huh?', 'woocommerce' ) );
89
+ }
90
+
91
+ $this->complete_setup();
92
+ remove_filter( 'admin_notices', array( $this, 'setup_wizard_notice') );
93
+ }
94
+
95
+ }
96
+
97
+ public function complete_setup(){
98
+ $this->woocommerce_wpml->settings['set_up_wizard_run'] = 1;
99
+ $this->woocommerce_wpml->settings['set_up_wizard_splash'] = 1;
100
+ $this->woocommerce_wpml->update_settings();
101
+ }
102
+
103
+ public function has_completed(){
104
+
105
+ return !empty( $this->woocommerce_wpml->settings['set_up_wizard_run'] );
106
+
107
+ }
108
+
109
+ public function splash_wizard_on_wcml_pages(){
110
+
111
+ if( isset( $_GET['src'] ) && $_GET['src'] == 'setup_later' ){
112
+ $this->woocommerce_wpml->settings['set_up_wizard_splash'] = 1;
113
+ $this->woocommerce_wpml->update_settings();
114
+ }
115
+
116
+ if( isset( $_GET['page'] ) && $_GET['page'] == 'wpml-wcml' && !$this->has_completed() && empty( $this->woocommerce_wpml->settings['set_up_wizard_splash'] )){
117
+ wp_redirect('admin.php?page=wcml-setup');
118
+ exit;
119
+ }
120
+ }
121
+
122
+ public function setup_wizard() {
123
+
124
+ $this->splash_wizard_on_wcml_pages();
125
+
126
+ if ( empty( $_GET['page'] ) || 'wcml-setup' !== $_GET['page'] ) {
127
+ return;
128
+ }
129
+
130
+ $this->step = isset( $_GET['step'] ) ? sanitize_key( $_GET['step'] ) : current( array_keys( $this->steps ) );
131
+
132
+ wp_enqueue_style( 'wcml-setup', WCML_PLUGIN_URL . '/res/css/wcml-setup.css', array( 'dashicons', 'install' ), WCML_VERSION );
133
+ wp_enqueue_script( 'wcml-setup', WCML_PLUGIN_URL . '/res/js/wcml-setup.js', array('jquery'), WCML_VERSION );
134
+
135
+ $this->setup_header();
136
+ $this->setup_steps();
137
+ $this->setup_content();
138
+ $this->setup_footer();
139
+
140
+ if( $this->step == 'ready' ){
141
+ $this->complete_setup();
142
+ }
143
+
144
+ exit;
145
+ }
146
+
147
+ private function setup_header() {
148
+ ?>
149
+ <!DOCTYPE html>
150
+ <html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
151
+ <head>
152
+ <meta name="viewport" content="width=device-width" />
153
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
154
+ <title><?php _e( 'WooCommerce Multilingual &rsaquo; Setup Wizard', 'woocommerce-multilingual' ); ?></title>
155
+ <?php wp_print_scripts( 'wcml-setup' ); ?>
156
+ <?php do_action( 'admin_print_styles' ); ?>
157
+ <?php do_action( 'admin_head' ); ?>
158
+ </head>
159
+ <body class="wcml-setup wp-core-ui">
160
+ <h1 id="wcml-logo"><a href="https://wpml.org/woocommerce-multilingual"><img src="<?php echo WCML_PLUGIN_URL ?>/res/images/banner-772x120.png" alt="WooCommerce Multilingual" /></a></h1>
161
+
162
+ <?php if( !empty( $this->steps[ $this->step ]['handler'] ) ): ?>
163
+ <form class="wcml-setup-form" method="post">
164
+ <input type="hidden" name="nonce" value="<?php echo wp_create_nonce( $this->step ) ?>" />
165
+ <input type="hidden" name="handle_step" value="<?php echo $this->step ?>" />
166
+ <?php endif; ?>
167
+ <?php
168
+ }
169
+
170
+ private function setup_content(){
171
+
172
+ echo '<div class="wcml-setup-content">';
173
+ call_user_func( $this->steps[ $this->step ]['view'] );
174
+ echo '</div>';
175
+
176
+ }
177
+
178
+ private function setup_footer() {
179
+ ?>
180
+ <?php if( !empty( $this->steps[ $this->step ]['handler'] ) ): ?>
181
+ </form>
182
+ <?php endif ?>
183
+ </body>
184
+ </html>
185
+ <?php
186
+ }
187
+
188
+ private function setup_steps() {
189
+
190
+ $steps = array_keys( $this->steps );
191
+ $step_index = array_search( $this->step, $steps );
192
+ $this->next_step = isset( $steps[$step_index + 1] ) ? $steps[$step_index + 1] : '';
193
+
194
+ $ouput_steps = $this->steps;
195
+ array_shift( $ouput_steps );
196
+ ?>
197
+ <ol class="wcml-setup-steps">
198
+ <?php foreach ( $ouput_steps as $step_key => $step ) : ?>
199
+ <li class="<?php
200
+ if ( $step_key === $this->step ) {
201
+ echo 'active';
202
+ } elseif ( array_search( $this->step, array_keys( $this->steps ) ) > array_search( $step_key, array_keys( $this->steps ) ) ) {
203
+ echo 'done';
204
+ }
205
+ ?>"><?php echo esc_html( $step['name'] ); ?></li>
206
+ <?php endforeach; ?>
207
+ </ol>
208
+ <?php
209
+ }
210
+
211
+ private function next_step_url(){
212
+ $url = admin_url('admin.php?page=wcml-setup&step=' . $this->next_step );
213
+ return $url;
214
+ }
215
+
216
+ public function setup_introduction(){
217
+ $ui = new WCML_Setup_Introduction_UI( $this->woocommerce_wpml, $this->next_step_url() );
218
+ echo $ui->get_view();
219
+ }
220
+
221
+ public function setup_store_pages(){
222
+
223
+ $ui = new WCML_Setup_Store_Pages_UI( $this->woocommerce_wpml, $this->sitepress, $this->next_step_url() );
224
+ echo $ui->get_view();
225
+ }
226
+
227
+ public function setup_attributes(){
228
+ $ui = new WCML_Setup_Attributes_UI( $this->woocommerce_wpml, $this->next_step_url() );
229
+ echo $ui->get_view();
230
+ }
231
+
232
+ public function setup_multi_currency(){
233
+ $ui = new WCML_Setup_Multi_Currency_UI( $this->woocommerce_wpml, $this->next_step_url() );
234
+ echo $ui->get_view();
235
+ }
236
+
237
+ public function setup_translation_interface(){
238
+ $ui = new WCML_Setup_Translation_interface_UI( $this->woocommerce_wpml, $this->next_step_url() );
239
+ echo $ui->get_view();
240
+ }
241
+
242
+ public function setup_ready(){
243
+ $ui = new WCML_Setup_Ready_UI( $this->woocommerce_wpml );
244
+ echo $ui->get_view();
245
+ }
246
+
247
+
248
+ public function redirect_filters( $url ){
249
+
250
+ if( isset($_POST['next_step_url']) && $_POST['next_step_url'] ){
251
+ $url = sanitize_text_field( $_POST['next_step_url'] );
252
+ }
253
+
254
+ return $url;
255
+ }
256
+
257
+
258
+ private function get_handler( $step ){
259
+ $handler = !empty( $this->steps[ $step ]['handler'] ) ? $this->steps[ $step ]['handler'] : '';
260
+ return $handler;
261
+
262
+ }
263
+
264
+ public function handle_steps(){
265
+
266
+ if( isset( $_POST[ 'handle_step' ] ) && $_POST['nonce'] == wp_create_nonce( $_POST[ 'handle_step' ] ) ){
267
+
268
+ $step_name = sanitize_text_field( $_POST[ 'handle_step' ] );
269
+
270
+ if( $handler = $this->get_handler( $step_name )){
271
+ call_user_func( $handler, $_POST );
272
+ }
273
+
274
+ }
275
+
276
+ }
277
+
278
+ /**
279
+ * handler
280
+ */
281
+ public function save_attributes( $data ){
282
+
283
+ if ( isset( $data['attributes'] ) ) {
284
+ $this->woocommerce_wpml->attributes->set_translatable_attributes( $data['attributes'] );
285
+ }
286
+
287
+ }
288
+
289
+ /**
290
+ * handler
291
+ */
292
+ public function save_multi_currency( $data ){
293
+
294
+ if( empty( $this->woocommerce_wpml->multi_currency )){
295
+ $this->woocommerce_wpml->multi_currency = new WCML_Multi_Currency();
296
+ }
297
+
298
+ if( !empty( $data['enabled'] ) ){
299
+ $this->woocommerce_wpml->multi_currency->enable();
300
+ } else{
301
+ $this->woocommerce_wpml->multi_currency->disable();
302
+ }
303
+
304
+ }
305
+
306
+ /**
307
+ * handler
308
+ */
309
+ public function save_translation_interface( $data ){
310
+
311
+ $this->woocommerce_wpml->settings['trnsl_interface'] = intval( $data['translation_interface'] );
312
+ $this->woocommerce_wpml->update_settings();
313
+
314
+ }
315
+
316
+ /**
317
+ * handler
318
+ */
319
+ public function install_store_pages( $data ){
320
+
321
+ if( !empty( $data['create_pages'] ) ) {
322
+ $this->woocommerce_wpml->store->create_missing_store_pages_with_redirect();
323
+ }elseif( !empty( $data['install_missing_pages'] ) ){
324
+ WC_Install::create_pages();
325
+ $this->woocommerce_wpml->store->create_missing_store_pages_with_redirect();
326
+ }
327
+
328
+ }
329
+
330
+
331
+
332
+ }
inc/{ajax-setup.class.php → class-wcml-ajax-setup.php} RENAMED
@@ -1,119 +1,119 @@
1
- <?php
2
-
3
-
4
- class WCML_Ajax_Setup{
5
-
6
- function __construct(){
7
-
8
- add_action('init', array($this, 'init'));
9
- add_action('localize_woocommerce_on_ajax', array($this, 'localize_woocommerce_on_ajax'));
10
-
11
- }
12
-
13
- function init(){
14
- if (wpml_is_ajax()){
15
- do_action('localize_woocommerce_on_ajax');
16
- }
17
-
18
- add_filter('woocommerce_params', array($this, 'filter_woocommerce_ajax_params'));
19
-
20
- add_filter('wc_checkout_params', array($this, 'add_language_parameter_to_ajax_url'));
21
- add_filter('wc_cart', array($this, 'add_language_parameter_to_ajax_url'));
22
- add_filter('wc_cart_fragments_params', array($this, 'add_language_parameter_to_ajax_url'));
23
- add_filter('wc_add_to_cart_params', array($this, 'add_language_parameter_to_ajax_url'));
24
-
25
- add_action( 'woocommerce_checkout_order_review', array($this,'filter_woocommerce_order_review'), 9 );
26
- add_action( 'woocommerce_checkout_order_review', array($this,'add_hidden_language_field') );
27
- add_action( 'woocommerce_checkout_update_order_review', array($this,'filter_woocommerce_order_review'), 9 );
28
-
29
- }
30
-
31
- function filter_woocommerce_order_review(){
32
- global $woocommerce;
33
- unload_textdomain('woocommerce');
34
- $woocommerce->load_plugin_textdomain();
35
- }
36
-
37
- function add_hidden_language_field(){
38
- if( function_exists('wpml_the_language_input_field') ){
39
- wpml_the_language_input_field();
40
- }else{
41
- global $sitepress;
42
- if (isset($sitepress) ) {
43
- return "<input type='hidden' name='lang' value='" . $sitepress->get_current_language() . "' />";
44
- }
45
- return null;
46
- }
47
- }
48
-
49
- function add_language_parameter_to_ajax_url($woocommerce_params){
50
- global $sitepress;
51
-
52
- if($sitepress->get_current_language() !== $sitepress->get_default_language()){
53
- $woocommerce_params['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
54
- }
55
-
56
- return $woocommerce_params;
57
- }
58
-
59
- function filter_woocommerce_ajax_params($woocommerce_params){
60
- global $sitepress, $post;
61
- $value = array();
62
- $value = $woocommerce_params;
63
-
64
- if($sitepress->get_current_language() !== $sitepress->get_default_language()){
65
- $value['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
66
- $value['checkout_url'] = add_query_arg('action', 'woocommerce-checkout', $value['ajax_url']);
67
- }
68
-
69
- if(!isset($post->ID)){
70
- return $value;
71
- }
72
-
73
- $ch_pages = wp_cache_get('ch_pages', 'wcml_ch_pages');
74
-
75
- if(empty($ch_pages)){
76
-
77
- $ch_pages = array(
78
-
79
- 'checkout_page_id' => get_option('woocommerce_checkout_page_id'),
80
- 'pay_page_id' => get_option('woocommerce_pay_page_id'),
81
- 'cart_page_id' => get_option('woocommerce_cart_page_id'));
82
-
83
- $ch_pages['translated_checkout_page_id'] = apply_filters( 'translate_object_id',$ch_pages['checkout_page_id'], 'page', false);
84
- $ch_pages['translated_pay_page_id'] = apply_filters( 'translate_object_id',$ch_pages['pay_page_id'], 'page', false);
85
- $ch_pages['translated_cart_page_id'] = apply_filters( 'translate_object_id',$ch_pages['cart_page_id'], 'page', false);
86
-
87
- }
88
-
89
- wp_cache_set( 'ch_pages', $ch_pages, 'wcml_ch_pages' );
90
-
91
- if($ch_pages['translated_cart_page_id'] == $post->ID){
92
- $value['is_cart'] = 1;
93
- $value['cart_url'] = get_permalink($ch_pages['translated_cart_page_id']);
94
- } else if($ch_pages['translated_checkout_page_id'] == $post->ID || $ch_pages['checkout_page_id'] == $post->ID){
95
- $value['is_checkout'] = 1;
96
-
97
- $_SESSION['wpml_globalcart_language'] = $sitepress->get_current_language();
98
-
99
- } else if($ch_pages['translated_pay_page_id'] == $post->ID){
100
- $value['is_pay_page'] = 1;
101
- }
102
-
103
- return $value;
104
- }
105
-
106
- function localize_woocommerce_on_ajax(){
107
- if( isset($_POST['action']) && in_array( $_POST['action'], array('wcml_product_data','wcml_update_product') ) ){
108
- return;
109
- }
110
-
111
- global $sitepress;
112
-
113
- $current_language = $sitepress->get_current_language();
114
-
115
- $sitepress->switch_lang($current_language, true);
116
- }
117
-
118
-
119
- }
1
+ <?php
2
+
3
+
4
+ class WCML_Ajax_Setup{
5
+
6
+ function __construct(){
7
+
8
+ add_action('init', array($this, 'init'));
9
+ add_action('localize_woocommerce_on_ajax', array($this, 'localize_woocommerce_on_ajax'));
10
+
11
+ }
12
+
13
+ function init(){
14
+ if (wpml_is_ajax()){
15
+ do_action('localize_woocommerce_on_ajax');
16
+ }
17
+
18
+ add_filter('woocommerce_params', array($this, 'filter_woocommerce_ajax_params'));
19
+
20
+ add_filter('wc_checkout_params', array($this, 'add_language_parameter_to_ajax_url'));
21
+ add_filter('wc_cart', array($this, 'add_language_parameter_to_ajax_url'));
22
+ add_filter('wc_cart_fragments_params', array($this, 'add_language_parameter_to_ajax_url'));
23
+ add_filter('wc_add_to_cart_params', array($this, 'add_language_parameter_to_ajax_url'));
24
+
25
+ add_action( 'woocommerce_checkout_order_review', array($this,'filter_woocommerce_order_review'), 9 );
26
+ add_action( 'woocommerce_checkout_order_review', array($this,'add_hidden_language_field') );
27
+ add_action( 'woocommerce_checkout_update_order_review', array($this,'filter_woocommerce_order_review'), 9 );
28
+
29
+ }
30
+
31
+ function filter_woocommerce_order_review(){
32
+ global $woocommerce;
33
+ unload_textdomain('woocommerce');
34
+ $woocommerce->load_plugin_textdomain();
35
+ }
36
+
37
+ function add_hidden_language_field(){
38
+ if( function_exists('wpml_the_language_input_field') ){
39
+ wpml_the_language_input_field();
40
+ }else{
41
+ global $sitepress;
42
+ if (isset($sitepress) ) {
43
+ return "<input type='hidden' name='lang' value='" . $sitepress->get_current_language() . "' />";
44
+ }
45
+ return null;
46
+ }
47
+ }
48
+
49
+ function add_language_parameter_to_ajax_url($woocommerce_params){
50
+ global $sitepress;
51
+
52
+ if($sitepress->get_current_language() !== $sitepress->get_default_language()){
53
+ $woocommerce_params['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
54
+ }
55
+
56
+ return $woocommerce_params;
57
+ }
58
+
59
+ function filter_woocommerce_ajax_params($woocommerce_params){
60
+ global $sitepress, $post;
61
+ $value = array();
62
+ $value = $woocommerce_params;
63
+
64
+ if($sitepress->get_current_language() !== $sitepress->get_default_language()){
65
+ $value['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
66
+ $value['checkout_url'] = add_query_arg('action', 'woocommerce-checkout', $value['ajax_url']);
67
+ }
68
+
69
+ if(!isset($post->ID)){
70
+ return $value;
71
+ }
72
+
73
+ $ch_pages = wp_cache_get('ch_pages', 'wcml_ch_pages');
74
+
75
+ if(empty($ch_pages)){
76
+
77
+ $ch_pages = array(
78
+
79
+ 'checkout_page_id' => get_option('woocommerce_checkout_page_id'),
80
+ 'pay_page_id' => get_option('woocommerce_pay_page_id'),
81
+ 'cart_page_id' => get_option('woocommerce_cart_page_id'));
82
+
83
+ $ch_pages['translated_checkout_page_id'] = apply_filters( 'translate_object_id',$ch_pages['checkout_page_id'], 'page', false);
84
+ $ch_pages['translated_pay_page_id'] = apply_filters( 'translate_object_id',$ch_pages['pay_page_id'], 'page', false);
85
+ $ch_pages['translated_cart_page_id'] = apply_filters( 'translate_object_id',$ch_pages['cart_page_id'], 'page', false);
86
+
87
+ }
88
+
89
+ wp_cache_set( 'ch_pages', $ch_pages, 'wcml_ch_pages' );
90
+
91
+ if($ch_pages['translated_cart_page_id'] == $post->ID){
92
+ $value['is_cart'] = 1;
93
+ $value['cart_url'] = get_permalink($ch_pages['translated_cart_page_id']);
94
+ } else if($ch_pages['translated_checkout_page_id'] == $post->ID || $ch_pages['checkout_page_id'] == $post->ID){
95
+ $value['is_checkout'] = 1;
96
+
97
+ $_SESSION['wpml_globalcart_language'] = $sitepress->get_current_language();
98
+
99
+ } else if($ch_pages['translated_pay_page_id'] == $post->ID){
100
+ $value['is_pay_page'] = 1;
101
+ }
102
+
103
+ return $value;
104
+ }
105
+
106
+ function localize_woocommerce_on_ajax(){
107
+ if( isset($_POST['action']) && in_array( $_POST['action'], array( 'wcml_product_data', 'wpml_translation_dialog_save_job' ) ) ){
108
+ return;
109
+ }
110
+
111
+ global $sitepress;
112
+
113
+ $current_language = $sitepress->get_current_language();
114
+
115
+ $sitepress->switch_lang($current_language, true);
116
+ }
117
+
118
+
119
+ }
inc/class-wcml-attributes.php ADDED
@@ -0,0 +1,385 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_Attributes{
4
+
5
+ private $woocommerce_wpml;
6
+ private $sitepress;
7
+ private $wpdb;
8
+
9
+ public function __construct( &$woocommerce_wpml, &$sitepress, &$wpdb ){
10
+ $this->woocommerce_wpml = $woocommerce_wpml;
11
+ $this->sitepress = $sitepress;
12
+ $this->wpdb = $wpdb;
13
+
14
+ add_action( 'init', array( $this, 'init' ) );
15
+
16
+ add_action( 'woocommerce_attribute_added', array( $this, 'set_attribute_readonly_config' ), 100, 2 );
17
+ add_filter( 'wpml_translation_job_post_meta_value_translated', array($this, 'filter_product_attributes_for_translation'), 10, 2 );
18
+
19
+ if( isset( $_POST['icl_ajx_action'] ) && $_POST['icl_ajx_action'] == 'icl_custom_tax_sync_options' ){
20
+ $this->icl_custom_tax_sync_options();
21
+ }
22
+
23
+ }
24
+
25
+ public function init(){
26
+
27
+ $is_attr_page = apply_filters( 'wcml_is_attributes_page', isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'product_attributes' && isset( $_GET[ 'post_type' ] ) && $_GET[ 'post_type' ] == 'product' );
28
+
29
+ if( $is_attr_page ){
30
+
31
+ add_action( 'admin_init', array( $this, 'not_translatable_html' ) );
32
+
33
+ if( isset( $_POST[ 'save_attribute' ] ) && isset( $_GET[ 'edit' ] ) ){
34
+ $this->set_attribute_readonly_config( $_GET[ 'edit' ], $_POST );
35
+ }
36
+ }
37
+
38
+ }
39
+
40
+ public function not_translatable_html(){
41
+ $attr_id = isset( $_GET[ 'edit' ] ) ? absint( $_GET[ 'edit' ] ) : false;
42
+
43
+ $attr_is_tnaslt = new WCML_Not_Translatable_Attributes( $attr_id, $this->woocommerce_wpml );
44
+ $attr_is_tnaslt->show();
45
+ }
46
+
47
+ public function get_attribute_terms( $attribute ){
48
+
49
+ return $this->wpdb->get_results($this->wpdb->prepare("
50
+ SELECT * FROM {$this->wpdb->term_taxonomy} x JOIN {$this->wpdb->terms} t ON x.term_id = t.term_id WHERE x.taxonomy = %s", $attribute ) );
51
+
52
+ }
53
+
54
+ public function set_attribute_readonly_config( $id, $attribute ){
55
+
56
+ $is_translatable = isset( $_POST[ 'wcml-is-translatable-attr' ] ) ? 1 : 0;
57
+ $attribute_name = wc_attribute_taxonomy_name( $attribute['attribute_name'] );
58
+ if( $is_translatable === 0 ){
59
+ //delete all translated attributes terms if "Translatable?" option un-checked
60
+ $this->delete_translated_attribute_terms( $attribute_name );
61
+ $this->set_variations_to_use_original_attributes( $attribute_name );
62
+ $this->set_original_attributes_for_products( $attribute_name );
63
+ }
64
+ $this->set_attribute_config_in_settings( $attribute_name, $is_translatable );
65
+ }
66
+
67
+ public function set_attribute_config_in_settings( $attribute_name, $is_translatable ){
68
+ $this->set_attribute_config_in_wcml_settings( $attribute_name, $is_translatable );
69
+ $this->set_attribute_config_in_wpml_settings( $attribute_name, $is_translatable );
70
+
71
+ $this->woocommerce_wpml->terms->update_terms_translated_status( $attribute_name );
72
+ }
73
+
74
+ public function set_attribute_config_in_wcml_settings( $attribute_name, $is_translatable ){
75
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
76
+ $wcml_settings[ 'attributes_settings' ][ $attribute_name ] = $is_translatable;
77
+ $this->woocommerce_wpml->update_settings( $wcml_settings );
78
+ }
79
+
80
+ public function set_attribute_config_in_wpml_settings( $attribute_name, $is_translatable ){
81
+
82
+ $sync_settings = $this->sitepress->get_setting( 'taxonomies_sync_option', array() );
83
+ $sync_settings[ $attribute_name ] = $is_translatable;
84
+ $this->sitepress->set_setting( 'taxonomies_sync_option', $sync_settings, true );
85
+ $this->sitepress->verify_taxonomy_translations( $attribute_name );
86
+ }
87
+
88
+ public function delete_translated_attribute_terms( $attribute ){
89
+ $terms = $this->get_attribute_terms( $attribute );
90
+
91
+ foreach( $terms as $term ){
92
+ $term_language_details = $this->sitepress->get_element_language_details( $term->term_id, 'tax_'.$attribute );
93
+ if( $term_language_details && $term_language_details->source_language_code ){
94
+ wp_delete_term( $term->term_id, $attribute );
95
+ }
96
+ }
97
+
98
+ }
99
+
100
+ public function set_variations_to_use_original_attributes( $attribute ){
101
+ $terms = $this->get_attribute_terms( $attribute );
102
+
103
+ foreach( $terms as $term ){
104
+ $term_language_details = $this->sitepress->get_element_language_details( $term->term_id, 'tax_'.$attribute );
105
+ if( $term_language_details && is_null( $term_language_details->source_language_code ) ){
106
+ $variations = $this->wpdb->get_results( $this->wpdb->prepare( "SELECT post_id FROM {$this->wpdb->postmeta} WHERE meta_key=%s AND meta_value = %s", 'attribute_'.$attribute, $term->slug ) );
107
+
108
+ foreach( $variations as $variation ){
109
+ //update taxonomy in translation of variation
110
+ foreach( $this->sitepress->get_active_languages() as $language ){
111
+
112
+ $trnsl_variation_id = apply_filters( 'translate_object_id', $variation->post_id, 'product_variation', false, $language['code'] );
113
+ if( !is_null( $trnsl_variation_id ) ){
114
+ update_post_meta( $trnsl_variation_id, 'attribute_'.$attribute, $term->slug );
115
+ }
116
+ }
117
+ }
118
+ }
119
+ }
120
+ }
121
+
122
+ public function set_original_attributes_for_products( $attribute ){
123
+
124
+ $terms = $this->get_attribute_terms( $attribute );
125
+ $cleared_products = array();
126
+ foreach( $terms as $term ) {
127
+ $term_language_details = $this->sitepress->get_element_language_details( $term->term_id, 'tax_'.$attribute );
128
+ if( $term_language_details && is_null( $term_language_details->source_language_code ) ){
129
+ $args = array(
130
+ 'tax_query' => array(
131
+ array(
132
+ 'taxonomy' => $attribute,
133
+ 'field' => 'slug',
134
+ 'terms' => $term->slug
135
+ )
136
+ )
137
+ );
138
+
139
+ $products = get_posts($args);
140
+
141
+ foreach( $products as $product ){
142
+
143
+ foreach( $this->sitepress->get_active_languages() as $language ) {
144
+
145
+ $trnsl_product_id = apply_filters( 'translate_object_id', $product->ID, 'product', false, $language['code'] );
146
+
147
+ if ( !is_null( $trnsl_product_id ) ) {
148
+ if( !in_array( $trnsl_product_id, $trnsl_product_id ) ){
149
+ wp_delete_object_term_relationships( $trnsl_product_id, $attribute );
150
+ $cleared_products[] = $trnsl_product_id;
151
+ }
152
+ wp_set_object_terms( $trnsl_product_id, $term->slug, $attribute, true );
153
+ }
154
+ }
155
+ }
156
+ }
157
+ }
158
+ }
159
+
160
+
161
+ public function is_translatable_attribute( $attr_name ){
162
+
163
+ if( !isset( $this->woocommerce_wpml->settings[ 'attributes_settings' ][ $attr_name ] ) ){
164
+ $this->set_attribute_config_in_settings( $attr_name, 1 );
165
+ }
166
+
167
+ return isset( $this->woocommerce_wpml->settings[ 'attributes_settings' ][ $attr_name ] ) ? $this->woocommerce_wpml->settings[ 'attributes_settings' ][ $attr_name ] : 1;
168
+ }
169
+
170
+ public function get_translatable_attributes(){
171
+ $attributes = wc_get_attribute_taxonomies();
172
+
173
+ $translatable_attributes = array();
174
+ foreach( $attributes as $attribute ){
175
+ if( $this->is_translatable_attribute( wc_attribute_taxonomy_name( $attribute->attribute_name ) ) ){
176
+ $translatable_attributes[] = $attribute;
177
+ }
178
+ }
179
+
180
+ return $translatable_attributes;
181
+ }
182
+
183
+ public function set_translatable_attributes( $attributes ){
184
+
185
+ foreach( $attributes as $name => $is_translatable ){
186
+
187
+ $attribute_name = wc_attribute_taxonomy_name( $name );
188
+ $this->set_attribute_config_in_settings( $attribute_name, $is_translatable );
189
+
190
+ }
191
+ }
192
+
193
+ public function sync_product_attr( $original_product_id, $tr_product_id, $language = false, $data = false ){
194
+
195
+ //get "_product_attributes" from original product
196
+ $orig_product_attrs = $this->get_product_atributes( $original_product_id );
197
+ $trnsl_product_attrs = $this->get_product_atributes( $tr_product_id );
198
+
199
+ $trnsl_labels = get_post_meta( $tr_product_id, 'attr_label_translations', true );
200
+
201
+ foreach ( $orig_product_attrs as $key => $orig_product_attr ) {
202
+ $sanitized_key = sanitize_title( $orig_product_attr[ 'name' ] );
203
+ if( $sanitized_key != $key ) {
204
+ $orig_product_attrs_buff = $orig_product_attrs[ $key ];
205
+ unset( $orig_product_attrs[ $key ] );
206
+ $orig_product_attrs[ $sanitized_key ] = $orig_product_attrs_buff;
207
+ $key_to_save = $sanitized_key;
208
+ }else{
209
+ $key_to_save = $key;
210
+ }
211
+ if ( $data ){
212
+ if ( isset( $data[ md5( $key ) ] ) && !empty( $data[ md5( $key ) ] ) && !is_array( $data[ md5( $key ) ] ) ) {
213
+ //get translation values from $data
214
+ $orig_product_attrs[ $key_to_save ][ 'value' ] = $data[ md5( $key ) ];
215
+ } else {
216
+ $orig_product_attrs[ $key_to_save ][ 'value' ] = '';
217
+ }
218
+
219
+ if ( isset( $data[ md5( $key . '_name' ) ] ) && !empty( $data[ md5( $key . '_name' ) ] ) && !is_array( $data[ md5( $key . '_name' ) ] ) ) {
220
+ //get translation values from $data
221
+ $trnsl_labels[ $language ][ $key_to_save ] = stripslashes( $data[ md5( $key . '_name' ) ] );
222
+ } else {
223
+ $trnsl_labels[ $language ][ $key_to_save ] = '';
224
+ }
225
+ }elseif( !$orig_product_attr[ 'is_taxonomy' ] ){
226
+ if( isset( $trnsl_product_attrs[ $key ] ) ){
227
+ $orig_product_attrs[ $key_to_save ][ 'value' ] = $trnsl_product_attrs[ $key ][ 'value' ];
228
+ }else{
229
+ unset ( $orig_product_attrs[ $key_to_save ] );
230
+ }
231
+ }
232
+ }
233
+
234
+ update_post_meta( $tr_product_id, 'attr_label_translations', $trnsl_labels );
235
+ //update "_product_attributes"
236
+ update_post_meta( $tr_product_id, '_product_attributes', $orig_product_attrs );
237
+ }
238
+
239
+ public function get_product_atributes( $product_id ){
240
+ $attributes = get_post_meta( $product_id, '_product_attributes', true );
241
+ if( !is_array( $attributes ) ){
242
+ $attributes = array();
243
+ }
244
+ return $attributes;
245
+ }
246
+
247
+ public function sync_default_product_attr( $orig_post_id, $transl_post_id, $lang ){
248
+ $original_default_attributes = get_post_meta( $orig_post_id, '_default_attributes', true );
249
+ if( !empty( $original_default_attributes ) ){
250
+ $unserialized_default_attributes = array();
251
+ foreach(maybe_unserialize( $original_default_attributes ) as $attribute => $default_term_slug ){
252
+ // get the correct language
253
+ if ( substr( $attribute, 0, 3 ) == 'pa_' ) {
254
+ //attr is taxonomy
255
+ if( $this->is_translatable_attribute( $attribute ) ){
256
+ $default_term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $attribute, $default_term_slug );
257
+ $tr_id = apply_filters( 'translate_object_id', $default_term_id, $attribute, false, $lang );
258
+
259
+ if( $tr_id ){
260
+ $translated_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_id, $attribute );
261
+ $unserialized_default_attributes[ $attribute ] = $translated_term->slug;
262
+ }
263
+ }else{
264
+ $unserialized_default_attributes[ $attribute ] = $default_term_slug;
265
+ }
266
+ }else{
267
+ //custom attr
268
+ $orig_product_attributes = get_post_meta( $orig_post_id, '_product_attributes', true );
269
+ $unserialized_orig_product_attributes = maybe_unserialize( $orig_product_attributes );
270
+
271
+ if( isset( $unserialized_orig_product_attributes[ $attribute ] ) ){
272
+ $orig_attr_values = explode( '|', $unserialized_orig_product_attributes[ $attribute ][ 'value' ] );
273
+
274
+ foreach( $orig_attr_values as $key => $orig_attr_value ){
275
+ $orig_attr_value_sanitized = strtolower( sanitize_title ( $orig_attr_value ) );
276
+
277
+ if( $orig_attr_value_sanitized == $default_term_slug || trim( $orig_attr_value ) == trim( $default_term_slug ) ){
278
+ $tnsl_product_attributes = get_post_meta( $transl_post_id, '_product_attributes', true );
279
+ $unserialized_tnsl_product_attributes = maybe_unserialize( $tnsl_product_attributes );
280
+
281
+ if( isset( $unserialized_tnsl_product_attributes[ $attribute ] ) ){
282
+ $trnsl_attr_values = explode( '|', $unserialized_tnsl_product_attributes[ $attribute ][ 'value' ] );
283
+
284
+ if( $orig_attr_value_sanitized == $default_term_slug ){
285
+ $trnsl_attr_value = strtolower( sanitize_title( trim( $trnsl_attr_values[ $key ] ) ) );
286
+ }else{
287
+ $trnsl_attr_value = trim( $trnsl_attr_values[ $key ] );
288
+ }
289
+ $unserialized_default_attributes[ $attribute ] = $trnsl_attr_value;
290
+ }
291
+ }
292
+ }
293
+ }
294
+ }
295
+ }
296
+
297
+ $data = array( 'meta_value' => maybe_serialize( $unserialized_default_attributes ) );
298
+ }else{
299
+ $data = array( 'meta_value' => maybe_serialize( array() ) );
300
+ }
301
+
302
+ $where = array( 'post_id' => $transl_post_id, 'meta_key' => '_default_attributes' );
303
+ $this->wpdb->update( $this->wpdb->postmeta, $data, $where );
304
+ }
305
+
306
+ /*
307
+ * get attribute translation
308
+ */
309
+ public function get_custom_attribute_translation( $product_id, $attribute_key, $attribute, $lang_code ){
310
+ $tr_post_id = apply_filters( 'translate_object_id', $product_id, 'product', false, $lang_code );
311
+ $transl = array();
312
+ if( $tr_post_id ){
313
+ if( !$attribute[ 'is_taxonomy' ] ){
314
+ $tr_attrs = get_post_meta($tr_post_id, '_product_attributes', true);
315
+ if( $tr_attrs ){
316
+ foreach( $tr_attrs as $key => $tr_attr ) {
317
+ if( $attribute_key == $key ){
318
+ $transl[ 'value' ] = $tr_attr[ 'value' ];
319
+ $trnsl_labels = maybe_unserialize( get_post_meta( $tr_post_id, 'attr_label_translations', true ) );
320
+
321
+ if( isset( $trnsl_labels[ $lang_code ][ $attribute_key ] ) ){
322
+ $transl[ 'name' ] = $trnsl_labels[ $lang_code ][ $attribute_key ];
323
+ }else{
324
+ $transl[ 'name' ] = $tr_attr[ 'name' ];
325
+ }
326
+ return $transl;
327
+ }
328
+ }
329
+ }
330
+ return false;
331
+ }
332
+ }
333
+ return false;
334
+ }
335
+
336
+ /*
337
+ * Get custom attribute translation
338
+ * Returned translated attribute or original if missed
339
+ */
340
+ public function get_custom_attr_translation( $product_id, $tr_product_id, $taxonomy, $attribute ){
341
+ $orig_product_attributes = get_post_meta( $product_id, '_product_attributes', true );
342
+ $unserialized_orig_product_attributes = maybe_unserialize( $orig_product_attributes );
343
+
344
+ foreach( $unserialized_orig_product_attributes as $orig_attr_key => $orig_product_attribute ){
345
+ $orig_attr_key = urldecode( $orig_attr_key );
346
+ if( strtolower( $taxonomy ) == $orig_attr_key ){
347
+ $values = explode( '|', $orig_product_attribute[ 'value' ] );
348
+
349
+ foreach( $values as $key_id => $value ){
350
+ if( trim( $value," " ) == $attribute ){
351
+ $attr_key_id = $key_id;
352
+ }
353
+ }
354
+ }
355
+ }
356
+
357
+ $trnsl_product_attributes = get_post_meta( $tr_product_id, '_product_attributes', true );
358
+ $unserialized_trnsl_product_attributes = maybe_unserialize( $trnsl_