CTX Feed – WooCommerce Product Feed Manager Plugin - Version 4.5.0

Version Description

(2022-08-24) = * Product query feature improved.

Download this release

Release Info

Developer wahid0003
Plugin Icon 128x128 CTX Feed – WooCommerce Product Feed Manager Plugin
Version 4.5.0
Comparing to
See all releases

Code changes from version 4.4.69 to 4.5.0

Files changed (164) hide show
  1. README.txt +5 -1
  2. V5/Common/CustomFileds.php +253 -0
  3. V5/Common/DisplayBanners.php +5 -0
  4. V5/Common/DisplayNotices.php +56 -0
  5. V5/Common/DownloadFiles.php +82 -0
  6. V5/Common/DropDownOptions.php +636 -0
  7. V5/Common/ExportFeed.php +46 -0
  8. V5/Common/Factory.php +43 -0
  9. V5/Common/Helper.php +14 -0
  10. V5/Common/Hooks.php +5 -0
  11. V5/Common/ImportFeed.php +104 -0
  12. V5/Common/SaveFeed.php +128 -0
  13. V5/Common/Status.php +5 -0
  14. V5/Common/Taxonomy.php +128 -0
  15. V5/Common/Widget.php +66 -0
  16. V5/Compatibility/DynamicDiscount.php +212 -0
  17. V5/Compatibility/ExcludeCaching.php +341 -0
  18. V5/Compatibility/MultiCurrency.php +5 -0
  19. V5/Compatibility/MultiLanguage.php +7 -0
  20. V5/Compatibility/VariationGallary.php +7 -0
  21. V5/CustomFields/AttributeInterface.php +9 -0
  22. V5/CustomFields/Attributes.php +24 -0
  23. V5/CustomFields/AvailabilityDate.php +143 -0
  24. V5/CustomFields/CustomField.php +25 -0
  25. V5/CustomFields/CustomFieldFactory.php +15 -0
  26. V5/CustomFields/CustomFieldInterface.php +18 -0
  27. V5/CustomFields/DateCustomField.php +14 -0
  28. V5/CustomFields/InputCustomFiled.php +212 -0
  29. V5/Download/FileDownload.php +161 -0
  30. V5/Download/Mimetypes.php +1112 -0
  31. V5/FTP/FtpClient.php +968 -0
  32. V5/FTP/FtpException.php +23 -0
  33. V5/FTP/FtpWrapper.php +116 -0
  34. V5/FTP/info.txt +3 -0
  35. V5/Feed/Custom2Feed.php +403 -0
  36. V5/Feed/CustomFeed.php +61 -0
  37. V5/Feed/FacebookFeed.php +61 -0
  38. V5/Feed/Feed.php +22 -0
  39. V5/Feed/FeedFactory.php +49 -0
  40. V5/Feed/FeedInterface.php +8 -0
  41. V5/Feed/GoogleFeed.php +121 -0
  42. V5/Feed/GoogleReviewFeed.php +62 -0
  43. V5/Feed/PinterestFeed.php +61 -0
  44. V5/File/CSV.php +99 -0
  45. V5/File/FileFactory.php +32 -0
  46. V5/File/FileInfo.php +27 -0
  47. V5/File/FileInterface.php +18 -0
  48. V5/File/JSON.php +43 -0
  49. V5/File/TXT.php +74 -0
  50. V5/File/XLS.php +75 -0
  51. V5/File/XML.php +194 -0
  52. V5/Filter/AdvanceFilter.php +134 -0
  53. V5/Filter/Filter.php +94 -0
  54. V5/Filter/ValidateProduct.php +55 -0
  55. V5/Helper/CommonHelper.php +94 -0
  56. V5/Helper/CustomFieldHelper.php +43 -0
  57. V5/Helper/FeedHelper.php +7 -0
  58. V5/Helper/ProductHelper.php +668 -0
  59. V5/Merchant/MerchantAttributeReplaceFactory.php +653 -0
  60. V5/Merchant/MerchantAttributesFactory.php +1174 -0
  61. V5/Merchant/Merchants.php +23 -0
  62. V5/Merchant/TemplateConfig.php +10379 -0
  63. V5/Merchant/TemplateInfo.php +437 -0
  64. V5/Merchant/Templates.php +5 -0
  65. V5/Notice/Dismiss.php +168 -0
  66. V5/Notice/Notice.php +276 -0
  67. V5/Notice/Notices.php +138 -0
  68. V5/Output/FormatOutput.php +413 -0
  69. V5/Override/Advance.php +61 -0
  70. V5/Override/BestpriceTemplate.php +14 -0
  71. V5/Override/Common.php +16 -0
  72. V5/Override/DaisyconTemplate.php +14 -0
  73. V5/Override/FacebookTemplate.php +14 -0
  74. V5/Override/GoogleTemplate.php +72 -0
  75. V5/Override/OverrideFactory.php +37 -0
  76. V5/Override/PinterestTemplate.php +28 -0
  77. V5/Override/Pinterest_rssTemplate.php +39 -0
  78. V5/Override/PricerunnerTemplate.php +14 -0
  79. V5/Override/SpartooTemplate.php +14 -0
  80. V5/Override/TiktokTemplate.php +52 -0
  81. V5/Override/TrovaprezziTemplate.php +14 -0
  82. V5/Price/GroupProductPrice.php +120 -0
  83. V5/Price/IconicBundleProductPrice.php +146 -0
  84. V5/Price/PriceFactory.php +63 -0
  85. V5/Price/PriceInterface.php +19 -0
  86. V5/Price/ProductPrice.php +51 -0
  87. V5/Price/SimpleProductPrice.php +87 -0
  88. V5/Price/SubscriptionProductPrice.php +5 -0
  89. V5/Price/VariableProductPrice.php +143 -0
  90. V5/Price/WCBundleProductPrice.php +123 -0
  91. V5/Price/WCCompositeProductPrice.php +118 -0
  92. V5/Price/WPCCompositeProductPrice.php +163 -0
  93. V5/Product/AttributeValueByType.php +252 -0
  94. V5/Product/ProductAttributeFactory.php +771 -0
  95. V5/Product/ProductFactory.php +104 -0
  96. V5/Product/ProductInfo.php +1340 -0
  97. V5/Query/BothQuery.php +29 -0
  98. V5/Query/Query.php +18 -0
  99. V5/Query/QueryFactory.php +28 -0
  100. V5/Query/QueryInterface.php +14 -0
  101. V5/Query/WCQuery.php +118 -0
  102. V5/Query/WCReviewQuery.php +43 -0
  103. V5/Query/WPQuery.php +140 -0
  104. V5/Shipping/CustomShipping.php +59 -0
  105. V5/Shipping/GoogleShipping.php +140 -0
  106. V5/Shipping/Shipping.php +220 -0
  107. V5/Shipping/ShippingFactory.php +28 -0
  108. V5/Structure/Custom2Structure.php +212 -0
  109. V5/Structure/CustomStructure.php +78 -0
  110. V5/Structure/FacebookStructure.php +129 -0
  111. V5/Structure/GoogleStructure.php +301 -0
  112. V5/Structure/PinterestStructure.php +233 -0
  113. V5/Structure/SkroutzStructure.php +5 -0
  114. V5/Structure/Structure.php +42 -0
  115. V5/Structure/StructureFactory.php +22 -0
  116. V5/Structure/StructureInterface.php +12 -0
  117. V5/Structure/TiktokStructure.php +5 -0
  118. V5/Tax/CustomTax.php +69 -0
  119. V5/Tax/GoogleTax.php +108 -0
  120. V5/Tax/Tax.php +31 -0
  121. V5/Tax/TaxFactory.php +24 -0
  122. V5/Tax/TaxInterface.php +7 -0
  123. V5/Tracker/FacebookTracker.php +251 -0
  124. V5/Tracker/GoogleTracker.php +229 -0
  125. V5/Tracker/PinterestTracker.php +312 -0
  126. V5/Tracker/SkroutzTracker.php +5 -0
  127. V5/Tracker/SnapchatTracker.php +20 -0
  128. V5/Tracker/TiktokTracker.php +231 -0
  129. V5/Tracker/TrackerFactory.php +10 -0
  130. V5/Tracker/TrackerInterface.php +7 -0
  131. V5/Utility/CTX_WC_Log_Handler.php +443 -0
  132. V5/Utility/Cache.php +63 -0
  133. V5/Utility/Config.php +689 -0
  134. V5/Utility/DropDown.php +69 -0
  135. V5/Utility/FileSystem.php +122 -0
  136. V5/Utility/Logs.php +208 -0
  137. V5/Utility/Settings.php +273 -0
  138. V5/autoload.php +20 -0
  139. admin/class-woo-feed-manage-list.php +9 -10
  140. admin/css/fancy-select.scss +0 -201
  141. admin/css/woo-feed-admin-pro.css +0 -13
  142. admin/css/woo-feed-admin-pro.scss +0 -968
  143. admin/css/woo-feed-admin.css +1 -10
  144. admin/css/woo-feed-admin.scss +0 -2319
  145. admin/images/features/3rd-party-plugin-support.svg +1 -1
  146. admin/images/features/category-mapping.svg +1 -1
  147. admin/images/features/customer-support.svg +1 -1
  148. admin/images/features/multilingual-feed.svg +1 -1
  149. admin/images/get-woo-feed-pro.svg +2 -2
  150. admin/images/payment-options/amex.svg +2 -1
  151. admin/images/payment-options/diners.svg +2 -1
  152. admin/images/payment-options/discover.svg +2 -1
  153. admin/images/payment-options/jcb.svg +2 -1
  154. admin/images/payment-options/mastercard.svg +1 -1
  155. admin/images/payment-options/visa.svg +2 -1
  156. admin/images/woo-feed-black-friday.svg +1 -1
  157. admin/images/woo-feed-icon.svg +1 -1
  158. admin/images/woo-feed-lite.svg +2 -2
  159. admin/images/woo-feed-logo.svg +2 -2
  160. admin/images/woo-feed-pro.svg +2 -2
  161. admin/js/fancy-select.min.js +1 -1
  162. admin/js/fancy-select.min.js.map +0 -1
  163. admin/js/jquery-sortable.min.js +1 -1
  164. admin/js/jquery-sortable.min.js.map +0 -1
README.txt CHANGED
@@ -5,7 +5,7 @@ Tags: WooCommerce Product Feed, WooCommerce, Google Shopping, Google Merchant, F
5
  Requires at least: 4.4
6
  Tested Up To: 6.0
7
  Requires PHP: 5.6
8
- Stable tag: 4.4.69
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -589,6 +589,10 @@ Using pro version:
589
  4. Category Mapping
590
 
591
  == Changelog ==
 
 
 
 
592
  = 4.4.69 (2022-07-19) =
593
  * Fixed: Fatal error issue solved when WooCommerce is not active
594
 
5
  Requires at least: 4.4
6
  Tested Up To: 6.0
7
  Requires PHP: 5.6
8
+ Stable tag: 4.5.0
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
589
  4. Category Mapping
590
 
591
  == Changelog ==
592
+
593
+ = 4.5.0 (2022-08-24) =
594
+ * Product query feature improved.
595
+
596
  = 4.4.69 (2022-07-19) =
597
  * Fixed: Fatal error issue solved when WooCommerce is not active
598
 
V5/Common/CustomFileds.php ADDED
@@ -0,0 +1,253 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Common;
4
+
5
+ use CTXFeed\V5\Helper\CustomFieldHelper;
6
+ use CTXFeed\V5\Utility\Settings;
7
+
8
+ class CustomFileds
9
+ {
10
+ public function init()
11
+ {
12
+ add_action('woocommerce_product_options_inventory_product_data', [$this, 'set_custom_field'], 10, 3);
13
+ add_action('woocommerce_product_after_variable_attributes', [
14
+ $this,
15
+ 'set_custom_field_for_variation'
16
+ ], 10, 3);
17
+ add_action('save_post_product', [$this, 'save_custom_field_value'], 10, 2);
18
+ add_action('woocommerce_save_product_variation', [$this, 'save_variation_custom_field_value'], 10, 2);
19
+ }
20
+
21
+ /**
22
+ * Set Custom Fields for Product.
23
+ *
24
+ * @return void
25
+ */
26
+ public function set_custom_field()
27
+ {
28
+
29
+ $custom_field_settings = Settings::get('woo_feed_identifier');
30
+ $custom_fields = CustomFieldHelper::get_fields();
31
+
32
+ if (!empty($custom_field_settings) && in_array('enable', $custom_field_settings, true)) {
33
+ echo '<div class="options_group">';
34
+ echo sprintf('<h4 class="%s" style="padding-left: 10px;color: black;">%s</h4>', esc_attr('woo-feed-option-title'), esc_html__('CUSTOM FIELDS by CTX Feed', 'woo-feed'));
35
+ foreach ($custom_fields as $field_Key => $custom_field) {
36
+ if (isset($custom_field_settings[$field_Key]) && 'enable' === $custom_field_settings[$field_Key] && in_array($custom_field[2], ['text', 'date'])) {
37
+
38
+ //identifier meta value for old and new version users
39
+ $custom_field_key_previous = sprintf('woo_feed_identifier_%s', strtolower($field_Key));
40
+ $custom_field_value_previous = get_post_meta(get_the_ID(), $custom_field_key_previous, true);
41
+
42
+ $custom_field_key = sprintf('woo_feed_%s', strtolower($field_Key));
43
+ $custom_field_value = get_post_meta(get_the_ID(), $custom_field_key, true);
44
+
45
+ if (empty($custom_field_value) && !empty($custom_field_value_previous)) {
46
+ $custom_field_key = $custom_field_key_previous;
47
+ $custom_field_value = $custom_field_value_previous;
48
+ }
49
+
50
+ $custom_field_id = esc_attr(wp_unslash("woo_feed_$field_Key"));
51
+ $custom_field_label = esc_attr(wp_unslash($custom_field[0]));
52
+ $custom_field_description = __('Set product ', 'woo-feed') . esc_html($custom_field_label) . __(' here.', 'woo-feed');
53
+
54
+ if (strpos($custom_field_id, 'availability_date')) {
55
+ woocommerce_wp_text_input(
56
+ array(
57
+ 'id' => "woo_feed_availability_date",
58
+ 'name' => "woo_feed_availability_date",
59
+ 'placeholder' => '',
60
+ 'label' => __('Availability Date', 'woo-feed'),
61
+ 'type' => 'date',
62
+ 'value' => $custom_field_value,
63
+ 'desc_tip' => false,
64
+ 'description' => __('Set availability date for backorder products.', 'woo-feed'),
65
+ )
66
+ );
67
+ } else {
68
+ woocommerce_wp_text_input(
69
+ array(
70
+ 'id' => $custom_field_id,
71
+ 'label' => $custom_field_label,
72
+ 'placeholder' => $custom_field_label,
73
+ 'type' => $custom_field[2],
74
+ 'value' => esc_attr(wp_unslash($custom_field_value)),
75
+ 'desc_tip' => true,
76
+ 'description' => $custom_field_description,
77
+ )
78
+ );
79
+ }
80
+
81
+ }
82
+ }
83
+ echo '</div>';
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Set Custom Fields for Product Variations.
89
+ *
90
+ * @param $loop
91
+ * @param $variation_data
92
+ * @param $variation
93
+ *
94
+ * @return void
95
+ */
96
+ public function set_custom_field_for_variation($loop, $variation_data, $variation)
97
+ {
98
+
99
+ $custom_field_settings = Settings::get('woo_feed_identifier');
100
+ $custom_fields = CustomFieldHelper::get_fields();
101
+
102
+ if (!empty($custom_field_settings) && in_array('enable', $custom_field_settings, true)) {
103
+ echo '<div class="woo-feed-variation-options">';
104
+
105
+ if (!empty($custom_fields)) {
106
+ echo '<div class="woo-feed-variation-options">';
107
+ echo "<hr>";
108
+ echo sprintf('<h4 class="%s">%s</h4>', esc_attr('woo-feed-variation-option-title'), esc_html__('CUSTOM FIELDS by CTX Feed', 'woo-feed'));
109
+ echo "<hr>";
110
+ echo '<div class="woo-feed-variation-items">';
111
+
112
+ foreach ($custom_fields as $field_Key => $custom_field) {
113
+ if (isset($custom_field_settings[$field_Key]) && 'enable' === $custom_field_settings[$field_Key] && in_array($custom_field[2], ['text', 'date'])) {
114
+ $custom_field_id = sprintf('woo_feed_%s_var[%d]', strtolower($field_Key), $variation->ID);
115
+ $custom_field_label = isset($custom_field[0]) ? $custom_field[0] : '';
116
+ $custom_field_description = sprintf('Set Variation %s here.', $custom_field_label);
117
+
118
+ //identifier meta value for old and new version users
119
+ if (metadata_exists('post', $variation->ID, 'woo_feed_' . strtolower($field_Key) . '_var')) {
120
+ $custom_field_key = sprintf('woo_feed_%s_var', strtolower($field_Key));
121
+ } else {
122
+ $custom_field_key = sprintf('woo_feed_identifier_%s_var', strtolower($field_Key));
123
+ }
124
+
125
+ $custom_field_value = esc_attr(get_post_meta($variation->ID, $custom_field_key, true));
126
+
127
+ if (strpos($custom_field_id, 'availability_date')) {
128
+ woocommerce_wp_text_input(
129
+ array(
130
+ 'id' => "woo_feed_availability_date_var{$loop}",
131
+ 'name' => "woo_feed_availability_date_var[{$loop}]",
132
+ 'placeholder' => '',
133
+ 'label' => __('Availability Date', 'woo-feed'),
134
+ 'type' => 'date',
135
+ 'desc_tip' => true,
136
+ 'description' => __('Set availability date for backorder products.', 'woo-feed'),
137
+ 'value' => esc_attr($custom_field_value),
138
+ 'wrapper_class' => 'form-row form-row-full',
139
+ )
140
+ );
141
+ } else {
142
+ woocommerce_wp_text_input(
143
+ array(
144
+ 'id' => $custom_field_id,
145
+ 'value' => $custom_field_value,
146
+ 'placeholder' => esc_html($custom_field_label),
147
+ 'label' => esc_html($custom_field_label),
148
+ 'desc_tip' => true,
149
+ 'description' => esc_html($custom_field_description),
150
+ 'wrapper_class' => 'form-row form-row-full',
151
+ )
152
+ );
153
+ }
154
+ }
155
+ }
156
+ echo '</div></div>';
157
+ }
158
+ echo "<hr>";
159
+ echo '</div>';
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Save Product Custom Field Value.
165
+ *
166
+ * @param int $post_id Product id.
167
+ *
168
+ * @return void
169
+ */
170
+ public function save_custom_field_value($post_id)
171
+ {
172
+
173
+ $custom_fields = CustomFieldHelper::get_fields();
174
+ $set_meta_val = '';
175
+
176
+ if (!empty($custom_fields)) {
177
+ foreach ($custom_fields as $key => $custom_field) {
178
+ $product_meta_key = "woo_feed_$key";
179
+
180
+ $new_meta_key = "woo_feed_identifier_$key";
181
+ $new_meta_val = get_post_meta($post_id, $new_meta_key, true);
182
+ $old_meta_val = get_post_meta($post_id, $product_meta_key, true);
183
+
184
+ if (!empty($old_meta_val)) {
185
+ $set_meta_val = $old_meta_val;
186
+ } else {
187
+ $set_meta_val = $new_meta_val;
188
+ }
189
+
190
+ if (isset($_POST[$product_meta_key])) {
191
+ $product_meta_value = sanitize_text_field($_POST[$product_meta_key]);
192
+ } elseif (isset($_POST[$new_meta_key])) {
193
+ $product_meta_value = sanitize_text_field($_POST[$new_meta_key]);
194
+ } else {
195
+ $product_meta_value = $set_meta_val;
196
+ }
197
+
198
+ if (isset($product_meta_value) && !empty($product_meta_value)) {
199
+ update_post_meta($post_id, $product_meta_key, $product_meta_value);
200
+ } else {
201
+ delete_post_meta($post_id, $product_meta_key);
202
+ }
203
+ }
204
+ }
205
+ }
206
+
207
+ /**
208
+ * Save Product Variation Custom Field Value.
209
+ *
210
+ * @param int $post_id Variation id.
211
+ *
212
+ * @return void
213
+ */
214
+ public function save_variation_custom_field_value($post_id, $loop)
215
+ {
216
+
217
+ $custom_fields = woo_feed_product_custom_fields();
218
+
219
+ if (!empty($custom_fields)) {
220
+ foreach ($custom_fields as $key => $value) {
221
+
222
+ $product_meta_key = "woo_feed_{$key}_var";
223
+
224
+ $new_meta_key = "woo_feed_identifier_{$key}_var";
225
+ $new_meta_val = get_post_meta($post_id, $new_meta_key, true);
226
+ $old_meta_val = get_post_meta($post_id, $product_meta_key, true);
227
+
228
+ if (!empty($old_meta_val)) {
229
+ $set_meta_val = $old_meta_val;
230
+ } else {
231
+ $set_meta_val = $new_meta_val;
232
+ }
233
+
234
+ if (isset($_POST[$product_meta_key][$post_id])) {
235
+ $product_meta_value = sanitize_text_field($_POST[$product_meta_key][$post_id]);
236
+ } elseif (isset($_POST[$product_meta_key][$loop])) {
237
+ $product_meta_value = sanitize_text_field($_POST[$product_meta_key][$loop]);
238
+ } elseif (isset($_POST[$new_meta_key] [$post_id])) {
239
+ $product_meta_value = sanitize_text_field($_POST[$new_meta_key][$post_id]);
240
+ } elseif (isset($_POST[$new_meta_key] [$loop])) {
241
+ $product_meta_value = sanitize_text_field($_POST[$new_meta_key][$loop]);
242
+ } else {
243
+ $product_meta_value = $set_meta_val;
244
+ }
245
+
246
+
247
+ if (isset($product_meta_value) && !empty($product_meta_value)) {
248
+ update_post_meta($post_id, $product_meta_key, $product_meta_value);
249
+ }
250
+ }
251
+ }
252
+ }
253
+ }
V5/Common/DisplayBanners.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Common;
3
+ class DisplayBanners {
4
+
5
+ }
V5/Common/DisplayNotices.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Common;
4
+
5
+
6
+ use CTXFeed\V5\Notice\Notices;
7
+
8
+ /**
9
+ * Class DisplayNotices
10
+ *
11
+ * @package CTXFeed
12
+ * @subpackage CTXFeed\V5\Common
13
+ */
14
+ class DisplayNotices {
15
+
16
+ public function __construct() {
17
+ add_action( 'admin_notices', [ $this, 'display_admin_notice' ] );
18
+ }
19
+
20
+ public static function init() {
21
+ if ( isset( $_REQUEST['wpf_notice_code'] ) ) {
22
+ $code = sanitize_text_field( $_REQUEST['wpf_notice_code'] );
23
+ $notices = new Notices();
24
+ $options = [
25
+ 'dismissible' => true,
26
+ 'type' => 'error',
27
+ 'capability' => 'manage_woocommerce',
28
+ 'option_prefix' => 'ctx_feed_',
29
+ ];
30
+
31
+ switch ( $code ) {
32
+ case 'log_file_not_found':
33
+ $title = esc_html__( 'Log File Not Found.', 'woo-feed' );
34
+ $content = esc_html__( 'Log file not fount. Please enable log from CTX Feed > Setting or Regenerate the Feed.', 'woo-feed' );
35
+ $options['type'] = 'warning';
36
+ $notices->add( uniqid( 'log_file_not_found', true ), $title, $content, $options );
37
+ break;
38
+ case 'feed_download_failed':
39
+ $title = esc_html__( 'Feed Download Failed.', 'woo-feed' );
40
+ $content = esc_html__( 'Failed to download feed file. Please regenerate the feed and try again.', 'woo-feed' );
41
+ $notices->add( uniqid( 'feed_download_failed', true ), $title, $content, $options );
42
+ break;
43
+ default:
44
+ break;
45
+
46
+ //TODO add notice for feed import and export
47
+ }
48
+
49
+ $notices->boot();
50
+ }
51
+ }
52
+
53
+ public function display_admin_notice() {
54
+
55
+ }
56
+ }
V5/Common/DownloadFiles.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Common;
4
+
5
+
6
+ use CTXFeed\V5\Download\FileDownload;
7
+ use CTXFeed\V5\Utility\CTX_WC_Log_Handler;
8
+
9
+ /**
10
+ * Class DownloadFiles
11
+ *
12
+ * @package CTXFeed\V5\Common
13
+ * @subpackage CTXFeed\V5\Common
14
+ */
15
+ class DownloadFiles {
16
+
17
+ public function __construct() {
18
+ add_action( 'admin_post_wf_download_feed_log', [ $this, 'download_log' ], 10 );
19
+ add_action( 'admin_post_wf_download_feed', [ $this, 'download_feed' ], 10 );
20
+ }
21
+
22
+ /**
23
+ * Download Feed Log.
24
+ *
25
+ * @return void
26
+ *
27
+ * @throw RuntimeException
28
+ */
29
+ public function download_log() {
30
+ if (
31
+ isset( $_REQUEST['feed'], $_REQUEST['_wpnonce'] )
32
+ && wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'wpf-log-download' )
33
+ ) {
34
+ $feed_name = sanitize_text_field( wp_unslash( $_REQUEST['feed'] ) );
35
+ $feed_name = str_replace( 'wf_feed_', '', $feed_name );
36
+ $log_file_path = CTX_WC_Log_Handler::get_log_file_path( $feed_name );
37
+
38
+ $file_name = sprintf(
39
+ '%s-%s-%s.log',
40
+ sanitize_title( $feed_name ),
41
+ gmdate( 'Y-m-d', time() ),
42
+ time()
43
+ );
44
+
45
+ if ( ! file_exists( $log_file_path ) ) {
46
+ exit( wp_redirect( add_query_arg( 'wpf_notice_code', 'log_file_not_found', admin_url( 'admin.php?page=webappick-manage-feeds' ) ) ) );
47
+ }
48
+
49
+ $fileDownload = new FileDownload( fopen( $log_file_path, 'rb' ) );
50
+ $fileDownload->sendDownload( $file_name );
51
+ } else {
52
+ exit( wp_redirect( add_query_arg( 'wpf_notice_code', 'log_file_not_found', admin_url( 'admin.php?page=webappick-manage-feeds' ) ) ) );
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Download feed.
58
+ *
59
+ * @return void
60
+ */
61
+ public function download_feed() {
62
+ if (
63
+ isset( $_REQUEST['feed'], $_REQUEST['_wpnonce'] )
64
+ && wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'wpf-download-feed' )
65
+ ) {
66
+ $feed_name = sanitize_text_field( wp_unslash( $_REQUEST['feed'] ) );
67
+ /* your file, somewhere opened with fopen() or tmpfile(), etc.. */
68
+ $config = Factory::get_feed_info( $feed_name );
69
+
70
+ if ( ! file_exists( $config->get_feed_path() ) ) {
71
+ exit( wp_redirect( add_query_arg( 'wpf_notice_code', 'feed_download_failed', admin_url( 'admin.php?page=webappick-manage-feeds' ) ) ) );
72
+ }
73
+
74
+ $fileData = fopen( $config->get_feed_path(), 'rb' );
75
+ $fileDownload = new FileDownload( $fileData );
76
+ $fileDownload->sendDownload( $config->get_feed_file_name() );
77
+ } else {
78
+ exit( wp_redirect( add_query_arg( 'wpf_notice_code', 'feed_download_failed', admin_url( 'admin.php?page=webappick-manage-feeds' ) ) ) );
79
+ }
80
+ }
81
+
82
+ }
V5/Common/DropDownOptions.php ADDED
@@ -0,0 +1,636 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Common;
4
+ use CTXFeed\V5\Product\ProductAttributeFactory;
5
+ use CTXFeed\V5\Utility\DropDown;
6
+
7
+ /**
8
+ * @package CTXFeed
9
+ * @subpackage CTXFeed\V5\Common\DropDownOptions
10
+ */
11
+ class DropDownOptions {
12
+ /**
13
+ * Country List
14
+ *
15
+ * @param bool $dropdown
16
+ * @param string $selected
17
+ *
18
+ * @return array
19
+ * @since 4.3.16
20
+ * @author Nazrul Islam Nayan
21
+ * @updated 15-07-2022
22
+ */
23
+ public static function feed_country( $dropdown = false, $selected = '' ) {
24
+ $countries = array(
25
+ 'AF' => 'Afghanistan',
26
+ 'AX' => 'Aland Islands',
27
+ 'AL' => 'Albania',
28
+ 'DZ' => 'Algeria',
29
+ 'AS' => 'American Samoa',
30
+ 'AD' => 'Andorra',
31
+ 'AO' => 'Angola',
32
+ 'AI' => 'Anguilla',
33
+ 'AQ' => 'Antarctica',
34
+ 'AG' => 'Antigua and Barbuda',
35
+ 'AR' => 'Argentina',
36
+ 'AM' => 'Armenia',
37
+ 'AW' => 'Aruba',
38
+ 'AU' => 'Australia',
39
+ 'AT' => 'Austria',
40
+ 'AZ' => 'Azerbaijan',
41
+ 'BS' => 'Bahamas the',
42
+ 'BH' => 'Bahrain',
43
+ 'BD' => 'Bangladesh',
44
+ 'BB' => 'Barbados',
45
+ 'BY' => 'Belarus',
46
+ 'BE' => 'Belgium',
47
+ 'BZ' => 'Belize',
48
+ 'BJ' => 'Benin',
49
+ 'BM' => 'Bermuda',
50
+ 'BT' => 'Bhutan',
51
+ 'BO' => 'Bolivia',
52
+ 'BA' => 'Bosnia and Herzegovina',
53
+ 'BW' => 'Botswana',
54
+ 'BV' => 'Bouvet Island (Bouvetoya)',
55
+ 'BR' => 'Brazil',
56
+ 'IO' => 'British Indian Ocean Territory (Chagos Archipelago)',
57
+ 'VG' => 'British Virgin Islands',
58
+ 'BN' => 'Brunei Darussalam',
59
+ 'BG' => 'Bulgaria',
60
+ 'BF' => 'Burkina Faso',
61
+ 'BI' => 'Burundi',
62
+ 'KH' => 'Cambodia',
63
+ 'CM' => 'Cameroon',
64
+ 'CA' => 'Canada',
65
+ 'CV' => 'Cape Verde',
66
+ 'KY' => 'Cayman Islands',
67
+ 'CF' => 'Central African Republic',
68
+ 'TD' => 'Chad',
69
+ 'CL' => 'Chile',
70
+ 'CN' => 'China',
71
+ 'CX' => 'Christmas Island',
72
+ 'CC' => 'Cocos (Keeling) Islands',
73
+ 'CO' => 'Colombia',
74
+ 'KM' => 'Comoros the',
75
+ 'CD' => 'Congo',
76
+ 'CG' => 'Congo the',
77
+ 'CK' => 'Cook Islands',
78
+ 'CR' => 'Costa Rica',
79
+ 'CI' => 'Cote d\'Ivoire',
80
+ 'HR' => 'Croatia',
81
+ 'CU' => 'Cuba',
82
+ 'CY' => 'Cyprus',
83
+ 'CZ' => 'Czech Republic',
84
+ 'DK' => 'Denmark',
85
+ 'DJ' => 'Djibouti',
86
+ 'DM' => 'Dominica',
87
+ 'DO' => 'Dominican Republic',
88
+ 'EC' => 'Ecuador',
89
+ 'EG' => 'Egypt',
90
+ 'SV' => 'El Salvador',
91
+ 'GQ' => 'Equatorial Guinea',
92
+ 'ER' => 'Eritrea',
93
+ 'EE' => 'Estonia',
94
+ 'ET' => 'Ethiopia',
95
+ 'FO' => 'Faroe Islands',
96
+ 'FK' => 'Falkland Islands (Malvinas)',
97
+ 'FJ' => 'Fiji the Fiji Islands',
98
+ 'FI' => 'Finland',
99
+ 'FR' => 'France',
100
+ 'GF' => 'French Guiana',
101
+ 'PF' => 'French Polynesia',
102
+ 'TF' => 'French Southern Territories',
103
+ 'GA' => 'Gabon',
104
+ 'GM' => 'Gambia the',
105
+ 'GE' => 'Georgia',
106
+ 'DE' => 'Germany',
107
+ 'GH' => 'Ghana',
108
+ 'GI' => 'Gibraltar',
109
+ 'GR' => 'Greece',
110
+ 'GL' => 'Greenland',
111
+ 'GD' => 'Grenada',
112
+ 'GP' => 'Guadeloupe',
113
+ 'GU' => 'Guam',
114
+ 'GT' => 'Guatemala',
115
+ 'GG' => 'Guernsey',
116
+ 'GN' => 'Guinea',
117
+ 'GW' => 'Guinea-Bissau',
118
+ 'GY' => 'Guyana',
119
+ 'HT' => 'Haiti',
120
+ 'HM' => 'Heard Island and McDonald Islands',
121
+ 'VA' => 'Holy See (Vatican City State)',
122
+ 'HN' => 'Honduras',
123
+ 'HK' => 'Hong Kong',
124
+ 'HU' => 'Hungary',
125
+ 'IS' => 'Iceland',
126
+ 'IN' => 'India',
127
+ 'ID' => 'Indonesia',
128
+ 'IR' => 'Iran',
129
+ 'IQ' => 'Iraq',
130
+ 'IE' => 'Ireland',
131
+ 'IM' => 'Isle of Man',
132
+ 'IL' => 'Israel',
133
+ 'IT' => 'Italy',
134
+ 'JM' => 'Jamaica',
135
+ 'JP' => 'Japan',
136
+ 'JE' => 'Jersey',
137
+ 'JO' => 'Jordan',
138
+ 'KZ' => 'Kazakhstan',
139
+ 'KE' => 'Kenya',
140
+ 'KI' => 'Kiribati',
141
+ 'KP' => 'Korea',
142
+ 'KR' => 'Korea',
143
+ 'KW' => 'Kuwait',
144
+ 'KG' => 'Kyrgyz Republic',
145
+ 'LA' => 'Lao',
146
+ 'LV' => 'Latvia',
147
+ 'LB' => 'Lebanon',
148
+ 'LS' => 'Lesotho',
149
+ 'LR' => 'Liberia',
150
+ 'LY' => 'Libyan Arab Jamahiriya',
151
+ 'LI' => 'Liechtenstein',
152
+ 'LT' => 'Lithuania',
153
+ 'LU' => 'Luxembourg',
154
+ 'MO' => 'Macao',
155
+ 'MK' => 'Macedonia',
156
+ 'MG' => 'Madagascar',
157
+ 'MW' => 'Malawi',
158
+ 'MY' => 'Malaysia',
159
+ 'MV' => 'Maldives',
160
+ 'ML' => 'Mali',
161
+ 'MT' => 'Malta',
162
+ 'MH' => 'Marshall Islands',
163
+ 'MQ' => 'Martinique',
164
+ 'MR' => 'Mauritania',
165
+ 'MU' => 'Mauritius',
166
+ 'YT' => 'Mayotte',
167
+ 'MX' => 'Mexico',
168
+ 'FM' => 'Micronesia',
169
+ 'MD' => 'Moldova',
170
+ 'MC' => 'Monaco',
171
+ 'MN' => 'Mongolia',
172
+ 'ME' => 'Montenegro',
173
+ 'MS' => 'Montserrat',
174
+ 'MA' => 'Morocco',
175
+ 'MZ' => 'Mozambique',
176
+ 'MM' => 'Myanmar',
177
+ 'NA' => 'Namibia',
178
+ 'NR' => 'Nauru',
179
+ 'NP' => 'Nepal',
180
+ 'AN' => 'Netherlands Antilles',
181
+ 'NL' => 'Netherlands',
182
+ 'NC' => 'New Caledonia',
183
+ 'NZ' => 'New Zealand',
184
+ 'NI' => 'Nicaragua',
185
+ 'NE' => 'Niger',
186
+ 'NG' => 'Nigeria',
187
+ 'NU' => 'Niue',
188
+ 'NF' => 'Norfolk Island',
189
+ 'MP' => 'Northern Mariana Islands',
190
+ 'NO' => 'Norway',
191
+ 'OM' => 'Oman',
192
+ 'PK' => 'Pakistan',
193
+ 'PW' => 'Palau',
194
+ 'PS' => 'Palestinian Territory',
195
+ 'PA' => 'Panama',
196
+ 'PG' => 'Papua New Guinea',
197
+ 'PY' => 'Paraguay',
198
+ 'PE' => 'Peru',
199
+ 'PH' => 'Philippines',
200
+ 'PN' => 'Pitcairn Islands',
201
+ 'PL' => 'Poland',
202
+ 'PT' => 'Portugal, Portuguese Republic',
203
+ 'PR' => 'Puerto Rico',
204
+ 'QA' => 'Qatar',
205
+ 'RE' => 'Reunion',
206
+ 'RO' => 'Romania',
207
+ 'RU' => 'Russian Federation',
208
+ 'RW' => 'Rwanda',
209
+ 'BL' => 'Saint Barthelemy',
210
+ 'SH' => 'Saint Helena',
211
+ 'KN' => 'Saint Kitts and Nevis',
212
+ 'LC' => 'Saint Lucia',
213
+ 'MF' => 'Saint Martin',
214
+ 'PM' => 'Saint Pierre and Miquelon',
215
+ 'VC' => 'Saint Vincent and the Grenadines',
216
+ 'WS' => 'Samoa',
217
+ 'SM' => 'San Marino',
218
+ 'ST' => 'Sao Tome and Principe',
219
+ 'SA' => 'Saudi Arabia',
220
+ 'SN' => 'Senegal',
221
+ 'RS' => 'Serbia',
222
+ 'SC' => 'Seychelles',
223
+ 'SL' => 'Sierra Leone',
224
+ 'SG' => 'Singapore',
225
+ 'SK' => 'Slovakia (Slovak Republic)',
226
+ 'SI' => 'Slovenia',
227
+ 'SB' => 'Solomon Islands',
228
+ 'SO' => 'Somalia, Somali Republic',
229
+ 'ZA' => 'South Africa',
230
+ 'GS' => 'South Georgia and the South Sandwich Islands',
231
+ 'ES' => 'Spain',
232
+ 'LK' => 'Sri Lanka',
233
+ 'SD' => 'Sudan',
234
+ 'SR' => 'Suriname',
235
+ 'SJ' => 'Svalbard & Jan Mayen Islands',
236
+ 'SZ' => 'Swaziland',
237
+ 'SE' => 'Sweden',
238
+ 'CH' => 'Switzerland',
239
+ 'SY' => 'Syrian Arab Republic',
240
+ 'TW' => 'Taiwan',
241
+ 'TJ' => 'Tajikistan',
242
+ 'TZ' => 'Tanzania',
243
+ 'TH' => 'Thailand',
244
+ 'TL' => 'Timor-Leste',
245
+ 'TG' => 'Togo',
246
+ 'TK' => 'Tokelau',
247
+ 'TO' => 'Tonga',
248
+ 'TT' => 'Trinidad and Tobago',
249
+ 'TN' => 'Tunisia',
250
+ 'TR' => 'Turkey',
251
+ 'TM' => 'Turkmenistan',
252
+ 'TC' => 'Turks and Caicos Islands',
253
+ 'TV' => 'Tuvalu',
254
+ 'UG' => 'Uganda',
255
+ 'UA' => 'Ukraine',
256
+ 'AE' => 'United Arab Emirates',
257
+ 'GB' => 'United Kingdom',
258
+ 'US' => 'United States',
259
+ 'UM' => 'United States Minor Outlying Islands',
260
+ 'VI' => 'United States Virgin Islands',
261
+ 'UY' => 'Uruguay, Eastern Republic of',
262
+ 'UZ' => 'Uzbekistan',
263
+ 'VU' => 'Vanuatu',
264
+ 'VE' => 'Venezuela',
265
+ 'VN' => 'Vietnam',
266
+ 'WF' => 'Wallis and Futuna',
267
+ 'EH' => 'Western Sahara',
268
+ 'YE' => 'Yemen',
269
+ 'ZM' => 'Zambia',
270
+ 'ZW' => 'Zimbabwe',
271
+ );
272
+
273
+ return self::Create_DropDown_IF_Needed( $countries, $dropdown, $selected );
274
+ }
275
+
276
+ /**
277
+ * Feed Template List.
278
+ *
279
+ * @param $dropdown
280
+ * @param $selected
281
+ *
282
+ * @return array|false|mixed|string|string[]
283
+ */
284
+ public static function provider( $dropdown = false, $selected = '' ) {
285
+ $merchant = [
286
+ 1 => [
287
+ 'optionGroup' => 'Custom Templates',
288
+ 'options' => [
289
+ 'custom' => esc_html__( 'Custom Template 1', 'woo-feed' ),
290
+ 'custom2' => esc_html__( 'Custom Template 2 (XML)', 'woo-feed' ),
291
+ ]
292
+ ],
293
+ 2 => [
294
+ 'optionGroup' => 'Popular Templates',
295
+ 'options' => [
296
+ 'google' => esc_html__( 'Google Shopping', 'woo-feed' ),
297
+ 'google_local' => esc_html__( 'Google Local Inventory Ads', 'woo-feed' ),
298
+ 'google_local_inventory' => esc_html__( 'Google Local Product Inventory', 'woo-feed' ),
299
+ 'googlereview' => esc_html__( 'Google Product Review', 'woo-feed' ),
300
+ 'google_shopping_action' => esc_html__( 'Google Shopping Action', 'woo-feed' ),
301
+ 'google_promotions' => esc_html__( 'Google Promotions', 'woo-feed' ),
302
+ 'google_dynamic_ads' => esc_html__( 'Google Dynamic Search Ads', 'woo-feed' ),
303
+ 'adwords' => esc_html__( 'Google Ads', 'woo-feed' ),
304
+ 'adwords_local_product' => esc_html__( 'Google Ads Local Product', 'woo-feed' ),
305
+ 'facebook' => esc_html__( 'Facebook Catalog / Instagram', 'woo-feed' ),
306
+ 'pinterest' => esc_html__( 'Pinterest Catalog', 'woo-feed' ),
307
+ 'pinterest_rss' => esc_html__( 'Pinterest RSS Board', 'woo-feed' ),
308
+ 'bing' => esc_html__( 'Bing Shopping', 'woo-feed' ),
309
+ 'bing_local_inventory' => esc_html__( 'Bing Local Inventory', 'woo-feed' ),
310
+ 'snapchat' => esc_html__( 'Snapchat', 'woo-feed' ),
311
+ 'tiktok' => esc_html__( 'TikTok', 'woo-feed' ),
312
+ 'idealo' => esc_html__( 'Idealo', 'woo-feed' ),
313
+ 'pricespy' => esc_html__( 'PriceSpy', 'woo-feed' ),
314
+ 'pricerunner' => esc_html__( 'Price Runner', 'woo-feed' ),
315
+ 'yandex_csv' => esc_html__( 'Yandex (CSV)', 'woo-feed' ),
316
+ 'yandex_xml' => esc_html__( 'Yandex (XML)', 'woo-feed' ),
317
+ ]
318
+ ],
319
+ 3 => [
320
+ 'optionGroup' => 'Other Templates',
321
+ 'options' => [
322
+ 'adform' => esc_html__( 'AdForm', 'woo-feed' ),
323
+ 'adroll' => esc_html__( 'AdRoll', 'woo-feed' ),
324
+ 'avantlink' => esc_html__( 'Avantlink', 'woo-feed' ),
325
+ 'become' => esc_html__( 'Become', 'woo-feed' ),
326
+ 'beslist.nl' => esc_html__( 'Beslist.nl', 'woo-feed' ),
327
+ 'bestprice' => esc_html__( 'Bestprice', 'woo-feed' ),
328
+ 'billiger.de' => esc_html__( 'Billiger.de', 'woo-feed' ),
329
+ 'bol' => esc_html__( 'Bol.com', 'woo-feed' ),
330
+ 'bonanza' => esc_html__( 'Bonanza', 'woo-feed' ),
331
+ 'catchdotcom' => esc_html__( 'Catch.com.au', 'woo-feed' ),
332
+ 'cdiscount.fr' => esc_html__( 'CDiscount.fr', 'woo-feed' ),
333
+ 'comparer.be' => esc_html__( 'Comparer.be', 'woo-feed' ),
334
+ 'connexity' => esc_html__( 'Connexity', 'woo-feed' ),
335
+ 'criteo' => esc_html__( 'Criteo', 'woo-feed' ),
336
+ 'crowdfox' => esc_html__( 'Crowdfox', 'woo-feed' ),
337
+ 'daisycon' => esc_html__( 'Daisycon Advertiser (General)', 'woo-feed' ),
338
+ 'daisycon_automotive' => esc_html__( 'Daisycon Advertiser (Automotive)', 'woo-feed' ),
339
+ 'daisycon_books' => esc_html__( 'Daisycon Advertiser (Books)', 'woo-feed' ),
340
+ 'daisycon_cosmetics' => esc_html__( 'Daisycon Advertiser (Cosmetics)', 'woo-feed' ),
341
+ 'daisycon_daily_offers' => esc_html__( 'Daisycon Advertiser (Daily Offers)', 'woo-feed' ),
342
+ 'daisycon_electronics' => esc_html__( 'Daisycon Advertiser (Electronics)', 'woo-feed' ),
343
+ 'daisycon_fashion' => esc_html__( 'Daisycon Advertiser (Fashion)', 'woo-feed' ),
344
+ 'daisycon_food_drinks' => esc_html__( 'Daisycon Advertiser (Food & Drinks)', 'woo-feed' ),
345
+ 'daisycon_holidays_accommodations_and_transport' => esc_html__( 'Daisycon Advertiser (Holidays: Accommodations and transport)', 'woo-feed' ),
346
+ 'daisycon_holidays_accommodations' => esc_html__( 'Daisycon Advertiser (Holidays: Accommodations)', 'woo-feed' ),
347
+ 'daisycon_holidays_trips' => esc_html__( 'Daisycon Advertiser (Holidays: Trips)', 'woo-feed' ),
348
+ 'daisycon_home_garden' => esc_html__( 'Daisycon Advertiser (Home & Garden)', 'woo-feed' ),
349
+ 'daisycon_housing' => esc_html__( 'Daisycon Advertiser (Housing)', 'woo-feed' ),
350
+ 'daisycon_magazines' => esc_html__( 'Daisycon Advertiser (Magazines)', 'woo-feed' ),
351
+ 'daisycon_studies_trainings' => esc_html__( 'Daisycon Advertiser (Studies & Trainings)', 'woo-feed' ),
352
+ 'daisycon_telecom_accessories' => esc_html__( 'Daisycon Advertiser (Telecom: Accessories)', 'woo-feed' ),
353
+ 'daisycon_telecom_all_in_one' => esc_html__( 'Daisycon Advertiser (Telecom: All-in-one)', 'woo-feed' ),
354
+ 'daisycon_telecom_gsm_subscription' => esc_html__( 'Daisycon Advertiser (Telecom: GSM + Subscription)', 'woo-feed' ),
355
+ 'daisycon_telecom_gsm' => esc_html__( 'Daisycon Advertiser (Telecom: GSM only)', 'woo-feed' ),
356
+ 'daisycon_telecom_sim' => esc_html__( 'Daisycon Advertiser (Telecom: Sim only)', 'woo-feed' ),
357
+ 'daisycon_work_jobs' => esc_html__( 'Daisycon Advertiser (Work & Jobs)', 'woo-feed' ),
358
+ 'dooyoo' => esc_html__( 'Dooyoo', 'woo-feed' ),
359
+ 'ecommerceit' => esc_html__( 'Ecommerce.it', 'woo-feed' ),
360
+ 'etsy' => esc_html__( 'Etsy', 'woo-feed' ),
361
+ 'fruugo' => esc_html__( 'Fruugo', 'woo-feed' ),
362
+ 'fashionchick' => esc_html__( 'Fashionchick.nl', 'woo-feed' ),
363
+ 'fruugo.au' => esc_html__( 'Fruugoaustralia.com', 'woo-feed' ),
364
+ 'fyndiq.se' => esc_html__( 'Fyndiq.se', 'woo-feed' ),
365
+ 'goedgeplaatst' => esc_html__( 'GoedGeplaatst.nl', 'woo-feed' ),
366
+ 'heureka.sk' => esc_html__( 'Heureka.sk', 'woo-feed' ),
367
+ 'hintaseuranta.fi' => esc_html__( 'Hintaseuranta.fi', 'woo-feed' ),
368
+ 'incurvy' => esc_html__( 'Incurvy', 'woo-feed' ),
369
+ 'jet' => esc_html__( 'Jet.com', 'woo-feed' ),
370
+ 'kelkoo' => esc_html__( 'Kelkoo', 'woo-feed' ),
371
+ 'kieskeurig.nl' => esc_html__( 'Kieskeurig.nl', 'woo-feed' ),
372
+ 'kijiji.ca' => esc_html__( 'Kijiji.ca', 'woo-feed' ),
373
+ 'leguide' => esc_html__( 'LeGuide', 'woo-feed' ),
374
+ 'marktplaats.nl' => esc_html__( 'Marktplaats.nl', 'woo-feed' ),
375
+ 'miinto.de' => esc_html__( 'Miinto.de', 'woo-feed' ),
376
+ 'miinto.nl' => esc_html__( 'Miinto.nl', 'woo-feed' ),
377
+ 'modalova' => esc_html__( 'Modalova', 'woo-feed' ),
378
+ 'modina.de' => esc_html__( 'Modina.de', 'woo-feed' ),
379
+ 'moebel.de' => esc_html__( 'Moebel.de', 'woo-feed' ),
380
+ 'myshopping.com.au' => esc_html__( 'Myshopping.com.au', 'woo-feed' ),
381
+ 'nextad' => esc_html__( 'TheNextAd', 'woo-feed' ),
382
+ 'nextag' => esc_html__( 'Nextag', 'woo-feed' ),
383
+ 'polyvore' => esc_html__( 'Polyvore', 'woo-feed' ),
384
+ 'pricegrabber' => esc_html__( 'Price Grabber', 'woo-feed' ),
385
+ 'prisjakt' => esc_html__( 'Prisjakt', 'woo-feed' ),
386
+ 'profit_share' => esc_html__( 'Profit Share', 'woo-feed' ),
387
+ 'rakuten.de' => esc_html__( 'Rakuten.de', 'woo-feed' ),
388
+ 'real' => esc_html__( 'Real', 'woo-feed' ),
389
+ 'shareasale' => esc_html__( 'ShareASale', 'woo-feed' ),
390
+ 'shopalike.fr' => esc_html__( 'Shopalike.fr', 'woo-feed' ),
391
+ 'shopbot' => esc_html__( 'Shopbot', 'woo-feed' ),
392
+ 'shopmania' => esc_html__( 'Shopmania', 'woo-feed' ),
393
+ 'shopping' => esc_html__( 'Shopping.com', 'woo-feed' ),
394
+ 'shopflix' => esc_html__( 'Shopflix (WellComm)', 'woo-feed' ),
395
+ 'shopzilla' => esc_html__( 'Shopzilla', 'woo-feed' ),
396
+ 'skinflint.co.uk' => esc_html__( 'SkinFlint.co.uk', 'woo-feed' ),
397
+ 'skroutz' => esc_html__( 'Skroutz.gr', 'woo-feed' ),
398
+ 'smartly.io' => esc_html__( 'Smartly.io', 'woo-feed' ),
399
+ 'spartoo.fi' => esc_html__( 'Spartoo.fi', 'woo-feed' ),
400
+ 'shopee' => esc_html__( 'Shopee', 'woo-feed' ),
401
+ 'stylight.com' => esc_html__( 'Stylight.com', 'woo-feed' ),
402
+ 'trovaprezzi' => esc_html__( 'Trovaprezzi.it', 'woo-feed' ),
403
+ 'twenga' => esc_html__( 'Twenga', 'woo-feed' ),
404
+ 'tweaker_xml' => esc_html__( 'Tweakers (XML)', 'woo-feed' ),
405
+ 'tweaker_csv' => esc_html__( 'Tweakers (CSV)', 'woo-feed' ),
406
+ 'vertaa.fi' => esc_html__( 'Vertaa.fi', 'woo-feed' ),
407
+ 'walmart' => esc_html__( 'Walmart', 'woo-feed' ),
408
+ 'webmarchand' => esc_html__( 'Webmarchand', 'woo-feed' ),
409
+ 'wine_searcher' => esc_html__( 'Wine Searcher', 'woo-feed' ),
410
+ 'wish' => esc_html__( 'Wish.com', 'woo-feed' ),
411
+ 'yahoo_nfa' => esc_html__( 'Yahoo NFA', 'woo-feed' ),
412
+ 'zap.co.il' => esc_html__( 'Zap.co.il', 'woo-feed' ),
413
+ 'zbozi.cz' => esc_html__( 'Zbozi.cz', 'woo-feed' ),
414
+ 'zalando' => esc_html__( 'Zalando', 'woo-feed' ),
415
+ 'admarkt' => esc_html__( 'Admarkt(marktplaats)', 'woo-feed' ),
416
+ 'glami' => esc_html__( 'GLAMI', 'woo-feed' ),
417
+ ]
418
+ ],
419
+ ];
420
+
421
+ return self::Create_DropDown_IF_Needed( $merchant, $dropdown, $selected );
422
+ }
423
+
424
+ /**
425
+ * Feed File Type List.
426
+ *
427
+ * @param $dropdown
428
+ * @param $selected
429
+ *
430
+ * @return array|false|mixed|string|string[]
431
+ */
432
+ public static function file_types( $dropdown = false, $selected = '' ) {
433
+ $types = array(
434
+ 'xml' => 'XML',
435
+ 'csv' => 'CSV',
436
+ 'tsv' => 'TSV',
437
+ 'xls' => 'XLS',
438
+ 'txt' => 'TXT',
439
+ 'json' => 'JSON',
440
+ );
441
+
442
+ return self::Create_DropDown_IF_Needed( $types, $dropdown, $selected );
443
+ }
444
+
445
+ /**
446
+ * Variation Options.
447
+ *
448
+ * @param $dropdown
449
+ * @param $selected
450
+ *
451
+ * @return array|false|mixed|string|string[]
452
+ */
453
+ public static function include_variation( $dropdown = false, $selected = '' ) {
454
+ $variation_options = array(
455
+ 'n' => esc_html__( 'Variable Products (Parent)', 'woo-feed' ),
456
+ 'y' => esc_html__( 'All Variations', 'woo-feed' ),
457
+ 'default' => esc_html__( 'Default Variation', 'woo-feed' ),
458
+ 'cheap' => esc_html__( 'Cheapest Variation', 'woo-feed' ),
459
+ 'first' => esc_html__( 'First Variation', 'woo-feed' ),
460
+ 'last' => esc_html__( 'Last Variation', 'woo-feed' ),
461
+ 'both' => esc_html__( 'Variable + Variations', 'woo-feed' ),
462
+ );
463
+
464
+ return self::Create_DropDown_IF_Needed( $variation_options, $dropdown, $selected );
465
+ }
466
+
467
+ /**
468
+ * Variation Price Options.
469
+ *
470
+ * @param $dropdown
471
+ * @param $selected
472
+ *
473
+ * @return array|false|mixed|string|string[]
474
+ */
475
+ public static function variation_price( $dropdown = false, $selected = '' ) {
476
+ $variation_price = array(
477
+ 'first' => esc_html__( 'First Variation Price', 'woo-feed' ),
478
+ 'max' => esc_html__( 'Max Variation Price', 'woo-feed' ),
479
+ 'min' => esc_html__( 'Min Variation Price', 'woo-feed' ),
480
+ );
481
+
482
+ return self::Create_DropDown_IF_Needed( $variation_price, $dropdown, $selected );
483
+ }
484
+
485
+ /**
486
+ * Variation Quantity Options.
487
+ *
488
+ * @param $dropdown
489
+ * @param $selected
490
+ *
491
+ * @return array|false|mixed|string|string[]
492
+ */
493
+ public static function variation_quantity( $dropdown = false, $selected = '' ) {
494
+ $variation_quantity = array(
495
+ 'first' => esc_html__( 'First Variation Price', 'woo-feed' ),
496
+ 'max' => esc_html__( 'Max Variation Price', 'woo-feed' ),
497
+ 'min' => esc_html__( 'Min Variation Price', 'woo-feed' ),
498
+ );
499
+
500
+ return self::Create_DropDown_IF_Needed( $variation_quantity, $dropdown, $selected );
501
+ }
502
+
503
+ /**
504
+ * CSV Feed Delimiters.
505
+ *
506
+ * @param $dropdown
507
+ * @param $selected
508
+ *
509
+ * @return array|false|mixed|string|string[]
510
+ */
511
+ public static function delimiters( $dropdown = false, $selected = '' ) {
512
+ $delimiters = [
513
+ ',' => 'Comma',
514
+ ':' => 'Colon',
515
+ ' ' => 'Space',
516
+ '|' => 'Pipe',
517
+ ';' => 'Semi Colon',
518
+ "\t" => 'TAB',
519
+ ];
520
+
521
+ return self::Create_DropDown_IF_Needed( $delimiters, $dropdown, $selected );
522
+ }
523
+
524
+ /**
525
+ * CSV Feed Enclosure.
526
+ *
527
+ * @param $dropdown
528
+ * @param $selected
529
+ *
530
+ * @return array|false|mixed|string|string[]
531
+ */
532
+ public static function enclosure( $dropdown = false, $selected = '' ) {
533
+ $enclosure = [
534
+ 'double' => '"',
535
+ 'single' => '\'',
536
+ ' ' => 'None',
537
+ ];
538
+
539
+ return self::Create_DropDown_IF_Needed( $enclosure, $dropdown, $selected );
540
+ }
541
+
542
+ /**
543
+ * Product Attributes.
544
+ *
545
+ * @param $dropdown
546
+ * @param $selected
547
+ *
548
+ * @return array|false|mixed|string|string[]
549
+ */
550
+ public static function product_attributes( $dropdown = false, $selected = '' ) {
551
+ $attributes = ProductAttributeFactory::getAttributes();
552
+ $cache_key = 'woo_feed_product_attribute_dropdown';
553
+
554
+ return self::Create_DropDown_IF_Needed( $attributes, $dropdown, $selected, $cache_key, true );
555
+ }
556
+
557
+ /**
558
+ * Comparing Condition. Used on Dynamic Attributes and
559
+ *
560
+ * @param $dropdown
561
+ * @param $selected
562
+ *
563
+ * @return array|false|mixed|string|string[]
564
+ */
565
+ public static function conditions( $dropdown = false, $selected = '' ) {
566
+ $conditions = array(
567
+ '==' => __( 'is / equal', 'woo-feed' ),
568
+ '!=' => __( 'is not / not equal', 'woo-feed' ),
569
+ '>=' => __( 'equals or greater than', 'woo-feed' ),
570
+ '>' => __( 'greater than', 'woo-feed' ),
571
+ '<=' => __( 'equals or less than', 'woo-feed' ),
572
+ '<' => __( 'less than', 'woo-feed' ),
573
+ 'contains' => __( 'contains', 'woo-feed' ),
574
+ 'nContains' => __( 'does not contain', 'woo-feed' ),
575
+ 'between' => __( 'between', 'woo-feed' ),
576
+ );
577
+
578
+ return self::Create_DropDown_IF_Needed( $conditions, $dropdown, $selected );
579
+ }
580
+
581
+ /**
582
+ * Variation Query Type at Settings.
583
+ *
584
+ * @param $dropdown
585
+ * @param $selected
586
+ *
587
+ * @return array|false|mixed|string|string[]
588
+ */
589
+ public static function variation_query_type( $dropdown = false, $selected = '' ) {
590
+ $variation_query_type = [
591
+ 'individual' => __( 'Individual', 'woo-feed' ),
592
+ 'variable' => __( 'Variable Dependable', 'woo-feed' ),
593
+ ];
594
+
595
+ return self::Create_DropDown_IF_Needed( $variation_query_type, $dropdown, $selected );
596
+ }
597
+
598
+ /**
599
+ * Product Query Type at Settings.
600
+ *
601
+ * @param $dropdown
602
+ * @param $selected
603
+ *
604
+ * @return array|false|mixed|string|string[]
605
+ */
606
+ public static function product_query_type( $dropdown = false, $selected = '' ) {
607
+ $product_query_type = [
608
+ 'wc' => __( 'WC_Product_Query', 'woo-feed' ),
609
+ 'wp' => __( 'WP_Query', 'woo-feed' ),
610
+ 'both' => __( 'Both', 'woo-feed' ),
611
+ ];
612
+
613
+ return self::Create_DropDown_IF_Needed( $product_query_type, $dropdown, $selected );
614
+ }
615
+
616
+
617
+ /**
618
+ * Make DropDown Option from array if needed else return the array.
619
+ *
620
+ * @param $array
621
+ * @param $DropDownStatus
622
+ * @param $selected
623
+ * @param string $cache_key
624
+ * @param bool $cache
625
+ *
626
+ * @return array|false|mixed|string|string[]
627
+ */
628
+ public static function Create_DropDown_IF_Needed( $array, $DropDownStatus, $selected, $cache_key = '', $cache = false ) {
629
+ if ( $DropDownStatus ) {
630
+ return Dropdown::Create( $array, $selected, $cache_key, $cache );
631
+ }
632
+
633
+ return $array;
634
+ }
635
+
636
+ }
V5/Common/ExportFeed.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Common;
4
+
5
+ use CTXFeed\V5\Download\FileDownload;
6
+ use CTXFeed\V5\Utility\Config;
7
+ use RuntimeException;
8
+
9
+ class ExportFeed {
10
+
11
+ public function __construct() {
12
+ add_action( 'admin_post_wf_export_feed', [ $this, 'export_feed' ], 10 );
13
+ }
14
+
15
+ /**
16
+ * @return void
17
+ */
18
+ public function export_feed() {
19
+ if ( isset( $_REQUEST['feed'], $_REQUEST['_wpnonce'] ) && ! empty( $_REQUEST['feed'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'wpf-export' ) ) {
20
+ $feed = sanitize_text_field( wp_unslash( $_REQUEST['feed'] ) );
21
+ $feed = str_replace( [ 'wf_feed_', 'wf_config' ], '', $feed );
22
+ $feed_info = maybe_unserialize( get_option( 'wf_feed_' . $feed ) );
23
+ $config = new Config( $feed_info );
24
+
25
+ $file_name = sprintf(
26
+ '%s-%s.wpf',
27
+ sanitize_title( $config->get_feed_file_name() ),
28
+ time()
29
+ );
30
+ $feed = wp_json_encode( $config->get_feed_rules() );
31
+ $meta = wp_json_encode( [
32
+ 'version' => WOO_FEED_FREE_VERSION,
33
+ 'file_name' => $file_name,
34
+ 'hash' => md5( $feed ),
35
+ ] );
36
+ $bin = pack( 'VA*VA*', strlen( $meta ), $meta, strlen( $feed ), $feed );
37
+ $feed = gzdeflate( $bin, 9 );
38
+
39
+ $fileDownload = FileDownload::createFromString( $feed );
40
+ $fileDownload->sendDownload( $file_name );
41
+ } else {
42
+ throw new RuntimeException( esc_html__( 'Invalid Request', 'woo-feed' ) );
43
+ }
44
+ }
45
+
46
+ }
V5/Common/Factory.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Common;
4
+
5
+ use CTXFeed\V5\Query\QueryFactory;
6
+ use CTXFeed\V5\Utility\Config;
7
+
8
+ class Factory {
9
+ /**
10
+ * Get Product Ids by Query Type
11
+ *
12
+ * @param $config
13
+ *
14
+ * @return \CTXFeed\V5\Query\Query
15
+ */
16
+ public static function get_product_ids( $config ) {
17
+ return QueryFactory::get_ids( $config );
18
+ }
19
+
20
+ /**
21
+ * @param string $name Feed Name
22
+ *
23
+ * @return \CTXFeed\V5\Utility\Config
24
+ */
25
+ public static function get_feed_config( $name ) {
26
+ $name = str_replace( [ 'wf_feed_', 'wf_config' ], '', sanitize_text_field( wp_unslash( $name ) ) );
27
+ $feedOption = maybe_unserialize( get_option( "wf_config" . $name ) );
28
+
29
+ return new Config( $feedOption );
30
+ }
31
+
32
+ /**
33
+ * @param string $name Feed Name
34
+ *
35
+ * @return \CTXFeed\V5\Utility\Config
36
+ */
37
+ public static function get_feed_info( $name ) {
38
+ $name = str_replace( [ 'wf_feed_', 'wf_config' ], '', sanitize_text_field( wp_unslash( $name ) ) );
39
+ $feedOption = maybe_unserialize( get_option( "wf_feed_" . $name ) );
40
+
41
+ return new Config( $feedOption );
42
+ }
43
+ }
V5/Common/Helper.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Common;
4
+
5
+
6
+ /**
7
+ * Class Helper
8
+ *
9
+ * @package CTXFeed\V5\Common
10
+ * @subpackage CTXFeed\V5\Common
11
+ */
12
+ class Helper {
13
+
14
+ }
V5/Common/Hooks.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Common;
3
+ class Hooks {
4
+
5
+ }
V5/Common/ImportFeed.php ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Common;
4
+
5
+ use RuntimeException;
6
+
7
+ class ImportFeed {
8
+
9
+ public function __construct() {
10
+ add_action( 'admin_post_wpf_import', [ $this, 'import_feed' ] );
11
+ }
12
+
13
+ /**
14
+ * @throws \Exception
15
+ */
16
+ public function import_feed() {
17
+ check_admin_referer( 'wpf_import' );
18
+
19
+ $wpf_import_file = isset( $_FILES['wpf_import_file'] ) ? $_FILES['wpf_import_file'] : '';
20
+ $wpf_import_feed_name = isset( $_POST['wpf_import_feed_name'] ) ? sanitize_text_field( wp_unslash( $_POST['wpf_import_feed_name'] ) ) : "";
21
+ $wpf_import_file_name = isset( $wpf_import_file['name'] ) ? sanitize_file_name( wp_unslash( $wpf_import_file['name'] ) ) : "";
22
+ $wpf_import_file_tmp_name = isset( $wpf_import_file['tmp_name'] ) ? sanitize_text_field( $wpf_import_file['tmp_name'] ) : "";
23
+
24
+ if (
25
+ $wpf_import_file &&
26
+ $wpf_import_feed_name &&
27
+ $wpf_import_file_name &&
28
+ $wpf_import_file_tmp_name &&
29
+ 'wpf' === pathinfo( wp_unslash( $wpf_import_file_name ), PATHINFO_EXTENSION ) // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
30
+ ) {
31
+ $data = file_get_contents( $wpf_import_file_tmp_name );
32
+
33
+ if ( empty( $data ) ) {
34
+ throw new RuntimeException( esc_html__( "Empty File Uploaded. Upload a Valid File.", 'woo-feed' ) );
35
+ }
36
+
37
+ $feed = gzinflate( $data );
38
+ if ( false === $feed ) {
39
+ throw new RuntimeException( esc_html__( 'Unable to read file content', 'woo-feed' ) );
40
+ }
41
+
42
+ // unpack meta data.
43
+ $meta_length = unpack( 'V', $feed );
44
+ if ( false === $meta_length ) {
45
+ throw new RuntimeException( esc_html__( 'Unable to read data from file.', 'woo-feed' ));
46
+ }
47
+ $meta = unpack( 'A*', substr( $feed, 4, $meta_length[1] ) )[1];
48
+ if ( false === $meta || 0 !== strpos( $meta, '{' ) ) {
49
+ throw new RuntimeException( esc_html__( 'Unable to read file info.', 'woo-feed' ));
50
+ }
51
+ $meta = json_decode( $meta, true );
52
+ // unpack feed data.
53
+ $feed = substr( $feed, $meta_length[1] + 8 ); // 4 bytes for each V (length data)
54
+ $feed = unpack( 'A*', $feed )[1];
55
+ if ( false === $feed || 0 !== strpos( $feed, '{' ) ) {
56
+ throw new RuntimeException( esc_html__( 'Unable to read feed data from file.', 'woo-feed' ));
57
+ }
58
+ if ( md5( $feed ) !== $meta['hash'] ) {
59
+ throw new RuntimeException( esc_html__( 'Unable to verify the file.', 'woo-feed' ));
60
+ }
61
+
62
+ $feed = json_decode( $feed, true );
63
+ if ( ! is_array( $feed ) ) {
64
+ throw new RuntimeException( esc_html__( 'Invalid or corrupted config file.', 'woo-feed' ));
65
+ }
66
+
67
+ $feed = woo_feed_parse_feed_rules( $feed );
68
+ $new_name = sanitize_text_field( wp_unslash( $_POST['wpf_import_feed_name'] ) );
69
+ $new_name = trim( $new_name );
70
+ if ( ! empty( $new_name ) ) {
71
+ $opt_name = $new_name;
72
+ $feed['filename'] = $new_name;
73
+ } else {
74
+ $opt_name = $feed['filename'];
75
+ $feed['filename'] = str_replace_trim( [ '-', '_' ], ' ', $feed['filename'] );
76
+ $feed['filename'] = sprintf(
77
+ '%s: %s',
78
+ esc_html__( ' Imported', 'woo-feed' ),
79
+ ucwords( $feed['filename'] )
80
+ );
81
+ }
82
+ // New Slug.
83
+ $opt_name = generate_unique_feed_file_name( $opt_name,
84
+ $feed['feedType'],
85
+ $feed['provider'] );
86
+ // save config.
87
+ $fileName = woo_feed_save_feed_config_data( $feed, $opt_name, false );
88
+ // Redirect back to the list.
89
+ wp_safe_redirect(
90
+ add_query_arg(
91
+ [
92
+ 'feed_imported' => (int) false !== $fileName,
93
+ 'feed_regenerate' => 1,
94
+ 'feed_name' => $fileName ?: '',
95
+ ],
96
+ esc_url( admin_url( 'admin.php?page=webappick-manage-feeds' ) )
97
+ )
98
+ );
99
+ die();
100
+ }
101
+
102
+ throw new RuntimeException( esc_html__( 'Invalid Request.', 'woo-feed' ));
103
+ }
104
+ }
V5/Common/SaveFeed.php ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Common;
4
+
5
+ use WP_Error;
6
+ use CTXFeed\V5\Utility\FileSystem;
7
+
8
+ /**
9
+ * This is used to save feed
10
+ *
11
+ * @package Woo_Feed
12
+ * @subpackage Woo_Feed/includes
13
+ * @since 1.0.0
14
+ * @author Ohidul Islam <wahid@webappick.com>
15
+ * @property $info
16
+ */
17
+ class SaveFeed {
18
+
19
+ /**
20
+ * @var array $config Contain Feed Configuration.
21
+ */
22
+ private static $config;
23
+
24
+ public static function Save( $path, $file, $content, $config ) {
25
+ self::checkDir( $path );
26
+ self::$config = $config;
27
+
28
+ $method = 'save' . strtoupper( self::$config->feedType );
29
+ $type = self::$config->feedType;
30
+
31
+ $content = apply_filters( "ctx_save_{$type}_file", $content, $config );
32
+
33
+ return self::$method( $path, $file, $content );
34
+ }
35
+
36
+ /**
37
+ * Check if the directory for feed file exist or not and make directory
38
+ *
39
+ * @param $path
40
+ *
41
+ * @return void
42
+ */
43
+ private static function checkDir( $path ) {
44
+ if ( ! file_exists( $path ) ) {
45
+ wp_mkdir_p( $path );
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Save CSV file.
51
+ *
52
+ * @param string $path WP Upload dir path.
53
+ * @param string $file filename with extension
54
+ * @param array $content File Contents.
55
+ *
56
+ * @return bool
57
+ */
58
+ private static function saveCSV( $path, $file, $content ) {
59
+ return FileSystem::WriteFile( $content, $path, $file );
60
+ }
61
+
62
+ /**
63
+ * Save TSV file.
64
+ *
65
+ * @param string $path WP Upload dir path.
66
+ * @param string $file filename with extension
67
+ * @param array $content File Contents.
68
+ *
69
+ * @return bool
70
+ */
71
+ private static function saveTSV( $path, $file, $content ) {
72
+ return self::saveCSV( $path, $file, $content );
73
+ }
74
+
75
+ /**
76
+ * Save TXT file.
77
+ *
78
+ * @param string $path WP Upload dir path.
79
+ * @param string $file filename with extension
80
+ * @param array $content File Contents.
81
+ *
82
+ * @return bool
83
+ */
84
+ private static function saveTXT( $path, $file, $content ) {
85
+ return self::saveCSV( $path, $file, $content );
86
+ }
87
+
88
+ /**
89
+ * Save XML File
90
+ *
91
+ * @param string $path WP Upload dir path.
92
+ * @param string $file filename with extension
93
+ * @param array $content File Contents.
94
+ *
95
+ * @return bool
96
+ */
97
+ private static function saveXML( $path, $file, $content ) {
98
+ return FileSystem::WriteFile( $content, $path, $file );
99
+ }
100
+
101
+ /**
102
+ * Save JSON File.
103
+ *
104
+ * @param string $path WP Upload dir path.
105
+ * @param string $file filename with extension
106
+ * @param mixed $content File Contents.
107
+ *
108
+ * @return mixed|WP_Error
109
+ */
110
+ private static function saveJSON( $path, $file, $content ) {
111
+ $content = json_encode( $content );
112
+
113
+ return FileSystem::WriteFile( $content, $path, $file );
114
+ }
115
+
116
+ /**
117
+ * Save XLS File.
118
+ *
119
+ * @param string $path WP Upload dir path.
120
+ * @param string $file filename with extension
121
+ * @param array $content File Contents.
122
+ *
123
+ * @return mixed|WP_Error
124
+ */
125
+ private static function saveXLS( $path, $file, $content ) {
126
+ return FileSystem::WriteFile( $content, $path, $file );
127
+ }
128
+ }
V5/Common/Status.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Common;
3
+ class Status {
4
+
5
+ }
V5/Common/Taxonomy.php ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Common;
4
+
5
+ use ArrayObject;
6
+ use FilterIterator;
7
+ use Walker_Category_Checklist;
8
+
9
+ class Taxonomy {
10
+ public function __construct() {
11
+ add_action( 'init', [ $this, 'register_custom_taxonomy' ] );
12
+ add_filter( 'wp_terms_checklist_args', [ $this, 'brand_term_radio_checklist' ] );
13
+ }
14
+
15
+ /**
16
+ * @return void
17
+ */
18
+ public function register_custom_taxonomy() {
19
+ $custom_fields = woo_feed_product_custom_fields();
20
+ $custom_taxonomies_filter = new TaxonomyFilter( $custom_fields );
21
+ $custom_taxonomies = iterator_to_array( $custom_taxonomies_filter );
22
+
23
+ $settings = woo_feed_get_options( 'all' );
24
+ if ( isset( $settings['woo_feed_taxonomy'], $settings['woo_feed_identifier'] ) ) {
25
+ $custom_attributes = array_merge( $settings['woo_feed_taxonomy'], $settings['woo_feed_identifier'] );
26
+ } else {
27
+ $custom_attributes = $settings['woo_feed_taxonomy'];
28
+ }
29
+
30
+ if ( isset( $custom_attributes['brand'] ) && 'enable' === $custom_attributes['brand'] ) {
31
+ if ( ! empty( $custom_taxonomies ) ) {
32
+ foreach ( $custom_taxonomies as $key => $value ) {
33
+ $taxonomy_name = esc_html( $value[0] );
34
+
35
+ $labels = array(
36
+ 'name' => $taxonomy_name . ' ' . __( 'by CTX Feed', 'woo-feed' ),
37
+ 'singular_name' => $taxonomy_name,
38
+ 'menu_name' => $taxonomy_name . 's ' . __( 'by CTX Feed', 'woo-feed' ),
39
+ 'all_items' => __( 'All', 'woo-feed' ) . ' ' . $taxonomy_name . 's',
40
+ 'parent_item' => __( 'Parent', 'woo-feed' ) . $taxonomy_name,
41
+ 'parent_item_colon' => __( 'Parent:', 'woo-feed' ) . $taxonomy_name . ':',
42
+ 'new_item_name' => __( 'New', 'woo-feed' ) . ' ' . $taxonomy_name . ' ' . __( 'Name', 'woo-feed' ),
43
+ 'add_new_item' => __( 'Add New', 'woo-feed' ) . ' ' . $taxonomy_name,
44
+ 'edit_item' => __( 'Edit', 'woo-feed' ) . ' ' . $taxonomy_name,
45
+ 'update_item' => __( 'Update', 'woo-feed' ) . ' ' . $taxonomy_name,
46
+ 'separate_items_with_commas' => __( 'Separate', 'woo-feed' ) . ' ' . $taxonomy_name . ' ' . __( 'with commas', 'woo-feed' ),
47
+ 'search_items' => __( 'Search', 'woo-feed' ) . ' ' . $taxonomy_name,
48
+ 'add_or_remove_items' => __( 'Add or remove', 'woo-feed' ) . ' ' . $taxonomy_name,
49
+ 'choose_from_most_used' => __( 'Choose from the most used', 'woo-feed' ) . ' ' . $taxonomy_name . 's',
50
+ );
51
+ $args = array(
52
+ 'labels' => $labels,
53
+ 'hierarchical' => true,
54
+ 'public' => true,
55
+ 'show_ui' => true,
56
+ 'show_admin_column' => false,
57
+ 'show_in_rest' => true,
58
+ 'show_in_nav_menus' => true,
59
+ 'show_tagcloud' => true,
60
+ 'show_in_quick_edit' => false,
61
+ );
62
+ $taxonomy_key = sprintf( 'woo-feed-%s', strtolower( $key ) );
63
+
64
+ register_taxonomy( $taxonomy_key, 'product', $args );
65
+ }
66
+ }
67
+ }
68
+
69
+ }
70
+
71
+ /**
72
+ * Use radio inputs product brand taxonomies
73
+ *
74
+ * @param $args
75
+ *
76
+ * @return mixed
77
+ */
78
+ public function brand_term_radio_checklist( $args ) {
79
+ if ( ! empty( $args['taxonomy'] ) && 'woo-feed-brand' === $args['taxonomy'] && ( empty( $args['walker'] ) || $args['walker'] instanceof \Walker ) ) {
80
+
81
+ $args['walker'] = new Woo_Feed_Brand_Walker_Category_Radio_Checklist();
82
+ }
83
+
84
+ return $args;
85
+ }
86
+ }
87
+
88
+ //Init Brand Taxonomy
89
+ $CTXBrandTaxonomy = new Taxonomy();
90
+
91
+
92
+
93
+
94
+
95
+ /**
96
+ * Woo_Feed_Custom_Taxonomy_Filter is special extension class of FilterIterator
97
+ *
98
+ * @since 4.3.93
99
+ */
100
+ class TaxonomyFilter extends FilterIterator {
101
+
102
+ public function __construct( array $items ) {
103
+ $object = new ArrayObject( $items );
104
+ parent::__construct( $object->getIterator() );
105
+ }
106
+
107
+ public function accept() {
108
+ return array_key_exists( 2, $this->current() ) ? $this->current()[2] : false;
109
+ }
110
+ }
111
+
112
+
113
+ /**
114
+ * Custom walker for switching checkbox inputs to radio.
115
+ *
116
+ * @see Walker_Category_Checklist
117
+ */
118
+ class Woo_Feed_Brand_Walker_Category_Radio_Checklist extends Walker_Category_Checklist {
119
+ public function walk( $elements, $max_depth, ...$args ) {
120
+ $output = parent::walk( $elements, $max_depth, ...$args );
121
+
122
+ return str_replace(
123
+ array( 'type="checkbox"', "type='checkbox'" ),
124
+ array( 'type="radio"', "type='radio'" ),
125
+ $output
126
+ );
127
+ }
128
+ }
V5/Common/Widget.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Common;
4
+
5
+ class Widget {
6
+ public function __construct() {
7
+ add_action( 'wp_dashboard_setup', [ $this, 'add_dashboard_widget' ], 1, 10 );
8
+ }
9
+
10
+ /**
11
+ * Add a widget to the dashboard.
12
+ *
13
+ * This function is hooked into the 'wp_dashboard_setup' action below.
14
+ */
15
+ public function add_dashboard_widget() {
16
+ global $wp_meta_boxes;
17
+
18
+ add_meta_box( 'aaaa_webappick_latest_news_dashboard_widget', __( 'Latest News from WebAppick Blog', 'woo-feed' ), 'dashboard_widget_render', 'dashboard', 'side', 'high' );
19
+
20
+ }
21
+
22
+ /**
23
+ * Function to get dashboard widget data.
24
+ */
25
+ public function dashboard_widget_render() {
26
+
27
+ // Enter the name of your blog here followed by /wp-json/wp/v2/posts and add filters like this one that limits the result to 2 posts.
28
+ $response = wp_remote_get( 'https://webappick.com/wp-json/wp/v2/posts?per_page=5' );
29
+
30
+ // Exit if error.
31
+ if ( is_wp_error( $response ) ) {
32
+ return;
33
+ }
34
+
35
+ // Get the body.
36
+ $posts = json_decode( wp_remote_retrieve_body( $response ), false );
37
+
38
+ // Exit if nothing is returned.
39
+ if ( empty( $posts ) ) {
40
+ return;
41
+ }
42
+ ?>
43
+ <p><a style="text-decoration: none;font-weight: bold;" href="<?php echo esc_url( 'https://webappick.com' ); ?>"
44
+ target=_balnk><?php echo esc_html__( "WEBAPPICK.COM", 'woo-feed' ); ?></a></p>
45
+ <hr>
46
+ <?php
47
+ // If there are posts.
48
+ // For each post.
49
+ foreach ( $posts as $post ) {
50
+ $date = date( 'M j, Y', strtotime( $post->modified ) ); ?>
51
+ <p class="webappick-feeds"><a style="text-decoration: none;" href="<?php echo esc_url( $post->link ); ?>"
52
+ target=_balnk><?php echo esc_html( $post->title->rendered ); ?></a>
53
+ - <?php echo $date; ?></p>
54
+ <span><?php echo wp_trim_words( $post->content->rendered, 35, '...' ); ?></span>
55
+ <?php
56
+ }
57
+ ?>
58
+ <hr>
59
+ <p><a style="text-decoration: none;" href="<?php echo esc_url( 'https://webappick.com/blog/' ); ?>"
60
+ target=_balnk><?php echo esc_html__( "Get more woocommerce tips & news on our blog...", 'woo-feed' ); ?></a>
61
+ </p>
62
+ <?php
63
+ }
64
+ }
65
+
66
+ $CTXDashboardWidget = new Widget();
V5/Compatibility/DynamicDiscount.php ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Compatibility;
3
+ class DynamicDiscount {
4
+
5
+ }
6
+
7
+ // Discounted price filter
8
+ add_filter( 'woo_feed_filter_product_sale_price', 'woo_feed_get_dynamic_discounted_product_price', 9, 4 );
9
+ add_filter( 'woo_feed_filter_product_sale_price_with_tax', 'woo_feed_get_dynamic_discounted_product_price', 9, 4 );
10
+
11
+ if ( ! function_exists('woo_feed_apply_tax_location_data') ) {
12
+ /**
13
+ * Filter and Change Location data for tax calculation
14
+ *
15
+ * @param array $location Location array.
16
+ * @param string $tax_class Tax class.
17
+ * @param WC_Customer $customer WooCommerce Customer Object.
18
+ *
19
+ * @return array
20
+ */
21
+ function woo_feed_apply_tax_location_data( $location, $tax_class, $customer ) {
22
+ // @TODO use filter. add tab in feed editor so user can set custom settings.
23
+ // @TODO tab should not list all country and cities. it only list available tax settings and user can just select one.
24
+ // @TODO then it will extract the location data from it to use here.
25
+ $wc_tax_location = [
26
+ WC()->countries->get_base_country(),
27
+ WC()->countries->get_base_state(),
28
+ WC()->countries->get_base_postcode(),
29
+ WC()->countries->get_base_city(),
30
+ ];
31
+ /**
32
+ * Filter Tax Location to apply before product loop
33
+ *
34
+ * @param array $tax_location
35
+ *
36
+ * @since 3.3.0
37
+ */
38
+ $tax_location = apply_filters('woo_feed_tax_location_data', $wc_tax_location);
39
+ if ( ! is_array($tax_location) || (is_array($tax_location) && 4 !== count($tax_location)) ) {
40
+ $tax_location = $wc_tax_location;
41
+ }
42
+
43
+ return $tax_location;
44
+ }
45
+ }
46
+
47
+ if ( ! function_exists('woo_feed_get_dynamic_discounted_product_price') ) {
48
+
49
+ /**
50
+ * Get price with dynamic discount
51
+ *
52
+ * @param WC_Product|WC_Product_Variable $product product object
53
+ * @param $price
54
+ * @param $config
55
+ * @param bool $tax product taxable or not
56
+ * @return mixed $price
57
+ */
58
+ function woo_feed_get_dynamic_discounted_product_price( $price, $product, $config, $tax ) {
59
+ $base_price = $price;
60
+ $discount_plugin_activate = false;
61
+
62
+
63
+ /**
64
+ * PLUGIN: Discount Rules for WooCommerce
65
+ * URL: https://wordpress.org/plugins/woo-discount-rules/
66
+ */
67
+ if ( is_plugin_active('woo-discount-rules/woo-discount-rules.php') ) {
68
+ $discount_plugin_activate = true;
69
+ if ( class_exists('Wdr\App\Controllers\Configuration') ) {
70
+ $config = Wdr\App\Controllers\Configuration::getInstance()->getConfig('calculate_discount_from', 'sale_price');
71
+
72
+ if ( isset($config) && ! empty($config) ) {
73
+ if ( 'regular_price' === $config ) {
74
+ $price = $product->get_regular_price();
75
+ } else {
76
+ $price = $product->get_price();
77
+ }
78
+ } else {
79
+ $price = $product->get_price();
80
+ }
81
+
82
+ if ( $product->is_type('variable') ) {
83
+ $min = $product->get_variation_price('min', false);
84
+ $max = $product->get_variation_price('max', false);
85
+
86
+ $price = $min;
87
+ if ( $max === $base_price ) {
88
+ $price = $max;
89
+ }
90
+ }
91
+
92
+ $price = apply_filters('advanced_woo_discount_rules_get_product_discount_price_from_custom_price', false, $product, 1, $price, 'discounted_price', true, true);
93
+
94
+ if ( empty($price) ) {
95
+ $price = $base_price;
96
+ }
97
+
98
+ if ( ! isset( $feedConfig['feedCurrency'] ) ) {
99
+ $feedConfig['feedCurrency'] = get_woocommerce_currency();
100
+ }
101
+
102
+ $price = apply_filters('wcml_raw_price_amount', $price, $feedConfig['feedCurrency'] );
103
+
104
+ }
105
+ }
106
+
107
+ /**
108
+ * PLUGIN: Dynamic Pricing With Discount Rules for WooCommerce
109
+ * URL: https://wordpress.org/plugins/aco-woo-dynamic-pricing/
110
+ *
111
+ * This plugin does not apply discount on product page.
112
+ *
113
+ * Don't apply discount manually.
114
+ */
115
+ // if (is_plugin_active('aco-woo-dynamic-pricing/start.php')) {
116
+ // $discount_plugin_activate = true;
117
+ // if (class_exists('AWDP_Discount')) {
118
+ // $price = AWDP_Discount::instance()->calculate_discount($product->get_price(), $product);
119
+ // }
120
+ // }
121
+
122
+ /**
123
+ * PLUGIN: Conditional Discounts for WooCommerce
124
+ * URL: https://wordpress.org/plugins/woo-advanced-discounts/
125
+ *
126
+ * NOTE:* Automatically apply discount to $product->get_sale_price() method.
127
+ */
128
+ // if (is_plugin_active('woo-advanced-discounts/wad.php')) {
129
+ // $discount_plugin_activate = true;
130
+ // $discount_amount = 0;
131
+ // global $wad_discounts;
132
+ // if (isset($wad_discounts["product"])) {
133
+ // foreach ($wad_discounts["product"] as $discount_id => $discount_obj) {
134
+ // if ($discount_obj->is_applicable($product->get_id())) {
135
+ // $wad_obj = new WAD_Discount($discount_id);
136
+ // if (isset($wad_obj->settings)) {
137
+ // $settings = $wad_obj->settings;
138
+ // $discount_type = $wad_obj->settings['action'];
139
+ // if (false !== strpos($discount_type, 'fixed')) {
140
+ // $discount_amount = (float) $wad_obj->get_discount_amount($price);
141
+ // } elseif (false !== strpos($discount_type, 'percentage')) {
142
+ // $percentage = $settings['percentage-or-fixed-amount'];
143
+ // $discount_amount = ($product->get_price() * ($percentage / 100));
144
+ // }
145
+ // }
146
+ // }
147
+ // }
148
+ // $price = (float) $product->get_price() - (float) $discount_amount;
149
+ // }
150
+ // }
151
+
152
+ /**
153
+ * PLUGIN: Pricing Deals for WooCommerce
154
+ * URL: https://wordpress.org/plugins/pricing-deals-for-woocommerce/
155
+ */
156
+ if ( is_plugin_active('pricing-deals-for-woocommerce/vt-pricing-deals.php') ) {
157
+ $discount_plugin_activate = true;
158
+ if ( class_exists('VTPRD_Controller') ) {
159
+ global $vtprd_rules_set;
160
+ $vtprd_rules_set = get_option('vtprd_rules_set');
161
+ if ( ! empty($vtprd_rules_set) && is_array($vtprd_rules_set) ) {
162
+ foreach ( $vtprd_rules_set as $vtprd_rule_set ) {
163
+ $status = $vtprd_rule_set->rule_on_off_sw_select;
164
+ if ( 'on' === $status || 'onForever' === $status ) {
165
+ $discount_type = $vtprd_rule_set->rule_deal_info[0]['discount_amt_type'];
166
+ $discount = $vtprd_rule_set->rule_deal_info[0]['discount_amt_count'];
167
+ if ( 'currency' === $discount_type || 'fixedPrice' === $discount_type ) {
168
+ $price = $product->get_price() - $discount;
169
+ } elseif ( 'percent' === $discount_type ) {
170
+ $price = $product->get_price() - (($product->get_price() * $discount) / 100);
171
+ }
172
+ }
173
+ }
174
+ }
175
+ }
176
+ }
177
+
178
+ //######################### YITH #########################################################
179
+ /**
180
+ * PLUGIN: YITH WOOCOMMERCE DYNAMIC PRICING AND DISCOUNTS
181
+ * URL: hhttps://yithemes.com/themes/plugins/yith-woocommerce-dynamic-pricing-and-discounts/
182
+ *
183
+ * NOTE:* YITH Automatically apply discount to $product->get_sale_price() method.
184
+ */
185
+ //######################### RightPress ###################################################
186
+ /**
187
+ * PLUGIN: WooCommerce Dynamic Pricing & Discounts
188
+ * URL: https://codecanyon.net/item/woocommerce-dynamic-pricing-discounts/7119279
189
+ *
190
+ * RightPress dynamic pricing supported. Filter Hooks applied to "woo_feed_apply_hooks_before_product_loop"
191
+ * to get the dynamic discounted price via $product->ger_sale_price(); method.
192
+ */
193
+ //###################### Dynamic Pricing ##################################################
194
+ /**
195
+ * PLUGIN: Dynamic Pricing
196
+ * URL: https://woocommerce.com/products/dynamic-pricing/
197
+ *
198
+ * Dynamic Pricing plugin doesn't show the options or any price change on your frontend.
199
+ * So a user will not even notice the discounts until he reaches the checkout.
200
+ * No need to add the compatibility.
201
+ */
202
+
203
+
204
+
205
+ // Get Price with tax
206
+ if ( $discount_plugin_activate && $tax ) {
207
+ $price = woo_feed_get_price_with_tax($price, $product);
208
+ }
209
+
210
+ return ( isset($base_price) || ($price > 0) && ($price < $base_price) ) ? $price : $base_price;
211
+ }
212
+ }
V5/Compatibility/ExcludeCaching.php ADDED
@@ -0,0 +1,341 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Compatibility;
4
+
5
+ use stdClass;
6
+
7
+ class ExcludeCaching {
8
+
9
+ public function __construct() {
10
+
11
+ // ########### Exclude Feed files from caching. #########################
12
+
13
+ //WP Rocket Cache
14
+ add_filter( 'rocket_cdn_reject_files', [ $this, 'exclude_feed_from_wp_rocket_cache' ], 10, 3 );
15
+ //LiteSpeed Cache
16
+ add_action( 'litespeed_init', [ $this, 'exclude_feed_from_litespeed_cache' ], 10, 0 );
17
+ //WP Fastest Cache
18
+ add_action( "admin_init", [ $this, 'exclude_feed_from_wp_fastest_cache' ], 10, 0 );
19
+ //WP Super Cache
20
+ add_action( "admin_init", [ $this, 'exclude_feed_from_wp_super_cache' ], 10, 0 );
21
+ //BREEZE Cache
22
+ add_action( "admin_init", [ $this, 'exclude_feed_from_breeze_cache' ], 10, 0 );
23
+ //WP Optimize Cache
24
+ add_action( "admin_init", [ $this, 'exclude_feed_from_wp_optimize_cache' ], 10, 0 );
25
+ //Cache Enabler Cache
26
+ add_action( "admin_init", [ $this, 'exclude_feed_from_cache_enabler_cache' ], 10, 0 );
27
+ //SWIFT Performance Cache
28
+ add_action( "admin_init", [ $this, 'exclude_feed_from_swift_performance_cache' ], 10, 0 );
29
+ //Speed Booster Cache
30
+ add_action( "admin_init", [ $this, 'exclude_feed_from_speed_booster_cache' ], 10, 0 );
31
+ //Comet Cache
32
+ add_action( "admin_init", [ $this, 'exclude_feed_from_comet_cache' ], 10, 0 );
33
+ //Hyper Cache
34
+ add_action( "admin_init", [ $this, 'exclude_feed_from_hyper_cache' ], 10, 0 );
35
+ //TODO: W3C Cache
36
+ //add_filter( 'w3tc_save_options', 'woo_save_w3tc_opt', 10, 3 );
37
+ }
38
+
39
+ /**
40
+ * Exclude Feed file URL form WP Rocket caching
41
+ *
42
+ * @param $files
43
+ *
44
+ * @return array
45
+ */
46
+ public function exclude_feed_from_wp_rocket_cache( $files ) {
47
+ return array_merge(
48
+ $files,
49
+ [
50
+ '/wp-content/uploads/woo-feed/(.*)',
51
+ ]
52
+ );
53
+ }
54
+
55
+ /**
56
+ * Exclude Feed file URL form LiteSpeed caching
57
+ *
58
+ * @return false
59
+ */
60
+ public function exclude_feed_from_litespeed_cache() {
61
+ if ( ! class_exists( 'LiteSpeed\Core' ) || ! defined( 'LSCWP_DIR' ) ) {
62
+ return false;
63
+ }
64
+
65
+ $litespeed_ex_paths = maybe_unserialize( get_option( 'litespeed.conf.cdn-exc' ) );
66
+ if ( $litespeed_ex_paths && is_array( $litespeed_ex_paths ) && ! in_array( '/wp-content/uploads/woo-feed', $litespeed_ex_paths, true ) ) {
67
+ $litespeed_ex_paths = array_merge(
68
+ $litespeed_ex_paths,
69
+ [ '/wp-content/uploads/woo-feed' ]
70
+ );
71
+ update_option( 'litespeed.conf.cdn-exc', $litespeed_ex_paths );
72
+ }
73
+
74
+ return false;
75
+ }
76
+
77
+ /**
78
+ * Exclude Feed file URL form WP Fastest caching
79
+ *
80
+ * @return false
81
+ */
82
+ public function exclude_feed_from_wp_fastest_cache() {
83
+
84
+ if ( ! class_exists( 'WpFastestCache' ) ) {
85
+ return false;
86
+ }
87
+
88
+ $wp_fastest_cache_ex_paths = json_decode( get_option( 'WpFastestCacheExclude' ), false );
89
+ if ( $wp_fastest_cache_ex_paths && is_array( $wp_fastest_cache_ex_paths ) ) {
90
+
91
+ $feed_path_exist = false;
92
+ foreach ( $wp_fastest_cache_ex_paths as $path ) {
93
+ if ( 'woo-feed' === $path->content ) {
94
+ $feed_path_exist = true;
95
+ break;
96
+ }
97
+ }
98
+
99
+ if ( ! $feed_path_exist ) {
100
+ $new_rule = new stdClass();
101
+ $new_rule->prefix = "contain";
102
+ $new_rule->content = 'woo-feed';
103
+ $new_rule->type = "page";
104
+
105
+ $wp_fastest_cache_ex_paths = array_merge(
106
+ $wp_fastest_cache_ex_paths,
107
+ [ $new_rule ]
108
+ );
109
+
110
+ update_option( 'WpFastestCacheExclude', wp_json_encode( $wp_fastest_cache_ex_paths ) );
111
+ }
112
+ } elseif ( empty( $wp_fastest_cache_ex_paths ) ) {
113
+ $wp_fastest_cache_ex_paths = [];
114
+ $new_rule = new stdClass();
115
+ $new_rule->prefix = "contain";
116
+ $new_rule->content = 'woo-feed';
117
+ $new_rule->type = "page";
118
+
119
+ $wp_fastest_cache_ex_paths = array_merge(
120
+ $wp_fastest_cache_ex_paths,
121
+ [ $new_rule ]
122
+ );
123
+
124
+ update_option( 'WpFastestCacheExclude', wp_json_encode( $wp_fastest_cache_ex_paths ) );
125
+ }
126
+
127
+ return false;
128
+ }
129
+
130
+ /**
131
+ * Exclude Feed file URL form WP Super caching
132
+ *
133
+ * @return false
134
+ */
135
+ public function exclude_feed_from_wp_super_cache() {
136
+
137
+ if ( ! function_exists( 'wpsc_init' ) ) {
138
+ return false;
139
+ }
140
+
141
+ $wp_super_ex_paths = get_option( 'ossdl_off_exclude' );
142
+ if ( $wp_super_ex_paths && strpos( $wp_super_ex_paths, 'woo-feed' ) === false ) {
143
+ $wp_super_ex_paths = explode( ',', $wp_super_ex_paths );
144
+ $wp_super_ex_paths = array_merge( $wp_super_ex_paths, [ 'woo-feed' ] );
145
+ update_option( 'ossdl_off_exclude', implode( ',', $wp_super_ex_paths ) );
146
+ }
147
+
148
+ return false;
149
+ }
150
+
151
+ /**
152
+ * Exclude Feed file URL form BREEZE caching
153
+ *
154
+ * @return false
155
+ */
156
+ public function exclude_feed_from_breeze_cache() {
157
+
158
+ if ( ! class_exists( 'Breeze_Admin' ) ) {
159
+ return false;
160
+ }
161
+
162
+ $breeze_settings = maybe_unserialize( get_option( 'breeze_cdn_integration' ) );
163
+ if ( is_array( $breeze_settings ) ) {
164
+ $woo_feed_files = [ '.xml', '.csv', '.tsv', '.txt', '.xls' ];
165
+ $woo_feed_files = array_unique( array_merge( $woo_feed_files, $breeze_settings['cdn-exclude-content'] ) );
166
+ $breeze_settings['cdn-exclude-content'] = $woo_feed_files;
167
+ update_option( 'breeze_cdn_integration', $breeze_settings );
168
+ }
169
+
170
+ return false;
171
+ }
172
+
173
+ /**
174
+ * Exclude Feed file URL form WP Optimize caching
175
+ *
176
+ * @return false
177
+ */
178
+ public function exclude_feed_from_wp_optimize_cache() {
179
+
180
+ if ( ! class_exists( 'WP_Optimize' ) ) {
181
+ return false;
182
+ }
183
+
184
+ $wp_optimize_ex_paths = maybe_unserialize( get_option( 'wpo_cache_config' ) );
185
+ // If page Caching enabled
186
+ if ( isset( $wp_optimize_ex_paths['enable_page_caching'] ) && $wp_optimize_ex_paths['enable_page_caching'] && is_array( $wp_optimize_ex_paths ) && ! in_array( '/wp-content/uploads/woo-feed', $wp_optimize_ex_paths['cache_exception_urls'], true ) ) {
187
+ $woo_feed_ex_path['cache_exception_urls'] = [ '/wp-content/uploads/woo-feed' ];
188
+ $wp_optimize_ex_paths = array_merge_recursive(
189
+ $wp_optimize_ex_paths,
190
+ $woo_feed_ex_path
191
+ );
192
+ update_option( 'wpo_cache_config', $wp_optimize_ex_paths );
193
+ }
194
+
195
+ return false;
196
+ }
197
+
198
+ /**
199
+ * Exclude Feed file URL form Cache Enabler caching
200
+ *
201
+ * @return false
202
+ */
203
+ public function exclude_feed_from_cache_enabler_cache() {
204
+
205
+ if ( ! class_exists( 'Cache_Enabler' ) ) {
206
+ return false;
207
+ }
208
+
209
+ $cache_enabler_ex_paths = maybe_unserialize( get_option( 'cache_enabler' ) );
210
+ if ( isset( $cache_enabler_ex_paths['excluded_page_paths'] ) && empty( $cache_enabler_ex_paths['excluded_page_paths'] ) ) {
211
+ $cache_enabler_ex_paths['excluded_page_paths'] = '/wp-content/uploads/woo-feed/';
212
+ update_option( 'cache_enabler', $cache_enabler_ex_paths );
213
+ }
214
+
215
+ return false;
216
+ }
217
+
218
+ /**
219
+ * Exclude Feed file URL form Swift Performance caching
220
+ *
221
+ * @return false
222
+ */
223
+ public function exclude_feed_from_swift_performance_cache() {
224
+
225
+ if ( ! class_exists( 'Swift_Performance_Lite' ) ) {
226
+ return false;
227
+ }
228
+
229
+ $swift_perform_ex_paths = maybe_unserialize( get_option( 'swift_performance_options' ) );
230
+
231
+ if ( $swift_perform_ex_paths && isset( $swift_perform_ex_paths['exclude-strings'] ) ) {
232
+ $exclude_strings = $swift_perform_ex_paths['exclude-strings'];
233
+ if ( is_array( $exclude_strings ) && ! in_array( '/wp-content/uploads/woo-feed', $exclude_strings, true ) ) {
234
+ $woo_feed_ex_path['exclude-strings'] = [ '/wp-content/uploads/woo-feed' ];
235
+ $swift_perform_ex_paths = array_merge_recursive(
236
+ $swift_perform_ex_paths,
237
+ $woo_feed_ex_path
238
+ );
239
+ } else {
240
+ $swift_perform_ex_paths['exclude-strings'] = [ '/wp-content/uploads/woo-feed' ];
241
+ }
242
+ update_option( 'swift_performance_options', $swift_perform_ex_paths );
243
+ } elseif ( empty( $swift_perform_ex_paths ) ) {
244
+ $swift_perform_ex_paths['exclude-strings'] = [ '/wp-content/uploads/woo-feed' ];
245
+ update_option( 'swift_performance_options', $swift_perform_ex_paths );
246
+ }
247
+
248
+ return false;
249
+ }
250
+
251
+ /**
252
+ * Exclude Feed file URL form Speed Booster Pack caching
253
+ *
254
+ * @return false
255
+ */
256
+ public function exclude_feed_from_speed_booster_cache() {
257
+
258
+ if ( ! class_exists( 'Speed_Booster_Pack' ) ) {
259
+ return false;
260
+ }
261
+
262
+ $feed_files = [];
263
+ $speed_booster_settings = maybe_unserialize( get_option( 'sbp_options' ) );
264
+ if ( isset( $speed_booster_settings['caching_exclude_urls'] ) ) {
265
+ $feed_files = woo_feed_get_feed_file_list();
266
+ $caching_exclude_urls = $speed_booster_settings['caching_exclude_urls'];
267
+ if ( ! empty( $caching_exclude_urls ) ) {
268
+ if ( ! empty( $feed_files ) ) {
269
+ foreach ( $feed_files as $file ) {
270
+ $file = str_replace( array( 'http://', 'https://' ), '', $file );
271
+ if ( ! in_array( $file, explode( "\n", $caching_exclude_urls ), true ) ) {
272
+ $caching_exclude_urls .= "\n" . $file;
273
+ }
274
+ }
275
+ }
276
+ } else {
277
+ $caching_exclude_urls = str_replace( array( 'http://', 'https://' ), '', implode( "\n", $feed_files ) );
278
+ }
279
+ $speed_booster_settings['caching_exclude_urls'] = $caching_exclude_urls;
280
+ update_option( 'sbp_options', $speed_booster_settings );
281
+ }
282
+
283
+ //TODO CDN extension exclude
284
+ return false;
285
+ }
286
+
287
+
288
+ /**
289
+ * Exclude Feed file URL form Comet Cache caching
290
+ *
291
+ * @return false
292
+ */
293
+ public function exclude_feed_from_comet_cache() {
294
+ if ( ! is_plugin_active( 'comet-cache/comet-cache.php' ) ) {
295
+ return false;
296
+ }
297
+
298
+ $comet_cache_settings = maybe_unserialize( get_option( 'comet_cache_options' ) );
299
+
300
+ if ( $comet_cache_settings && isset( $comet_cache_settings['exclude_uris'] ) ) {
301
+ $exclude_uris = $comet_cache_settings['exclude_uris'];
302
+ if ( strpos( $exclude_uris, '/wp-content/uploads/woo-feed' ) === false ) {
303
+ $exclude_uris .= "\n/wp-content/uploads/woo-feed";
304
+ $comet_cache_settings['exclude_uris'] = $exclude_uris;
305
+ update_option( 'comet_cache_options', $comet_cache_settings );
306
+ }
307
+ }
308
+
309
+ return false;
310
+ }
311
+
312
+
313
+ /**
314
+ * Exclude Feed file URL form Swift Performance caching
315
+ *
316
+ * @return false
317
+ */
318
+ public function exclude_feed_from_hyper_cache() {
319
+
320
+ if ( ! class_exists( 'HyperCache' ) ) {
321
+ return false;
322
+ }
323
+
324
+ $hyper_cache_settings = maybe_unserialize( get_option( 'hyper-cache' ) );
325
+ if ( $hyper_cache_settings && isset( $hyper_cache_settings['reject_uris'] ) ) {
326
+ $exclude_strings = $hyper_cache_settings['reject_uris'];
327
+ if ( is_array( $exclude_strings ) && ! in_array( '/wp-content/uploads/woo-feed', $exclude_strings, true ) ) {
328
+ $woo_feed_ex_path['reject_uris'] = [ '/wp-content/uploads/woo-feed' ];
329
+ $woo_feed_ex_path['reject_uris_enabled'] = 1;
330
+ $hyper_cache_settings = array_merge_recursive(
331
+ $hyper_cache_settings,
332
+ $woo_feed_ex_path
333
+ );
334
+ }
335
+ update_option( 'hyper-cache', $hyper_cache_settings );
336
+ }
337
+
338
+ return false;
339
+ }
340
+ }
341
+
V5/Compatibility/MultiCurrency.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Compatibility;
3
+ class MultiCurrency {
4
+
5
+ }
V5/Compatibility/MultiLanguage.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Compatibility;
3
+ class MultiLanguage {
4
+ public function __construct( ) {
5
+ // add_filter( 'woo_feed_wcml_price', 'woo_feed_get_wcml_price', 10, 3 );
6
+ }
7
+ }
V5/Compatibility/VariationGallary.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Compatibility;
4
+
5
+ class VariationGallary {
6
+
7
+ }
V5/CustomFields/AttributeInterface.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WebAppick\Attributes;
4
+
5
+ interface AttributeInterface{
6
+
7
+ public function get_value($post);
8
+
9
+ }
V5/CustomFields/Attributes.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Executes all the necessary classes for attributes
4
+ *
5
+ * @since 4.7
6
+ *
7
+ * */
8
+
9
+ use WebAppick\Attributes\AvailabilityDate;
10
+
11
+ // Security Check
12
+ defined( 'ABSPATH' ) || die();
13
+
14
+
15
+ $feed_settings = get_option( 'woo_feed_settings' );
16
+
17
+ $availability_date_settings = isset( $feed_settings['woo_feed_identifier']['availability_date'] )
18
+ ? $feed_settings['woo_feed_identifier']['availability_date']
19
+ : 'enable' ;
20
+
21
+ // Availability Date
22
+ if ( $availability_date_settings === 'enable' ) {
23
+ new AvailabilityDate();
24
+ }
V5/CustomFields/AvailabilityDate.php ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Adding availability date to products.
4
+ *
5
+ * */
6
+
7
+ namespace WebAppick\Attributes;
8
+
9
+ class AvailabilityDate implements AttributeInterface {
10
+
11
+ /**
12
+ * Initializes hooks
13
+ *
14
+ * @return void
15
+ * @since 4.4.14
16
+ */
17
+ public function __construct () {
18
+
19
+ // Display Field
20
+ add_action( 'woocommerce_product_options_inventory_product_data' , [&$this, 'admin_render_simple'], 11 ); // Simple product
21
+ add_action( 'woocommerce_product_after_variable_attributes' , [&$this, 'admin_render_variable'], 11, 3 ); // Variable product
22
+
23
+ // Save Field
24
+ add_action('woocommerce_process_product_meta', [ &$this, 'admin_simple_save' ] ); // Simple product
25
+ add_action('woocommerce_save_product_variation', [ &$this, 'admin_variable_save' ], 10, 2 ); // Variable product
26
+
27
+
28
+ }
29
+
30
+ /**
31
+ * Renders availability date fields for simple product.
32
+ *
33
+ * @return void
34
+ * @since 4.4.14
35
+ */
36
+ public function admin_render_simple() {
37
+
38
+ global $woocommerce, $post;
39
+
40
+ $availability_date = get_post_meta( $post->ID, 'woo_feed_availability_date', true );
41
+
42
+ // Add Availability Date Field
43
+ $field_data = array(
44
+ 'id' => "woo_feed_availability_date",
45
+ 'name' => "woo_feed_availability_date",
46
+ 'placeholder' => '',
47
+ 'label' => __('Availability Date', 'woo-feed'),
48
+ 'type' => 'date',
49
+ 'value' => esc_attr( $availability_date ),
50
+ 'desc_tip' => false,
51
+ 'description' => __( 'Set availability date for backorder products.', 'woo-feed' ),
52
+ );
53
+
54
+ woocommerce_wp_text_input( $field_data );
55
+
56
+ }
57
+
58
+ /**
59
+ * Renders availability date fields for variable products.
60
+ *
61
+ * @param int $loop
62
+ *
63
+ * @return void
64
+ * @since 4.4.14
65
+ */
66
+ public function admin_render_variable( $loop, $variation_data, $variation ) {
67
+
68
+ global $post;
69
+
70
+ $availability_date = get_post_meta( $variation->ID, 'woo_feed_availability_date_var', true );
71
+
72
+ // Add Availability Date Field
73
+ $field_data = array(
74
+ 'id' => "woo_feed_availability_date_var{$loop}",
75
+ 'name' => "woo_feed_availability_date_var[{$loop}]",
76
+ 'placeholder' => '',
77
+ 'label' => __('Availability Date', 'woo-feed'),
78
+ 'type' => 'date',
79
+ 'desc_tip' => true,
80
+ 'description' => __( 'Set availability date for backorder products.', 'woo-feed' ),
81
+ 'value' => esc_attr( $availability_date ),
82
+ 'wrapper_class' => 'form-row form-row-full',
83
+ );
84
+
85
+ woocommerce_wp_text_input( $field_data );
86
+
87
+ }
88
+
89
+ /**
90
+ * Saves availability date fields for simple product
91
+ *
92
+ * @param $post_id
93
+ *
94
+ * @return void
95
+ * @since 4.4.14
96
+ */
97
+ public function admin_simple_save( $post_id ) {
98
+ $woo_feed_availability_date = !empty( $_POST['woo_feed_availability_date'] ) ? $_POST['woo_feed_availability_date'] : '';
99
+ if( $woo_feed_availability_date ) {
100
+ update_post_meta($post_id, 'woo_feed_availability_date', esc_attr( $woo_feed_availability_date ));
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Saves availability date fields for variable product
106
+ *
107
+ * @param int $post_id
108
+ * @param int $loop
109
+ *
110
+ * @return void
111
+ * @since 4.4.14
112
+ */
113
+ public function admin_variable_save( $post_id, $loop ) {
114
+ $var = !empty($_POST['woo_feed_availability_date_var'][$loop]) ? $_POST['woo_feed_availability_date_var'][$loop] : '';
115
+ if( $var) {
116
+ update_post_meta($post_id, 'woo_feed_availability_date_var', esc_attr( $var ));
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Generates value for feed
122
+ *
123
+ * @param $product
124
+ *
125
+ * @return false|string
126
+ * @since 4.4.14
127
+ */
128
+ public function get_value( $product ){
129
+
130
+ if( $product->get_stock_status() !== 'onbackorder' ) {
131
+ return '';
132
+ }
133
+
134
+ $value = get_post_meta( $product->get_id(), 'woo_feed_availability_date', true );
135
+
136
+ if( isset( $value ) && !empty( $value ) ) {
137
+ return date( 'c', strtotime( $value ) );
138
+ }
139
+
140
+ return false;
141
+
142
+ }
143
+ }
V5/CustomFields/CustomField.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\CustomFields;
4
+
5
+ /**
6
+ * Class CustomField
7
+ *
8
+ * @package CTXFeed
9
+ * @subpackage CTXFeed\V5\CustomField
10
+ */
11
+ class CustomField {
12
+ private $customField;
13
+
14
+ public function __construct( CustomFieldInterface $customField ) {
15
+ $this->customField = $customField;
16
+ }
17
+
18
+ public function set() {
19
+ return $this->customField->set_custom_field();
20
+ }
21
+
22
+ public function save( $post_id ) {
23
+ return $this->customField->save_custom_field_value( $post_id );
24
+ }
25
+ }
V5/CustomFields/CustomFieldFactory.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\CustomFields;
4
+
5
+ /**
6
+ * Class CustomFieldFactory
7
+ *
8
+ * @package CTXFeed
9
+ * @subpackage CTXFeed\V5\CustomField
10
+ */
11
+ class CustomFieldFactory {
12
+ public static function init() {
13
+ new InputCustomFiled();
14
+ }
15
+ }
V5/CustomFields/CustomFieldInterface.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\CustomFields;
4
+ /**
5
+ * Class CustomFieldInterface
6
+ *
7
+ * @package CTXFeed
8
+ * @subpackage CTXFeed\V5\CustomField
9
+ */
10
+ interface CustomFieldInterface {
11
+ public function __construct();
12
+
13
+ public function set_custom_field();
14
+ public function set_custom_field_for_variation($loop, $variation_data, $variation);
15
+
16
+ public function save_custom_field_value($post_id);
17
+ public function save_variation_custom_field_value($post_id);
18
+ }
V5/CustomFields/DateCustomField.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\CustomField;
4
+
5
+
6
+ /**
7
+ * Class DateCustomField
8
+ *
9
+ * @package CTXFeed\V5\CustomField
10
+ * @subpackage CTXFeed\V5\CustomField
11
+ */
12
+ class DateCustomField {
13
+
14
+ }
V5/CustomFields/InputCustomFiled.php ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\CustomFields;
4
+
5
+ use CTXFeed\V5\Helper\CustomFieldHelper;
6
+ use CTXFeed\V5\Utility\Settings;
7
+
8
+ /**
9
+ * Class InputCustomFiled
10
+ *
11
+ * @package CTXFeed
12
+ * @subpackage CTXFeed\V5\CustomField
13
+ */
14
+ class InputCustomFiled implements CustomFieldInterface {
15
+ public function __construct() {
16
+ add_action( 'woocommerce_product_options_inventory_product_data', [ $this, 'set_custom_field' ], 10, 3 );
17
+ add_action( 'woocommerce_product_after_variable_attributes', [
18
+ $this,
19
+ 'set_custom_field_for_variation'
20
+ ], 10, 3 );
21
+ add_action( 'save_post_product', [ $this, 'save_custom_field_value' ], 10, 2 );
22
+ add_action( 'woocommerce_save_product_variation', [ $this, 'save_variation_custom_field_value' ], 10, 2 );
23
+ }
24
+
25
+ /**
26
+ * Set Custom Fields for Product.
27
+ *
28
+ * @return void
29
+ */
30
+ public function set_custom_field() {
31
+
32
+ $custom_field_settings = Settings::get( 'woo_feed_identifier' );
33
+ $custom_fields = CustomFieldHelper::get_fields();
34
+
35
+ if ( ! empty( $custom_field_settings ) && in_array( 'enable', $custom_field_settings, true ) ) {
36
+ echo '<div class="options_group">';
37
+ echo sprintf( '<h4 class="%s" style="padding-left: 10px;color: black;">%s</h4>', esc_attr( 'woo-feed-option-title' ), esc_html__( 'CUSTOM FIELDS by CTX Feed', 'woo-feed' ) );
38
+ foreach ( $custom_fields as $field_Key => $custom_field ) {
39
+ if ( isset( $custom_field_settings[ $field_Key ] ) && 'enable' === $custom_field_settings[ $field_Key ] && 'input' === $custom_field[2] ) {
40
+
41
+ //identifier meta value for old and new version users
42
+ $custom_field_key_previous = sprintf( 'woo_feed_identifier_%s', strtolower( $field_Key ) );
43
+ $custom_field_value_previous = get_post_meta( get_the_ID(), $custom_field_key_previous, true );
44
+
45
+ $custom_field_key = sprintf( 'woo_feed_%s', strtolower( $field_Key ) );
46
+ $custom_field_value = get_post_meta( get_the_ID(), $custom_field_key, true );
47
+
48
+ if ( empty( $custom_field_value ) && ! empty( $custom_field_value_previous ) ) {
49
+ $custom_field_key = $custom_field_key_previous;
50
+ $custom_field_value = $custom_field_value_previous;
51
+ }
52
+
53
+ $custom_field_id = esc_attr( wp_unslash( "woo_feed_$field_Key" ) );
54
+ $custom_field_label = esc_attr( wp_unslash( $custom_field[0] ) );
55
+ $custom_field_description = __( 'Set product ', 'woo-feed' ) . esc_html( $custom_field_label ) . __( ' here.', 'woo-feed' );
56
+
57
+ woocommerce_wp_text_input(
58
+ array(
59
+ 'id' => $custom_field_id,
60
+ 'label' => $custom_field_label,
61
+ 'placeholder' => $custom_field_label,
62
+ 'desc_tip' => true,
63
+ 'value' => esc_attr( wp_unslash( $custom_field_value ) ),
64
+ 'description' => $custom_field_description,
65
+ )
66
+ );
67
+ }
68
+ }
69
+ echo '</div>';
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Set Custom Fields for Product Variations.
75
+ *
76
+ * @param $loop
77
+ * @param $variation_data
78
+ * @param $variation
79
+ *
80
+ * @return void
81
+ */
82
+ public function set_custom_field_for_variation( $loop, $variation_data, $variation ) {
83
+
84
+ $custom_field_settings = Settings::get( 'woo_feed_identifier' );
85
+ $custom_fields = CustomFieldHelper::get_fields();
86
+
87
+ if ( ! empty( $custom_field_settings ) && in_array( 'enable', $custom_field_settings, true ) ) {
88
+ echo '<div class="woo-feed-variation-options">';
89
+
90
+ if ( ! empty( $custom_fields ) ) {
91
+ echo '<div class="woo-feed-variation-options">';
92
+ echo "<hr>";
93
+ echo sprintf( '<h4 class="%s">%s</h4>', esc_attr( 'woo-feed-variation-option-title' ), esc_html__( 'CUSTOM FIELDS by CTX Feed', 'woo-feed' ) );
94
+ echo "<hr>";
95
+ echo '<div class="woo-feed-variation-items">';
96
+
97
+ foreach ( $custom_fields as $field_Key => $custom_field ) {
98
+ if ( isset( $custom_field_settings[ $field_Key ] ) && 'enable' === $custom_field_settings[ $field_Key ] && 'input' === $custom_field[2] ) {
99
+ $custom_field_id = sprintf( 'woo_feed_%s_var[%d]', strtolower( $field_Key ), $variation->ID );
100
+ $custom_field_label = isset( $custom_field[0] ) ? $custom_field[0] : '';
101
+ $custom_field_description = sprintf( 'Set Variation %s here.', $custom_field_label );
102
+
103
+ //identifier meta value for old and new version users
104
+ if ( metadata_exists( 'post', $variation->ID, 'woo_feed_' . strtolower( $field_Key ) . '_var' ) ) {
105
+ $custom_field_key = sprintf( 'woo_feed_%s_var', strtolower( $field_Key ) );
106
+ } else {
107
+ $custom_field_key = sprintf( 'woo_feed_identifier_%s_var', strtolower( $field_Key ) );
108
+ }
109
+
110
+ woocommerce_wp_text_input(
111
+ array(
112
+ 'id' => $custom_field_id,
113
+ 'value' => esc_attr( get_post_meta( $variation->ID, $custom_field_key, true ) ),
114
+ 'placeholder' => esc_html( $custom_field_label ),
115
+ 'label' => esc_html( $custom_field_label ),
116
+ 'desc_tip' => true,
117
+ 'description' => esc_html( $custom_field_description ),
118
+ 'wrapper_class' => 'form-row form-row-full',
119
+ )
120
+ );
121
+ }
122
+ }
123
+ echo '</div></div>';
124
+ }
125
+ echo "<hr>";
126
+ echo '</div>';
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Save Product Custom Field Value.
132
+ *
133
+ * @param int $post_id Product id.
134
+ *
135
+ * @return void
136
+ */
137
+ public function save_custom_field_value( $post_id ) {
138
+ $custom_fields = CustomFieldHelper::get_fields();
139
+ $set_meta_val = '';
140
+
141
+ if ( ! empty( $custom_fields ) ) {
142
+ foreach ( $custom_fields as $key => $custom_field ) {
143
+ $product_meta_key = "woo_feed_$key";
144
+
145
+ $new_meta_key = "woo_feed_identifier_$key";
146
+ $new_meta_val = get_post_meta( $post_id, $new_meta_key, true );
147
+ $old_meta_val = get_post_meta( $post_id, $product_meta_key, true );
148
+
149
+ if ( ! empty( $old_meta_val ) ) {
150
+ $set_meta_val = $old_meta_val;
151
+ } else {
152
+ $set_meta_val = $new_meta_val;
153
+ }
154
+
155
+ if ( isset( $_POST[ $product_meta_key ] ) ) {
156
+ $product_meta_value = sanitize_text_field( $_POST[ $product_meta_key ] );
157
+ } elseif ( isset( $_POST[ $new_meta_key ] ) ) {
158
+ $product_meta_value = sanitize_text_field( $_POST[ $new_meta_key ] );
159
+ } else {
160
+ $product_meta_value = $set_meta_val;
161
+ }
162
+
163
+ if ( isset( $product_meta_value ) && ! empty( $product_meta_value ) ) {
164
+ update_post_meta( $post_id, $product_meta_key, $product_meta_value );
165
+ } else {
166
+ delete_post_meta( $post_id, $product_meta_key );
167
+ }
168
+ }
169
+ }
170
+ }
171
+
172
+ /**
173
+ * Save Product Variation Custom Field Value.
174
+ *
175
+ * @param int $post_id Variation id.
176
+ *
177
+ * @return void
178
+ */
179
+ public function save_variation_custom_field_value( $post_id) {
180
+ $custom_fields = woo_feed_product_custom_fields();
181
+
182
+ if ( ! empty( $custom_fields ) ) {
183
+ foreach ( $custom_fields as $key => $value ) {
184
+
185
+ $product_meta_key = "woo_feed_{$key}_var";
186
+
187
+ $new_meta_key = "woo_feed_identifier_{$key}_var";
188
+ $new_meta_val = get_post_meta( $post_id, $new_meta_key, true );
189
+ $old_meta_val = get_post_meta( $post_id, $product_meta_key, true );
190
+
191
+ if ( ! empty( $old_meta_val ) ) {
192
+ $set_meta_val = $old_meta_val;
193
+ } else {
194
+ $set_meta_val = $new_meta_val;
195
+ }
196
+
197
+ if ( isset( $_POST[ $product_meta_key ][ $post_id ] ) ) {
198
+ $product_meta_value = sanitize_text_field( $_POST[ $product_meta_key ][ $post_id ] );
199
+ } elseif ( isset( $_POST[ $new_meta_key ] [ $post_id ] ) ) {
200
+ $product_meta_value = sanitize_text_field( $_POST[ $new_meta_key ][ $post_id ] );
201
+ } else {
202
+ $product_meta_value = $set_meta_val;
203
+ }
204
+
205
+
206
+ if ( isset( $product_meta_value ) && ! empty( $product_meta_value ) ) {
207
+ update_post_meta( $post_id, $product_meta_key, $product_meta_value );
208
+ }
209
+ }
210
+ }
211
+ }
212
+ }
V5/Download/FileDownload.php ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Provides the possibility to easily create file downloads in PHP
4
+ *
5
+ * @author Jannik Zschiesche <hello@apfelbox.net>
6
+ * @version 1.0
7
+ * @license MIT
8
+ */
9
+
10
+ namespace CTXFeed\V5\Download;
11
+
12
+ /**
13
+ * Provides a simple way to create file downloads in PHP
14
+ */
15
+ class FileDownload
16
+ {
17
+ /**
18
+ * The pointer to the file to download
19
+ *
20
+ * @var resource
21
+ */
22
+ private $filePointer;
23
+
24
+
25
+
26
+ /**
27
+ * Constructs a new file download
28
+ *
29
+ * @param resource $filePointer
30
+ *
31
+ * @throws \InvalidArgumentException
32
+ */
33
+ public function __construct ($filePointer)
34
+ {
35
+ if (!is_resource($filePointer))
36
+ {
37
+ throw new \InvalidArgumentException("You must pass a file pointer to the ctor");
38
+ }
39
+
40
+ $this->filePointer = $filePointer;
41
+ }
42
+
43
+
44
+
45
+ /**
46
+ * Sends the download to the browser
47
+ *
48
+ * @param string $filename
49
+ * @param bool $forceDownload
50
+ *
51
+ * @throws \RuntimeException is thrown, if the headers are already sent
52
+ */
53
+ public function sendDownload ($filename, $forceDownload = true)
54
+ {
55
+ if (headers_sent())
56
+ {
57
+ throw new \RuntimeException("Cannot send file to the browser, since the headers were already sent.");
58
+ }
59
+
60
+ header("Pragma: public");
61
+ header("Expires: 0");
62
+ header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
63
+ header("Cache-Control: private", false);
64
+ header("Content-Type: {$this->getMimeType($filename)}; charset=utf-8");
65
+
66
+ if ($forceDownload)
67
+ {
68
+ header("Content-Disposition: attachment; filename=\"{$filename}\";" );
69
+ }
70
+ else
71
+ {
72
+ header("Content-Disposition: filename=\"{$filename}\";" );
73
+ }
74
+
75
+ header("Content-Transfer-Encoding: binary");
76
+ header("Content-Length: {$this->getFileSize()}");
77
+
78
+ @ob_clean();
79
+
80
+ rewind($this->filePointer);
81
+ fpassthru($this->filePointer);
82
+ }
83
+
84
+
85
+
86
+ /**
87
+ * Returns the mime type of a file name
88
+ *
89
+ * @param string $fileName
90
+ *
91
+ * @return string
92
+ */
93
+ private function getMimeType ($fileName)
94
+ {
95
+ $fileExtension = pathinfo($fileName, PATHINFO_EXTENSION);
96
+ $mimeTypeHelper = Mimetypes::getInstance();
97
+ $mimeType = $mimeTypeHelper->fromExtension($fileExtension);
98
+
99
+ return !is_null($mimeType) ? $mimeType : "application/force-download";
100
+ }
101
+
102
+
103
+
104
+ /**
105
+ * Returns the file size of the file
106
+ *
107
+ * @return int
108
+ */
109
+ private function getFileSize ()
110
+ {
111
+ $stat = fstat($this->filePointer);
112
+ return $stat['size'];
113
+ }
114
+
115
+
116
+
117
+ /**
118
+ * Creates a new file download from a file path
119
+ *
120
+ * @static
121
+ *
122
+ * @param string $filePath
123
+ *
124
+ * @throws \InvalidArgumentException is thrown, if the given file does not exist or is not readable
125
+ *
126
+ * @return FileDownload
127
+ */
128
+ public static function createFromFilePath ($filePath)
129
+ {
130
+ if (!is_file($filePath))
131
+ {
132
+ throw new \InvalidArgumentException("File does not exist");
133
+ }
134
+
135
+ if (!is_readable($filePath))
136
+ {
137
+ throw new \InvalidArgumentException("File to download is not readable.");
138
+ }
139
+
140
+ return new FileDownload(fopen($filePath, "rb"));
141
+ }
142
+
143
+
144
+
145
+ /**
146
+ * Creates a new file download helper with a given content
147
+ *
148
+ * @static
149
+ *
150
+ * @param string $content the file content
151
+ *
152
+ * @return FileDownload
153
+ */
154
+ public static function createFromString ($content)
155
+ {
156
+ $file = tmpfile();
157
+ fwrite($file, $content);
158
+
159
+ return new FileDownload($file);
160
+ }
161
+ }
V5/Download/Mimetypes.php ADDED
@@ -0,0 +1,1112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright (c) 2011-2016 [Ryan Parman](http://ryanparman.com)
4
+ * Copyright (c) 2011-2012 [Michael Dowling](https://github.com/mtdowling)
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
7
+ * this software and associated documentation files (the "Software"), to deal in
8
+ * the Software without restriction, including without limitation the rights to
9
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10
+ * of the Software, and to permit persons to whom the Software is furnished to do
11
+ * so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE.
23
+ *
24
+ * <http://opensource.org/licenses/MIT>
25
+ */
26
+
27
+ namespace CTXFeed\V5\Download;
28
+
29
+ /**
30
+ * Provides mappings of file extensions to mimetypes.
31
+ * API-compatible with Guzzle\Http\Mimetypes (http://guzzlephp.org).
32
+ * @link https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x/docs/conf/mime.types
33
+ */
34
+ class Mimetypes
35
+ {
36
+ /**
37
+ * @var self
38
+ */
39
+ protected static $instance;
40
+
41
+ /**
42
+ * Returns an associative array with extension => mimetype mappings.
43
+ *
44
+ * Generated from source on 26 Sep 2016, 10:26am UTC.
45
+ *
46
+ * @return array An associative array with extension => mimetype mappings.
47
+ */
48
+ public function getMimeTypes()
49
+ {
50
+ return [
51
+ '3dml' => 'text/vnd.in3d.3dml',
52
+ '3ds' => 'image/x-3ds',
53
+ '3g2' => 'video/3gpp2',
54
+ '3gp' => 'video/3gpp',
55
+ '7z' => 'application/x-7z-compressed',
56
+ 'aab' => 'application/x-authorware-bin',
57
+ 'aac' => 'audio/x-aac',
58
+ 'aam' => 'application/x-authorware-map',
59
+ 'aas' => 'application/x-authorware-seg',
60
+ 'abw' => 'application/x-abiword',
61
+ 'ac' => 'application/pkix-attr-cert',
62
+ 'acc' => 'application/vnd.americandynamics.acc',
63
+ 'ace' => 'application/x-ace-compressed',
64
+ 'acu' => 'application/vnd.acucobol',
65
+ 'acutc' => 'application/vnd.acucorp',
66
+ 'adp' => 'audio/adpcm',
67
+ 'aep' => 'application/vnd.audiograph',
68
+ 'afm' => 'application/x-font-type1',
69
+ 'afp' => 'application/vnd.ibm.modcap',
70
+ 'ahead' => 'application/vnd.ahead.space',
71
+ 'ai' => 'application/postscript',
72
+ 'aif' => 'audio/x-aiff',
73
+ 'aifc' => 'audio/x-aiff',
74
+ 'aiff' => 'audio/x-aiff',
75
+ 'air' => 'application/vnd.adobe.air-application-installer-package+zip',
76
+ 'ait' => 'application/vnd.dvb.ait',
77
+ 'ami' => 'application/vnd.amiga.ami',
78
+ 'apk' => 'application/vnd.android.package-archive',
79
+ 'appcache' => 'text/cache-manifest',
80
+ 'application' => 'application/x-ms-application',
81
+ 'apr' => 'application/vnd.lotus-approach',
82
+ 'arc' => 'application/x-freearc',
83
+ 'asa' => 'text/plain',
84
+ 'asax' => 'application/octet-stream',
85
+ 'asc' => 'application/pgp-signature',
86
+ 'ascx' => 'text/plain',
87
+ 'asf' => 'video/x-ms-asf',
88
+ 'ashx' => 'text/plain',
89
+ 'asm' => 'text/x-asm',
90
+ 'asmx' => 'text/plain',
91
+ 'aso' => 'application/vnd.accpac.simply.aso',
92
+ 'asp' => 'text/plain',
93
+ 'aspx' => 'text/plain',
94
+ 'asx' => 'video/x-ms-asf',
95
+ 'atc' => 'application/vnd.acucorp',
96
+ 'atom' => 'application/atom+xml',
97
+ 'atomcat' => 'application/atomcat+xml',
98
+ 'atomsvc' => 'application/atomsvc+xml',
99
+ 'atx' => 'application/vnd.antix.game-component',
100
+ 'au' => 'audio/basic',
101
+ 'avi' => 'video/x-msvideo',
102
+ 'aw' => 'application/applixware',
103
+ 'axd' => 'text/plain',
104
+ 'azf' => 'application/vnd.airzip.filesecure.azf',
105
+ 'azs' => 'application/vnd.airzip.filesecure.azs',
106
+ 'azw' => 'application/vnd.amazon.ebook',
107
+ 'bat' => 'application/x-msdownload',
108
+ 'bcpio' => 'application/x-bcpio',
109
+ 'bdf' => 'application/x-font-bdf',
110
+ 'bdm' => 'application/vnd.syncml.dm+wbxml',
111
+ 'bed' => 'application/vnd.realvnc.bed',
112
+ 'bh2' => 'application/vnd.fujitsu.oasysprs',
113
+ 'bin' => 'application/octet-stream',
114
+ 'blb' => 'application/x-blorb',
115
+ 'blorb' => 'application/x-blorb',
116
+ 'bmi' => 'application/vnd.bmi',
117
+ 'bmp' => 'image/bmp',
118
+ 'book' => 'application/vnd.framemaker',
119
+ 'box' => 'application/vnd.previewsystems.box',
120
+ 'boz' => 'application/x-bzip2',
121
+ 'bpk' => 'application/octet-stream',
122
+ 'btif' => 'image/prs.btif',
123
+ 'bz' => 'application/x-bzip',
124
+ 'bz2' => 'application/x-bzip2',
125
+ 'c' => 'text/x-c',
126
+ 'c11amc' => 'application/vnd.cluetrust.cartomobile-config',
127
+ 'c11amz' => 'application/vnd.cluetrust.cartomobile-config-pkg',
128
+ 'c4d' => 'application/vnd.clonk.c4group',
129
+ 'c4f' => 'application/vnd.clonk.c4group',
130
+ 'c4g' => 'application/vnd.clonk.c4group',
131
+ 'c4p' => 'application/vnd.clonk.c4group',
132
+ 'c4u' => 'application/vnd.clonk.c4group',
133
+ 'cab' => 'application/vnd.ms-cab-compressed',
134
+ 'caf' => 'audio/x-caf',
135
+ 'cap' => 'application/vnd.tcpdump.pcap',
136
+ 'car' => 'application/vnd.curl.car',
137
+ 'cat' => 'application/vnd.ms-pki.seccat',
138
+ 'cb7' => 'application/x-cbr',
139
+ 'cba' => 'application/x-cbr',
140
+ 'cbr' => 'application/x-cbr',
141
+ 'cbt' => 'application/x-cbr',
142
+ 'cbz' => 'application/x-cbr',
143
+ 'cc' => 'text/x-c',
144
+ 'cct' => 'application/x-director',
145
+ 'ccxml' => 'application/ccxml+xml',
146
+ 'cdbcmsg' => 'application/vnd.contact.cmsg',
147
+ 'cdf' => 'application/x-netcdf',
148
+ 'cdkey' => 'application/vnd.mediastation.cdkey',
149
+ 'cdmia' => 'application/cdmi-capability',
150
+ 'cdmic' => 'application/cdmi-container',
151
+ 'cdmid' => 'application/cdmi-domain',
152
+ 'cdmio' => 'application/cdmi-object',
153
+ 'cdmiq' => 'application/cdmi-queue',
154
+ 'cdx' => 'chemical/x-cdx',
155
+ 'cdxml' => 'application/vnd.chemdraw+xml',
156
+ 'cdy' => 'application/vnd.cinderella',
157
+ 'cer' => 'application/pkix-cert',
158
+ 'cfc' => 'application/x-coldfusion',
159
+ 'cfm' => 'application/x-coldfusion',
160
+ 'cfs' => 'application/x-cfs-compressed',
161
+ 'cgm' => 'image/cgm',
162
+ 'chat' => 'application/x-chat',
163
+ 'chm' => 'application/vnd.ms-htmlhelp',
164
+ 'chrt' => 'application/vnd.kde.kchart',
165
+ 'cif' => 'chemical/x-cif',
166
+ 'cii' => 'application/vnd.anser-web-certificate-issue-initiation',
167
+ 'cil' => 'application/vnd.ms-artgalry',
168
+ 'cla' => 'application/vnd.claymore',
169
+ 'class' => 'application/java-vm',
170
+ 'clkk' => 'application/vnd.crick.clicker.keyboard',
171
+ 'clkp' => 'application/vnd.crick.clicker.palette',
172
+ 'clkt' => 'application/vnd.crick.clicker.template',
173
+ 'clkw' => 'application/vnd.crick.clicker.wordbank',
174
+ 'clkx' => 'application/vnd.crick.clicker',
175
+ 'clp' => 'application/x-msclip',
176
+ 'cmc' => 'application/vnd.cosmocaller',
177
+ 'cmdf' => 'chemical/x-cmdf',
178
+ 'cml' => 'chemical/x-cml',
179
+ 'cmp' => 'application/vnd.yellowriver-custom-menu',
180
+ 'cmx' => 'image/x-cmx',
181
+ 'cod' => 'application/vnd.rim.cod',
182
+ 'com' => 'application/x-msdownload',
183
+ 'conf' => 'text/plain',
184
+ 'cpio' => 'application/x-cpio',
185
+ 'cpp' => 'text/x-c',
186
+ 'cpt' => 'application/mac-compactpro',
187
+ 'crd' => 'application/x-mscardfile',
188
+ 'crl' => 'application/pkix-crl',
189
+ 'crt' => 'application/x-x509-ca-cert',
190
+ 'crx' => 'application/octet-stream',
191
+ 'cryptonote' => 'application/vnd.rig.cryptonote',
192
+ 'cs' => 'text/plain',
193
+ 'csh' => 'application/x-csh',
194
+ 'csml' => 'chemical/x-csml',
195
+ 'csp' => 'application/vnd.commonspace',
196
+ 'css' => 'text/css',
197
+ 'cst' => 'application/x-director',
198
+ 'csv' => 'text/csv',
199
+ 'cu' => 'application/cu-seeme',
200
+ 'curl' => 'text/vnd.curl',
201
+ 'cww' => 'application/prs.cww',
202
+ 'cxt' => 'application/x-director',
203
+ 'cxx' => 'text/x-c',
204
+ 'dae' => 'model/vnd.collada+xml',
205
+ 'daf' => 'application/vnd.mobius.daf',
206
+ 'dart' => 'application/vnd.dart',
207
+ 'dataless' => 'application/vnd.fdsn.seed',
208
+ 'davmount' => 'application/davmount+xml',
209
+ 'dbk' => 'application/docbook+xml',
210
+ 'dcr' => 'application/x-director',
211
+ 'dcurl' => 'text/vnd.curl.dcurl',
212
+ 'dd2' => 'application/vnd.oma.dd2+xml',
213
+ 'ddd' => 'application/vnd.fujixerox.ddd',
214
+ 'deb' => 'application/x-debian-package',
215
+ 'def' => 'text/plain',
216
+ 'deploy' => 'application/octet-stream',
217
+ 'der' => 'application/x-x509-ca-cert',
218
+ 'dfac' => 'application/vnd.dreamfactory',
219
+ 'dgc' => 'application/x-dgc-compressed',
220
+ 'dic' => 'text/x-c',
221
+ 'dir' => 'application/x-director',
222
+ 'dis' => 'application/vnd.mobius.dis',
223
+ 'dist' => 'application/octet-stream',
224
+ 'distz' => 'application/octet-stream',
225
+ 'djv' => 'image/vnd.djvu',
226
+ 'djvu' => 'image/vnd.djvu',
227
+ 'dll' => 'application/x-msdownload',
228
+ 'dmg' => 'application/x-apple-diskimage',
229
+ 'dmp' => 'application/vnd.tcpdump.pcap',
230
+ 'dms' => 'application/octet-stream',
231
+ 'dna' => 'application/vnd.dna',
232
+ 'doc' => 'application/msword',
233
+ 'docm' => 'application/vnd.ms-word.document.macroenabled.12',
234
+ 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
235
+ 'dot' => 'application/msword',
236
+ 'dotm' => 'application/vnd.ms-word.template.macroenabled.12',
237
+ 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
238
+ 'dp' => 'application/vnd.osgi.dp',
239
+ 'dpg' => 'application/vnd.dpgraph',
240
+ 'dra' => 'audio/vnd.dra',
241
+ 'dsc' => 'text/prs.lines.tag',
242
+ 'dssc' => 'application/dssc+der',
243
+ 'dtb' => 'application/x-dtbook+xml',
244
+ 'dtd' => 'application/xml-dtd',
245
+ 'dts' => 'audio/vnd.dts',
246
+ 'dtshd' => 'audio/vnd.dts.hd',
247
+ 'dump' => 'application/octet-stream',
248
+ 'dvb' => 'video/vnd.dvb.file',
249
+ 'dvi' => 'application/x-dvi',
250
+ 'dwf' => 'model/vnd.dwf',
251
+ 'dwg' => 'image/vnd.dwg',
252
+ 'dxf' => 'image/vnd.dxf',
253
+ 'dxp' => 'application/vnd.spotfire.dxp',
254
+ 'dxr' => 'application/x-director',
255
+ 'ecelp4800' => 'audio/vnd.nuera.ecelp4800',
256
+ 'ecelp7470' => 'audio/vnd.nuera.ecelp7470',
257
+ 'ecelp9600' => 'audio/vnd.nuera.ecelp9600',
258
+ 'ecma' => 'application/ecmascript',
259
+ 'edm' => 'application/vnd.novadigm.edm',
260
+ 'edx' => 'application/vnd.novadigm.edx',
261
+ 'efif' => 'application/vnd.picsel',
262
+ 'ei6' => 'application/vnd.pg.osasli',
263
+ 'elc' => 'application/octet-stream',
264
+ 'emf' => 'application/x-msmetafile',
265
+ 'eml' => 'message/rfc822',
266
+ 'emma' => 'application/emma+xml',
267
+ 'emz' => 'application/x-msmetafile',
268
+ 'eol' => 'audio/vnd.digital-winds',
269
+ 'eot' => 'application/vnd.ms-fontobject',
270
+ 'eps' => 'application/postscript',
271
+ 'epub' => 'application/epub+zip',
272
+ 'es3' => 'application/vnd.eszigno3+xml',
273
+ 'esa' => 'application/vnd.osgi.subsystem',
274
+ 'esf' => 'application/vnd.epson.esf',
275
+ 'et3' => 'application/vnd.eszigno3+xml',
276
+ 'etx' => 'text/x-setext',
277
+ 'eva' => 'application/x-eva',
278
+ 'evy' => 'application/x-envoy',
279
+ 'exe' => 'application/x-msdownload',
280
+ 'exi' => 'application/exi',
281
+ 'ext' => 'application/vnd.novadigm.ext',
282
+ 'ez' => 'application/andrew-inset',
283
+ 'ez2' => 'application/vnd.ezpix-album',
284
+ 'ez3' => 'application/vnd.ezpix-package',
285
+ 'f' => 'text/x-fortran',
286
+ 'f4v' => 'video/x-f4v',
287
+ 'f77' => 'text/x-fortran',
288
+ 'f90' => 'text/x-fortran',
289
+ 'fbs' => 'image/vnd.fastbidsheet',
290
+ 'fcdt' => 'application/vnd.adobe.formscentral.fcdt',
291
+ 'fcs' => 'application/vnd.isac.fcs',
292
+ 'fdf' => 'application/vnd.fdf',
293
+ 'fe_launch' => 'application/vnd.denovo.fcselayout-link',
294
+ 'fg5' => 'application/vnd.fujitsu.oasysgp',
295
+ 'fgd' => 'application/x-director',
296
+ 'fh' => 'image/x-freehand',
297
+ 'fh4' => 'image/x-freehand',
298
+ 'fh5' => 'image/x-freehand',
299
+ 'fh7' => 'image/x-freehand',
300
+ 'fhc' => 'image/x-freehand',
301
+ 'fig' => 'application/x-xfig',
302
+ 'flac' => 'audio/x-flac',
303
+ 'fli' => 'video/x-fli',
304
+ 'flo' => 'application/vnd.micrografx.flo',
305
+ 'flv' => 'video/x-flv',
306
+ 'flw' => 'application/vnd.kde.kivio',
307
+ 'flx' => 'text/vnd.fmi.flexstor',
308
+ 'fly' => 'text/vnd.fly',
309
+ 'fm' => 'application/vnd.framemaker',
310
+ 'fnc' => 'application/vnd.frogans.fnc',
311
+ 'for' => 'text/x-fortran',
312
+ 'fpx' => 'image/vnd.fpx',
313
+ 'frame' => 'application/vnd.framemaker',
314
+ 'fsc' => 'application/vnd.fsc.weblaunch',
315
+ 'fst' => 'image/vnd.fst',
316
+ 'ftc' => 'application/vnd.fluxtime.clip',
317
+ 'fti' => 'application/vnd.anser-web-funds-transfer-initiation',
318
+ 'fvt' => 'video/vnd.fvt',
319
+ 'fxp' => 'application/vnd.adobe.fxp',
320
+ 'fxpl' => 'application/vnd.adobe.fxp',
321
+ 'fzs' => 'application/vnd.fuzzysheet',
322
+ 'g2w' => 'application/vnd.geoplan',
323
+ 'g3' => 'image/g3fax',
324
+ 'g3w' => 'application/vnd.geospace',
325
+ 'gac' => 'application/vnd.groove-account',
326
+ 'gam' => 'application/x-tads',
327
+ 'gbr' => 'application/rpki-ghostbusters',
328
+ 'gca' => 'application/x-gca-compressed',
329
+ 'gdl' => 'model/vnd.gdl',
330
+ 'geo' => 'application/vnd.dynageo',
331
+ 'gex' => 'application/vnd.geometry-explorer',
332
+ 'ggb' => 'application/vnd.geogebra.file',
333
+ 'ggt' => 'application/vnd.geogebra.tool',
334
+ 'ghf' => 'application/vnd.groove-help',
335
+ 'gif' => 'image/gif',
336
+ 'gim' => 'application/vnd.groove-identity-message',
337
+ 'gml' => 'application/gml+xml',
338
+ 'gmx' => 'application/vnd.gmx',
339
+ 'gnumeric' => 'application/x-gnumeric',
340
+ 'gph' => 'application/vnd.flographit',
341
+ 'gpx' => 'application/gpx+xml',
342
+ 'gqf' => 'application/vnd.grafeq',
343
+ 'gqs' => 'application/vnd.grafeq',
344
+ 'gram' => 'application/srgs',
345
+ 'gramps' => 'application/x-gramps-xml',
346
+ 'gre' => 'application/vnd.geometry-explorer',
347
+ 'grv' => 'application/vnd.groove-injector',
348
+ 'grxml' => 'application/srgs+xml',
349
+ 'gsf' => 'application/x-font-ghostscript',
350
+ 'gtar' => 'application/x-gtar',
351
+ 'gtm' => 'application/vnd.groove-tool-message',
352
+ 'gtw' => 'model/vnd.gtw',
353
+ 'gv' => 'text/vnd.graphviz',
354
+ 'gxf' => 'application/gxf',
355
+ 'gxt' => 'application/vnd.geonext',
356
+ 'gz' => 'application/x-gzip',
357
+ 'h' => 'text/x-c',
358
+ 'h261' => 'video/h261',
359
+ 'h263' => 'video/h263',
360
+ 'h264' => 'video/h264',
361
+ 'hal' => 'application/vnd.hal+xml',
362
+ 'hbci' => 'application/vnd.hbci',
363
+ 'hdf' => 'application/x-hdf',
364
+ 'hh' => 'text/x-c',
365
+ 'hlp' => 'application/winhlp',
366
+ 'hpgl' => 'application/vnd.hp-hpgl',
367
+ 'hpid' => 'application/vnd.hp-hpid',
368
+ 'hps' => 'application/vnd.hp-hps',
369
+ 'hqx' => 'application/mac-binhex40',
370
+ 'hta' => 'application/octet-stream',
371
+ 'htc' => 'text/html',
372
+ 'htke' => 'application/vnd.kenameaapp',
373
+ 'htm' => 'text/html',
374
+ 'html' => 'text/html',
375
+ 'hvd' => 'application/vnd.yamaha.hv-dic',
376
+ 'hvp' => 'application/vnd.yamaha.hv-voice',
377
+ 'hvs' => 'application/vnd.yamaha.hv-script',
378
+ 'i2g' => 'application/vnd.intergeo',
379
+ 'icc' => 'application/vnd.iccprofile',
380
+ 'ice' => 'x-conference/x-cooltalk',
381
+ 'icm' => 'application/vnd.iccprofile',
382
+ 'ico' => 'image/x-icon',
383
+ 'ics' => 'text/calendar',
384
+ 'ief' => 'image/ief',
385
+ 'ifb' => 'text/calendar',
386
+ 'ifm' => 'application/vnd.shana.informed.formdata',
387
+ 'iges' => 'model/iges',
388
+ 'igl' => 'application/vnd.igloader',
389
+ 'igm' => 'application/vnd.insors.igm',
390
+ 'igs' => 'model/iges',
391
+ 'igx' => 'application/vnd.micrografx.igx',
392
+ 'iif' => 'application/vnd.shana.informed.interchange',
393
+ 'imp' => 'application/vnd.accpac.simply.imp',
394
+ 'ims' => 'application/vnd.ms-ims',
395
+ 'in' => 'text/plain',
396
+ 'ini' => 'text/plain',
397
+ 'ink' => 'application/inkml+xml',
398
+ 'inkml' => 'application/inkml+xml',
399
+ 'install' => 'application/x-install-instructions',
400
+ 'iota' => 'application/vnd.astraea-software.iota',
401
+ 'ipa' => 'application/octet-stream',
402
+ 'ipfix' => 'application/ipfix',
403
+ 'ipk' => 'application/vnd.shana.informed.package',
404
+ 'irm' => 'application/vnd.ibm.rights-management',
405
+ 'irp' => 'application/vnd.irepository.package+xml',
406
+ 'iso' => 'application/x-iso9660-image',
407
+ 'itp' => 'application/vnd.shana.informed.formtemplate',
408
+ 'ivp' => 'application/vnd.immervision-ivp',
409
+ 'ivu' => 'application/vnd.immervision-ivu',
410
+ 'jad' => 'text/vnd.sun.j2me.app-descriptor',
411
+ 'jam' => 'application/vnd.jam',
412
+ 'jar' => 'application/java-archive',
413
+ 'java' => 'text/x-java-source',
414
+ 'jisp' => 'application/vnd.jisp',
415
+ 'jlt' => 'application/vnd.hp-jlyt',
416
+ 'jnlp' => 'application/x-java-jnlp-file',
417
+ 'joda' => 'application/vnd.joost.joda-archive',
418
+ 'jpe' => 'image/jpeg',
419
+ 'jpeg' => 'image/jpeg',
420
+ 'jpg' => 'image/jpeg',
421
+ 'jpgm' => 'video/jpm',
422
+ 'jpgv' => 'video/jpeg',
423
+ 'jpm' => 'video/jpm',
424
+ 'js' => 'text/javascript',
425
+ 'json' => 'application/json',
426
+ 'jsonml' => 'application/jsonml+json',
427
+ 'kar' => 'audio/midi',
428
+ 'karbon' => 'application/vnd.kde.karbon',
429
+ 'kfo' => 'application/vnd.kde.kformula',
430
+ 'kia' => 'application/vnd.kidspiration',
431
+ 'kml' => 'application/vnd.google-earth.kml+xml',
432
+ 'kmz' => 'application/vnd.google-earth.kmz',
433
+ 'kne' => 'application/vnd.kinar',
434
+ 'knp' => 'application/vnd.kinar',
435
+ 'kon' => 'application/vnd.kde.kontour',
436
+ 'kpr' => 'application/vnd.kde.kpresenter',
437
+ 'kpt' => 'application/vnd.kde.kpresenter',
438
+ 'kpxx' => 'application/vnd.ds-keypoint',
439
+ 'ksp' => 'application/vnd.kde.kspread',
440
+ 'ktr' => 'application/vnd.kahootz',
441
+ 'ktx' => 'image/ktx',
442
+ 'ktz' => 'application/vnd.kahootz',
443
+ 'kwd' => 'application/vnd.kde.kword',
444
+ 'kwt' => 'application/vnd.kde.kword',
445
+ 'lasxml' => 'application/vnd.las.las+xml',
446
+ 'latex' => 'application/x-latex',
447
+ 'lbd' => 'application/vnd.llamagraphics.life-balance.desktop',
448
+ 'lbe' => 'application/vnd.llamagraphics.life-balance.exchange+xml',
449
+ 'les' => 'application/vnd.hhe.lesson-player',
450
+ 'lha' => 'application/x-lzh-compressed',
451
+ 'link66' => 'application/vnd.route66.link66+xml',
452
+ 'list' => 'text/plain',
453
+ 'list3820' => 'application/vnd.ibm.modcap',
454
+ 'listafp' => 'application/vnd.ibm.modcap',
455
+ 'lnk' => 'application/x-ms-shortcut',
456
+ 'log' => 'text/plain',
457
+ 'lostxml' => 'application/lost+xml',
458
+ 'lrf' => 'application/octet-stream',
459
+ 'lrm' => 'application/vnd.ms-lrm',
460
+ 'ltf' => 'application/vnd.frogans.ltf',
461
+ 'lvp' => 'audio/vnd.lucent.voice',
462
+ 'lwp' => 'application/vnd.lotus-wordpro',
463
+ 'lz' => 'application/x-lzip',
464
+ 'lzh' => 'application/x-lzh-compressed',
465
+ 'lzma' => 'application/x-lzma',
466
+ 'lzo' => 'application/x-lzop',
467
+ 'm13' => 'application/x-msmediaview',
468
+ 'm14' => 'application/x-msmediaview',
469
+ 'm1v' => 'video/mpeg',
470
+ 'm21' => 'application/mp21',
471
+ 'm2a' => 'audio/mpeg',
472
+ 'm2v' => 'video/mpeg',
473
+ 'm3a' => 'audio/mpeg',
474
+ 'm3u' => 'audio/x-mpegurl',
475
+ 'm3u8' => 'application/vnd.apple.mpegurl',
476
+ 'm4a' => 'audio/mp4',
477
+ 'm4u' => 'video/vnd.mpegurl',
478
+ 'm4v' => 'video/mp4',
479
+ 'ma' => 'application/mathematica',
480
+ 'mads' => 'application/mads+xml',
481
+ 'mag' => 'application/vnd.ecowin.chart',
482
+ 'maker' => 'application/vnd.framemaker',
483
+ 'man' => 'text/troff',
484
+ 'mar' => 'application/octet-stream',
485
+ 'mathml' => 'application/mathml+xml',
486
+ 'mb' => 'application/mathematica',
487
+ 'mbk' => 'application/vnd.mobius.mbk',
488
+ 'mbox' => 'application/mbox',
489
+ 'mc1' => 'application/vnd.medcalcdata',
490
+ 'mcd' => 'application/vnd.mcd',
491
+ 'mcurl' => 'text/vnd.curl.mcurl',
492
+ 'mdb' => 'application/x-msaccess',
493
+ 'mdi' => 'image/vnd.ms-modi',
494
+ 'me' => 'text/troff',
495
+ 'mesh' => 'model/mesh',
496
+ 'meta4' => 'application/metalink4+xml',
497
+ 'metalink' => 'application/metalink+xml',
498
+ 'mets' => 'application/mets+xml',
499
+ 'mfm' => 'application/vnd.mfmp',
500
+ 'mft' => 'application/rpki-manifest',
501
+ 'mgp' => 'application/vnd.osgeo.mapguide.package',
502
+ 'mgz' => 'application/vnd.proteus.magazine',
503
+ 'mid' => 'audio/midi',
504
+ 'midi' => 'audio/midi',
505
+ 'mie' => 'application/x-mie',
506
+ 'mif' => 'application/vnd.mif',
507
+ 'mime' => 'message/rfc822',
508
+ 'mj2' => 'video/mj2',
509
+ 'mjp2' => 'video/mj2',
510
+ 'mk3d' => 'video/x-matroska',
511
+ 'mka' => 'audio/x-matroska',
512
+ 'mks' => 'video/x-matroska',
513
+ 'mkv' => 'video/x-matroska',
514
+ 'mlp' => 'application/vnd.dolby.mlp',
515
+ 'mmd' => 'application/vnd.chipnuts.karaoke-mmd',
516
+ 'mmf' => 'application/vnd.smaf',
517
+ 'mmr' => 'image/vnd.fujixerox.edmics-mmr',
518
+ 'mng' => 'video/x-mng',
519
+ 'mny' => 'application/x-msmoney',
520
+ 'mobi' => 'application/x-mobipocket-ebook',
521
+ 'mods' => 'application/mods+xml',
522
+ 'mov' => 'video/quicktime',
523
+ 'movie' => 'video/x-sgi-movie',
524
+ 'mp2' => 'audio/mpeg',
525
+ 'mp21' => 'application/mp21',
526
+ 'mp2a' => 'audio/mpeg',
527
+ 'mp3' => 'audio/mpeg',
528
+ 'mp4' => 'video/mp4',
529
+ 'mp4a' => 'audio/mp4',
530
+ 'mp4s' => 'application/mp4',
531
+ 'mp4v' => 'video/mp4',
532
+ 'mpc' => 'application/vnd.mophun.certificate',
533
+ 'mpe' => 'video/mpeg',
534
+ 'mpeg' => 'video/mpeg',
535
+ 'mpg' => 'video/mpeg',
536
+ 'mpg4' => 'video/mp4',
537
+ 'mpga' => 'audio/mpeg',
538
+ 'mpkg' => 'application/vnd.apple.installer+xml',
539
+ 'mpm' => 'application/vnd.blueice.multipass',
540
+ 'mpn' => 'application/vnd.mophun.application',
541
+ 'mpp' => 'application/vnd.ms-project',
542
+ 'mpt' => 'application/vnd.ms-project',
543
+ 'mpy' => 'application/vnd.ibm.minipay',
544
+ 'mqy' => 'application/vnd.mobius.mqy',
545
+ 'mrc' => 'application/marc',
546
+ 'mrcx' => 'application/marcxml+xml',
547
+ 'ms' => 'text/troff',
548
+ 'mscml' => 'application/mediaservercontrol+xml',
549
+ 'mseed' => 'application/vnd.fdsn.mseed',
550
+ 'mseq' => 'application/vnd.mseq',
551
+ 'msf' => 'application/vnd.epson.msf',
552
+ 'msh' => 'model/mesh',
553
+ 'msi' => 'application/x-msdownload',
554
+ 'msl' => 'application/vnd.mobius.msl',
555
+ 'msty' => 'application/vnd.muvee.style',
556
+ 'mts' => 'model/vnd.mts',
557
+ 'mus' => 'application/vnd.musician',
558
+ 'musicxml' => 'application/vnd.recordare.musicxml+xml',
559
+ 'mvb' => 'application/x-msmediaview',
560
+ 'mwf' => 'application/vnd.mfer',
561
+ 'mxf' => 'application/mxf',
562
+ 'mxl' => 'application/vnd.recordare.musicxml',
563
+ 'mxml' => 'application/xv+xml',
564
+ 'mxs' => 'application/vnd.triscape.mxs',
565
+ 'mxu' => 'video/vnd.mpegurl',
566
+ 'n-gage' => 'application/vnd.nokia.n-gage.symbian.install',
567
+ 'n3' => 'text/n3',
568
+ 'nb' => 'application/mathematica',
569
+ 'nbp' => 'application/vnd.wolfram.player',
570
+ 'nc' => 'application/x-netcdf',
571
+ 'ncx' => 'application/x-dtbncx+xml',
572
+ 'nfo' => 'text/x-nfo',
573
+ 'ngdat' => 'application/vnd.nokia.n-gage.data',
574
+ 'nitf' => 'application/vnd.nitf',
575
+ 'nlu' => 'application/vnd.neurolanguage.nlu',
576
+ 'nml' => 'application/vnd.enliven',
577
+ 'nnd' => 'application/vnd.noblenet-directory',
578
+ 'nns' => 'application/vnd.noblenet-sealer',
579
+ 'nnw' => 'application/vnd.noblenet-web',
580
+ 'npx' => 'image/vnd.net-fpx',
581
+ 'nsc' => 'application/x-conference',
582
+ 'nsf' => 'application/vnd.lotus-notes',
583
+ 'ntf' => 'application/vnd.nitf',
584
+ 'nzb' => 'application/x-nzb',
585
+ 'oa2' => 'application/vnd.fujitsu.oasys2',
586
+ 'oa3' => 'application/vnd.fujitsu.oasys3',
587
+ 'oas' => 'application/vnd.fujitsu.oasys',
588
+ 'obd' => 'application/x-msbinder',
589
+ 'obj' => 'application/x-tgif',
590
+ 'oda' => 'application/oda',
591
+ 'odb' => 'application/vnd.oasis.opendocument.database',
592
+ 'odc' => 'application/vnd.oasis.opendocument.chart',
593
+ 'odf' => 'application/vnd.oasis.opendocument.formula',
594
+ 'odft' => 'application/vnd.oasis.opendocument.formula-template',
595
+ 'odg' => 'application/vnd.oasis.opendocument.graphics',
596
+ 'odi' => 'application/vnd.oasis.opendocument.image',
597
+ 'odm' => 'application/vnd.oasis.opendocument.text-master',
598
+ 'odp' => 'application/vnd.oasis.opendocument.presentation',
599
+ 'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
600
+ 'odt' => 'application/vnd.oasis.opendocument.text',
601
+ 'oga' => 'audio/ogg',
602
+ 'ogg' => 'audio/ogg',
603
+ 'ogv' => 'video/ogg',
604
+ 'ogx' => 'application/ogg',
605
+ 'omdoc' => 'application/omdoc+xml',
606
+ 'onepkg' => 'application/onenote',
607
+ 'onetmp' => 'application/onenote',
608
+ 'onetoc' => 'application/onenote',
609
+ 'onetoc2' => 'application/onenote',
610
+ 'opf' => 'application/oebps-package+xml',
611
+ 'opml' => 'text/x-opml',
612
+ 'oprc' => 'application/vnd.palm',
613
+ 'org' => 'application/vnd.lotus-organizer',
614
+ 'osf' => 'application/vnd.yamaha.openscoreformat',
615
+ 'osfpvg' => 'application/vnd.yamaha.openscoreformat.osfpvg+xml',
616
+ 'otc' => 'application/vnd.oasis.opendocument.chart-template',
617
+ 'otf' => 'application/x-font-otf',
618
+ 'otg' => 'application/vnd.oasis.opendocument.graphics-template',
619
+ 'oth' => 'application/vnd.oasis.opendocument.text-web',
620
+ 'oti' => 'application/vnd.oasis.opendocument.image-template',
621
+ 'otp' => 'application/vnd.oasis.opendocument.presentation-template',
622
+ 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template',
623
+ 'ott' => 'application/vnd.oasis.opendocument.text-template',
624
+ 'oxps' => 'application/oxps',
625
+ 'oxt' => 'application/vnd.openofficeorg.extension',
626
+ 'p' => 'text/x-pascal',
627
+ 'p10' => 'application/pkcs10',
628
+ 'p12' => 'application/x-pkcs12',
629
+ 'p7b' => 'application/x-pkcs7-certificates',
630
+ 'p7c' => 'application/pkcs7-mime',
631
+ 'p7m' => 'application/pkcs7-mime',
632
+ 'p7r' => 'application/x-pkcs7-certreqresp',
633
+ 'p7s' => 'application/pkcs7-signature',
634
+ 'p8' => 'application/pkcs8',
635
+ 'pas' => 'text/x-pascal',
636
+ 'paw' => 'application/vnd.pawaafile',
637
+ 'pbd' => 'application/vnd.powerbuilder6',
638
+ 'pbm' => 'image/x-portable-bitmap',
639
+ 'pcap' => 'application/vnd.tcpdump.pcap',
640
+ 'pcf' => 'application/x-font-pcf',
641
+ 'pcl' => 'application/vnd.hp-pcl',
642
+ 'pclxl' => 'application/vnd.hp-pclxl',
643
+ 'pct' => 'image/x-pict',
644
+ 'pcurl' => 'application/vnd.curl.pcurl',
645
+ 'pcx' => 'image/x-pcx',
646
+ 'pdb' => 'application/vnd.palm',
647
+ 'pdf' => 'application/pdf',
648
+ 'pfa' => 'application/x-font-type1',
649
+ 'pfb' => 'application/x-font-type1',
650
+ 'pfm' => 'application/x-font-type1',
651
+ 'pfr' => 'application/font-tdpfr',
652
+ 'pfx' => 'application/x-pkcs12',
653
+ 'pgm' => 'image/x-portable-graymap',
654
+ 'pgn' => 'application/x-chess-pgn',
655
+ 'pgp' => 'application/pgp-encrypted',
656
+ 'phar' => 'application/octet-stream',
657
+ 'php' => 'text/plain',
658
+ 'phps' => 'application/x-httpd-phps',
659
+ 'pic' => 'image/x-pict',
660
+ 'pkg' => 'application/octet-stream',
661
+ 'pki' => 'application/pkixcmp',
662
+ 'pkipath' => 'application/pkix-pkipath',
663
+ 'plb' => 'application/vnd.3gpp.pic-bw-large',
664
+ 'plc' => 'application/vnd.mobius.plc',
665
+ 'plf' => 'application/vnd.pocketlearn',
666
+ 'plist' => 'application/x-plist',
667
+ 'pls' => 'application/pls+xml',
668
+ 'pml' => 'application/vnd.ctc-posml',
669
+ 'png' => 'image/png',
670
+ 'pnm' => 'image/x-portable-anymap',
671
+ 'portpkg' => 'application/vnd.macports.portpkg',
672
+ 'pot' => 'application/vnd.ms-powerpoint',
673
+ 'potm' => 'application/vnd.ms-powerpoint.template.macroenabled.12',
674
+ 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
675
+ 'ppam' => 'application/vnd.ms-powerpoint.addin.macroenabled.12',
676
+ 'ppd' => 'application/vnd.cups-ppd',
677
+ 'ppm' => 'image/x-portable-pixmap',
678
+ 'pps' => 'application/vnd.ms-powerpoint',
679
+ 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroenabled.12',
680
+ 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
681
+ 'ppt' => 'application/vnd.ms-powerpoint',
682
+ 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroenabled.12',
683
+ 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
684
+ 'pqa' => 'application/vnd.palm',
685
+ 'prc' => 'application/x-mobipocket-ebook',
686
+ 'pre' => 'application/vnd.lotus-freelance',
687
+ 'prf' => 'application/pics-rules',
688
+ 'ps' => 'application/postscript',
689
+ 'psb' => 'application/vnd.3gpp.pic-bw-small',
690
+ 'psd' => 'image/vnd.adobe.photoshop',
691
+ 'psf' => 'application/x-font-linux-psf',
692
+ 'pskcxml' => 'application/pskc+xml',
693
+ 'ptid' => 'application/vnd.pvi.ptid1',
694
+ 'pub' => 'application/x-mspublisher',
695
+ 'pvb' => 'application/vnd.3gpp.pic-bw-var',
696
+ 'pwn' => 'application/vnd.3m.post-it-notes',
697
+ 'pya' => 'audio/vnd.ms-playready.media.pya',
698
+ 'pyv' => 'video/vnd.ms-playready.media.pyv',
699
+ 'qam' => 'application/vnd.epson.quickanime',
700
+ 'qbo' => 'application/vnd.intu.qbo',
701
+ 'qfx' => 'application/vnd.intu.qfx',
702
+ 'qps' => 'application/vnd.publishare-delta-tree',
703
+ 'qt' => 'video/quicktime',
704
+ 'qwd' => 'application/vnd.quark.quarkxpress',
705
+ 'qwt' => 'application/vnd.quark.quarkxpress',
706
+ 'qxb' => 'application/vnd.quark.quarkxpress',
707
+ 'qxd' => 'application/vnd.quark.quarkxpress',
708
+ 'qxl' => 'application/vnd.quark.quarkxpress',
709
+ 'qxt' => 'application/vnd.quark.quarkxpress',
710
+ 'ra' => 'audio/x-pn-realaudio',
711
+ 'ram' => 'audio/x-pn-realaudio',
712
+ 'rar' => 'application/x-rar-compressed',
713
+ 'ras' => 'image/x-cmu-raster',
714
+ 'rb' => 'text/plain',
715
+ 'rcprofile' => 'application/vnd.ipunplugged.rcprofile',
716
+ 'rdf' => 'application/rdf+xml',
717
+ 'rdz' => 'application/vnd.data-vision.rdz',
718
+ 'rep' => 'application/vnd.businessobjects',
719
+ 'res' => 'application/x-dtbresource+xml',
720
+ 'resx' => 'text/xml',
721
+ 'rgb' => 'image/x-rgb',
722
+ 'rif' => 'application/reginfo+xml',
723
+ 'rip' => 'audio/vnd.rip',
724
+ 'ris' => 'application/x-research-info-systems',
725
+ 'rl' => 'application/resource-lists+xml',
726
+ 'rlc' => 'image/vnd.fujixerox.edmics-rlc',
727
+ 'rld' => 'application/resource-lists-diff+xml',
728
+ 'rm' => 'application/vnd.rn-realmedia',
729
+ 'rmi' => 'audio/midi',
730
+ 'rmp' => 'audio/x-pn-realaudio-plugin',
731
+ 'rms' => 'application/vnd.jcp.javame.midlet-rms',
732
+ 'rmvb' => 'application/vnd.rn-realmedia-vbr',
733
+ 'rnc' => 'application/relax-ng-compact-syntax',
734
+ 'roa' => 'application/rpki-roa',
735
+ 'roff' => 'text/troff',
736
+ 'rp9' => 'application/vnd.cloanto.rp9',
737
+ 'rpm' => 'application/x-rpm',
738
+ 'rpss' => 'application/vnd.nokia.radio-presets',
739
+ 'rpst' => 'application/vnd.nokia.radio-preset',
740
+ 'rq' => 'application/sparql-query',
741
+ 'rs' => 'application/rls-services+xml',
742
+ 'rsd' => 'application/rsd+xml',
743
+ 'rss' => 'application/rss+xml',
744
+ 'rtf' => 'application/rtf',
745
+ 'rtx' => 'text/richtext',
746
+ 's' => 'text/x-asm',
747
+ 's3m' => 'audio/s3m',
748
+ 's7z' => 'application/x-7z-compressed',
749
+ 'saf' => 'application/vnd.yamaha.smaf-audio',
750
+ 'safariextz' => 'application/octet-stream',
751
+ 'sass' => 'text/x-sass',
752
+ 'sbml' => 'application/sbml+xml',
753
+ 'sc' => 'application/vnd.ibm.secure-container',
754
+ 'scd' => 'application/x-msschedule',
755
+ 'scm' => 'application/vnd.lotus-screencam',
756
+ 'scq' => 'application/scvp-cv-request',
757
+ 'scs' => 'application/scvp-cv-response',
758
+ 'scss' => 'text/x-scss',
759
+ 'scurl' => 'text/vnd.curl.scurl',
760
+ 'sda' => 'application/vnd.stardivision.draw',
761
+ 'sdc' => 'application/vnd.stardivision.calc',
762
+ 'sdd' => 'application/vnd.stardivision.impress',
763
+ 'sdkd' => 'application/vnd.solent.sdkm+xml',
764
+ 'sdkm' => 'application/vnd.solent.sdkm+xml',
765
+ 'sdp' => 'application/sdp',
766
+ 'sdw' => 'application/vnd.stardivision.writer',
767
+ 'see' => 'application/vnd.seemail',
768
+ 'seed' => 'application/vnd.fdsn.seed',
769
+ 'sema' => 'application/vnd.sema',
770
+ 'semd' => 'application/vnd.semd',
771
+ 'semf' => 'application/vnd.semf',
772
+ 'ser' => 'application/java-serialized-object',
773
+ 'setpay' => 'application/set-payment-initiation',
774
+ 'setreg' => 'application/set-registration-initiation',
775
+ 'sfd-hdstx' => 'application/vnd.hydrostatix.sof-data',
776
+ 'sfs' => 'application/vnd.spotfire.sfs',
777
+ 'sfv' => 'text/x-sfv',
778
+ 'sgi' => 'image/sgi',
779
+ 'sgl' => 'application/vnd.stardivision.writer-global',
780
+ 'sgm' => 'text/sgml',
781
+ 'sgml' => 'text/sgml',
782
+ 'sh' => 'application/x-sh',
783
+ 'shar' => 'application/x-shar',
784
+ 'shf' => 'application/shf+xml',
785
+ 'sid' => 'image/x-mrsid-image',
786
+ 'sig' => 'application/pgp-signature',
787
+ 'sil' => 'audio/silk',
788
+ 'silo' => 'model/mesh',
789
+ 'sis' => 'application/vnd.symbian.install',
790
+ 'sisx' => 'application/vnd.symbian.install',
791
+ 'sit' => 'application/x-stuffit',
792
+ 'sitx' => 'application/x-stuffitx',
793
+ 'skd' => 'application/vnd.koan',
794
+ 'skm' => 'application/vnd.koan',
795
+ 'skp' => 'application/vnd.koan',
796
+ 'skt' => 'application/vnd.koan',
797
+ 'sldm' => 'application/vnd.ms-powerpoint.slide.macroenabled.12',
798
+ 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
799
+ 'slt' => 'application/vnd.epson.salt',
800
+ 'sm' => 'application/vnd.stepmania.stepchart',
801
+ 'smf' => 'application/vnd.stardivision.math',
802
+ 'smi' => 'application/smil+xml',
803
+ 'smil' => 'application/smil+xml',
804
+ 'smv' => 'video/x-smv',
805
+ 'smzip' => 'application/vnd.stepmania.package',
806
+ 'snd' => 'audio/basic',
807
+ 'snf' => 'application/x-font-snf',
808
+ 'so' => 'application/octet-stream',
809
+ 'spc' => 'application/x-pkcs7-certificates',
810
+ 'spf' => 'application/vnd.yamaha.smaf-phrase',
811
+ 'spl' => 'application/x-futuresplash',
812
+ 'spot' => 'text/vnd.in3d.spot',
813
+ 'spp' => 'application/scvp-vp-response',
814
+ 'spq' => 'application/scvp-vp-request',
815
+ 'spx' => 'audio/ogg',
816
+ 'sql' => 'application/x-sql',
817
+ 'src' => 'application/x-wais-source',
818
+ 'srt' => 'application/x-subrip',
819
+ 'sru' => 'application/sru+xml',
820
+ 'srx' => 'application/sparql-results+xml',
821
+ 'ssdl' => 'application/ssdl+xml',
822
+ 'sse' => 'application/vnd.kodak-descriptor',
823
+ 'ssf' => 'application/vnd.epson.ssf',
824
+ 'ssml' => 'application/ssml+xml',
825
+ 'st' => 'application/vnd.sailingtracker.track',
826
+ 'stc' => 'application/vnd.sun.xml.calc.template',
827
+ 'std' => 'application/vnd.sun.xml.draw.template',
828
+ 'stf' => 'application/vnd.wt.stf',
829
+ 'sti' => 'application/vnd.sun.xml.impress.template',
830
+ 'stk' => 'application/hyperstudio',
831
+ 'stl' => 'application/vnd.ms-pki.stl',
832
+ 'str' => 'application/vnd.pg.format',
833
+ 'stw' => 'application/vnd.sun.xml.writer.template',
834
+ 'styl' => 'text/x-styl',
835
+ 'sub' => 'image/vnd.dvb.subtitle',
836
+ 'sus' => 'application/vnd.sus-calendar',
837
+ 'susp' => 'application/vnd.sus-calendar',
838
+ 'sv4cpio' => 'application/x-sv4cpio',
839
+ 'sv4crc' => 'application/x-sv4crc',
840
+ 'svc' => 'application/vnd.dvb.service',
841
+ 'svd' => 'application/vnd.svd',
842
+ 'svg' => 'image/svg+xml',
843
+ 'svgz' => 'image/svg+xml',
844
+ 'swa' => 'application/x-director',
845
+ 'swf' => 'application/x-shockwave-flash',
846
+ 'swi' => 'application/vnd.aristanetworks.swi',
847
+ 'sxc' => 'application/vnd.sun.xml.calc',
848
+ 'sxd' => 'application/vnd.sun.xml.draw',
849
+ 'sxg' => 'application/vnd.sun.xml.writer.global',
850
+ 'sxi' => 'application/vnd.sun.xml.impress',
851
+ 'sxm' => 'application/vnd.sun.xml.math',
852
+ 'sxw' => 'application/vnd.sun.xml.writer',
853
+ 't' => 'text/troff',
854
+ 't3' => 'application/x-t3vm-image',
855
+ 'taglet' => 'application/vnd.mynfc',
856
+ 'tao' => 'application/vnd.tao.intent-module-archive',
857
+ 'tar' => 'application/x-tar',
858
+ 'tcap' => 'application/vnd.3gpp2.tcap',
859
+ 'tcl' => 'application/x-tcl',
860
+ 'teacher' => 'application/vnd.smart.teacher',
861
+ 'tei' => 'application/tei+xml',
862
+ 'teicorpus' => 'application/tei+xml',
863
+ 'tex' => 'application/x-tex',
864
+ 'texi' => 'application/x-texinfo',
865
+ 'texinfo' => 'application/x-texinfo',
866
+ 'text' => 'text/plain',
867
+ 'tfi' => 'application/thraud+xml',
868
+ 'tfm' => 'application/x-tex-tfm',
869
+ 'tga' => 'image/x-tga',
870
+ 'tgz' => 'application/x-gzip',
871
+ 'thmx' => 'application/vnd.ms-officetheme',
872
+ 'tif' => 'image/tiff',
873
+ 'tiff' => 'image/tiff',
874
+ 'tmo' => 'application/vnd.tmobile-livetv',
875
+ 'torrent' => 'application/x-bittorrent',
876
+ 'tpl' => 'application/vnd.groove-tool-template',
877
+ 'tpt' => 'application/vnd.trid.tpt',
878
+ 'tr' => 'text/troff',
879
+ 'tra' => 'application/vnd.trueapp',
880
+ 'trm' => 'application/x-msterminal',
881
+ 'tsd' => 'application/timestamped-data',
882
+ 'tsv' => 'text/tab-separated-values',
883
+ 'ttc' => 'application/x-font-ttf',
884
+ 'ttf' => 'application/x-font-ttf',
885
+ 'ttl' => 'text/turtle',
886
+ 'twd' => 'application/vnd.simtech-mindmapper',
887
+ 'twds' => 'application/vnd.simtech-mindmapper',
888
+ 'txd' => 'application/vnd.genomatix.tuxedo',
889
+ 'txf' => 'application/vnd.mobius.txf',
890
+ 'txt' => 'text/plain',
891
+ 'u32' => 'application/x-authorware-bin',
892
+ 'udeb' => 'application/x-debian-package',
893
+ 'ufd' => 'application/vnd.ufdl',
894
+ 'ufdl' => 'application/vnd.ufdl',
895
+ 'ulx' => 'application/x-glulx',
896
+ 'umj' => 'application/vnd.umajin',
897
+ 'unityweb' => 'application/vnd.unity',
898
+ 'uoml' => 'application/vnd.uoml+xml',
899
+ 'uri' => 'text/uri-list',
900
+ 'uris' => 'text/uri-list',
901
+ 'urls' => 'text/uri-list',
902
+ 'ustar' => 'application/x-ustar',
903
+ 'utz' => 'application/vnd.uiq.theme',
904
+ 'uu' => 'text/x-uuencode',
905
+ 'uva' => 'audio/vnd.dece.audio',
906
+ 'uvd' => 'application/vnd.dece.data',
907
+ 'uvf' => 'application/vnd.dece.data',
908
+ 'uvg' => 'image/vnd.dece.graphic',
909
+ 'uvh' => 'video/vnd.dece.hd',
910
+ 'uvi' => 'image/vnd.dece.graphic',
911
+ 'uvm' => 'video/vnd.dece.mobile',
912
+ 'uvp' => 'video/vnd.dece.pd',
913
+ 'uvs' => 'video/vnd.dece.sd',
914
+ 'uvt' => 'application/vnd.dece.ttml+xml',
915
+ 'uvu' => 'video/vnd.uvvu.mp4',
916
+ 'uvv' => 'video/vnd.dece.video',
917
+ 'uvva' => 'audio/vnd.dece.audio',
918
+ 'uvvd' => 'application/vnd.dece.data',
919
+ 'uvvf' => 'application/vnd.dece.data',
920
+ 'uvvg' => 'image/vnd.dece.graphic',
921
+ 'uvvh' => 'video/vnd.dece.hd',
922
+ 'uvvi' => 'image/vnd.dece.graphic',
923
+ 'uvvm' => 'video/vnd.dece.mobile',
924
+ 'uvvp' => 'video/vnd.dece.pd',
925
+ 'uvvs' => 'video/vnd.dece.sd',
926
+ 'uvvt' => 'application/vnd.dece.ttml+xml',
927
+ 'uvvu' => 'video/vnd.uvvu.mp4',
928
+ 'uvvv' => 'video/vnd.dece.video',
929
+ 'uvvx' => 'application/vnd.dece.unspecified',
930
+ 'uvvz' => 'application/vnd.dece.zip',
931
+ 'uvx' => 'application/vnd.dece.unspecified',
932
+ 'uvz' => 'application/vnd.dece.zip',
933
+ 'vcard' => 'text/vcard',
934
+ 'vcd' => 'application/x-cdlink',
935
+ 'vcf' => 'text/x-vcard',
936
+ 'vcg' => 'application/vnd.groove-vcard',
937
+ 'vcs' => 'text/x-vcalendar',
938
+ 'vcx' => 'application/vnd.vcx',
939
+ 'vis' => 'application/vnd.visionary',
940
+ 'viv' => 'video/vnd.vivo',
941
+ 'vob' => 'video/x-ms-vob',
942
+ 'vor' => 'application/vnd.stardivision.writer',
943
+ 'vox' => 'application/x-authorware-bin',
944
+ 'vrml' => 'model/vrml',
945
+ 'vsd' => 'application/vnd.visio',
946
+ 'vsf' => 'application/vnd.vsf',
947
+ 'vss' => 'application/vnd.visio',
948
+ 'vst' => 'application/vnd.visio',
949
+ 'vsw' => 'application/vnd.visio',
950
+ 'vtu' => 'model/vnd.vtu',
951
+ 'vxml' => 'application/voicexml+xml',
952
+ 'w3d' => 'application/x-director',
953
+ 'wad' => 'application/x-doom',
954
+ 'wav' => 'audio/x-wav',
955
+ 'wax' => 'audio/x-ms-wax',
956
+ 'wbmp' => 'image/vnd.wap.wbmp',
957
+ 'wbs' => 'application/vnd.criticaltools.wbs+xml',
958
+ 'wbxml' => 'application/vnd.wap.wbxml',
959
+ 'wcm' => 'application/vnd.ms-works',
960
+ 'wdb' => 'application/vnd.ms-works',
961
+ 'wdp' => 'image/vnd.ms-photo',
962
+ 'weba' => 'audio/webm',
963
+ 'webm' => 'video/webm',
964
+ 'webp' => 'image/webp',
965
+ 'wg' => 'application/vnd.pmi.widget',
966
+ 'wgt' => 'application/widget',
967
+ 'wks' => 'application/vnd.ms-works',
968
+ 'wm' => 'video/x-ms-wm',
969
+ 'wma' => 'audio/x-ms-wma',
970
+ 'wmd' => 'application/x-ms-wmd',
971
+ 'wmf' => 'application/x-msmetafile',
972
+ 'wml' => 'text/vnd.wap.wml',
973
+ 'wmlc' => 'application/vnd.wap.wmlc',
974
+ 'wmls' => 'text/vnd.wap.wmlscript',
975
+ 'wmlsc' => 'application/vnd.wap.wmlscriptc',
976
+ 'wmv' => 'video/x-ms-wmv',
977
+ 'wmx' => 'video/x-ms-wmx',
978
+ 'wmz' => 'application/x-ms-wmz',
979
+ 'woff' => 'application/x-font-woff',
980
+ 'wpd' => 'application/vnd.wordperfect',
981
+ 'wpl' => 'application/vnd.ms-wpl',
982
+ 'wps' => 'application/vnd.ms-works',
983
+ 'wqd' => 'application/vnd.wqd',
984
+ 'wri' => 'application/x-mswrite',
985
+ 'wrl' => 'model/vrml',
986
+ 'wsdl' => 'application/wsdl+xml',
987
+ 'wspolicy' => 'application/wspolicy+xml',
988
+ 'wtb' => 'application/vnd.webturbo',
989
+ 'wvx' => 'video/x-ms-wvx',
990
+ 'x32' => 'application/x-authorware-bin',
991
+ 'x3d' => 'model/x3d+xml',
992
+ 'x3db' => 'model/x3d+binary',
993
+ 'x3dbz' => 'model/x3d+binary',
994
+ 'x3dv' => 'model/x3d+vrml',
995
+ 'x3dvz' => 'model/x3d+vrml',
996
+ 'x3dz' => 'model/x3d+xml',
997
+ 'xaml' => 'application/xaml+xml',
998
+ 'xap' => 'application/x-silverlight-app',
999
+ 'xar' => 'application/vnd.xara',
1000
+ 'xbap' => 'application/x-ms-xbap',
1001
+ 'xbd' => 'application/vnd.fujixerox.docuworks.binder',
1002
+ 'xbm' => 'image/x-xbitmap',
1003
+ 'xdf' => 'application/xcap-diff+xml',
1004
+ 'xdm' => 'application/vnd.syncml.dm+xml',
1005
+ 'xdp' => 'application/vnd.adobe.xdp+xml',
1006
+ 'xdssc' => 'application/dssc+xml',
1007
+ 'xdw' => 'application/vnd.fujixerox.docuworks',
1008
+ 'xenc' => 'application/xenc+xml',
1009
+ 'xer' => 'application/patch-ops-error+xml',
1010
+ 'xfdf' => 'application/vnd.adobe.xfdf',
1011
+ 'xfdl' => 'application/vnd.xfdl',
1012
+ 'xht' => 'application/xhtml+xml',
1013
+ 'xhtml' => 'application/xhtml+xml',
1014
+ 'xhvml' => 'application/xv+xml',
1015
+ 'xif' => 'image/vnd.xiff',
1016
+ 'xla' => 'application/vnd.ms-excel',
1017
+ 'xlam' => 'application/vnd.ms-excel.addin.macroenabled.12',
1018
+ 'xlc' => 'application/vnd.ms-excel',
1019
+ 'xlf' => 'application/x-xliff+xml',
1020
+ 'xlm' => 'application/vnd.ms-excel',
1021
+ 'xls' => 'application/vnd.ms-excel',
1022
+ 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroenabled.12',
1023
+ 'xlsm' => 'application/vnd.ms-excel.sheet.macroenabled.12',
1024
+ 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
1025
+ 'xlt' => 'application/vnd.ms-excel',
1026
+ 'xltm' => 'application/vnd.ms-excel.template.macroenabled.12',
1027
+ 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
1028
+ 'xlw' => 'application/vnd.ms-excel',
1029
+ 'xm' => 'audio/xm',
1030
+ 'xml' => 'application/xml',
1031
+ 'xo' => 'application/vnd.olpc-sugar',
1032
+ 'xop' => 'application/xop+xml',
1033
+ 'xpi' => 'application/x-xpinstall',
1034
+ 'xpl' => 'application/xproc+xml',
1035
+ 'xpm' => 'image/x-xpixmap',
1036
+ 'xpr' => 'application/vnd.is-xpr',
1037
+ 'xps' => 'application/vnd.ms-xpsdocument',
1038
+ 'xpw' => 'application/vnd.intercon.formnet',
1039
+ 'xpx' => 'application/vnd.intercon.formnet',
1040
+ 'xsl' => 'application/xml',
1041
+ 'xslt' => 'application/xslt+xml',
1042
+ 'xsm' => 'application/vnd.syncml+xml',
1043
+ 'xspf' => 'application/xspf+xml',
1044
+ 'xul' => 'application/vnd.mozilla.xul+xml',
1045
+ 'xvm' => 'application/xv+xml',
1046
+ 'xvml' => 'application/xv+xml',
1047
+ 'xwd' => 'image/x-xwindowdump',
1048
+ 'xyz' => 'chemical/x-xyz',
1049
+ 'xz' => 'application/x-xz',
1050
+ 'yaml' => 'text/yaml',
1051
+ 'yang' => 'application/yang',
1052
+ 'yin' => 'application/yin+xml',
1053
+ 'yml' => 'text/yaml',
1054
+ 'z' => 'application/x-compress',
1055
+ 'z1' => 'application/x-zmachine',
1056
+ 'z2' => 'application/x-zmachine',
1057
+ 'z3' => 'application/x-zmachine',
1058
+ 'z4' => 'application/x-zmachine',
1059
+ 'z5' => 'application/x-zmachine',
1060
+ 'z6' => 'application/x-zmachine',
1061
+ 'z7' => 'application/x-zmachine',
1062
+ 'z8' => 'application/x-zmachine',
1063
+ 'zaz' => 'application/vnd.zzazz.deck+xml',
1064
+ 'zip' => 'application/zip',
1065
+ 'zir' => 'application/vnd.zul',
1066
+ 'zirz' => 'application/vnd.zul',
1067
+ 'zmm' => 'application/vnd.handheld-entertainment+xml',
1068
+ '123' => 'application/vnd.lotus-1-2-3',
1069
+ ];
1070
+ }
1071
+
1072
+ /**
1073
+ * Get a singleton instance of the class
1074
+ *
1075
+ * @return self
1076
+ * @codeCoverageIgnore
1077
+ */
1078
+ public static function getInstance()
1079
+ {
1080
+ if (!self::$instance) {
1081
+ self::$instance = new self();
1082
+ }
1083
+
1084
+ return self::$instance;
1085
+ }
1086
+
1087
+ /**
1088
+ * Get a mimetype value from a file extension
1089
+ *
1090
+ * @param string $extension File extension
1091
+ *
1092
+ * @return string|null
1093
+ *
1094
+ */
1095
+ public function fromExtension($extension)
1096
+ {
1097
+ $mimetypes = $this->getMimeTypes();
1098
+ return isset($mimetypes[$extension]) ? $mimetypes[$extension] : null;
1099
+ }
1100
+
1101
+ /**
1102
+ * Get a mimetype from a filename
1103
+ *
1104
+ * @param string $filename Filename to generate a mimetype from
1105
+ *
1106
+ * @return string|null
1107
+ */
1108
+ public function fromFilename($filename)
1109
+ {
1110
+ return $this->fromExtension(pathinfo($filename, PATHINFO_EXTENSION));
1111
+ }
1112
+ }
V5/FTP/FtpClient.php ADDED
@@ -0,0 +1,968 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This file is part of the `nicolab/php-ftp-client` package.
4
+ *
5
+ * (c) Nicolas Tallefourtane <dev@nicolab.net>
6
+ *
7
+ * For the full copyright and license information, please view the LICENSE
8
+ * file that was distributed with this source code.
9
+ *
10
+ * @copyright Nicolas Tallefourtane http://nicolab.net
11
+ */
12
+ namespace CTXFeed\V5\FTP;
13
+
14
+ use Countable;
15
+
16
+ /**
17
+ * The FTP and SSL-FTP client for PHP.
18
+ *
19
+ * @method bool alloc(int $filesize, string &$result = null) Allocates space for a file to be uploaded
20
+ * @method bool append(string $remote_file, string $local_file, int $mode = FTP_BINARY) Append the contents of a file to another file on the FTP server
21
+ * @method bool cdup() Changes to the parent directory
22
+ * @method bool chdir(string $directory) Changes the current directory on a FTP server
23
+ * @method int chmod(int $mode, string $filename) Set permissions on a file via FTP
24
+ * @method bool delete(string $path) Deletes a file on the FTP server
25
+ * @method bool exec(string $command) Requests execution of a command on the FTP server
26
+ * @method bool fget(resource $handle, string $remote_file, int $mode, int $resumepos = 0) Downloads a file from the FTP server and saves to an open file
27
+ * @method bool fput(string $remote_file, resource $handle, int $mode, int $startpos = 0) Uploads from an open file to the FTP server
28
+ * @method mixed get_option(int $option) Retrieves various runtime behaviours of the current FTP stream
29
+ * @method bool get(string $local_file, string $remote_file, int $mode, int $resumepos = 0) Downloads a file from the FTP server
30
+ * @method int mdtm(string $remote_file) Returns the last modified time of the given file
31
+ * @method array mlsd(string $remote_dir) Returns a list of files in the given directory
32
+ * @method int nb_continue() Continues retrieving/sending a file (non-blocking)
33
+ * @method int nb_fget(resource $handle, string $remote_file, int $mode, int $resumepos = 0) Retrieves a file from the FTP server and writes it to an open file (non-blocking)
34
+ * @method int nb_fput(string $remote_file, resource $handle, int $mode, int $startpos = 0) Stores a file from an open file to the FTP server (non-blocking)
35
+ * @method int nb_get(string $local_file, string $remote_file, int $mode, int $resumepos = 0) Retrieves a file from the FTP server and writes it to a local file (non-blocking)
36
+ * @method int nb_put(string $remote_file, string $local_file, int $mode, int $startpos = 0) Stores a file on the FTP server (non-blocking)
37
+ * @method bool pasv(bool $pasv) Turns passive mode on or off
38
+ * @method bool put(string $remote_file, string $local_file, int $mode, int $startpos = 0) Uploads a file to the FTP server
39
+ * @method string pwd() Returns the current directory name
40
+ * @method bool quit() Closes an FTP connection
41
+ * @method array raw(string $command) Sends an arbitrary command to an FTP server
42
+ * @method bool rename(string $oldname, string $newname) Renames a file or a directory on the FTP server
43
+ * @method bool set_option(int $option, mixed $value) Set miscellaneous runtime FTP options
44
+ * @method bool site(string $command) Sends a SITE command to the server
45
+ * @method int size(string $remote_file) Returns the size of the given file
46
+ * @method string systype() Returns the system type identifier of the remote FTP server
47
+ *
48
+ * @author Nicolas Tallefourtane <dev@nicolab.net>
49
+ */
50
+ class FtpClient implements Countable
51
+ {
52
+ /**
53
+ * The connection with the server.
54
+ *
55
+ * @var resource
56
+ */
57
+ protected $conn;
58
+
59
+ /**
60
+ * PHP FTP functions wrapper.
61
+ *
62
+ * @var FtpWrapper
63
+ */
64
+ private $ftp;
65
+
66
+ /**
67
+ * Constructor.
68
+ *
69
+ * @param resource|null $connection
70
+ * @throws FtpException If FTP extension is not loaded.
71
+ */
72
+ public function __construct($connection = null)
73
+ {
74
+ if (!extension_loaded('ftp')) {
75
+ throw new FtpException('FTP extension is not loaded!');
76
+ }
77
+
78
+ if ($connection) {
79
+ $this->conn = $connection;
80
+ }
81
+
82
+ $this->setWrapper(new FtpWrapper($this->conn));
83
+ }
84
+
85
+ /**
86
+ * Close the connection when the object is destroyed.
87
+ */
88
+ public function __destruct()
89
+ {
90
+ if ($this->conn) {
91
+ $this->ftp->close();
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Call an internal method or a FTP method handled by the wrapper.
97
+ *
98
+ * Wrap the FTP PHP functions to call as method of FtpClient object.
99
+ * The connection is automaticaly passed to the FTP PHP functions.
100
+ *
101
+ * @param string $method
102
+ * @param array $arguments
103
+ * @return mixed
104
+ * @throws FtpException When the function is not valid
105
+ */
106
+ public function __call($method, array $arguments)
107
+ {
108
+ return $this->ftp->__call($method, $arguments);
109
+ }
110
+
111
+ /**
112
+ * Overwrites the PHP limit
113
+ *
114
+ * @param string|null $memory The memory limit, if null is not modified
115
+ * @param int $time_limit The max execution time, unlimited by default
116
+ * @param bool $ignore_user_abort Ignore user abort, true by default
117
+ * @return FtpClient
118
+ */
119
+ public function setPhpLimit($memory = null, $time_limit = 0, $ignore_user_abort = true)
120
+ {
121
+ if (null !== $memory) {
122
+ ini_set('memory_limit', $memory);
123
+ }
124
+
125
+ ignore_user_abort($ignore_user_abort);
126
+ set_time_limit($time_limit);
127
+
128
+ return $this;
129
+ }
130
+
131
+ /**
132
+ * Get the help information of the remote FTP server.
133
+ *
134
+ * @return array
135
+ */
136
+ public function help()
137
+ {
138
+ return $this->ftp->raw('help');
139
+ }
140
+
141
+ /**
142
+ * Open a FTP connection.
143
+ *
144
+ * @param string $host
145
+ * @param bool $ssl
146
+ * @param int $port
147
+ * @param int $timeout
148
+ *
149
+ * @return FtpClient
150
+ * @throws FtpException If unable to connect
151
+ */
152
+ public function connect($host, $ssl = false, $port = 21, $timeout = 90)
153
+ {
154
+ if ($ssl) {
155
+ $this->conn = $this->ftp->ssl_connect($host, $port, $timeout);
156
+ } else {
157
+ $this->conn = $this->ftp->connect($host, $port, $timeout);
158
+ }
159
+
160
+ if (!$this->conn) {
161
+ throw new FtpException('Unable to connect');
162
+ }
163
+
164
+ return $this;
165
+ }
166
+
167
+ /**
168
+ * Closes the current FTP connection.
169
+ *
170
+ * @return bool
171
+ */
172
+ public function close()
173
+ {
174
+ if ($this->conn) {
175
+ $this->ftp->close();
176
+ $this->conn = null;
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Get the connection with the server.
182
+ *
183
+ * @return resource
184
+ */
185
+ public function getConnection()
186
+ {
187
+ return $this->conn;
188
+ }
189
+
190
+ /**
191
+ * Get the wrapper.
192
+ *
193
+ * @return FtpWrapper
194
+ */
195
+ public function getWrapper()
196
+ {
197
+ return $this->ftp;
198
+ }
199
+
200
+ /**
201
+ * Logs in to an FTP connection.
202
+ *
203
+ * @param string $username
204
+ * @param string $password
205
+ *
206
+ * @return FtpClient
207
+ * @throws FtpException If the login is incorrect
208
+ */
209
+ public function login($username = 'anonymous', $password = '')
210
+ {
211
+ $result = $this->ftp->login($username, $password);
212
+
213
+ if ($result === false) {
214
+ throw new FtpException('Login incorrect');
215
+ }
216
+
217
+ return $this;
218
+ }
219
+
220
+ /**
221
+ * Returns the last modified time of the given file.
222
+ * Return -1 on error
223
+ *
224
+ * @param string $remoteFile
225
+ * @param string|null $format
226
+ *
227
+ * @return int
228
+ */
229
+ public function modifiedTime($remoteFile, $format = null)
230
+ {
231
+ $time = $this->ftp->mdtm($remoteFile);
232
+
233
+ if ($time !== -1 && $format !== null) {
234
+ return date($format, $time);
235
+ }
236
+
237
+ return $time;
238
+ }
239
+
240
+ /**
241
+ * Changes to the parent directory.
242
+ *
243
+ * @throws FtpException
244
+ * @return FtpClient
245
+ */
246
+ public function up()
247
+ {
248
+ $result = $this->ftp->cdup();
249
+
250
+ if ($result === false) {
251
+ throw new FtpException('Unable to get parent folder');
252
+ }
253
+
254
+ return $this;
255
+ }
256
+
257
+ /**
258
+ * Returns a list of files in the given directory.
259
+ *
260
+ * @param string $directory The directory, by default is "." the current directory
261
+ * @param bool $recursive
262
+ * @param callable $filter A callable to filter the result, by default is asort() PHP function.
263
+ * The result is passed in array argument,
264
+ * must take the argument by reference !
265
+ * The callable should proceed with the reference array
266
+ * because is the behavior of several PHP sorting
267
+ * functions (by reference ensure directly the compatibility
268
+ * with all PHP sorting functions).
269
+ *
270
+ * @return array
271
+ * @throws FtpException If unable to list the directory
272
+ */
273
+ public function nlist($directory = '.', $recursive = false, $filter = 'sort')
274
+ {
275
+ if (!$this->isDir($directory)) {
276
+ throw new FtpException('"'.$directory.'" is not a directory');
277
+ }
278
+
279
+ $files = $this->ftp->nlist($directory);
280
+
281
+ if ($files === false) {
282
+ throw new FtpException('Unable to list directory');
283
+ }
284
+
285
+ $result = array();
286
+ $dir_len = strlen($directory);
287
+
288
+ // if it's the current
289
+ if (false !== ($kdot = array_search('.', $files))) {
290
+ unset($files[$kdot]);
291
+ }
292
+
293
+ // if it's the parent
294
+ if(false !== ($kdot = array_search('..', $files))) {
295
+ unset($files[$kdot]);
296
+ }
297
+
298
+ if (!$recursive) {
299
+ $result = $files;
300
+
301
+ // working with the reference (behavior of several PHP sorting functions)
302
+ $filter($result);
303
+
304
+ return $result;
305
+ }
306
+
307
+ // utils for recursion
308
+ $flatten = function (array $arr) use (&$flatten) {
309
+ $flat = [];
310
+
311
+ foreach ($arr as $k => $v) {
312
+ if (is_array($v)) {
313
+ $flat = array_merge($flat, $flatten($v));
314
+ } else {
315
+ $flat[] = $v;
316
+ }
317
+ }
318
+
319
+ return $flat;
320
+ };
321
+
322
+ foreach ($files as $file) {
323
+ $file = $directory.'/'.$file;
324
+
325
+ // if contains the root path (behavior of the recursivity)
326
+ if (0 === strpos($file, $directory, $dir_len)) {
327
+ $file = substr($file, $dir_len);
328
+ }
329
+
330
+ if ($this->isDir($file)) {
331
+ $result[] = $file;
332
+ $items = $flatten($this->nlist($file, true, $filter));
333
+
334
+ foreach ($items as $item) {
335
+ $result[] = $item;
336
+ }
337
+
338
+ } else {
339
+ $result[] = $file;
340
+ }
341
+ }
342
+
343
+ $result = array_unique($result);
344
+ $filter($result);
345
+
346
+ return $result;
347
+ }
348
+
349
+ /**
350
+ * Creates a directory.
351
+ *
352
+ * @see FtpClient::rmdir()
353
+ * @see FtpClient::remove()
354
+ * @see FtpClient::put()
355
+ * @see FtpClient::putAll()
356
+ *
357
+ * @param string $directory The directory
358
+ * @param bool $recursive
359
+ * @return bool
360
+ */
361
+ public function mkdir($directory, $recursive = false)
362
+ {
363
+ if (!$recursive or $this->isDir($directory)) {
364
+ return $this->ftp->mkdir($directory);
365
+ }
366
+
367
+ $result = false;
368
+ $pwd = $this->ftp->pwd();
369
+ $parts = explode('/', $directory);
370
+
371
+ foreach ($parts as $part) {
372
+ if ($part == '') {
373
+ continue;
374
+ }
375
+
376
+ if (!@$this->ftp->chdir($part)) {
377
+ $result = $this->ftp->mkdir($part);
378
+ $this->ftp->chdir($part);
379
+ }
380
+ }
381
+
382
+ $this->ftp->chdir($pwd);
383
+
384
+ return $result;
385
+ }
386
+
387
+ /**
388
+ * Remove a directory.
389
+ *
390
+ * @see FtpClient::mkdir()
391
+ * @see FtpClient::cleanDir()
392
+ * @see FtpClient::remove()
393
+ * @see FtpClient::delete()
394
+ * @param string $directory
395
+ * @param bool $recursive Forces deletion if the directory is not empty
396
+ * @return bool
397
+ * @throws FtpException If unable to list the directory to remove
398
+ */
399
+ public function rmdir($directory, $recursive = true)
400
+ {
401
+ if ($recursive) {
402
+ $files = $this->nlist($directory, false, 'rsort');
403
+
404
+ // remove children
405
+ foreach ($files as $file) {
406
+ $this->remove($file, true);
407
+ }
408
+ }
409
+
410
+ // remove the directory
411
+ return $this->ftp->rmdir($directory);
412
+ }
413
+
414
+ /**
415
+ * Empty directory.
416
+ *
417
+ * @see FtpClient::remove()
418
+ * @see FtpClient::delete()
419
+ * @see FtpClient::rmdir()
420
+ *
421
+ * @param string $directory
422
+ * @return bool
423
+ */
424
+ public function cleanDir($directory)
425
+ {
426
+ if (!$files = $this->nlist($directory)) {
427
+ return $this->isEmpty($directory);
428
+ }
429
+
430
+ // remove children
431
+ foreach ($files as $file) {
432
+ $this->remove($file, true);
433
+ }
434
+
435
+ return $this->isEmpty($directory);
436
+ }
437
+
438
+ /**
439
+ * Remove a file or a directory.
440
+ *
441
+ * @see FtpClient::rmdir()
442
+ * @see FtpClient::cleanDir()
443
+ * @see FtpClient::delete()
444
+ * @param string $path The path of the file or directory to remove
445
+ * @param bool $recursive Is effective only if $path is a directory, {@see FtpClient::rmdir()}
446
+ * @return bool
447
+ */
448
+ public function remove($path, $recursive = false)
449
+ {
450
+ if ($path == '.' || $path == '..') {
451
+ return false;
452
+ }
453
+
454
+ try {
455
+ if (@$this->ftp->delete($path)
456
+ or ($this->isDir($path)
457
+ and $this->rmdir($path, $recursive))) {
458
+ return true;
459
+ } else {
460
+ // in special cases the delete can fail (for example, at Symfony's "r+e.gex[c]a(r)s" directory)
461
+ $newPath = preg_replace('/[^A-Za-z0-9\/]/', '', $path);
462
+ if ($this->rename($path, $newPath)) {
463
+ if (@$this->ftp->delete($newPath)
464
+ or ($this->isDir($newPath)
465
+ and $this->rmdir($newPath, $recursive))) {
466
+ return true;
467
+ }
468
+ }
469
+ }
470
+
471
+ return false;
472
+ } catch (\Exception $e) {
473
+ return false;
474
+ }
475
+ }
476
+
477
+ /**
478
+ * Check if a directory exist.
479
+ *
480
+ * @param string $directory
481
+ * @return bool
482
+ * @throws FtpException
483
+ */
484
+ public function isDir($directory)
485
+ {
486
+ $pwd = $this->ftp->pwd();
487
+
488
+ if ($pwd === false) {
489
+ throw new FtpException('Unable to resolve the current directory');
490
+ }
491
+
492
+ if (@$this->ftp->chdir($directory)) {
493
+ $this->ftp->chdir($pwd);
494
+ return true;
495
+ }
496
+
497
+ $this->ftp->chdir($pwd);
498
+
499
+ return false;
500
+ }
501
+
502
+ /**
503
+ * Check if a directory is empty.
504
+ *
505
+ * @param string $directory
506
+ * @return bool
507
+ */
508
+ public function isEmpty($directory)
509
+ {
510
+ return $this->countItems($directory, null, false) === 0 ? true : false;
511
+ }
512
+
513
+ /**
514
+ * Scan a directory and returns the details of each item.
515
+ *
516
+ * @see FtpClient::nlist()
517
+ * @see FtpClient::rawlist()
518
+ * @see FtpClient::parseRawList()
519
+ * @see FtpClient::dirSize()
520
+ * @param string $directory
521
+ * @param bool $recursive
522
+ * @return array
523
+ */
524
+ public function scanDir($directory = '.', $recursive = false)
525
+ {
526
+ return $this->parseRawList($this->rawlist($directory, $recursive));
527
+ }
528
+
529
+ /**
530
+ * Returns the total size of the given directory in bytes.
531
+ *
532
+ * @param string $directory The directory, by default is the current directory.
533
+ * @param bool $recursive true by default
534
+ * @return int The size in bytes.
535
+ */
536
+ public function dirSize($directory = '.', $recursive = true)
537
+ {
538
+ $items = $this->scanDir($directory, $recursive);
539
+ $size = 0;
540
+
541
+ foreach ($items as $item) {
542
+ $size += (int) $item['size'];
543
+ }
544
+
545
+ return $size;
546
+ }
547
+
548
+ /**
549
+ * Count the items (file, directory, link, unknown).
550
+ *
551
+ * @param string $directory The directory, by default is the current directory.
552
+ * @param string|null $type The type of item to count (file, directory, link, unknown)
553
+ * @param bool $recursive true by default
554
+ * @return int
555
+ */
556
+ public function countItems($directory = '.', $type = null, $recursive = true)
557
+ {
558
+ $items = (null === $type ? $this->nlist($directory, $recursive)
559
+ : $this->scanDir($directory, $recursive));
560
+
561
+ $count = 0;
562
+ foreach ($items as $item) {
563
+ if (null === $type or $item['type'] == $type) {
564
+ $count++;
565
+ }
566
+ }
567
+
568
+ return $count;
569
+ }
570
+
571
+ /**
572
+ * Count the items (file, directory, link, unknown).
573
+ * This method call `countItems()` with the default arguments.
574
+ *
575
+ * @see countItems
576
+ * @return int
577
+ */
578
+ public function count(): int
579
+ {
580
+ return $this->countItems();
581
+ }
582
+
583
+ /**
584
+ * Downloads a file from the FTP server into a string
585
+ *
586
+ * @param string $remote_file
587
+ * @param int $mode
588
+ * @param int $resumepos
589
+ * @return string|null
590
+ */
591
+ public function getContent($remote_file, $mode = FTP_BINARY, $resumepos = 0)
592
+ {
593
+ $handle = fopen('php://temp', 'r+');
594
+
595
+ if ($this->ftp->fget($handle, $remote_file, $mode, $resumepos)) {
596
+ rewind($handle);
597
+ return stream_get_contents($handle);
598
+ }
599
+
600
+ return null;
601
+ }
602
+
603
+ /**
604
+ * Uploads a file to the server from a string.
605
+ *
606
+ * @param string $remote_file
607
+ * @param string $content
608
+ * @return FtpClient
609
+ * @throws FtpException When the transfer fails
610
+ */
611
+ public function putFromString($remote_file, $content)
612
+ {
613
+ $handle = fopen('php://temp', 'w');
614
+
615
+ fwrite($handle, $content);
616
+ rewind($handle);
617
+
618
+ if ($this->ftp->fput($remote_file, $handle, FTP_BINARY)) {
619
+ return $this;
620
+ }
621
+
622
+ throw new FtpException('Unable to put the file "'.$remote_file.'"');
623
+ }
624
+
625
+ /**
626
+ * Uploads a file to the server.
627
+ *
628
+ * @param string $local_file
629
+ * @return FtpClient
630
+ * @throws FtpException When the transfer fails
631
+ */
632
+ public function putFromPath($local_file)
633
+ {
634
+ $remote_file = basename($local_file);
635
+ $handle = fopen($local_file, 'r');
636
+
637
+ if ($this->ftp->fput($remote_file, $handle, FTP_BINARY)) {
638
+ rewind($handle);
639
+ return $this;
640
+ }
641
+
642
+ throw new FtpException(
643
+ 'Unable to put the remote file from the local file "'.$local_file.'"'
644
+ );
645
+ }
646
+
647
+ /**
648
+ * Upload files.
649
+ *
650
+ * @param string $source_directory
651
+ * @param string $target_directory
652
+ * @param int $mode
653
+ * @return FtpClient
654
+ */
655
+ public function putAll($source_directory, $target_directory, $mode = FTP_BINARY)
656
+ {
657
+ $d = dir($source_directory);
658
+
659
+ // do this for each file in the directory
660
+ while ($file = $d->read()) {
661
+
662
+ // to prevent an infinite loop
663
+ if ($file != "." && $file != "..") {
664
+
665
+ // do the following if it is a directory
666
+ if (is_dir($source_directory.'/'.$file)) {
667
+ if (!$this->isDir($target_directory.'/'.$file)) {
668
+
669
+ // create directories that do not yet exist
670
+ $this->ftp->mkdir($target_directory.'/'.$file);
671
+ }
672
+
673
+ // recursive part
674
+ $this->putAll(
675
+ $source_directory.'/'.$file, $target_directory.'/'.$file,
676
+ $mode
677
+ );
678
+ } else {
679
+
680
+ // put the files
681
+ $this->ftp->put(
682
+ $target_directory.'/'.$file, $source_directory.'/'.$file,
683
+ $mode
684
+ );
685
+ }
686
+ }
687
+ }
688
+
689
+ $d->close();
690
+
691
+ return $this;
692
+ }
693
+
694
+ /**
695
+ * Downloads all files from remote FTP directory
696
+ *
697
+ * @param string $source_directory The remote directory
698
+ * @param string $target_directory The local directory
699
+ * @param int $mode
700
+ * @return FtpClient
701
+ */
702
+ public function getAll($source_directory, $target_directory, $mode = FTP_BINARY)
703
+ {
704
+ if ($source_directory != ".") {
705
+ if ($this->ftp->chdir($source_directory) == false) {
706
+ throw new FtpException("Unable to change directory: ".$source_directory);
707
+ }
708
+
709
+ if (!(is_dir($target_directory))) {
710
+ mkdir($target_directory);
711
+ }
712
+
713
+ chdir($target_directory);
714
+ }
715
+
716
+ $contents = $this->ftp->nlist(".");
717
+
718
+ foreach ($contents as $file) {
719
+ if ($file == '.' || $file == '..') {
720
+ continue;
721
+ }
722
+
723
+ $this->ftp->get($target_directory."/".$file, $file, $mode);
724
+ }
725
+
726
+ $this->ftp->chdir("..");
727
+ chdir("..");
728
+
729
+ return $this;
730
+ }
731
+
732
+ /**
733
+ * Returns a detailed list of files in the given directory.
734
+ *
735
+ * @see FtpClient::nlist()
736
+ * @see FtpClient::scanDir()
737
+ * @see FtpClient::dirSize()
738
+ * @param string $directory The directory, by default is the current directory
739
+ * @param bool $recursive
740
+ * @return array
741
+ * @throws FtpException
742
+ */
743
+ public function rawlist($directory = '.', $recursive = false)
744
+ {
745
+ if (!$this->isDir($directory)) {
746
+ throw new FtpException('"'.$directory.'" is not a directory.');
747
+ }
748
+
749
+ if (strpos($directory, " ") > 0) {
750
+ $ftproot = $this->ftp->pwd();
751
+ $this->ftp->chdir($directory);
752
+ $list = $this->ftp->rawlist("");
753
+ $this->ftp->chdir($ftproot);
754
+ } else {
755
+ $list = $this->ftp->rawlist($directory);
756
+ }
757
+
758
+ $items = array();
759
+
760
+ if (!$list) {
761
+ return $items;
762
+ }
763
+
764
+ if (false == $recursive) {
765
+ foreach ($list as $path => $item) {
766
+ $chunks = preg_split("/\s+/", $item);
767
+
768
+ // if not "name"
769
+ if (!isset($chunks[8]) || strlen($chunks[8]) === 0 || $chunks[8] == '.' || $chunks[8] == '..') {
770
+ continue;
771
+ }
772
+
773
+ $path = $directory.'/'.$chunks[8];
774
+
775
+ if (isset($chunks[9])) {
776
+ $nbChunks = count($chunks);
777
+
778
+ for ($i = 9; $i < $nbChunks; $i++) {
779
+ $path .= ' '.$chunks[$i];
780
+ }
781
+ }
782
+
783
+
784
+ if (substr($path, 0, 2) == './') {
785
+ $path = substr($path, 2);
786
+ }
787
+
788
+ $items[ $this->rawToType($item).'#'.$path ] = $item;
789
+ }
790
+
791
+ return $items;
792
+ }
793
+
794
+ $path = '';
795
+
796
+ foreach ($list as $item) {
797
+ $len = strlen($item);
798
+
799
+ if (!$len
800
+
801
+ // "."
802
+ || ($item[$len-1] == '.' && $item[$len-2] == ' '
803
+
804
+ // ".."
805
+ or $item[$len-1] == '.' && $item[$len-2] == '.' && $item[$len-3] == ' ')
806
+ ) {
807
+
808
+ continue;
809
+ }
810
+
811
+ $chunks = preg_split("/\s+/", $item);
812
+
813
+ // if not "name"
814
+ if (!isset($chunks[8]) || strlen($chunks[8]) === 0 || $chunks[8] == '.' || $chunks[8] == '..') {
815
+ continue;
816
+ }
817
+
818
+ $path = $directory.'/'.$chunks[8];
819
+
820
+ if (isset($chunks[9])) {
821
+ $nbChunks = count($chunks);
822
+
823
+ for ($i = 9; $i < $nbChunks; $i++) {
824
+ $path .= ' '.$chunks[$i];
825
+ }
826
+ }
827
+
828
+ if (substr($path, 0, 2) == './') {
829
+ $path = substr($path, 2);
830
+ }
831
+
832
+ $items[$this->rawToType($item).'#'.$path] = $item;
833
+
834
+ if ($item[0] == 'd') {
835
+ $sublist = $this->rawlist($path, true);
836
+
837
+ foreach ($sublist as $subpath => $subitem) {
838
+ $items[$subpath] = $subitem;
839
+ }
840
+ }
841
+ }
842
+
843
+ return $items;
844
+ }
845
+
846
+ /**
847
+ * Parse raw list.
848
+ *
849
+ * @see FtpClient::rawlist()
850
+ * @see FtpClient::scanDir()
851
+ * @see FtpClient::dirSize()
852
+ * @param array $rawlist
853
+ * @return array
854
+ */
855
+ public function parseRawList(array $rawlist)
856
+ {
857
+ $items = array();
858
+ $path = '';
859
+
860
+ foreach ($rawlist as $key => $child) {
861
+ $chunks = preg_split("/\s+/", $child, 9);
862
+
863
+ if (isset($chunks[8]) && ($chunks[8] == '.' or $chunks[8] == '..')) {
864
+ continue;
865
+ }
866
+
867
+ if (count($chunks) === 1) {
868
+ $len = strlen($chunks[0]);
869
+
870
+ if ($len && $chunks[0][$len-1] == ':') {
871
+ $path = substr($chunks[0], 0, -1);
872
+ }
873
+
874
+ continue;
875
+ }
876
+
877
+ // Prepare for filename that has space
878
+ $nameSlices = array_slice($chunks, 8, true);
879
+
880
+ $item = [
881
+ 'permissions' => $chunks[0],
882
+ 'number' => $chunks[1],
883
+ 'owner' => $chunks[2],
884
+ 'group' => $chunks[3],
885
+ 'size' => $chunks[4],
886
+ 'month' => $chunks[5],
887
+ 'day' => $chunks[6],
888
+ 'time' => $chunks[7],
889
+ 'name' => implode(' ', $nameSlices),
890
+ 'type' => $this->rawToType($chunks[0]),
891
+ ];
892
+
893
+ if ($item['type'] == 'link' && isset($chunks[10])) {
894
+ $item['target'] = $chunks[10]; // 9 is "->"
895
+ }
896
+
897
+ // if the key is not the path, behavior of ftp_rawlist() PHP function
898
+ if (is_int($key) || false === strpos($key, $item['name'])) {
899
+ array_splice($chunks, 0, 8);
900
+
901
+ $key = $item['type'].'#'
902
+ .($path ? $path.'/' : '')
903
+ .implode(' ', $chunks);
904
+
905
+ if ($item['type'] == 'link') {
906
+ // get the first part of 'link#the-link.ext -> /path/of/the/source.ext'
907
+ $exp = explode(' ->', $key);
908
+ $key = rtrim($exp[0]);
909
+ }
910
+
911
+ $items[$key] = $item;
912
+ } else {
913
+ // the key is the path, behavior of FtpClient::rawlist() method()
914
+ $items[$key] = $item;
915
+ }
916
+ }
917
+
918
+ return $items;
919
+ }
920
+
921
+ /**
922
+ * Convert raw info (drwx---r-x ...) to type (file, directory, link, unknown).
923
+ * Only the first char is used for resolving.
924
+ *
925
+ * @param string $permission Example : drwx---r-x
926
+ *
927
+ * @return string The file type (file, directory, link, unknown)
928
+ * @throws FtpException
929
+ */
930
+ public function rawToType($permission)
931
+ {
932
+ if (!is_string($permission)) {
933
+ throw new FtpException('The "$permission" argument must be a string, "'
934
+ .gettype($permission).'" given.');
935
+ }
936
+
937
+ if (empty($permission[0])) {
938
+ return 'unknown';
939
+ }
940
+
941
+ switch ($permission[0]) {
942
+ case '-':
943
+ return 'file';
944
+
945
+ case 'd':
946
+ return 'directory';
947
+
948
+ case 'l':
949
+ return 'link';
950
+
951
+ default:
952
+ return 'unknown';
953
+ }
954
+ }
955
+
956
+ /**
957
+ * Set the wrapper which forward the PHP FTP functions to use in FtpClient instance.
958
+ *
959
+ * @param FtpWrapper $wrapper
960
+ * @return FtpClient
961
+ */
962
+ protected function setWrapper(FtpWrapper $wrapper)
963
+ {
964
+ $this->ftp = $wrapper;
965
+
966
+ return $this;
967
+ }
968
+ }
V5/FTP/FtpException.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This file is part of the `nicolab/php-ftp-client` package.
4
+ *
5
+ * (c) Nicolas Tallefourtane <dev@nicolab.net>
6
+ *
7
+ * For the full copyright and license information, please view the LICENSE
8
+ * file that was distributed with this source code.
9
+ *
10
+ * @copyright Nicolas Tallefourtane http://nicolab.net
11
+ */
12
+ namespace CTXFeed\V5\FTP;
13
+
14
+ use Exception;
15
+
16
+ /**
17
+ * The FtpException class.
18
+ * Exception thrown if an error on runtime of the FTP client occurs.
19
+ *
20
+ * @inheritDoc
21
+ * @author Nicolas Tallefourtane <dev@nicolab.net>
22
+ */
23
+ class FtpException extends Exception {}
V5/FTP/FtpWrapper.php ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This file is part of the `nicolab/php-ftp-client` package.
4
+ *
5
+ * (c) Nicolas Tallefourtane <dev@nicolab.net>
6
+ *
7
+ * For the full copyright and license information, please view the LICENSE
8
+ * file that was distributed with this source code.
9
+ *
10
+ * @copyright Nicolas Tallefourtane http://nicolab.net
11
+ */
12
+ namespace CTXFeed\V5\FTP;
13
+
14
+ /**
15
+ * Wrap the PHP FTP functions
16
+ *
17
+ * @method bool alloc(int $filesize, string &$result = null) Allocates space for a file to be uploaded
18
+ * @method bool cdup() Changes to the parent directory
19
+ * @method bool chdir(string $directory) Changes the current directory on a FTP server
20
+ * @method int chmod(int $mode, string $filename) Set permissions on a file via FTP
21
+ * @method bool close() Closes an FTP connection
22
+ * @method bool delete(string $path) Deletes a file on the FTP server
23
+ * @method bool exec(string $command) Requests execution of a command on the FTP server
24
+ * @method bool fget(resource $handle, string $remote_file, int $mode, int $resumepos = 0) Downloads a file from the FTP server and saves to an open file
25
+ * @method bool fput(string $remote_file, resource $handle, int $mode, int $startpos = 0) Uploads from an open file to the FTP server
26
+ * @method mixed get_option(int $option) Retrieves various runtime behaviours of the current FTP stream
27
+ * @method bool get(string $local_file, string $remote_file, int $mode, int $resumepos = 0) Downloads a file from the FTP server
28
+ * @method bool login(string $username, string $password) Logs in to an FTP connection
29
+ * @method int mdtm(string $remote_file) Returns the last modified time of the given file
30
+ * @method bool mkdir(string $directory) Creates a directory
31
+ * @method array mlsd(string $remote_dir) Returns a list of files in the given directory
32
+ * @method int nb_continue() Continues retrieving/sending a file (non-blocking)
33
+ * @method int nb_fget(resource $handle, string $remote_file, int $mode, int $resumepos = 0) Retrieves a file from the FTP server and writes it to an open file (non-blocking)
34
+ * @method int nb_fput(string $remote_file, resource $handle, int $mode, int $startpos = 0) Stores a file from an open file to the FTP server (non-blocking)
35
+ * @method int nb_get(string $local_file, string $remote_file, int $mode, int $resumepos = 0) Retrieves a file from the FTP server and writes it to a local file (non-blocking)
36
+ * @method int nb_put(string $remote_file, string $local_file, int $mode, int $startpos = 0) Stores a file on the FTP server (non-blocking)
37
+ * @method array nlist(string $directory) Returns a list of file names in the given directory; remote_dir parameter may also include arguments
38
+ * @method bool pasv(bool $pasv) Turns passive mode on or off
39
+ * @method bool put(string $remote_file, string $local_file, int $mode, int $startpos = 0) Uploads a file to the FTP server
40
+ * @method string pwd() Returns the current directory name
41
+ * @method bool quit() Closes an FTP connection
42
+ * @method array raw(string $command) Sends an arbitrary command to an FTP server
43
+ * @method array rawlist(string $directory, bool $recursive = false) Returns a detailed list of files in the given directory
44
+ * @method bool rename(string $oldname, string $newname) Renames a file or a directory on the FTP server
45
+ * @method bool rmdir(string $directory) Removes a directory
46
+ * @method bool set_option(int $option, mixed $value) Set miscellaneous runtime FTP options
47
+ * @method bool site(string $command) Sends a SITE command to the server
48
+ * @method int size(string $remote_file) Returns the size of the given file
49
+ * @method string systype() Returns the system type identifier of the remote FTP server
50
+ *
51
+ * @author Nicolas Tallefourtane <dev@nicolab.net>
52
+ */
53
+ class FtpWrapper
54
+ {
55
+ /**
56
+ * The connection with the server
57
+ *
58
+ * @var resource
59
+ */
60
+ protected $conn;
61
+
62
+ /**
63
+ * Constructor.
64
+ *
65
+ * @param resource &$connection The FTP (or SSL-FTP) connection (takes by reference).
66
+ */
67
+ public function __construct(&$connection)
68
+ {
69
+ $this->conn = &$connection;
70
+ }
71
+
72
+ /**
73
+ * Forward the method call to FTP functions
74
+ *
75
+ * @param string $function
76
+ * @param array $arguments
77
+ * @return mixed
78
+ * @throws FtpException When the function is not valid
79
+ */
80
+ public function __call($function, array $arguments)
81
+ {
82
+ $function = 'ftp_' . $function;
83
+
84
+ if (function_exists($function)) {
85
+ array_unshift($arguments, $this->conn);
86
+ return @call_user_func_array($function, $arguments);
87
+ }
88
+
89
+ throw new FtpException("{$function} is not a valid FTP function");
90
+ }
91
+
92
+ /**
93
+ * Opens a FTP connection
94
+ *
95
+ * @param string $host
96
+ * @param int $port
97
+ * @param int $timeout
98
+ * @return resource
99
+ */
100
+ public function connect($host, $port = 21, $timeout = 90)
101
+ {
102
+ return @ftp_connect($host, $port, $timeout);
103
+ }
104
+
105
+ /**
106
+ * Opens a Secure SSL-FTP connection
107
+ * @param string $host
108
+ * @param int $port
109
+ * @param int $timeout
110
+ * @return resource
111
+ */
112
+ public function ssl_connect($host, $port = 21, $timeout = 90)
113
+ {
114
+ return @ftp_ssl_connect($host, $port, $timeout);
115
+ }
116
+ }
V5/FTP/info.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ https://github.com/lazzard/php-ftp-client
2
+ https://github.com/altayalp/php-ftp-client
3
+ https://github.com/Nicolab/php-ftp-client
V5/Feed/Custom2Feed.php ADDED
@@ -0,0 +1,403 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Feed;
4
+
5
+ use CTXFeed\V5\Output\FormatOutput;
6
+ use CTXFeed\V5\Utility\Config;
7
+ use CTXFeed\V5\File\FileFactory;
8
+ use CTXFeed\V5\Helper\FeedHelper;
9
+ use CTXFeed\V5\Helper\ProductHelper;
10
+ use CTXFeed\V5\Product\AttributeValueByType;
11
+ use CTXFeed\V5\Product\ProductFactory;
12
+ use CTXFeed\V5\Product\ProductInfo;
13
+ use CTXFeed\V5\Utility\Settings;
14
+
15
+ class Custom2Feed implements FeedInterface {
16
+ /**
17
+ * @var Config $config Contain Feed Config.
18
+ */
19
+ private $config;
20
+ /**
21
+ * @var array $ids Contain Product Ids.
22
+ */
23
+ private $ids;
24
+ /**
25
+ * @var array $structure Contain Feed Structure.
26
+ */
27
+ private $structure;
28
+
29
+ private $feedHeader;
30
+ /**
31
+ * This variable is responsible for holding feed string
32
+ *
33
+ * @since 1.0.0
34
+ * @var string $feedString Contains feed information
35
+ * @access public
36
+ */
37
+ private $feedString;
38
+ private $feedFooter;
39
+ private $s;
40
+ private $productEngine;
41
+ private $variationElementsStart;
42
+
43
+ public function __construct( $ids, $config ) {
44
+ $this->ids = $ids;
45
+ $this->config = $config;
46
+ $getStructure = FeedFactory::get_structure( $config );
47
+ $this->structure = $getStructure['structure'];
48
+ $this->variationElementsStart = $getStructure['variationElementsStart'];
49
+ }
50
+
51
+ /**
52
+ * Get Feed Body.
53
+ *
54
+ * @return string
55
+ */
56
+ public function get_feed() {
57
+ // $feed = ProductFactory::get_content( $this->ids, $this->config ,$this->structure);
58
+ // $feed = $feed->make_body();
59
+ //
60
+ // return self::removeHeaderFooter( $feed );
61
+
62
+ // Get XML Elements from feed config
63
+ $Elements = $this->structure;
64
+
65
+ if ( ! empty( $this->structure ) && ! empty( $this->ids ) ) {
66
+ foreach ( $this->ids as $pid ) {
67
+ $product = wc_get_product( $pid );
68
+ $this->productEngine = new ProductInfo( $product, $this->config );
69
+ //TODO: PRODUCT VALIDATION AND FILTER IMPLEMENTATION
70
+
71
+
72
+ //TODO Filter products by Condition
73
+ // if (isset($this->config['fattribute']) && count($this->config['fattribute']) && !$this->productEngine->filter_product($product)) {
74
+
75
+
76
+ // Start making XML Elements
77
+ foreach ( $Elements as $each => $element ) {
78
+
79
+
80
+ if ( $each === $this->variationElementsStart && $product->is_type( 'variable' ) && $product->has_child() ) {
81
+
82
+ $variations = $product->get_children();
83
+ foreach ( $variations as $variation ) {
84
+ $variation = wc_get_product( $variation );
85
+ foreach ( $Elements as $variationElement ) {
86
+ if ( $variationElement['for'] === 'variation' ) {
87
+ // $element['elementTextInfo'] = '';
88
+ // $element['attr_type'] = 'text';
89
+ // $element['attr_value'] = $image;
90
+ // unset( $variationElement['attr_code'] );
91
+ $this->feedString .= $this->make_xml_element( $variationElement, $variation );
92
+ }
93
+ }
94
+ }
95
+
96
+ }
97
+
98
+ if ( $element['for'] === 'variation' ) {
99
+ continue;
100
+ }
101
+
102
+ if ( $element['for'] === 'ifVariationAvailable' && $product->get_type() !== 'variable' ) {
103
+ continue;
104
+ }
105
+
106
+ if ( $element['for'] === 'images' && isset( $element['attr_code'] ) ) {
107
+ $images = $this->productEngine->custom_xml_images( $product );
108
+ if ( ! empty( $images ) ) {
109
+ foreach ( $images as $image ) {
110
+ $element['elementTextInfo'] = $image;
111
+ $element['attr_type'] = 'text';
112
+ $element['attr_value'] = $image;
113
+ unset( $element['attr_code'] );
114
+ $this->feedString .= $this->make_xml_element( $element, $product );
115
+ }
116
+ }
117
+ } elseif ( $element['for'] === 'categories' && isset( $element['attr_code'] ) ) {
118
+ $categories = $this->productEngine->custom_xml_categories( $product );
119
+ if ( ! empty( $categories ) ) {
120
+ foreach ( $categories as $category ) {
121
+ $element['elementTextInfo'] = $category;
122
+ $element['attr_type'] = 'text';
123
+ $element['attr_value'] = $category;
124
+ unset( $element['attr_code'] );
125
+ $this->feedString .= $this->make_xml_element( $element, $product );
126
+ }
127
+ }
128
+ } else {
129
+ $this->feedString .= $this->make_xml_element( $element, $product );
130
+ }
131
+ }
132
+
133
+ }
134
+ }
135
+
136
+ return $this->feedString;
137
+ }
138
+
139
+ /**
140
+ * Get Feed Header.
141
+ *
142
+ * @return string
143
+ */
144
+ public function get_header() {
145
+ $getHeader = explode( '{{each product start}}', $this->config->feed_config_custom2 );
146
+ $header = trim( $getHeader[0] );
147
+ $getNodes = explode( "\n", $header );
148
+
149
+ if ( ! empty( $getNodes ) ) {
150
+ foreach ( $getNodes as $value ) {
151
+ // Add header info to feed file
152
+ $value = preg_replace( '/\\\\/', '', $value );
153
+ if ( strpos( $value, 'return' ) !== false ) {
154
+ $return = woo_feed_get_string_between( $value, '{(', ')}' );
155
+ $return_value = $this->process_eval( $return );
156
+ $value = preg_replace( '/\{\(.*?\)\}/', $return_value, $value );
157
+ }
158
+ $this->feedHeader .= $value;
159
+ $this->s += 2;
160
+ }
161
+ } else {
162
+ $this->feedHeader .= '<?xml version="1.0" encoding="utf-8" ?>' . "\n";
163
+ }
164
+
165
+ return $this->feedHeader;
166
+ }
167
+
168
+ /**
169
+ * Get Feed Footer.
170
+ *
171
+ * @return string
172
+ */
173
+ public function get_footer() {
174
+ $getFooter = explode( '{{each product end}}', $this->config->feed_config_custom2 );
175
+ $getNodes = explode( "\n", $getFooter[1] );
176
+ if ( ! empty( $getNodes ) ) {
177
+ foreach ( $getNodes as $value ) {
178
+ $this->s -= 2;
179
+ // Add header info to feed file
180
+ $this->feedFooter .= $value;
181
+ }
182
+ }
183
+
184
+ return $this->feedFooter;
185
+ }
186
+
187
+ /**
188
+ * @param $element
189
+ * @param $product
190
+ *
191
+ * @return string
192
+ */
193
+ public function make_xml_element( $element, $product ) {
194
+ $p = false;
195
+ $string = '';
196
+ $start = '';
197
+ $end = '';
198
+ $output = '';
199
+
200
+
201
+ $this->productEngine = new ProductInfo( $product, $this->config );
202
+
203
+ // Start XML Element
204
+ if (
205
+ empty( $element['elementTextInfo'] ) && // Get the root element.
206
+ empty( $element['end'] ) &&
207
+ 6 === count( $element )
208
+ ) {
209
+
210
+ // Start XML Element
211
+ $elementStart = $this->processStartingElement( $element, $product );
212
+
213
+ $end .= '<' . $elementStart . '>';
214
+ $string .= $end . "\n";
215
+ $p = true;
216
+ } elseif ( ! empty( $element['start'] ) ) {
217
+ $elementStart = $this->processStartingElement( $element, $product );
218
+ $start .= '<' . $elementStart . '>';
219
+ }
220
+
221
+ // Make XML Element Text
222
+ if ( ! empty( $element['elementTextInfo'] ) ) {
223
+ if ( 'attribute' === $element['attr_type'] ) {
224
+ $output = ProductHelper::getAttributeValueByType( $element['attr_code'], $product, $this->config );
225
+ $output = ProductHelper::str_replace( $output, $element['attr_code'], $this->config );
226
+ } elseif ( 'return' === $element['attr_type'] ) {
227
+ $output = $this->getReturnTypeValue( $element, $product );
228
+ } elseif ( 'php' === $element['attr_type'] ) {
229
+ if ( isset( $element['to_return'] ) && ! empty( $element['to_return'] ) ) {
230
+ $output = $this->returnPHPFunction( $element['to_return'] );
231
+ }
232
+ } elseif ( 'text' === $element['attr_type'] ) {
233
+ $output = ( isset( $element['attr_value'] ) && ! empty( $element['attr_value'] ) ) ? $element['attr_value'] : '';
234
+ }
235
+
236
+ $pluginAttribute = null;
237
+ if ( 'attribute' === $element['attr_type'] ) {
238
+ $pluginAttribute = $element['attr_code'];
239
+ }
240
+
241
+ // Format output according to commands
242
+ if ( array_key_exists( 'formatter', $element ) ) {
243
+ $formatOutput = new FormatOutput( $product, $this->config, $pluginAttribute );
244
+ $output = $formatOutput->process_command( $output, $element['formatter'] );
245
+ }
246
+ $p = false;
247
+ }
248
+
249
+ // End XML Element
250
+ if ( '/' . $element['end'] === $element['start'] && empty( $element['elementTextInfo'] ) && 6 === count( $element ) ) {
251
+ if ( ! empty( $element['end'] ) ) {
252
+ $end .= '<' . $element['start'] . '>';
253
+ }
254
+ $string .= $end . "\n";
255
+ $p = true;
256
+ } else if ( ! empty( $element['end'] ) ) {
257
+ $end .= '</' . $element['end'] . ">\n";
258
+ }
259
+
260
+ if ( ! $p ) {
261
+ // Add Prefix and Suffix
262
+ $prefix = isset( $element['prefix'] ) ? preg_replace( '!\s+!', ' ', $element['prefix'] ) : '';
263
+ $suffix = isset( $element['suffix'] ) ? preg_replace( '!\s+!', ' ', $element['suffix'] ) : '';
264
+ // $output = $this->productEngine->process_prefix_suffix( $output, $prefix, $suffix, isset( $element['attr_code'] ) ? $element['attr_code'] : '' );
265
+
266
+ // Add CDATA if needed
267
+ if ( ! empty( $output ) ) {
268
+ $output = $this->addCDATA( $element['include_cdata'], $output );
269
+ }
270
+
271
+ $string .= $start . $output . $end;
272
+ $p = false;
273
+ }
274
+
275
+ return $string;
276
+ }
277
+
278
+
279
+ /**
280
+ * Add Quotation mark to store code value.
281
+ *
282
+ * @return string
283
+ */
284
+ public function addQuotation( $string ) {
285
+ return "'" . str_replace( array( "'", "\"", "&quot;" ), "", htmlspecialchars( $string ) ) . "'";
286
+ }
287
+
288
+ /**
289
+ * Remove Quotation mark from xml element.
290
+ *
291
+ * @return string
292
+ */
293
+ public function removeQuotation( $string ) {
294
+ return str_replace( array( "'", "\"", "&quot;" ), "", $string );
295
+ }
296
+
297
+ /**
298
+ * Extract Start Code attributes value and replace.
299
+ *
300
+ * @param $element
301
+ * @param $product
302
+ *
303
+ * @return array|string
304
+ */
305
+ public function processStartingElement( $element, $product ) {
306
+ $elementStart = stripslashes( $element['start'] );
307
+ if ( ! empty( $element['start_code'] ) ) {
308
+ $start_attr_codes = array();
309
+ foreach ( $element['start_code'] as $attrValue ) {
310
+ if ( strpos( $attrValue, 'return' ) !== false ) {
311
+ $start_attr_code = woo_feed_get_string_between( $attrValue, '{(', ')}' );
312
+ $tempAttribute = array(
313
+ 'to_return' => $start_attr_code,
314
+ 'attr' => $attrValue,
315
+ );
316
+ $start_attr_code = $this->getReturnTypeValue( $tempAttribute, $product );
317
+ $start_attr_codes[ stripslashes( $attrValue ) ] = $this->addQuotation( $start_attr_code );
318
+
319
+ } else {
320
+ $start_attr_code = woo_feed_get_string_between( $attrValue, '{', '}' );
321
+ $start_attr_code = $this->getAttributeTypeAndValue( $start_attr_code, $product );
322
+ $start_attr_codes[ $attrValue ] = $this->addQuotation( $start_attr_code );
323
+
324
+ }
325
+ }
326
+ $elementStart = str_replace( array_keys( $start_attr_codes ), array_values( $start_attr_codes ), $elementStart );
327
+ }
328
+
329
+ return $elementStart;
330
+ }
331
+
332
+
333
+ public function process_eval( $attribute ) {
334
+ $return = preg_replace( '/\\\\/', '', $attribute );
335
+
336
+ return eval( $return );
337
+ }
338
+
339
+ public function getReturnTypeValue( $attribute, $product ) {
340
+ $variables = array();
341
+ if ( ! empty( $attribute ) && strpos( $attribute['to_return'], '$' ) !== false ) {
342
+ $pattern = '/\$\S+/';
343
+ preg_match_all( $pattern, $attribute['to_return'], $matches, PREG_SET_ORDER );
344
+ $matches = array_column( $matches, 0 );
345
+ foreach ( $matches as $variable ) {
346
+ if ( strpos( $variable, '$' ) !== false ) {
347
+ $variable = str_replace( array( '$', ';' ), '', $variable );
348
+ $attribute['attr_code'] = $variable;
349
+ $variables[ $attribute['attr_code'] ] = $this->getAttributeTypeAndValue( $attribute['attr_code'], $product );
350
+ }
351
+ }
352
+ }
353
+
354
+ extract( $variables, EXTR_OVERWRITE ); // phpcs:ignore
355
+ $return = $attribute['to_return'];
356
+ $return = preg_replace( '/\\\\/', '', $return );
357
+
358
+ return eval( $return );
359
+ }
360
+
361
+ public function getAttributeTypeAndValue( $attribute, $product ) {
362
+
363
+ return ProductHelper::getAttributeValueByType( $attribute, $product, $this->config );
364
+
365
+ }
366
+
367
+ /** Return the php function of the attribute
368
+ *
369
+ * @param $function
370
+ *
371
+ * @return mixed
372
+ */
373
+ private function returnPHPFunction( $function ) {
374
+ return $function;
375
+ }
376
+
377
+ /** Add CDATA to String
378
+ *
379
+ * @param string $status
380
+ * @param string $output
381
+ *
382
+ * @return string
383
+ */
384
+ private function addCDATA( $status, $output ) {
385
+ if ( 'yes' === $status ) {
386
+ $output = $this->removeCDATA( $output );
387
+
388
+ return '<![CDATA[' . $output . ']]>';
389
+ }
390
+
391
+ return $output;
392
+ }
393
+
394
+ /** Remove CDATA from String
395
+ *
396
+ * @param string $output
397
+ *
398
+ * @return string
399
+ */
400
+ private function removeCDATA( $output ) {
401
+ return str_replace( [ "<![CDATA[", "]]>" ], "", $output );
402
+ }
403
+ }
V5/Feed/CustomFeed.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Feed;
3
+ use CTXFeed\V5\File\FileFactory;
4
+ use CTXFeed\V5\Product\ProductFactory;
5
+ use CTXFeed\V5\Utility\Config;
6
+
7
+ class CustomFeed implements FeedInterface {
8
+ /**
9
+ * @var Config $config Contain Feed Config.
10
+ */
11
+ private $config;
12
+ /**
13
+ * @var array $ids Contain Product Ids.
14
+ */
15
+ private $ids;
16
+ /**
17
+ * @var array $structure Contain Feed Structure.
18
+ */
19
+ private $structure;
20
+
21
+ public function __construct( $ids, $config ) {
22
+ $this->ids = $ids;
23
+ $this->config = $config;
24
+ $this->structure = FeedFactory::get_structure( $config );
25
+ }
26
+
27
+ /**
28
+ * Get Feed Body.
29
+ *
30
+ * @return false|string
31
+ */
32
+ public function get_feed() {
33
+ $feed = ProductFactory::get_content( $this->ids, $this->config, $this->structure );
34
+
35
+ return $feed->make_body();
36
+ }
37
+
38
+ /**
39
+ * Get Feed Header.
40
+ *
41
+ * @return mixed
42
+ */
43
+ public function get_header() {
44
+ $feed = FileFactory::GetData( $this->structure, $this->config );
45
+ $feed = $feed->make_header_footer();
46
+
47
+ return $feed['header'];
48
+ }
49
+
50
+ /**
51
+ * Get Feed Footer.
52
+ *
53
+ * @return mixed
54
+ */
55
+ public function get_footer() {
56
+ $feed = FileFactory::GetData( $this->structure, $this->config );
57
+ $feed = $feed->make_header_footer();
58
+
59
+ return $feed['footer'];
60
+ }
61
+ }
V5/Feed/FacebookFeed.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Feed;
3
+ use CTXFeed\V5\File\FileFactory;
4
+ use CTXFeed\V5\Product\ProductFactory;
5
+ use CTXFeed\V5\Utility\Config;
6
+
7
+ class FacebookFeed implements FeedInterface {
8
+ /**
9
+ * @var Config $config Contain Feed Config.
10
+ */
11
+ private $config;
12
+ /**
13
+ * @var array $ids Contain Product Ids.
14
+ */
15
+ private $ids;
16
+ /**
17
+ * @var array $structure Contain Feed Structure.
18
+ */
19
+ private $structure;
20
+
21
+ public function __construct( $ids, $config ) {
22
+ $this->ids = $ids;
23
+ $this->config = $config;
24
+ $this->structure = FeedFactory::get_structure( $config);
25
+ }
26
+
27
+ /**
28
+ * Get Feed Body.
29
+ *
30
+ * @return false|string
31
+ */
32
+ public function get_feed() {
33
+ $feed = ProductFactory::get_content( $this->ids, $this->config, $this->structure );
34
+
35
+ return $feed->make_body();
36
+ }
37
+
38
+ /**
39
+ * Get Feed Header.
40
+ *
41
+ * @return mixed
42
+ */
43
+ public function get_header() {
44
+ $feed = FileFactory::GetData( $this->structure, $this->config );
45
+ $feed = $feed->make_header_footer();
46
+
47
+ return $feed['header'];
48
+ }
49
+
50
+ /**
51
+ * Get Feed Footer.
52
+ *
53
+ * @return mixed
54
+ */
55
+ public function get_footer() {
56
+ $feed = FileFactory::GetData( $this->ids, $this->config );
57
+ $feed = $feed->make_header_footer();
58
+
59
+ return $feed['footer'];
60
+ }
61
+ }
V5/Feed/Feed.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Feed;
3
+ class Feed {
4
+ private $template;
5
+
6
+ public function __construct( FeedInterface $template ) {
7
+ $this->template = $template;
8
+ }
9
+
10
+ public function get_feed() {
11
+ return $this->template->get_feed();
12
+ }
13
+
14
+ public function get_header() {
15
+ return $this->template->get_header();
16
+ }
17
+
18
+ public function get_footer() {
19
+ return $this->template->get_footer();
20
+ }
21
+
22
+ }
V5/Feed/FeedFactory.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Feed;
3
+ use CTXFeed\V5\Utility\Config;
4
+ use CTXFeed\V5\Structure\CustomStructure;
5
+
6
+ class FeedFactory {
7
+
8
+ public static function MakeFeed( $ids, $config ) {
9
+ $class = "\CTXFeed\V5\Feed\\".ucfirst( $config->get_feed_template() ) . 'Feed';
10
+
11
+ if ( ! class_exists( $class ) && in_array( $config->provider, self::get_grouped_templates(), true ) ) {
12
+ $class = array_search( $config->provider, self::get_grouped_templates(), true );
13
+
14
+ return new Feed( new $class( $ids, $config ) );
15
+ }
16
+
17
+ if ( class_exists( $class ) ) {
18
+ return new Feed( new $class( $ids, $config ) );
19
+ }
20
+
21
+ return new Feed( new CustomFeed( $ids, $config ) );
22
+ }
23
+
24
+ public static function get_structure( $config ) {
25
+
26
+ $template = ucfirst( str_replace( [ '_', '.' ], '', $config->provider ) );
27
+ $file_type = strtoupper( $config->feedType );
28
+ $class = "\CTXFeed\V5\Structure\\".$template . 'Structure';
29
+ $method = 'get' . $file_type . 'Structure';
30
+
31
+ if ( class_exists( $class ) && method_exists( $class, $method ) ) {
32
+ return ( new $class( $config ) )->$method();
33
+ }
34
+
35
+ return ( new CustomStructure( $config ) )->$method();
36
+ }
37
+
38
+ public static function get_feed_config( $config ) {
39
+ return new Config( $config );
40
+ }
41
+
42
+ public static function get_grouped_templates() {
43
+ return [
44
+ 'google' => [ 'google_shopping_action', 'google_local', 'google_local_inventory' ],
45
+ 'custom2' => [ 'custom2', 'admarkt', 'yandex_xml', 'glami' ],
46
+ 'pinterest' => [ 'pinterest', 'pinterest_rss' ],
47
+ ];
48
+ }
49
+ }
V5/Feed/FeedInterface.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Feed;
3
+ interface FeedInterface {
4
+ public function get_feed( );
5
+ public function get_header( );
6
+ public function get_footer( );
7
+ }
8
+
V5/Feed/GoogleFeed.php ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Feed;
4
+
5
+ use CTXFeed\V5\File\FileFactory;
6
+ use CTXFeed\V5\Filter\ValidateProduct;
7
+ use CTXFeed\V5\Helper\ProductHelper;
8
+ use CTXFeed\V5\Product\ProductFactory;
9
+ use CTXFeed\V5\Utility\Config;
10
+ use CTXFeed\V5\Utility\Logs;
11
+
12
+ class GoogleFeed implements FeedInterface {
13
+ /**
14
+ * @var Config $config Contain Feed Config.
15
+ */
16
+ private $config;
17
+ /**
18
+ * @var array $ids Contain Product Ids.
19
+ */
20
+ private $ids;
21
+ /**
22
+ * @var array $structure Contain Feed Structure.
23
+ */
24
+ private $structure;
25
+
26
+ public function __construct( $ids, $config ) {
27
+ $this->ids = $ids;
28
+ $this->config = $config;
29
+ $this->structure = FeedFactory::get_structure( $config );
30
+ }
31
+
32
+ /**
33
+ * Get Feed Body.
34
+ *
35
+ * @return false|string
36
+ */
37
+ public function get_feed() {
38
+ $feed = ProductFactory::get_content( $this->ids, $this->config, $this->structure );
39
+
40
+ return $feed->make_body();
41
+ }
42
+
43
+ /**
44
+ * Get Feed Header.
45
+ *
46
+ * @return mixed
47
+ */
48
+ public function get_header() {
49
+ $feed = FileFactory::GetData( $this->structure, $this->config );
50
+ $feed = $feed->make_header_footer();
51
+
52
+ return $feed['header'];
53
+ }
54
+
55
+ /**
56
+ * Get Feed Footer.
57
+ *
58
+ * @return mixed
59
+ */
60
+ public function get_footer() {
61
+ $feed = FileFactory::GetData( $this->ids, $this->config );
62
+ $feed = $feed->make_header_footer();
63
+
64
+ return $feed['footer'];
65
+ }
66
+
67
+ /**
68
+ * @param $ids
69
+ * @param $config
70
+ * @param $structure
71
+ *
72
+ * @return \CTXFeed\V5\File\FileInfo
73
+ */
74
+ // private function get_content( $ids, $config, $structure ) {
75
+ // $info = [];
76
+ // Logs::log_feed_process( $config->filename, 'Getting Products Information.' );
77
+ // Logs::log_feed_process( $config->filename, 'Validating Product' );
78
+ //
79
+ // foreach ( $ids as $id ) {
80
+ // $product = wc_get_product( $id );
81
+ //
82
+ // // Validate Product and add for feed.
83
+ // if ( ValidateProduct::is_valid( $product, $config, $id ) ) {
84
+ // $info1 = [];
85
+ // $info [] = $this->get_product_info( $product, $structure, $config, $info1 );
86
+ // }
87
+ // }
88
+ //
89
+ // return FileFactory::GetData( $info, $config );
90
+ // }
91
+
92
+ /**
93
+ * @param $product
94
+ * @param $structure
95
+ * @param $config
96
+ * @param $info
97
+ *
98
+ * @return array
99
+ */
100
+ // private function get_product_info( $product, $structure, $config, $info ) {
101
+ // if ( is_array( $structure ) ) {
102
+ // foreach ( $structure as $key => $attribute ) {
103
+ // if ( is_array( $attribute ) ) {
104
+ // $value[ $key ] = $this->get_product_info( $product, $attribute, $config, $info );
105
+ // } else {
106
+ // $getValue ="";
107
+ //// if(strpos($attribute,':')){
108
+ ////
109
+ //// }else{
110
+ ////
111
+ //// }
112
+ // $value[ $key ] = ProductHelper::getAttributeValueByType( $attribute, $product, $config );
113
+ // }
114
+ // }
115
+ // } else {
116
+ // return $info;
117
+ // }
118
+ //
119
+ // return $value;
120
+ // }
121
+ }
V5/Feed/GoogleReviewFeed.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Feed;
3
+ //TODO: Google Review Implementation
4
+ use CTXFeed\V5\Utility\Config;
5
+ use CTXFeed\V5\File\FileFactory;
6
+ use CTXFeed\V5\Product\ProductFactory;
7
+
8
+ class GoogleReviewFeed implements FeedInterface {
9
+ /**
10
+ * @var Config $config Contain Feed Config.
11
+ */
12
+ private $config;
13
+ /**
14
+ * @var array $ids Contain Product Ids.
15
+ */
16
+ private $ids;
17
+ /**
18
+ * @var mixed
19
+ */
20
+ private $structure;
21
+
22
+ public function __construct( $ids, $config ) {
23
+ $this->ids = $ids;
24
+ $this->config = $config;
25
+ $this->structure = FeedFactory::get_structure( $config);
26
+ }
27
+
28
+ /**
29
+ * Get Feed Body.
30
+ *
31
+ * @return false|string
32
+ */
33
+ public function get_feed() {
34
+ $feed = ProductFactory::get_content( $this->ids, $this->config,$this->structure );
35
+
36
+ return $feed->make_body();
37
+ }
38
+
39
+ /**
40
+ * Get Feed Header.
41
+ *
42
+ * @return mixed
43
+ */
44
+ public function get_header() {
45
+ $feed = FileFactory::GetData( $this->structure, $this->config );
46
+ $feed = $feed->make_header_footer();
47
+
48
+ return $feed['header'];
49
+ }
50
+
51
+ /**
52
+ * Get Feed Footer.
53
+ *
54
+ * @return mixed
55
+ */
56
+ public function get_footer() {
57
+ $feed = FileFactory::GetData( $this->ids, $this->config );
58
+ $feed = $feed->make_header_footer();
59
+
60
+ return $feed['footer'];
61
+ }
62
+ }
V5/Feed/PinterestFeed.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Feed;
3
+ use CTXFeed\V5\Utility\Config;
4
+ use CTXFeed\V5\File\FileFactory;
5
+ use CTXFeed\V5\Product\ProductFactory;
6
+
7
+ class PinterestFeed implements FeedInterface {
8
+ /**
9
+ * @var Config $config Contain Feed Config.
10
+ */
11
+ private $config;
12
+ /**
13
+ * @var array $ids Contain Product Ids.
14
+ */
15
+ private $ids;
16
+ /**
17
+ * @var array $structure Contain Feed Structure.
18
+ */
19
+ private $structure;
20
+
21
+ public function __construct( $ids, $config ) {
22
+ $this->ids = $ids;
23
+ $this->config = $config;
24
+ $this->structure = FeedFactory::get_structure( $config );
25
+ }
26
+
27
+ /**
28
+ * Get Feed Body.
29
+ *
30
+ * @return false|string
31
+ */
32
+ public function get_feed() {
33
+ $feed = ProductFactory::get_content( $this->ids, $this->config, $this->structure );
34
+
35
+ return $feed->make_body();
36
+ }
37
+
38
+ /**
39
+ * Get Feed Header.
40
+ *
41
+ * @return mixed
42
+ */
43
+ public function get_header() {
44
+ $feed = FileFactory::GetData( $this->structure, $this->config );
45
+ $feed = $feed->make_header_footer();
46
+
47
+ return $feed['header'];
48
+ }
49
+
50
+ /**
51
+ * Get Feed Footer.
52
+ *
53
+ * @return mixed
54
+ */
55
+ public function get_footer() {
56
+ $feed = FileFactory::GetData( $this->ids, $this->config );
57
+ $feed = $feed->make_header_footer();
58
+
59
+ return $feed['footer'];
60
+ }
61
+ }
V5/File/CSV.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\File;
4
+ use CTXFeed\V5\Utility\Config;
5
+
6
+ /**
7
+ *
8
+ */
9
+ class CSV implements FileInterface {
10
+
11
+ /**
12
+ * @var
13
+ */
14
+ private $data;
15
+ /**
16
+ * @var Config $config
17
+ */
18
+ private $config;
19
+
20
+ /**
21
+ * @param $data
22
+ * @param $config
23
+ */
24
+ public function __construct( $data, $config ) {
25
+
26
+ $this->data = $data;
27
+ $this->config = $config;
28
+ }
29
+
30
+ /**
31
+ * Make Header & Footer.
32
+ *
33
+ * @return array
34
+ */
35
+ public function make_header_footer() {
36
+ $HF = [
37
+ 'header' => '',
38
+ 'footer' => '',
39
+ ];
40
+
41
+
42
+ $enclosure = $this->config->get_enclosure();
43
+ $delimiter = $this->config->get_delimiter();
44
+
45
+ if ( ! empty( $this->data ) && is_array( $this->data ) ) {
46
+ $first = $this->implode_all( $delimiter, $enclosure, $this->data, 'key' ) . "\n";
47
+
48
+ $HF = [
49
+ 'header' => $first,
50
+ 'footer' => '',
51
+ ];
52
+ }
53
+
54
+ return apply_filters( "ctx_make_{$this->config->feedType}_feed_header_footer", $HF, $this->data, $this->config );
55
+ }
56
+
57
+ /**
58
+ * Make CSV body.
59
+ *
60
+ * @return string
61
+ */
62
+ public function make_body() {
63
+
64
+ $column = '';
65
+ $enclosure = $this->config->get_enclosure();
66
+ $delimiter = $this->config->get_delimiter();
67
+
68
+ foreach ( $this->data as $product ) {
69
+ $column .= $this->implode_all( $delimiter, $enclosure, $product ) . "\n";
70
+ }
71
+
72
+ return apply_filters( "ctx_make_{$this->config->feedType}_feed_body", $column, $this->data, $this->config );
73
+ }
74
+
75
+ /**
76
+ * Convert Multi Dimension array to string.
77
+ *
78
+ * @param $delimiter
79
+ * @param $enclosure
80
+ * @param $arr
81
+ * @param string $kv Key or Value
82
+ *
83
+ * @return string
84
+ */
85
+ private function implode_all( $delimiter, $enclosure, $arr, $kv = 'value' ) {
86
+ foreach ( $arr as $i => $iValue ) {
87
+ if ( is_array( $iValue ) ) {
88
+ if ( 'value' === $kv ) {
89
+ $arr[ $i ] = $enclosure . $this->implode_all( $delimiter, $enclosure, $iValue, $kv ) . $enclosure;
90
+ } else {
91
+ $arr[ $i ] = $enclosure . array_key_first( $iValue ) . $enclosure;
92
+ }
93
+ }
94
+ }
95
+
96
+ return implode( $delimiter, $arr );
97
+ }
98
+ }
99
+
V5/File/FileFactory.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\File;
3
+ use CTXFeed\V5\Utility\Config;
4
+ use CTXFeed\V5\File\CSV;
5
+ use CTXFeed\V5\File\TXT;
6
+ use CTXFeed\V5\File\XLS;
7
+ use CTXFeed\V5\File\XML;
8
+ use CTXFeed\V5\File\JSON;
9
+
10
+ /**
11
+ *
12
+ */
13
+ class FileFactory {
14
+ /**
15
+ * Get Feed file data by file type.
16
+ *
17
+ * @param array $data Contain Products array.
18
+ * @param Config $config Contain Feed Configurations.
19
+ *
20
+ * @return FileInfo
21
+ */
22
+ public static function GetData( $data, $config ) {
23
+ $type = $config->feedType;
24
+ $class = "\CTXFeed\V5\File\\".strtoupper( $type );
25
+
26
+ if ( class_exists( $class ) ) {
27
+ return new FileInfo( new $class( $data, $config ) );
28
+ }
29
+
30
+ return new FileInfo( new CSV( $data, $config ));
31
+ }
32
+ }
V5/File/FileInfo.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\File;
3
+ class FileInfo {
4
+ private $file;
5
+
6
+ public function __construct( FileInterface $file) {
7
+ $this->file = $file;
8
+ }
9
+
10
+ /**
11
+ * Make Header Footer.
12
+ *
13
+ * @return array
14
+ */
15
+ public function make_header_footer() {
16
+ return $this->file->make_header_footer();
17
+ }
18
+
19
+ /**
20
+ * Make XML body
21
+ *
22
+ * @return false|string
23
+ */
24
+ public function make_body() {
25
+ return $this->file->make_body();
26
+ }
27
+ }
V5/File/FileInterface.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\File;
3
+ interface FileInterface {
4
+ /**
5
+ * Make Header & Footer.
6
+ *
7
+ * @return array
8
+ */
9
+ public function make_header_footer();
10
+
11
+ /**
12
+ * Make Feed File body.
13
+ *
14
+ * @return false|string
15
+ */
16
+ public function make_body();
17
+ }
18
+
V5/File/JSON.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\File;
4
+ class JSON implements FileInterface {
5
+
6
+ private $data;
7
+ private $config;
8
+
9
+ public function __construct( $data, $config ) {
10
+
11
+ $this->data = $data;
12
+ $this->config = $config;
13
+ }
14
+
15
+ /**
16
+ * Make Header & Footer.
17
+ *
18
+ * @return array
19
+ */
20
+ public function make_header_footer() {
21
+ $HF = [
22
+ 'header' => '',
23
+ 'footer' => '',
24
+ ];
25
+
26
+ return apply_filters( "ctx_make_{$this->config->feedType}_feed_header_footer", $HF, $this->data, $this->config );
27
+ }
28
+
29
+ /**
30
+ * Make JSON body.
31
+ *
32
+ * @return string
33
+ */
34
+ public function make_body() {
35
+
36
+ $content = $this->data;
37
+
38
+ //TODO: Multi dimension to single array.
39
+ return apply_filters( "ctx_make_{$this->config->feedType}_feed_body", $content, $this->data, $this->config );
40
+ }
41
+
42
+ }
43
+
V5/File/TXT.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\File;
3
+ class TXT implements FileInterface {
4
+
5
+ private $data;
6
+ private $config;
7
+
8
+ public function __construct( $data, $config ) {
9
+
10
+ $this->data = $data;
11
+ $this->config = $config;
12
+ }
13
+
14
+ /**
15
+ * Make Header & Footer.
16
+ *
17
+ * @return array
18
+ */
19
+ public function make_header_footer() {
20
+ $HF = [
21
+ 'header' => '',
22
+ 'footer' => '',
23
+ ];
24
+
25
+ if ( ! empty( $this->data ) && is_array( $this->data ) ) {
26
+ $first = array_key_first( $this->data );
27
+
28
+ $HF = [
29
+ 'header' => array_keys( $this->data[ $first ] ),
30
+ 'footer' => '',
31
+ ];
32
+ }
33
+
34
+ return apply_filters( "ctx_make_{$this->config->feedType}_feed_header_footer", $HF, $this->data, $this->config );
35
+ }
36
+
37
+ /**
38
+ * Make CSV body.
39
+ *
40
+ * @return string
41
+ */
42
+ public function make_body( ) {
43
+
44
+ $column = '';
45
+ $enclosure = ! $this->config->get_enclosure() ? '"' : $this->config->get_enclosure();
46
+ $delimiter = $enclosure . $this->config->get_delimiter() . $enclosure;
47
+
48
+ foreach ( $this->data as $product ) {
49
+ $column .= $enclosure . $this->implode_all( $delimiter, $enclosure, $product ) . $enclosure . "\n";
50
+ }
51
+
52
+ return apply_filters( "ctx_make_{$this->config->feedType}_feed_body", $column, $this->data, $this->config );
53
+ }
54
+
55
+ /**
56
+ * Convert Multi Dimension array to string.
57
+ *
58
+ * @param $delimiter
59
+ * @param $enclosure
60
+ * @param $arr
61
+ *
62
+ * @return string
63
+ */
64
+ private function implode_all( $delimiter, $enclosure, $arr ) {
65
+ foreach ( $arr as $i => $iValue ) {
66
+ if ( is_array( $iValue ) ) {
67
+ $arr[ $i ] = $this->implode_all( $delimiter, $enclosure, $iValue );
68
+ }
69
+ }
70
+
71
+ return implode( $delimiter, $arr );
72
+ }
73
+ }
74
+
V5/File/XLS.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\File;
3
+ class XLS implements FileInterface {
4
+
5
+
6
+ private $data;
7
+ private $config;
8
+
9
+ public function __construct( $data, $config ) {
10
+
11
+ $this->data = $data;
12
+ $this->config = $config;
13
+ }
14
+
15
+ /**
16
+ * Make Header & Footer.
17
+ *
18
+ * @return array
19
+ */
20
+ public function make_header_footer() {
21
+ $HF = [
22
+ 'header' => '',
23
+ 'footer' => '',
24
+ ];
25
+
26
+ if ( ! empty( $this->data ) && is_array( $this->data ) ) {
27
+ $first = array_key_first( $this->data );
28
+
29
+ $HF = [
30
+ 'header' => array_keys( $this->data[ $first ] ),
31
+ 'footer' => '',
32
+ ];
33
+ }
34
+
35
+ return apply_filters( "ctx_make_{$this->config->feedType}_feed_header_footer", $HF, $this->data, $this->config );
36
+ }
37
+
38
+ /**
39
+ * Make CSV body.
40
+ *
41
+ * @return string
42
+ */
43
+ public function make_body( ) {
44
+
45
+ $column = '';
46
+ $enclosure = ! $this->config->get_enclosure() ? '"' : $this->config->get_enclosure();
47
+ $delimiter = $enclosure . $this->config->get_delimiter() . $enclosure;
48
+
49
+ foreach ( $this->data as $product ) {
50
+ $column .= $enclosure . $this->implode_all( $delimiter, $enclosure, $product ) . $enclosure . "\n";
51
+ }
52
+
53
+ return apply_filters( "ctx_make_{$this->config->feedType}_feed_body", $column, $this->data, $this->config );
54
+ }
55
+
56
+ /**
57
+ * Convert Multi Dimension array to string.
58
+ *
59
+ * @param $delimiter
60
+ * @param $enclosure
61
+ * @param $arr
62
+ *
63
+ * @return string
64
+ */
65
+ private function implode_all( $delimiter, $enclosure, $arr ) {
66
+ foreach ( $arr as $i => $iValue ) {
67
+ if ( is_array( $iValue ) ) {
68
+ $arr[ $i ] = $this->implode_all( $delimiter, $enclosure, $iValue );
69
+ }
70
+ }
71
+
72
+ return implode( $delimiter, $arr );
73
+ }
74
+ }
75
+
V5/File/XML.php ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\File;
4
+
5
+ use DOMDocument;
6
+ use SimpleXMLElement;
7
+
8
+ /**
9
+ * Make XML Feed.
10
+ *
11
+ * @package CTXFeed
12
+ * @subpackage CTXFeed\V5\File
13
+ */
14
+ class XML implements FileInterface {
15
+ /**
16
+ * @var
17
+ */
18
+ private $data;
19
+ /**
20
+ * @var
21
+ */
22
+ private $config;
23
+ private $feedBody;
24
+
25
+ /**
26
+ * @param $data
27
+ * @param $config
28
+ */
29
+ public function __construct( $data, $config ) {
30
+
31
+ $this->data = $data;
32
+ $this->config = $config;
33
+ }
34
+
35
+ /**
36
+ * Make Header & Footer.
37
+ *
38
+ * @return array
39
+ */
40
+ public function make_header_footer() {
41
+ $HF = $this->get_header_footer( $this->config );
42
+
43
+ return apply_filters( "ctx_make_{$this->config->feedType}_feed_header_footer", $HF, $this->data, $this->config );
44
+ }
45
+
46
+ /**
47
+ * Convert an array to XML.
48
+ *
49
+ * @param array $array array to convert
50
+ * @param mixed $xml xml object
51
+ */
52
+ public function array_to_xml( $array, &$xml ) {
53
+ foreach ( $array as $key => $value ) {
54
+ if ( is_array( $value ) ) {
55
+ if ( ! is_numeric( $key ) ) {
56
+ $this->feedBody .= "<$key>" . PHP_EOL;
57
+ self::array_to_xml( $value, $child );
58
+ $this->feedBody .= "</$key>" . PHP_EOL;
59
+ } else {
60
+ self::array_to_xml( $value, $xml );
61
+ }
62
+ } else {
63
+ if ( ! in_array( $key, [ 'g:tax', 'g:shipping' ], true ) ) {
64
+ $value = htmlentities( $value, ENT_XML1 | ENT_QUOTES, 'UTF-8' );
65
+ }
66
+ $this->feedBody .= "<$key>" . $value . "</$key>" . PHP_EOL;
67
+ }
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Make XML body.
73
+ *
74
+ * @return false|string
75
+ */
76
+ public function make_body() {
77
+ // create simpleXML object
78
+
79
+ $xml = '';
80
+ $this->array_to_xml( $this->data, $xml );
81
+
82
+ return apply_filters( "ctx_make_{$this->config->feedType}_feed_body", $this->feedBody, $this->data, $this->config );
83
+ }
84
+
85
+ /**
86
+ * Create XML File Header and Footer.
87
+ *
88
+ * @param $config
89
+ *
90
+ * @return array
91
+ */
92
+ private function get_header_footer( $config ) {
93
+
94
+ $xml_wrapper['header'] = $this->makeHeader( $config );
95
+ $xml_wrapper['footer'] = "\n" . $this->makeFooter( $config );
96
+
97
+
98
+ $config->itemWrapper = str_replace( ' ', '_', $config->itemWrapper );
99
+ $config->itemsWrapper = str_replace( ' ', '_', $config->itemsWrapper );
100
+
101
+ if ( file_exists( WOO_FEED_FREE_ADMIN_PATH . 'partials/templates/' . $config->provider . '.txt' ) ) {
102
+ $txt = file_get_contents( WOO_FEED_FREE_ADMIN_PATH . 'partials/templates/' . $config->provider . '.txt' );
103
+ $txt = trim( $txt );
104
+ $txt = explode( '{separator}', $txt );
105
+ if ( 2 === count( $txt ) ) {
106
+ $xml_wrapper['header'] = $this->makeHeader( $config, trim( $txt[0] ) );
107
+ $xml_wrapper['footer'] = "\n" . $this->makeFooter( $config, trim( $txt[1] ) );
108
+ }
109
+ }
110
+
111
+ return $xml_wrapper;
112
+ }
113
+
114
+ /**
115
+ * Replace template variables.
116
+ *
117
+ *
118
+ * @param $header
119
+ * @param $config
120
+ *
121
+ * @return array|string|string[]
122
+ */
123
+ private function replaceTemplateVariable( $header, $config ) {
124
+
125
+ $variables = [
126
+ '{DateTimeNow}' => gmdate( 'Y-m-d H:i:s', strtotime( current_time( 'mysql' ) ) ),
127
+ '{BlogName}' => get_bloginfo( 'name' ),
128
+ '{BlogURL}' => get_bloginfo( 'url' ),
129
+ '{BlogDescription}' => "CTX Feed - This product feed is generated with the CTX Feed - WooCommerce Product Feed Manager plugin by WebAppick.com. For all your support questions check out our plugin Docs on https://webappick.com/docs or e-mail to: support@webappick.com",
130
+ '{BlogEmail}' => get_bloginfo( 'admin_email' ),
131
+ ];
132
+
133
+ $variables = apply_filters( 'ctx_xml_header_template_variables', $variables, $config );
134
+
135
+ return str_replace( array_keys( $variables ), array_values( $variables ), $header );
136
+ }
137
+
138
+ /**
139
+ * Make XML Header.
140
+ *
141
+ * @param $config
142
+ * @param $override
143
+ *
144
+ * @return mixed|void
145
+ */
146
+ private function makeHeader( $config, $override = '' ) {
147
+ $config->itemsWrapper = str_replace( ' ', '_', $config->itemsWrapper );
148
+ if ( ! empty( $override ) ) {
149
+ $header = $override;
150
+ } else {
151
+ $header = '<?xml version="1.0" encoding="UTF-8" ?>' . PHP_EOL . "<" . wp_unslash( $config->itemsWrapper ) . ">";
152
+ }
153
+
154
+ if ( ! empty( $config->extraHeader ) ) {
155
+ $header .= PHP_EOL . wp_unslash( $config->extraHeader );
156
+ }
157
+
158
+ // replace template variables.
159
+ $header = $this->replaceTemplateVariable( $header, $config );
160
+
161
+ return apply_filters( 'ctx_make_xml_header', $header, $config );
162
+ }
163
+
164
+ /**
165
+ * Make XML Footer.
166
+ *
167
+ * @param $config
168
+ * @param $override
169
+ *
170
+ * @return mixed|void
171
+ */
172
+ private function makeFooter( $config, $override = '' ) {
173
+ if ( ! empty( $override ) ) {
174
+ $footer = $override;
175
+ } else {
176
+ $footer = '</' . $config->itemsWrapper . '>';
177
+ }
178
+
179
+ return apply_filters( 'ctx_make_xml_footer', $footer, $config );
180
+ }
181
+
182
+ /**
183
+ * @param $feed
184
+ *
185
+ * @return array|string|string[]
186
+ */
187
+ private function removeHeaderFooter( $feed ) {
188
+ return str_replace(
189
+ [ '<?xml version="1.0" encoding="utf-8"?>', '<?xml version="1.0"?>', '<products>', '</products>' ],
190
+ '',
191
+ $feed
192
+ );
193
+ }
194
+ }
V5/Filter/AdvanceFilter.php ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Filter;
3
+ use CTXFeed\V5\Common\Config;
4
+ use CTXFeed\V5\Helper\ProductHelper;
5
+ use WC_Product;
6
+
7
+ class AdvanceFilter {
8
+
9
+ /**
10
+ * Filter Products by Conditions
11
+ *
12
+ * @param WC_Product $product
13
+ * @param Config $config
14
+ *
15
+ * @return bool
16
+ * @since 3.2.0
17
+ */
18
+ public static function filter_product( $product, $config ) {
19
+
20
+ if ( isset( $config['fattribute'] ) && count( $config['fattribute'] ) ) {
21
+
22
+ // Filtering Variable
23
+ $fAttributes = $config['fattribute'];
24
+ $conditions = $config['condition'];
25
+ $filterCompare = $config['filterCompare'];
26
+ $concatType = isset( $config['concatType'] ) ? $config['concatType'] : [];
27
+
28
+ // Backward compatibility for <= v5.2.25
29
+ $filterType = isset( $config['filterType'] ) && ! empty( $config['filterType'] )
30
+ ? $config['filterType']
31
+ : 2;
32
+
33
+ $filterType = $filterType === 1
34
+ ? 'OR'
35
+ : 'AND';
36
+
37
+ // Tracking Variables
38
+ $totalOr = 0;
39
+ $effectiveOrCount = 0;
40
+
41
+ foreach ( $fAttributes as $key => $check ) {
42
+
43
+ $flag = false;
44
+
45
+ // Backward compatibility for <= v5.2.25
46
+ $concatOperator = isset( $concatType[ $key ] ) && ! empty( $concatType[ $key ] )
47
+ ? $concatType[ $key ]
48
+ : $filterType;
49
+
50
+ if ( $concatOperator === 'OR' ) {
51
+ $totalOr ++;
52
+ }
53
+
54
+ $conditionName = ProductHelper::getAttributeValueByType( $check, $product, $config );
55
+ $condition = $conditions[ $key ];
56
+ $conditionCompare = stripslashes( $filterCompare[ $key ] );
57
+ // DEBUG HERE
58
+ // echo "Product Name: ".$product->get_name() .''.$product->get_id(); echo "<br>";
59
+ // echo "Name: ".$conditionName; echo "<br>";
60
+ // echo "Condition: ".$condition; echo "<br>";
61
+ // echo "Compare: ".$conditionCompare; echo "<br>"; echo "<br>";
62
+
63
+ switch ( $condition ) {
64
+
65
+ case '==':
66
+ if ( strtolower( $conditionName ) === strtolower( $conditionCompare ) ) {
67
+ $flag = true;
68
+ }
69
+ break;
70
+ case '!=':
71
+ if ( strtolower( $conditionName ) !== strtolower( $conditionCompare ) ) {
72
+ $flag = true;
73
+ }
74
+ break;
75
+ case '>=':
76
+ if ( strtolower( $conditionName ) >= strtolower( $conditionCompare ) ) {
77
+ $flag = true;
78
+ }
79
+ break;
80
+ case '<=':
81
+ if ( strtolower( $conditionName ) <= strtolower( $conditionCompare ) ) {
82
+ $flag = true;
83
+ }
84
+ break;
85
+ case '>':
86
+ if ( strtolower( $conditionName ) > strtolower( $conditionCompare ) ) {
87
+ $flag = true;
88
+ }
89
+ break;
90
+ case '<':
91
+ if ( strtolower( $conditionName ) < strtolower( $conditionCompare ) ) {
92
+ $flag = true;
93
+ }
94
+ break;
95
+ case 'contains':
96
+ if ( false !== stripos( $conditionName, $conditionCompare ) ) {
97
+ $flag = true;
98
+ }
99
+ break;
100
+ case 'nContains':
101
+ if ( false === stripos( $conditionName, $conditionCompare ) ) {
102
+ $flag = true;
103
+ }
104
+ break;
105
+ case 'between':
106
+ $compare_items = explode( '-', $conditionCompare );
107
+ if ( $conditionName >= $compare_items[0] && $conditionName <= $compare_items[1] ) {
108
+ $flag = true;
109
+ }
110
+ break;
111
+ default:
112
+ break;
113
+ }
114
+
115
+
116
+ if ( $concatOperator === 'OR' && $flag ) {
117
+ $effectiveOrCount ++;
118
+ }
119
+
120
+ if ( $concatOperator === 'AND' && ! $flag ) {
121
+ return false;
122
+ }
123
+ }
124
+
125
+ if ( $totalOr > 0 && $effectiveOrCount === 0 ) {
126
+ return false;
127
+ }
128
+ }
129
+
130
+ return true;
131
+ }
132
+
133
+
134
+ }
V5/Filter/Filter.php ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Filter;
3
+ use CTXFeed\V5\Utility\Config;
4
+ use WC_Product;
5
+
6
+ class Filter {
7
+ /**
8
+ * @var WC_Product $product
9
+ */
10
+ private $product;
11
+ private $config;
12
+
13
+ public function __construct( $product, $feedRules ) {
14
+ $this->product = $product;
15
+ $this->config = new Config( $feedRules );
16
+ }
17
+
18
+ /**
19
+ * @return bool
20
+ */
21
+ public function exclude() {
22
+ $exclude = false;
23
+
24
+ // Remove Out Of Stock Product.
25
+ if ( $this->config->remove_outofstock_product() && $this->product->get_stock_status() === 'outofstock' ) {
26
+ $exclude = true;
27
+ }
28
+
29
+ // Remove On Backorder Product.
30
+ if ( $this->config->remove_backorder_product() && $this->product->get_stock_status() === 'onbackorder' ) {
31
+ $exclude = true;
32
+ }
33
+
34
+ //TODO Remove Hidden Product.
35
+
36
+ //TODO Remove empty title product.
37
+
38
+ // Remove empty description product.
39
+ if ( $this->config->remove_empty_description() && empty( $this->product->get_description() ) ) {
40
+ $exclude = true;
41
+ }
42
+
43
+ // Remove empty image product.
44
+ if ( $this->config->remove_empty_image() && empty( $this->product->get_image( 'woocommerce_thumbnail', [], false ) ) ) {
45
+ $exclude = true;
46
+ }
47
+
48
+ // Remove empty price product.
49
+ if ( $this->config->remove_empty_price() && empty( $this->product->get_price() ) ) {
50
+ $exclude = true;
51
+ }
52
+
53
+ // Exclude for variation
54
+ if ( $this->product->is_type( 'variation' ) ) {
55
+ $exclude = $this->exclude_variation( $exclude );
56
+ }
57
+
58
+
59
+ return apply_filters( 'ctx_filter_product_before_include', $exclude, $this->product, $this->config );
60
+ }
61
+
62
+ public function exclude_variation( $exclude ) {
63
+ $id = $this->product->get_id();
64
+ if ( $this->product->is_type( 'variation' ) ) {
65
+ $id = $this->product->get_parent_id();
66
+ }
67
+
68
+ // Remove products which are set to exclude.
69
+ $exclude_products = $this->config->get_products_to_exclude();
70
+ if ( $exclude_products && in_array( $this->product->get_id(), $exclude_products, true ) ) {
71
+ $exclude = true;
72
+ }
73
+
74
+ // Only add products which are set to include.
75
+ $include_products = $this->config->get_products_to_include();
76
+ if ( $include_products && ! in_array( $this->product->get_id(), $include_products, true ) ) {
77
+ $exclude = true;
78
+ }
79
+
80
+ // Remove categories which are set to exclude.
81
+ $exclude_categories = $this->config->get_categories_to_exclude();
82
+ if ( $exclude_categories && has_term( $exclude_categories, 'product_cat', $id ) ) {
83
+ $exclude = true;
84
+ }
85
+
86
+ // Only add categories which are set to include.
87
+ $include_categories = $this->config->get_categories_to_include();
88
+ if ( $include_categories && ! has_term( $include_categories, 'product_cat', $id ) ) {
89
+ $exclude = true;
90
+ }
91
+
92
+ return $exclude;
93
+ }
94
+ }
V5/Filter/ValidateProduct.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Filter;
4
+
5
+ use CTXFeed\V5\Utility\Config;
6
+ use CTXFeed\V5\Helper\CommonHelper;
7
+ use CTXFeed\V5\Utility\Logs;
8
+ use WC_Product;
9
+
10
+ /**
11
+ *
12
+ */
13
+ class ValidateProduct {
14
+ /**
15
+ * Validate Product.
16
+ *
17
+ * @param $product
18
+ * @param $config
19
+ * @param int $id Product id.
20
+ *
21
+ * @return mixed|void
22
+ */
23
+ public static function is_valid($product, $config, $id ) {
24
+ $valid = true;
25
+ // Skip for invalid products
26
+ if ( ! is_object( $product ) ) {
27
+ $valid = false;
28
+ Logs::log_feed_process( $config->filename, sprintf( 'Product with id: %s is not a valid object', $id ) );
29
+ }
30
+
31
+ // Skip orphaned variation.
32
+ if ( $product->is_type( 'variation' ) && ! $product->get_parent_id() ) {
33
+ $valid = false;
34
+ Logs::log_feed_process( $config->filename, sprintf( 'Orphaned Variation %s is skipped', $id ) );
35
+ }
36
+
37
+ // Skip for invisible products.
38
+ if ( ! $product->is_visible() ) {
39
+ $valid = false;
40
+ Logs::log_feed_process( $config->filename, sprintf( 'Product with id: %s is not visible on catalog.', $id ) );
41
+ }
42
+
43
+ // Remove unsupported product types.
44
+ if ( ! in_array( $product->get_type(), CommonHelper::supported_product_types(), true ) ) {
45
+ $valid = false;
46
+ Logs::log_feed_process( $config->filename, sprintf( 'Product with id: %s is a %s product. Product Type %s is not supported.', $id, $product->get_type(), $product->get_type() ) );
47
+ }
48
+
49
+ /**
50
+ * This filter hook should return false to exclude the product from feed.
51
+ */
52
+
53
+ return apply_filters( 'ctx_validate_product_before_include', $valid, $product, $config );
54
+ }
55
+ }
V5/Helper/CommonHelper.php ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Helper;
3
+ class CommonHelper {
4
+
5
+
6
+ public static function supported_product_types() {
7
+ return [
8
+ 'simple',
9
+ 'variable',
10
+ 'variation',
11
+ 'grouped',
12
+ 'external',
13
+ 'composite',
14
+ 'bundle',
15
+ 'bundled',
16
+ 'yith_bundle',
17
+ 'yith-composite',
18
+ 'subscription',
19
+ 'variable-subscription',
20
+ 'woosb',
21
+ ];
22
+ }
23
+
24
+ public static function remove_shortcodes( $content ) {
25
+ if ( $content === '' ) {
26
+ return '';
27
+ }
28
+
29
+ $content = do_shortcode( $content );
30
+
31
+ $content = woo_feed_stripInvalidXml( $content );
32
+
33
+ // Covers all kinds of shortcodes
34
+ $expression = '/\[\/*[a-zA-Z1-90_| -=\'"\{\}]*\/*\]/m';
35
+
36
+ $content = preg_replace( $expression, '', $content );
37
+
38
+ return strip_shortcodes( $content );
39
+ }
40
+
41
+ public static function add_utm_parameter( $utm, $url ) {
42
+
43
+
44
+ if ( ! empty( $utm['utm_source'] ) && ! empty( $utm['utm_medium'] ) && ! empty( $utm['utm_campaign'] ) ) {
45
+
46
+ $utm = [
47
+ 'utm_source' => str_replace( ' ', '+', $utm['utm_source'] ),
48
+ 'utm_medium' => str_replace( ' ', '+', $utm['utm_medium'] ),
49
+ 'utm_campaign' => str_replace( ' ', '+', $utm['utm_campaign'] ),
50
+ 'utm_term' => str_replace( ' ', '+', $utm['utm_term'] ),
51
+ 'utm_content' => str_replace( ' ', '+', $utm['utm_content'] ),
52
+ ];
53
+
54
+ $url = add_query_arg( array_filter( $utm ), $url );
55
+
56
+ }
57
+
58
+ return $url;
59
+ }
60
+
61
+ /**
62
+ * Remove Feed Option Name Prefix and return the slug
63
+ *
64
+ * @param string $feed
65
+ *
66
+ * @return string
67
+ */
68
+ public static function get_feed_option_name( $feed ) {
69
+ return str_replace( [ 'wf_feed_', 'wf_config' ], '', $feed );
70
+ }
71
+
72
+ /**
73
+ * Check WooCommerce Version
74
+ *
75
+ * @param string $version
76
+ *
77
+ * @return bool
78
+ */
79
+ public static function wc_version_check( $version = '3.0' ) {
80
+ if ( ! function_exists( 'get_plugins' ) ) {
81
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
82
+ }
83
+ $plugins = get_plugins();
84
+ if ( array_key_exists( 'woocommerce/woocommerce.php', $plugins ) ) {
85
+ $currentVersion = $plugins['woocommerce/woocommerce.php']['Version'];
86
+ if ( version_compare( $currentVersion, $version, '>=' ) ) {
87
+ return true;
88
+ }
89
+ }
90
+
91
+ return false;
92
+ }
93
+
94
+ }
V5/Helper/CustomFieldHelper.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Helper;
4
+
5
+
6
+ /**
7
+ * Class CustomFieldHelper
8
+ *
9
+ * @package CTXFeed\V5\Helper
10
+ * @subpackage CTXFeed\V5\Helper
11
+ */
12
+ class CustomFieldHelper {
13
+ public static function get_fields() {
14
+ /**
15
+ * Here array of a field contain 3 elements
16
+ * 1. Name
17
+ * 2. Is this fields enabled by default
18
+ * 3. Is this fields is a custom taxonomy
19
+ */
20
+ $custom_fields = array(
21
+ 'brand' => array( __( 'Brand', 'woo-feed' ), true, 'taxonomy' ),
22
+ 'gtin' => array( __( 'GTIN', 'woo-feed' ), true, 'text' ),
23
+ 'mpn' => array( __( 'MPN', 'woo-feed' ), true, 'text' ),
24
+ 'ean' => array( __( 'EAN', 'woo-feed' ), true, 'text' ),
25
+ 'isbn' => array( __( 'ISBN', 'woo-feed' ), true, 'text' ),
26
+ 'age_group' => array( __( 'Age group', 'woo-feed' ), true, 'text' ),
27
+ 'gender' => array( __( 'Gender', 'woo-feed' ), true, 'text' ),
28
+ 'material' => array( __( 'Material', 'woo-feed' ), true, 'text' ),
29
+ 'cost_of_good_sold' => array( __( 'Cost of good sold', 'woo-feed' ), true, 'text' ),
30
+ 'availability_date' => array( __( 'Availability Date', 'woo-feed' ), true, 'date' ),
31
+ 'unit' => array( __( 'Unit', 'woo-feed' ), true, 'text' ),
32
+ 'unit_pricing_measure' => array( __( 'Unit Price Measure', 'woo-feed' ), true, 'text' ),
33
+ 'unit_pricing_base_measure' => array( __( 'Unit Price Base Measure', 'woo-feed' ), true, 'text' ),
34
+ 'custom_field_0' => array( __( 'Custom field 0', 'woo-feed' ), true, 'text' ),
35
+ 'custom_field_1' => array( __( 'Custom field 1', 'woo-feed' ), true, 'text' ),
36
+ 'custom_field_2' => array( __( 'Custom field 2', 'woo-feed' ), true, 'text' ),
37
+ 'custom_field_3' => array( __( 'Custom field 3', 'woo-feed' ), true, 'text' ),
38
+ 'custom_field_4' => array( __( 'Custom field 4', 'woo-feed' ), true, 'text' ),
39
+ );
40
+
41
+ return apply_filters( 'woo_feed_product_custom_fields', $custom_fields );
42
+ }
43
+ }
V5/Helper/FeedHelper.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Helper;
3
+ class FeedHelper {
4
+
5
+
6
+
7
+ }
V5/Helper/ProductHelper.php ADDED
@@ -0,0 +1,668 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Helper;
4
+
5
+ use CTXFeed\V5\Product\AttributeValueByType;
6
+ use CTXFeed\V5\Query\QueryFactory;
7
+ use CTXFeed\V5\Utility\Config;
8
+ use WC_Product;
9
+ use WC_Product_External;
10
+ use WC_Product_Grouped;
11
+ use WC_Product_Variable;
12
+ use WC_Product_Variation;
13
+
14
+ class ProductHelper {
15
+ /**
16
+ * Advance Custom Field (ACF) Prefix
17
+ *
18
+ * @since 3.1.18
19
+ * @var string
20
+ */
21
+ const PRODUCT_ACF_FIELDS = 'acf_fields_';
22
+ /**
23
+ * Post meta prefix for dropdown item
24
+ *
25
+ * @since 3.1.18
26
+ * @var string
27
+ */
28
+ const POST_META_PREFIX = 'wf_cattr_';
29
+ /**
30
+ * Product Attribute (taxonomy & local) Prefix
31
+ *
32
+ * @since 3.1.18
33
+ * @var string
34
+ */
35
+ const PRODUCT_ATTRIBUTE_PREFIX = 'wf_attr_';
36
+ /**
37
+ * Product Taxonomy Prefix
38
+ *
39
+ * @since 3.1.18
40
+ * @var string
41
+ */
42
+ const PRODUCT_TAXONOMY_PREFIX = 'wf_taxo_';
43
+ /**
44
+ * Product Category Mapping Prefix
45
+ *
46
+ * @since 3.1.18
47
+ * @var string
48
+ */
49
+ const PRODUCT_CATEGORY_MAPPING_PREFIX = 'wf_cmapping_';
50
+ /**
51
+ * Product Dynamic Attribute Prefix
52
+ *
53
+ * @since 3.1.18
54
+ * @var string
55
+ */
56
+ const PRODUCT_DYNAMIC_ATTRIBUTE_PREFIX = 'wf_dattribute_';
57
+ /**
58
+ * WordPress Option Prefix
59
+ *
60
+ * @since 3.1.18
61
+ * @var string
62
+ */
63
+ const WP_OPTION_PREFIX = 'wf_option_';
64
+ /**
65
+ * Extra Attribute Prefix
66
+ *
67
+ * @since 3.2.20
68
+ */
69
+ const PRODUCT_EXTRA_ATTRIBUTE_PREFIX = 'wf_extra_';
70
+ /**
71
+ * Product Attribute Mappings Prefix
72
+ *
73
+ * @since 3.3.2*
74
+ */
75
+ const PRODUCT_ATTRIBUTE_MAPPING_PREFIX = 'wp_attr_mapping_';
76
+ /**
77
+ * Product Custom Field Prefix
78
+ *
79
+ * @since 3.1.18
80
+ * @var string
81
+ */
82
+ const PRODUCT_CUSTOM_IDENTIFIER = 'woo_feed_';
83
+
84
+ /**
85
+ * @param Config $config Feed Configuration.
86
+ *
87
+ * @return object
88
+ */
89
+ public static function get_ids( $config ) {
90
+ return QueryFactory::get_ids( $config );
91
+ }
92
+
93
+ /**
94
+ * Get Product Gallery Items (URL) array.
95
+ * This can contains empty array values
96
+ *
97
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product
98
+ *
99
+ * @return string[]
100
+ * @since 3.2.6
101
+ */
102
+ public static function get_product_gallery( $product ) {
103
+ $imgUrls = [];
104
+ $attachmentIds = [];
105
+
106
+ if ( $product->is_type( 'variation' ) ) {
107
+ if ( class_exists( 'Woo_Variation_Gallery' ) ) {
108
+ /**
109
+ * Get Variation Additional Images for "Additional Variation Images Gallery for WooCommerce"
110
+ *
111
+ * @plugin Additional Variation Images Gallery for WooCommerce
112
+ * @link https://wordpress.org/plugins/woo-variation-gallery/
113
+ */
114
+ $attachmentIds = get_post_meta( $product->get_id(), 'woo_variation_gallery_images', true );
115
+ } elseif ( class_exists( 'WooProductVariationGallery' ) ) {
116
+ /**
117
+ * Get Variation Additional Images for "Variation Images Gallery for WooCommerce"
118
+ *
119
+ * @plugin Variation Images Gallery for WooCommerce
120
+ * @link https://wordpress.org/plugins/woo-product-variation-gallery/
121
+ */
122
+ $attachmentIds = get_post_meta( $product->get_id(), 'rtwpvg_images', true );
123
+ } elseif ( class_exists( 'WC_Additional_Variation_Images' ) ) {
124
+ /**
125
+ * Get Variation Additional Images for "WooCommerce Additional Variation Images"
126
+ *
127
+ * @plugin WooCommerce Additional Variation Images
128
+ * @link https://woocommerce.com/products/woocommerce-additional-variation-images/
129
+ */
130
+ $attachmentIds = explode( ',', get_post_meta( $product->get_id(), '_wc_additional_variation_images', true ) );
131
+ } elseif ( class_exists( 'WOODMART_Theme' ) ) {
132
+ /**
133
+ * Get Variation Additional Images for "WOODMART Theme -> Variation Gallery Images Feature"
134
+ *
135
+ * @theme WOODMART
136
+ * @link https://themeforest.net/item/woodmart-woocommerce-wordpress-theme/20264492
137
+ */
138
+ $var_id = $product->get_id();
139
+ $parent_id = $product->get_parent_id();
140
+
141
+ $variation_obj = get_post_meta( $parent_id, 'woodmart_variation_gallery_data', true );
142
+ if ( isset( $variation_obj, $variation_obj[ $var_id ] ) ) {
143
+ $attachmentIds = explode( ',', $variation_obj[ $var_id ] );
144
+ } else {
145
+ $attachmentIds = explode( ',', get_post_meta( $var_id, 'wd_additional_variation_images_data', true ) );
146
+ }
147
+ } else {
148
+ /**
149
+ * If any Variation Gallery Image plugin not installed then get Variable Product Additional Image Ids .
150
+ */
151
+ $attachmentIds = wc_get_product( $product->get_parent_id() )->get_gallery_image_ids();
152
+ }
153
+ }
154
+
155
+ /**
156
+ * Get Variable Product Gallery Image ids if Product is not a variation
157
+ * or variation does not have any gallery images
158
+ */
159
+ if ( empty( $attachmentIds ) ) {
160
+ $attachmentIds = $product->get_gallery_image_ids();
161
+ }
162
+
163
+ if ( $attachmentIds && is_array( $attachmentIds ) ) {
164
+ $mKey = 1;
165
+ foreach ( $attachmentIds as $attachmentId ) {
166
+ $imgUrls[ $mKey ] = woo_feed_get_formatted_url( wp_get_attachment_url( $attachmentId ) );
167
+ $mKey ++;
168
+ }
169
+ }
170
+
171
+ return $imgUrls;
172
+ }
173
+
174
+ /**
175
+ * Get Product Meta Value.
176
+ *
177
+ * @param $meta
178
+ * @param WC_Product $product
179
+ * @param $config
180
+ *
181
+ * @return mixed|void
182
+ */
183
+ public static function get_product_meta( $meta, $product, $config ) {
184
+ $value = get_post_meta( $product->get_id(), $meta, true );
185
+ // if empty get meta value of parent post
186
+ if ( '' === $value && $product->is_type( 'variation' ) ) {
187
+ $value = get_post_meta( $product->get_parent_id(), $meta, true );
188
+ }
189
+
190
+ return apply_filters( 'woo_feed_filter_product_meta', $value, $product, $config );
191
+ }
192
+
193
+ /**
194
+ * Get Product Custom Field values.
195
+ *
196
+ * @param $field
197
+ * @param WC_Product $product
198
+ * @param $config
199
+ *
200
+ * @return mixed
201
+ */
202
+ public static function get_custom_filed( $field, $product, $config ) {
203
+ $meta = $field;
204
+ if ( $product->is_type( 'variation' ) ) {
205
+ $meta = $field . '_var';
206
+ }
207
+
208
+ $meta = apply_filters( 'woo_feed_custom_field_meta', $meta, $product, $config );
209
+
210
+ if ( strpos( $meta, '_identifier' ) !== false ) {
211
+ $old_meta_key = $meta;
212
+ $new_meta_key = str_replace( '_identifier', '', $meta );
213
+ } else {
214
+ $new_meta_key = $meta;
215
+ $old_meta_key = str_replace( 'woo_feed_', 'woo_feed_identifier_', $meta );
216
+ }
217
+
218
+ $new_meta_value = self::get_product_meta( $new_meta_key, $product, $config );
219
+ $old_meta_value = self::get_product_meta( $old_meta_key, $product, $config );
220
+
221
+ if ( empty( $new_meta_value ) ) {
222
+ return self::format_custom_field_value( $old_meta_value, $meta );
223
+ }
224
+
225
+ return self::format_custom_field_value( $new_meta_value, $meta );
226
+ }
227
+
228
+ private static function format_custom_field_value( $value, $meta ) {
229
+ if ( strpos( $meta, 'availability_date' ) ) {
230
+ return date( 'c', strtotime( $value ) );
231
+ }
232
+
233
+ return $value;
234
+ }
235
+
236
+ /**
237
+ * Get Product Taxonomy.
238
+ *
239
+ * @param string $taxonomy
240
+ * @param WC_Product $product
241
+ * @param Config $config
242
+ *
243
+ * @return mixed|void
244
+ */
245
+ public static function get_product_taxonomy( $taxonomy, $product, $config ) {
246
+ $id = woo_feed_parent_product_id( $product );
247
+ $separator = apply_filters( 'woo_feed_product_taxonomy_term_list_separator', ',', $config, $product );
248
+ $term_list = get_the_term_list( $id, $taxonomy, '', $separator, '' );
249
+
250
+ if ( is_object( $term_list ) && get_class( $term_list ) === 'WP_Error' ) {
251
+ $term_list = '';
252
+ }
253
+ $getTaxonomy = woo_feed_strip_all_tags( $term_list );
254
+
255
+ return apply_filters( 'woo_feed_filter_product_taxonomy', $getTaxonomy, $product, $config );
256
+ }
257
+
258
+ /**
259
+ * Ger Product Attribute
260
+ *
261
+ * @param $attr
262
+ *
263
+ * @param $product
264
+ * @param \CTXFeed\V5\Utility\Config $config
265
+ *
266
+ * @return string
267
+ * @since 2.2.3
268
+ */
269
+ public static function get_product_attribute( $attr, $product, $config ) {
270
+ $id = $product->get_id();
271
+
272
+ if ( woo_feed_wc_version_check( 3.2 ) ) {
273
+ if ( woo_feed_wc_version_check( 3.6 ) ) {
274
+ $attr = str_replace( 'pa_', '', $attr );
275
+ }
276
+ $value = $product->get_attribute( $attr );
277
+
278
+ // if empty get attribute of parent post
279
+ if ( '' === $value && $product->is_type( 'variation' ) ) {
280
+ $product = wc_get_product( $product->get_parent_id() );
281
+ $value = $product->get_attribute( $attr );
282
+ }
283
+
284
+ $getAttribute = $value;
285
+ } else {
286
+ $getAttribute = implode( ',', wc_get_product_terms( $id, $attr, array( 'fields' => 'names' ) ) );
287
+ }
288
+
289
+ return apply_filters( 'woo_feed_filter_product_attribute', $getAttribute, $attr, $product, $config );
290
+ }
291
+
292
+
293
+
294
+ /**
295
+ * Get ACF Field values
296
+ *
297
+ * @param WC_Product $product
298
+ * @param string $field_key ACF Filed Key with prefix "acf_fields_"
299
+ *
300
+ * @return mixed|string
301
+ */
302
+ public
303
+ static function get_acf_field(
304
+ $product, $field_key
305
+ ) {
306
+ $field = str_replace( 'acf_fields_', '', $field_key );
307
+ if ( class_exists( 'ACF' ) ) {
308
+ return get_field( $field, $product->get_id() );
309
+ }
310
+
311
+ return '';
312
+ }
313
+
314
+ /**
315
+ * Return Category Mapping Values by Product Id [Parent Product for variation]
316
+ *
317
+ * @param string $mappingName Category Mapping Name
318
+ * @param int $product_id Product ID / Parent Product ID for variation product
319
+ *
320
+ * @return mixed
321
+ */
322
+ public
323
+ static function get_category_mapping(
324
+ $mappingName, $product_id
325
+ ) {
326
+ $getValue = maybe_unserialize( get_option( $mappingName ) );
327
+ $cat_map_value = '';
328
+ $suggestive_category_list_merchants = array(
329
+ 'google',
330
+ 'facebook',
331
+ 'pinterest',
332
+ 'bing',
333
+ 'bing_local_inventory',
334
+ 'snapchat'
335
+ );
336
+
337
+ if ( ! isset( $getValue['cmapping'] ) && ! isset( $getValue['gcl-cmapping'] ) ) {
338
+ return '';
339
+ }
340
+
341
+ //get product terms
342
+ $categories = get_the_terms( $product_id, 'product_cat' );
343
+
344
+ //get cmapping value
345
+ if ( isset( $getValue['gcl-cmapping'] ) && in_array( $getValue['mappingprovider'], $suggestive_category_list_merchants, true ) ) {
346
+ $cmapping = is_array( $getValue['gcl-cmapping'] ) ? array_reverse( $getValue['gcl-cmapping'], true ) : $getValue['gcl-cmapping'];
347
+ } else {
348
+ $cmapping = is_array( $getValue['cmapping'] ) ? array_reverse( $getValue['cmapping'], true ) : $getValue['cmapping'];
349
+ }
350
+
351
+ // Fixes empty mapped category issue
352
+ if ( ! empty( $categories ) && is_array( $categories ) && count( $categories ) ) {
353
+ $categories = array_reverse( $categories );
354
+ foreach ( $categories as $category ) {
355
+ if ( isset( $cmapping[ $category->term_id ] ) && ! empty( $cmapping[ $category->term_id ] ) ) {
356
+ $cat_map_value = $cmapping[ $category->term_id ];
357
+ break;
358
+ }
359
+ }
360
+ }
361
+
362
+ return $cat_map_value;
363
+ }
364
+
365
+ /**
366
+ * Get Attribute Mapping Value.
367
+ *
368
+ * @param WC_Product $product
369
+ * @param $attribute
370
+ * @param $merchant_attribute
371
+ * @param $config
372
+ *
373
+ * @return string
374
+ */
375
+ public
376
+ static function get_attribute_mapping(
377
+ $product, $attribute, $merchant_attribute, $config
378
+ ) {
379
+ $getAttributeValueByType = new AttributeValueByType( $attribute, $merchant_attribute, $product, $config );
380
+ $attributes = get_option( $attribute );
381
+ $glue = ! empty( $attributes['glue'] ) ? $attributes['glue'] : " ";
382
+ $output = '';
383
+
384
+ if ( isset( $attributes['mapping'] ) ) {
385
+ foreach ( $attributes['mapping'] as $map ) {
386
+ $get_value = $getAttributeValueByType->get_value( $map );
387
+ if ( ! empty( $get_value ) ) {
388
+ $output .= $glue . $get_value;
389
+ }
390
+ }
391
+ }
392
+
393
+ //trim extra glue
394
+ $output = trim( $output, $glue );
395
+
396
+ // remove extra whitespace
397
+ $output = preg_replace( '!\s\s+!', ' ', $output );
398
+
399
+ return apply_filters( 'woo_feed_filter_attribute_mapping', $output, $attribute, $product, $config );
400
+ }
401
+
402
+ /**
403
+ * Get the value of a dynamic attribute
404
+ *
405
+ * @param WC_Product $product
406
+ * @param $attributeName
407
+ * @param $merchant_attribute
408
+ * @param $config
409
+ *
410
+ * @return mixed|string
411
+ * @since 3.2.0
412
+ */
413
+ public
414
+ static function get_dynamic_attribute(
415
+ $product, $attributeName, $merchant_attribute, $config
416
+ ) {
417
+ $getAttributeValueByType = new AttributeValueByType( $attributeName, $merchant_attribute, $product, $config );
418
+ $getValue = maybe_unserialize( get_option( $attributeName ) );
419
+ $wfDAttributeCode = isset( $getValue['wfDAttributeCode'] ) ? $getValue['wfDAttributeCode'] : '';
420
+ $attribute = isset( $getValue['attribute'] ) ? (array) $getValue['attribute'] : array();
421
+ $condition = isset( $getValue['condition'] ) ? (array) $getValue['condition'] : array();
422
+ $compare = isset( $getValue['compare'] ) ? (array) $getValue['compare'] : array();
423
+ $type = isset( $getValue['type'] ) ? (array) $getValue['type'] : array();
424
+
425
+ $prefix = isset( $getValue['prefix'] ) ? (array) $getValue['prefix'] : array();
426
+ $suffix = isset( $getValue['suffix'] ) ? (array) $getValue['suffix'] : array();
427
+
428
+ $value_attribute = isset( $getValue['value_attribute'] ) ? (array) $getValue['value_attribute'] : array();
429
+ $value_pattern = isset( $getValue['value_pattern'] ) ? (array) $getValue['value_pattern'] : array();
430
+
431
+ $default_type = isset( $getValue['default_type'] ) ? $getValue['default_type'] : 'attribute';
432
+ $default_value_attribute = isset( $getValue['default_value_attribute'] ) ? $getValue['default_value_attribute'] : '';
433
+ $default_value_pattern = isset( $getValue['default_value_pattern'] ) ? $getValue['default_value_pattern'] : '';
434
+
435
+ $result = '';
436
+
437
+ // Check If Attribute Code exist
438
+ if ( $wfDAttributeCode && count( $attribute ) ) {
439
+ foreach ( $attribute as $key => $name ) {
440
+ if ( ! empty( $name ) ) {
441
+ $conditionName = $getAttributeValueByType->get_value( $name );
442
+ if ( 'weight' === $name ) {
443
+ $unit = ' ' . get_option( 'woocommerce_weight_unit' );
444
+ if ( ! empty( $unit ) ) {
445
+ $conditionName = (float) str_replace( $unit, '', $conditionName );
446
+ }
447
+ }
448
+
449
+ $conditionCompare = $compare[ $key ];
450
+ $conditionOperator = $condition[ $key ];
451
+
452
+ if ( ! empty( $conditionCompare ) ) {
453
+ $conditionCompare = trim( $conditionCompare );
454
+ }
455
+ $conditionValue = '';
456
+ if ( 'pattern' === $type[ $key ] ) {
457
+ $conditionValue = $value_pattern[ $key ];
458
+ } elseif ( 'attribute' === $type[ $key ] ) {
459
+ $conditionValue = $getAttributeValueByType->get_value( $value_attribute[ $key ] );
460
+ } elseif ( 'remove' === $type[ $key ] ) {
461
+ $conditionValue = '';
462
+ }
463
+
464
+ switch ( $conditionOperator ) {
465
+ case '==':
466
+ if ( $conditionName == $conditionCompare ) {
467
+ $result = self::price_format( $name, $conditionName, $conditionValue );
468
+ if ( '' !== $result ) {
469
+ $result = $prefix[ $key ] . $result . $suffix[ $key ];
470
+ }
471
+ }
472
+ break;
473
+ case '!=':
474
+ if ( $conditionName != $conditionCompare ) {
475
+ $result = self::price_format( $name, $conditionName, $conditionValue );
476
+ if ( '' !== $result ) {
477
+ $result = $prefix[ $key ] . $result . $suffix[ $key ];
478
+ }
479
+ }
480
+ break;
481
+ case '>=':
482
+ if ( $conditionName >= $conditionCompare ) {
483
+ $result = self::price_format( $name, $conditionName, $conditionValue );
484
+ if ( '' !== $result ) {
485
+ $result = $prefix[ $key ] . $result . $suffix[ $key ];
486
+ }
487
+ }
488
+
489
+ break;
490
+ case '<=':
491
+ if ( $conditionName <= $conditionCompare ) {
492
+ $result = self::price_format( $name, $conditionName, $conditionValue );
493
+ if ( '' !== $result ) {
494
+ $result = $prefix[ $key ] . $result . $suffix[ $key ];
495
+ }
496
+ }
497
+ break;
498
+ case '>':
499
+ if ( $conditionName > $conditionCompare ) {
500
+ $result = self::price_format( $name, $conditionName, $conditionValue );
501
+ if ( '' !== $result ) {
502
+ $result = $prefix[ $key ] . $result . $suffix[ $key ];
503
+ }
504
+ }
505
+ break;
506
+ case '<':
507
+ if ( $conditionName < $conditionCompare ) {
508
+ $result = self::price_format( $name, $conditionName, $conditionValue );
509
+ if ( '' !== $result ) {
510
+ $result = $prefix[ $key ] . $result . $suffix[ $key ];
511
+ }
512
+ }
513
+ break;
514
+ case 'contains':
515
+ if ( false !== stripos( $conditionName, $conditionCompare ) ) {
516
+ $result = self::price_format( $name, $conditionName, $conditionValue );
517
+ if ( '' !== $result ) {
518
+ $result = $prefix[ $key ] . $result . $suffix[ $key ];
519
+ }
520
+ }
521
+ break;
522
+ case 'nContains':
523
+ if ( stripos( $conditionName, $conditionCompare ) === false ) {
524
+ $result = self::price_format( $name, $conditionName, $conditionValue );
525
+ if ( '' !== $result ) {
526
+ $result = $prefix[ $key ] . $result . $suffix[ $key ];
527
+ }
528
+ }
529
+ break;
530
+ case 'between':
531
+ $compare_items = explode( ',', $conditionCompare );
532
+
533
+ if ( isset( $compare_items[1] ) && is_numeric( $compare_items[0] ) && is_numeric( $compare_items[1] ) ) {
534
+ if ( $conditionName >= $compare_items[0] && $conditionName <= $compare_items[1] ) {
535
+ $result = self::price_format( $name, $conditionName, $conditionValue );
536
+ if ( '' !== $result ) {
537
+ $result = $prefix[ $key ] . $result . $suffix[ $key ];
538
+ }
539
+ }
540
+ } else {
541
+ $result = '';
542
+ }
543
+ break;
544
+ default:
545
+ break;
546
+ }
547
+ }
548
+ }
549
+ }
550
+
551
+ if ( '' === $result ) {
552
+ if ( 'pattern' === $default_type ) {
553
+ $result = $default_value_pattern;
554
+ } elseif ( 'attribute' === $default_type ) {
555
+ if ( ! empty( $default_value_attribute ) ) {
556
+ $result = $getAttributeValueByType->get_value( $default_value_attribute );
557
+ }
558
+ } elseif ( 'remove' === $default_type ) {
559
+ $result = '';
560
+ }
561
+ }
562
+
563
+ return apply_filters( 'woo_feed_after_dynamic_attribute_value', $result, $product, $attributeName, $merchant_attribute, $config );
564
+ }
565
+
566
+ /**
567
+ * Format price value
568
+ *
569
+ * @param string $name Attribute Name
570
+ * @param int $conditionName condition
571
+ * @param int $result price
572
+ *
573
+ * @return array|float|int|string
574
+ * @since 3.2.0
575
+ */
576
+ private
577
+ static function price_format(
578
+ $name, $conditionName, $result
579
+ ) {
580
+ // calc and return the output.
581
+ if ( false !== strpos( $name, 'price' ) || false !== strpos( $name, 'weight' ) ) {
582
+ if ( false !== strpos( $result, '+' ) && false !== strpos( $result, '%' ) ) {
583
+ $result = str_replace_trim( '+', '', $result );
584
+ $result = str_replace_trim( '%', '', $result );
585
+ if ( is_numeric( $result ) ) {
586
+ $result = $conditionName + ( ( $conditionName * $result ) / 100 );
587
+ }
588
+ } elseif ( false !== strpos( $result, '-' ) && false !== strpos( $result, '%' ) ) {
589
+ $result = str_replace_trim( '-', '', $result );
590
+ $result = str_replace_trim( '%', '', $result );
591
+ if ( is_numeric( $result ) ) {
592
+ $result = ( ( $conditionName * $result ) / 100 ) - $conditionName;
593
+ }
594
+ } elseif ( false !== strpos( $result, '*' ) && false !== strpos( $result, '%' ) ) {
595
+ $result = str_replace_trim( '*', '', $result );
596
+ $result = str_replace_trim( '%', '', $result );
597
+ if ( is_numeric( $result ) ) {
598
+ $result = ( ( $conditionName * $result ) / 100 );
599
+ }
600
+ } elseif ( false !== strpos( $result, '+' ) ) {
601
+ $result = str_replace_trim( '+', '', $result );
602
+ if ( is_numeric( $result ) ) {
603
+ $result = ( $conditionName + $result );
604
+ }
605
+ } elseif ( false !== strpos( $result, '-' ) ) {
606
+ $result = str_replace_trim( '-', '', $result );
607
+ if ( is_numeric( $result ) ) {
608
+ $result = $conditionName - $result;
609
+ }
610
+ } elseif ( false !== strpos( $result, '*' ) ) {
611
+ $result = str_replace_trim( '*', '', $result );
612
+ if ( is_numeric( $result ) ) {
613
+ $result = ( $conditionName * $result );
614
+ }
615
+ } elseif ( false !== strpos( $result, '/' ) ) {
616
+ $result = str_replace_trim( '/', '', $result );
617
+ if ( is_numeric( $result ) ) {
618
+ $result = ( $conditionName / $result );
619
+ }
620
+ }
621
+ }
622
+
623
+ return $result;
624
+ }
625
+
626
+ /**
627
+ * Get attribute value by type
628
+ *
629
+ * @param string $attribute Product attribute
630
+ * @param WC_Product $product
631
+ * @param Config $config Configuration
632
+ *
633
+ * @return mixed
634
+ */
635
+ public
636
+ static function getAttributeValueByType(
637
+ $attribute, $product, $config, $merchant_attribute = null
638
+ ) {
639
+ return ( new AttributeValueByType( $attribute, $product, $config, $merchant_attribute ) )->get_value();
640
+ }
641
+
642
+ /**
643
+ * @param string $output
644
+ * @param string $productAttribute
645
+ * @param Config $config
646
+ *
647
+ * @return string
648
+ */
649
+ public
650
+ static function str_replace(
651
+ $output, $productAttribute, $config
652
+ ) {
653
+ // str_replace array can contain duplicate subjects, so better loop through...
654
+ foreach ( $config->get_string_replace() as $str_replace ) {
655
+ if ( empty( $str_replace['subject'] ) || $productAttribute !== $str_replace['subject'] ) {
656
+ continue;
657
+ }
658
+
659
+ if ( strpos( $str_replace['search'], '/' ) === false ) {
660
+ $output = preg_replace( stripslashes( '/' . $str_replace['search'] . '/mi' ), $str_replace['replace'], $output );
661
+ } else {
662
+ $output = str_replace( $str_replace['search'], $str_replace['replace'], $output );
663
+ }
664
+ }
665
+
666
+ return $output;
667
+ }
668
+ }
V5/Merchant/MerchantAttributeReplaceFactory.php ADDED
@@ -0,0 +1,653 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Merchant;
4
+ class MerchantAttributeReplaceFactory {
5
+ public static function data( $template, $file_type ) {
6
+ $data = [
7
+ 'google' => [
8
+ 'XML' => [
9
+ 'id' => array( 'g:id', false ),
10
+ 'webitemid' => array( 'g:webitemid', false ),
11
+ 'region_id' => array( 'g:region_id', false ),
12
+ 'title' => array( 'g:title', true ),
13
+ 'description' => array( 'g:description', true ),
14
+ 'link' => array( 'link', true ),
15
+ 'canonical_link' => array( 'g:canonical_link', true ),
16
+ 'mobile_link' => array( 'mobile_link', true ),
17
+ 'product_type' => array( 'g:product_type', true ),
18
+ 'current_category' => array( 'g:google_product_category', true ),
19
+ 'image' => array( 'g:image_link', true ),
20
+ 'images' => array( 'g:additional_image_link', false ),
21
+ 'images_1' => array( 'g:additional_image_link', true ),
22
+ 'images_2' => array( 'g:additional_image_link', true ),
23
+ 'images_3' => array( 'g:additional_image_link', true ),
24
+ 'images_4' => array( 'g:additional_image_link', true ),
25
+ 'images_5' => array( 'g:additional_image_link', true ),
26
+ 'images_6' => array( 'g:additional_image_link', true ),
27
+ 'images_7' => array( 'g:additional_image_link', true ),
28
+ 'images_8' => array( 'g:additional_image_link', true ),
29
+ 'images_9' => array( 'g:additional_image_link', true ),
30
+ 'images_10' => array( 'g:additional_image_link', true ),
31
+ 'condition' => array( 'g:condition', false ),
32
+ 'availability' => array( 'g:availability', false ),
33
+ 'availability_date' => array( 'g:availability_date', false ),
34
+ 'inventory' => array( 'g:inventory', false ),
35
+ 'price' => array( 'g:price', true ),
36
+ 'sale_price' => array( 'g:sale_price', true ),
37
+ 'sale_price_effective_date' => array( 'g:sale_price_effective_date', true ),
38
+ 'brand' => array( 'g:brand', true ),
39
+ 'sku' => array( 'g:mpn', true ),
40
+ 'upc' => array( 'g:gtin', true ),
41
+ 'identifier_exists' => array( 'g:identifier_exists', true ),
42
+ 'item_group_id' => array( 'g:item_group_id', false ),
43
+ 'external_seller_id' => array( 'g:external_seller_id', false ),
44
+ 'product_length' => array( 'g:product_length', true ),
45
+ 'product_width' => array( 'g:product_width', true ),
46
+ 'product_height' => array( 'g:product_height', true ),
47
+ 'product_weight' => array( 'g:product_weight', true ),
48
+ 'product_highlight_1' => array( 'g:product_highlight', true ),
49
+ 'product_highlight_2' => array( 'g:product_highlight', true ),
50
+ 'product_highlight_3' => array( 'g:product_highlight', true ),
51
+ 'product_highlight_4' => array( 'g:product_highlight', true ),
52
+ 'product_highlight_5' => array( 'g:product_highlight', true ),
53
+ 'product_highlight_6' => array( 'g:product_highlight', true ),
54
+ 'product_highlight_7' => array( 'g:product_highlight', true ),
55
+ 'product_highlight_8' => array( 'g:product_highlight', true ),
56
+ 'product_highlight_9' => array( 'g:product_highlight', true ),
57
+ 'product_highlight_10' => array( 'g:product_highlight', true ),
58
+ 'color' => array( 'g:color', true ),
59
+ 'gender' => array( 'g:gender', true ),
60
+ 'age_group' => array( 'g:age_group', true ),
61
+ 'material' => array( 'g:material', true ),
62
+ 'pattern' => array( 'g:pattern', true ),
63
+ 'size' => array( 'g:size', true ),
64
+ 'size_type' => array( 'g:size_type', true ),
65
+ 'size_system' => array( 'g:size_system', true ),
66
+ 'tax' => array( 'g:tax', true ),
67
+ 'country' => array( 'g:country', true ),
68
+ 'region' => array( 'g:region', true ),
69
+ 'postal_code' => array( 'g:postal_code', true ),
70
+ 'rate' => array( 'g:rate', true ),
71
+ 'tax_ship' => array( 'g:tax_ship', true ),
72
+ 'tax_category' => array( 'g:tax_category', true ),
73
+ 'free_shipping_label' => array( 'g:free_shipping_label', true ),
74
+ 'free_shipping_limit' => array( 'g:free_shipping_limit', true ),
75
+ 'average_review_rating' => array( 'g:average_review_rating', true ),
76
+ 'number_of_ratings' => array( 'g:number_of_ratings', true ),
77
+ 'number_of_reviews' => array( 'g:number_of_reviews', true ),
78
+ 'shipping' => array( 'g:shipping', true ),
79
+ 'weight' => array( 'g:shipping_weight', false ),
80
+ 'length' => array( 'g:shipping_length', false ),
81
+ 'width' => array( 'g:shipping_width', false ),
82
+ 'height' => array( 'g:shipping_height', false ),
83
+ 'ships_from_country' => array( 'g:ships_from_country', false ),
84
+ 'shipping_label' => array( 'g:shipping_label', false ),
85
+ 'multipack' => array( 'g:multipack', true ),
86
+ 'is_bundle' => array( 'g:is_bundle', true ),
87
+ 'adult' => array( 'g:adult', true ),
88
+ 'ads_redirect' => array( 'g:ads_redirect', true ),
89
+ 'custom_label_0' => array( 'g:custom_label_0', true ),
90
+ 'custom_label_1' => array( 'g:custom_label_1', true ),
91
+ 'custom_label_2' => array( 'g:custom_label_2', true ),
92
+ 'custom_label_3' => array( 'g:custom_label_3', true ),
93
+ 'custom_label_4' => array( 'g:custom_label_4', true ),
94
+ 'excluded_destination' => array( 'g:excluded_destination', true ),
95
+ 'shopping_ads_excluded_country' => array( 'g:shopping_ads_excluded_country', true ),
96
+ 'included_destination' => array( 'g:included_destination', true ),
97
+ 'expiration_date' => array( 'g:expiration_date', true ),
98
+ 'unit_pricing_measure' => array( 'g:unit_pricing_measure', true ),
99
+ 'unit_pricing_base_measure' => array( 'g:unit_pricing_base_measure', true ),
100
+ 'subscription_cost' => array( 'g:subscription_cost', true ),
101
+ 'months' => array( 'g:months', true ),
102
+ 'amount' => array( 'g:amount', true ),
103
+ 'period' => array( 'g:period', true ),
104
+ 'product_detail' => array( 'g:product_detail', true ),
105
+ 'section_name' => array( 'g:section_name', true ),
106
+ 'attribute_name' => array( 'g:attribute_name', true ),
107
+ 'attribute_value' => array( 'g:attribute_value', true ),
108
+ 'product_highlight' => array( 'g:product_highlight', true ),
109
+
110
+ 'material_1' => array( 'g:material', true ),
111
+ 'material_2' => array( 'g:material', true ),
112
+ 'energy_efficiency_class' => array( 'g:energy_efficiency_class', true ),
113
+ 'min_energy_efficiency_class' => array( 'g:min_energy_efficiency_class', true ),
114
+ 'max_energy_efficiency_class' => array( 'g:max_energy_efficiency_class', true ),
115
+ 'loyalty_points' => array( 'g:loyalty_points', true ),
116
+ 'installment' => array( 'g:installment', true ),
117
+ 'promotion_id' => array( 'g:promotion_id', true ),
118
+ 'product_applicability' => array( 'g:product_applicability', true ),
119
+ 'offer_type' => array( 'g:offer_type', true ),
120
+ 'long_title' => array( 'g:long_title', true ),
121
+ 'promotion_effective_dates' => array( 'g:promotion_effective_dates', true ),
122
+ 'redemption_channel' => array( 'g:redemption_channel', true ),
123
+ 'promotion_destination' => array( 'g:promotion_destination', true ),
124
+ 'percent_off' => array( 'g:percent_off', true ),
125
+ 'money_off_amount' => array( 'g:money_off_amount', true ),
126
+ 'get_this_quantity_discounted' => array( 'g:get_this_quantity_discounted', true ),
127
+ 'free_shipping' => array( 'g:free_shipping', true ),
128
+ 'free_gift_value' => array( 'g:free_gift_value', true ),
129
+ 'free_gift_description' => array( 'g:free_gift_description', true ),
130
+ 'promotion_display_dates' => array( 'g:promotion_display_dates', true ),
131
+ 'generic_redemption_code' => array( 'g:generic_redemption_code', true ),
132
+ 'fine_print' => array( 'g:fine_print', true ),
133
+ 'promotion_price' => array( 'g:promotion_price', true ),
134
+ 'coupon_value_type' => array( 'g:coupon_value_type', true ),
135
+ 'limit_quantity' => array( 'g:limit_quantity', true ),
136
+ 'limit_value' => array( 'g:limit_value', true ),
137
+ 'minimum_purchase_amount' => array( 'g:minimum_purchase_amount', true ),
138
+ 'item_id_exclusion' => array( 'g:item_id_exclusion', true ),
139
+ 'product_type_exclusion' => array( 'g:product_type_exclusion', true ),
140
+ 'brand_exclusion' => array( 'g:brand_exclusion', true ),
141
+ 'item_group_id_exclusion' => array( 'g:item_group_id_exclusion', true ),
142
+ 'cost_of_goods_sold' => array( 'g:cost_of_goods_sold', true ),
143
+ 'sell_on_google_quantity' => array( 'g:sell_on_google_quantity', false ),
144
+ 'location_id' => array( 'g:location_id', false ),
145
+ 'location_group_name' => array( 'g:location_group_name', false ),
146
+ 'min_handling_time' => array( 'g:min_handling_time', false ),
147
+ 'max_handling_time' => array( 'g:max_handling_time', false ),
148
+ 'max_transit_time' => array( 'g:max_transit_time', false ),
149
+ 'min_transit_time' => array( 'g:min_transit_time', false ),
150
+ 'transit_time_label' => array( 'g:transit_time_label', false ),
151
+ 'return_address_label' => array( 'g:return_address_label', false ),
152
+ 'return_policy_label' => array( 'g:return_policy_label', false ),
153
+ 'store_code' => array( 'g:store_code', false ),
154
+ 'quantity' => array( 'g:quantity', true ),
155
+ 'pickup_method' => array( 'g:pickup_method', true ),
156
+ 'pickup_sla' => array( 'g:pickup_sla', true ),
157
+ 'pickup_link_template' => array( 'g:pickup_link_template', true ),
158
+ 'link_template' => array( 'g:link_template', true ),
159
+ 'mobile_link_template' => array( 'g:mobile_link_template', true ),
160
+ 'mobile_pickup_link_template' => array( 'g:mobile_pickup_link_template', true ),
161
+ 'google_funded_promotion_eligibility' => array(
162
+ 'g:google_funded_promotion_eligibility',
163
+ false,
164
+ ),
165
+ ],
166
+ 'CSV' => [
167
+ 'id' => array( 'id', false ),
168
+ 'webitemid' => array( 'webitemid', false ),
169
+ 'region_id' => array( 'region_id', false ),
170
+ 'title' => array( 'title', true ),
171
+ 'description' => array( 'description', true ),
172
+ 'link' => array( 'link', true ),
173
+ 'canonical_link' => array( 'canonical link', true ),
174
+ 'mobile_link' => array( 'mobile_link', true ),
175
+ 'product_type' => array( 'product type', true ),
176
+ 'current_category' => array( 'google product category', true ),
177
+ 'image' => array( 'image link', true ),
178
+ 'images' => array( 'additional image link', true ),
179
+ 'images_1' => array( 'additional image link 1', true ),
180
+ 'images_2' => array( 'additional image link 2', true ),
181
+ 'images_3' => array( 'additional image link 3', true ),
182
+ 'images_4' => array( 'additional image link 4', true ),
183
+ 'images_5' => array( 'additional image link 5', true ),
184
+ 'images_6' => array( 'additional image link 6', true ),
185
+ 'images_7' => array( 'additional image link 7', true ),
186
+ 'images_8' => array( 'additional image link 8', true ),
187
+ 'images_9' => array( 'additional image link 9', true ),
188
+ 'images_10' => array( 'additional image link 10', true ),
189
+ 'condition' => array( 'condition', false ),
190
+ 'availability' => array( 'availability', false ),
191
+ 'availability_date' => array( 'availability date', false ),
192
+ 'inventory' => array( 'inventory', false ),
193
+ 'price' => array( 'price', true ),
194
+ 'sale_price' => array( 'sale price', true ),
195
+ 'sale_price_effective_date' => array( 'sale price effective date', true ),
196
+ 'brand' => array( 'brand', true ),
197
+ 'sku' => array( 'mpn', true ),
198
+ 'upc' => array( 'gtin', true ),
199
+ 'identifier_exists' => array( 'identifier exists', true ),
200
+ 'item_group_id' => array( 'item group id', false ),
201
+ 'external_seller_id' => array( 'external seller id', false ),
202
+ 'product_length' => array( 'product length', true ),
203
+ 'product_width' => array( 'product width', true ),
204
+ 'product_height' => array( 'product height', true ),
205
+ 'product_weight' => array( 'product weight', true ),
206
+ 'product_highlight' => array( 'product highlight', true ),
207
+ 'color' => array( 'color', true ),
208
+ 'gender' => array( 'gender', true ),
209
+ 'age_group' => array( 'age group', true ),
210
+ 'material' => array( 'material', true ),
211
+ 'pattern' => array( 'pattern', true ),
212
+ 'size' => array( 'size', true ),
213
+ 'size_type' => array( 'size type', true ),
214
+ 'size_system' => array( 'size system', true ),
215
+ 'free_shipping_label' => array( 'free_shipping_label', true ),
216
+ 'free_shipping_limit' => array( 'free_shipping_limit', true ),
217
+ 'average_review_rating' => array( 'average_review_rating', true ),
218
+ 'number_of_ratings' => array( 'number_of_ratings', true ),
219
+ 'number_of_reviews' => array( 'number_of_reviews', true ),
220
+ 'tax' => array(
221
+ 'tax(country:region:rate:postal_code:tax_ship)',
222
+ true
223
+ ),
224
+ 'tax_category' => array( 'tax category', true ),
225
+ 'shipping' => array( 'shipping', true ),
226
+ 'weight' => array( 'shipping weight', false ),
227
+ 'length' => array( 'shipping length', false ),
228
+ 'width' => array( 'shipping width', false ),
229
+ 'height' => array( 'shipping height', false ),
230
+ 'ships_from_country' => array( 'ships from country', false ),
231
+ 'shipping_label' => array( 'shipping label', false ),
232
+ 'shipping_country' => array( 'shipping country', false ),
233
+ 'shipping_service' => array( 'shipping service', false ),
234
+ 'shipping_price' => array( 'shipping price', false ),
235
+ 'shipping_region' => array( 'shipping region', false ),
236
+ 'multipack' => array( 'multipack', true ),
237
+ 'is_bundle' => array( 'is bundle', true ),
238
+ 'adult' => array( 'adult', true ),
239
+ 'ads_redirect' => array( 'ads redirect', true ),
240
+ 'custom_label_0' => array( 'custom label 0', true ),
241
+ 'custom_label_1' => array( 'custom label 1', true ),
242
+ 'custom_label_2' => array( 'custom label 2', true ),
243
+ 'custom_label_3' => array( 'custom label 3', true ),
244
+ 'custom_label_4' => array( 'custom label 4', true ),
245
+ 'excluded_destination' => array( 'excluded destination', true ),
246
+ 'shopping_ads_excluded_country' => array( 'shopping ads excluded country', true ),
247
+ 'included_destination' => array( 'included destination', true ),
248
+ 'expiration_date' => array( 'expiration date', true ),
249
+ 'unit_pricing_measure' => array( 'unit pricing measure', true ),
250
+ 'unit_pricing_base_measure' => array( 'unit pricing base measure', true ),
251
+ 'installment_months' => array( 'months', true ),
252
+ 'installment_amount' => array( 'amount', true ),
253
+ 'subscription_period' => array( 'period', true ),
254
+ 'subscription_period_length' => array( 'period_length', true ),
255
+ 'subscription_amount' => array( 'amount', true ),
256
+ 'energy_efficiency_class' => array( 'energy efficiency class', true ),
257
+ 'min_energy_efficiency_class' => array( 'min energy efficiency class', true ),
258
+ 'max_energy_efficiency_class' => array( 'max energy efficiency class', true ),
259
+ 'loyalty_points' => array( 'loyalty points', true ),
260
+ 'installment' => array( 'installment', true ),
261
+ 'promotion_id' => array( 'promotion id', true ),
262
+ 'cost_of_goods_sold' => array( 'cost of goods sold', true ),
263
+ 'sell_on_google_quantity' => array( 'sell on google quantity', false ),
264
+ 'min_handling_time' => array( 'min handling time', false ),
265
+ 'max_handling_time' => array( 'max handling time', false ),
266
+ 'transit_time_label' => array( 'transit time label', false ),
267
+ 'return_address_label' => array( 'return address label', false ),
268
+ 'return_policy_label' => array( 'return policy label', false ),
269
+ 'store_code' => array( 'store code', false ),
270
+ 'pickup_method' => array( 'pickup method', true ),
271
+ 'pickup_sla' => array( 'pickup sla', true ),
272
+ 'pickup_link_template' => array( 'pickup link template', true ),
273
+ 'link_template' => array( 'link template', true ),
274
+ 'mobile_link_template' => array( 'mobile link template', true ),
275
+ 'mobile_pickup_link_template' => array( 'mobile pickup link template', true ),
276
+ 'google_funded_promotion_eligibility' => array(
277
+ 'google funded promotion eligibility',
278
+ false,
279
+ ),
280
+ ],
281
+ 'JSON' => [],
282
+ ],
283
+ 'facebook' => [
284
+ 'XML' => [
285
+ 'id' => array( 'g:id', false ),
286
+ 'title' => array( 'g:title', true ),
287
+ 'description' => array( 'g:description', true ),
288
+ 'link' => array( 'g:link', true ),
289
+ 'mobile_link' => array( 'g:mobile_link', true ),
290
+ 'product_type' => array( 'g:product_type', true ),
291
+ 'current_category' => array( 'g:google_product_category', true ),
292
+ 'image' => array( 'g:image_link', true ),
293
+ 'images' => array( 'g:additional_image_link', false ),
294
+ 'images_1' => array( 'g:additional_image_link', true ),
295
+ 'images_2' => array( 'g:additional_image_link', true ),
296
+ 'images_3' => array( 'g:additional_image_link', true ),
297
+ 'images_4' => array( 'g:additional_image_link', true ),
298
+ 'images_5' => array( 'g:additional_image_link', true ),
299
+ 'images_6' => array( 'g:additional_image_link', true ),
300
+ 'images_7' => array( 'g:additional_image_link', true ),
301
+ 'images_8' => array( 'g:additional_image_link', true ),
302
+ 'images_9' => array( 'g:additional_image_link', true ),
303
+ 'images_10' => array( 'g:additional_image_link', true ),
304
+ 'condition' => array( 'g:condition', false ),
305
+ 'availability' => array( 'g:availability', false ),
306
+ 'inventory' => array( 'g:inventory', false ),
307
+ 'override' => array( 'g:override', false ),
308
+ 'price' => array( 'g:price', true ),
309
+ 'sale_price' => array( 'g:sale_price', true ),
310
+ 'sale_price_effective_date' => array( 'g:sale_price_effective_date', true ),
311
+ 'brand' => array( 'g:brand', true ),
312
+ 'sku' => array( 'g:mpn', true ),
313
+ 'upc' => array( 'g:gtin', true ),
314
+ 'identifier_exists' => array( 'g:identifier_exists', true ),
315
+ 'item_group_id' => array( 'g:item_group_id', false ),
316
+ 'color' => array( 'g:color', true ),
317
+ 'gender' => array( 'g:gender', true ),
318
+ 'age_group' => array( 'g:age_group', true ),
319
+ 'material' => array( 'g:material', true ),
320
+ 'pattern' => array( 'g:pattern', true ),
321
+ 'size' => array( 'g:size', true ),
322
+ 'size_type' => array( 'g:size_type', true ),
323
+ 'size_system' => array( 'g:size_system', true ),
324
+ 'tax' => array( 'tax', true ),
325
+ 'weight' => array( 'g:shipping_weight', false ),
326
+ 'length' => array( 'g:shipping_length', false ),
327
+ 'width' => array( 'g:shipping_width', false ),
328
+ 'height' => array( 'g:shipping_height', false ),
329
+ 'ships_from_country' => array( 'g:ships_from_country', false ),
330
+ 'shipping_label' => array( 'g:shipping_label', false ),
331
+ 'shipping_country' => array( 'g:shipping_country', false ),
332
+ 'shipping_service' => array( 'g:shipping_service', false ),
333
+ 'shipping_price' => array( 'g:shipping_price', false ),
334
+ 'shipping_region' => array( 'g:shipping_region', false ),
335
+ 'multipack' => array( 'g:multipack', true ),
336
+ 'is_bundle' => array( 'g:is_bundle', true ),
337
+ 'adult' => array( 'g:adult', true ),
338
+ 'adwords_redirect' => array( 'g:adwords_redirect', true ),
339
+ 'custom_label_0' => array( 'g:custom_label_0', true ),
340
+ 'custom_label_1' => array( 'g:custom_label_1', true ),
341
+ 'custom_label_2' => array( 'g:custom_label_2', true ),
342
+ 'custom_label_3' => array( 'g:custom_label_3', true ),
343
+ 'custom_label_4' => array( 'g:custom_label_4', true ),
344
+ 'excluded_destination' => array( 'g:excluded_destination', true ),
345
+ 'expiration_date' => array( 'g:expiration_date', true ),
346
+ 'unit_pricing_measure' => array( 'g:unit_pricing_measure', true ),
347
+ 'unit_pricing_base_measure' => array( 'g:unit_pricing_base_measure', true ),
348
+ 'energy_efficiency_class' => array( 'g:energy_efficiency_class', true ),
349
+ 'loyalty_points' => array( 'g:loyalty_points', true ),
350
+ 'installment' => array( 'g:installment', true ),
351
+ 'promotion_id' => array( 'g:promotion_id', true ),
352
+ 'cost_of_goods_sold' => array( 'g:cost_of_goods_sold', true ),
353
+ 'availability_date' => array( 'g:availability_date', true ),
354
+ 'tax_category' => array( 'g:tax_category', true ),
355
+ 'included_destination' => array( 'g:included_destination', true ),
356
+ 'quantity_to_sell_on_facebook' => array( 'g:quantity_to_sell_on_facebook', true ),
357
+ ],
358
+ 'CSV' => [
359
+ 'id' => array( 'id', false ),
360
+ 'title' => array( 'title', true ),
361
+ 'description' => array( 'description', true ),
362
+ 'link' => array( 'link', true ),
363
+ 'mobile_link' => array( 'mobile_link', true ),
364
+ 'product_type' => array( 'product type', true ),
365
+ 'current_category' => array( 'google product category', true ),
366
+ 'image' => array( 'image link', true ),
367
+ 'images' => array( 'additional image link', true ),
368
+ 'additional_image_link' => array( 'additional image link', true ),
369
+ 'images_1' => array( 'additional image link', true ),
370
+ 'images_2' => array( 'additional image link', true ),
371
+ 'images_3' => array( 'additional image link', true ),
372
+ 'images_4' => array( 'additional image link', true ),
373
+ 'images_5' => array( 'additional image link', true ),
374
+ 'images_6' => array( 'additional image link', true ),
375
+ 'images_7' => array( 'additional image link', true ),
376
+ 'images_8' => array( 'additional image link', true ),
377
+ 'images_9' => array( 'additional image link', true ),
378
+ 'images_10' => array( 'additional image link', true ),
379
+ 'condition' => array( 'condition', false ),
380
+ 'availability' => array( 'availability', false ),
381
+ 'inventory' => array( 'inventory', false ),
382
+ 'override' => array( 'override', false ),
383
+ 'price' => array( 'price', true ),
384
+ 'sale_price' => array( 'sale price', true ),
385
+ 'sale_price_effective_date' => array( 'sale price effective date', true ),
386
+ 'brand' => array( 'brand', true ),
387
+ 'sku' => array( 'mpn', true ),
388
+ 'upc' => array( 'gtin', true ),
389
+ 'identifier_exists' => array( 'identifier exists', true ),
390
+ 'item_group_id' => array( 'item group id', false ),
391
+ 'color' => array( 'color', true ),
392
+ 'gender' => array( 'gender', true ),
393
+ 'age_group' => array( 'age group', true ),
394
+ 'material' => array( 'material', true ),
395
+ 'pattern' => array( 'pattern', true ),
396
+ 'size' => array( 'size', true ),
397
+ 'size_type' => array( 'size type', true ),
398
+ 'size_system' => array( 'size system', true ),
399
+ 'tax' => array( 'tax', true ),
400
+ 'weight' => array( 'shipping weight', false ),
401
+ 'length' => array( 'shipping length', false ),
402
+ 'width' => array( 'shipping width', false ),
403
+ 'height' => array( 'shipping height', false ),
404
+ 'ships_from_country' => array( 'ships from country', false ),
405
+ 'shipping_label' => array( 'shipping label', false ),
406
+ 'shipping_country' => array( 'shipping country', false ),
407
+ 'shipping_service' => array( 'shipping service', false ),
408
+ 'shipping_price' => array( 'shipping price', false ),
409
+ 'shipping_region' => array( 'shipping region', false ),
410
+ 'multipack' => array( 'multipack', true ),
411
+ 'is_bundle' => array( 'is bundle', true ),
412
+ 'adult' => array( 'adult', true ),
413
+ 'adwords_redirect' => array( 'adwords redirect', true ),
414
+ 'custom_label_0' => array( 'custom label 0', true ),
415
+ 'custom_label_1' => array( 'custom label 1', true ),
416
+ 'custom_label_2' => array( 'custom label 2', true ),
417
+ 'custom_label_3' => array( 'custom label 3', true ),
418
+ 'custom_label_4' => array( 'custom label 4', true ),
419
+ 'excluded_destination' => array( 'excluded destination', true ),
420
+ 'expiration_date' => array( 'expiration date', true ),
421
+ 'unit_pricing_measure' => array( 'unit pricing measure', true ),
422
+ 'unit_pricing_base_measure' => array( 'unit pricing base measure', true ),
423
+ 'energy_efficiency_class' => array( 'energy efficiency class', true ),
424
+ 'loyalty_points' => array( 'loyalty points', true ),
425
+ 'installment' => array( 'installment', true ),
426
+ 'promotion_id' => array( 'promotion id', true ),
427
+ 'cost_of_goods_sold' => array( 'cost of goods sold', true ),
428
+ 'availability_date' => array( 'availability date', true ),
429
+ 'tax_category' => array( 'tax category', true ),
430
+ 'included_destination' => array( 'included destination', true ),
431
+ 'quantity_to_sell_on_facebook' => array( 'quantity_to_sell_on_facebook', true ),
432
+ ],
433
+ 'JSON' => [],
434
+ ],
435
+ 'pinterest' => [
436
+ 'XML' => [
437
+ 'id' => array( 'g:id', false ),
438
+ 'title' => array( 'title', true ),
439
+ 'description' => array( 'description', true ),
440
+ 'link' => array( 'link', true ),
441
+ 'mobile_link' => array( 'mobile_link', true ),
442
+ 'product_type' => array( 'g:product_type', true ),
443
+ 'current_category' => array( 'g:google_product_category', true ),
444
+ 'image' => array( 'g:image_link', true ),
445
+ 'images' => array( 'g:additional_image_link', false ),
446
+ 'images_1' => array( 'g:additional_image_link', true ),
447
+ 'images_2' => array( 'g:additional_image_link', true ),
448
+ 'images_3' => array( 'g:additional_image_link', true ),
449
+ 'images_4' => array( 'g:additional_image_link', true ),
450
+ 'images_5' => array( 'g:additional_image_link', true ),
451
+ 'images_6' => array( 'g:additional_image_link', true ),
452
+ 'images_7' => array( 'g:additional_image_link', true ),
453
+ 'images_8' => array( 'g:additional_image_link', true ),
454
+ 'images_9' => array( 'g:additional_image_link', true ),
455
+ 'images_10' => array( 'g:additional_image_link', true ),
456
+ 'condition' => array( 'g:condition', false ),
457
+ 'availability' => array( 'g:availability', false ),
458
+ 'availability_date' => array( 'g:availability_date', false ),
459
+ 'inventory' => array( 'g:inventory', false ),
460
+ 'price' => array( 'g:price', true ),
461
+ 'sale_price' => array( 'g:sale_price', true ),
462
+ 'sale_price_effective_date' => array( 'g:sale_price_effective_date', true ),
463
+ 'brand' => array( 'g:brand', true ),
464
+ 'sku' => array( 'g:mpn', true ),
465
+ 'upc' => array( 'g:gtin', true ),
466
+ 'identifier_exists' => array( 'g:identifier_exists', true ),
467
+ 'item_group_id' => array( 'g:item_group_id', false ),
468
+ 'color' => array( 'g:color', true ),
469
+ 'gender' => array( 'g:gender', true ),
470
+ 'age_group' => array( 'g:age_group', true ),
471
+ 'material' => array( 'g:material', true ),
472
+ 'pattern' => array( 'g:pattern', true ),
473
+ 'size' => array( 'g:size', true ),
474
+ 'size_type' => array( 'g:size_type', true ),
475
+ 'size_system' => array( 'g:size_system', true ),
476
+ 'tax' => array( 'tax', true ),
477
+ 'tax_country' => array( 'g:tax_country', true ),
478
+ 'tax_region' => array( 'g:tax_region', true ),
479
+ 'tax_rate' => array( 'g:tax_rate', true ),
480
+ 'tax_ship' => array( 'g:tax_ship', true ),
481
+ 'tax_category' => array( 'g:tax_category', true ),
482
+ 'free_shipping_label' => array( 'g:free_shipping_label', true ),
483
+ 'free_shipping_limit' => array( 'g:free_shipping_limit', true ),
484
+ 'average_review_rating' => array( 'g:average_review_rating', true ),
485
+ 'number_of_ratings' => array( 'g:number_of_ratings', true ),
486
+ 'number_of_reviews' => array( 'g:number_of_reviews', true ),
487
+ 'weight' => array( 'g:shipping_weight', false ),
488
+ 'length' => array( 'g:shipping_length', false ),
489
+ 'width' => array( 'g:shipping_width', false ),
490
+ 'height' => array( 'g:shipping_height', false ),
491
+ 'ships_from_country' => array( 'g:ships_from_country', false ),
492
+ 'shipping_label' => array( 'g:shipping_label', false ),
493
+ 'shipping_country' => array( 'g:shipping_country', false ),
494
+ 'shipping_service' => array( 'g:shipping_service', false ),
495
+ 'shipping_price' => array( 'g:shipping_price', false ),
496
+ 'shipping_region' => array( 'g:shipping_region', false ),
497
+ 'multipack' => array( 'g:multipack', true ),
498
+ 'is_bundle' => array( 'g:is_bundle', true ),
499
+ 'adult' => array( 'g:adult', true ),
500
+ 'adwords_redirect' => array( 'g:adwords_redirect', true ),
501
+ 'custom_label_0' => array( 'g:custom_label_0', true ),
502
+ 'custom_label_1' => array( 'g:custom_label_1', true ),
503
+ 'custom_label_2' => array( 'g:custom_label_2', true ),
504
+ 'custom_label_3' => array( 'g:custom_label_3', true ),
505
+ 'custom_label_4' => array( 'g:custom_label_4', true ),
506
+ 'excluded_destination' => array( 'g:excluded_destination', true ),
507
+ 'included_destination' => array( 'g:included_destination', true ),
508
+ 'expiration_date' => array( 'g:expiration_date', true ),
509
+ 'unit_pricing_measure' => array( 'g:unit_pricing_measure', true ),
510
+ 'unit_pricing_base_measure' => array( 'g:unit_pricing_base_measure', true ),
511
+ 'energy_efficiency_class' => array( 'g:energy_efficiency_class', true ),
512
+ 'loyalty_points' => array( 'g:loyalty_points', true ),
513
+ 'installment' => array( 'g:installment', true ),
514
+ 'promotion_id' => array( 'g:promotion_id', true ),
515
+ 'cost_of_goods_sold' => array( 'g:cost_of_goods_sold', true ),
516
+ ],
517
+ 'CSV' => [
518
+ 'id' => array( 'id', false ),
519
+ 'title' => array( 'title', true ),
520
+ 'description' => array( 'description', true ),
521
+ 'link' => array( 'link', true ),
522
+ 'mobile_link' => array( 'mobile_link', true ),
523
+ 'product_type' => array( 'product_type', true ),
524
+ 'current_category' => array( 'google_product_category', true ),
525
+ 'image' => array( 'image_link', true ),
526
+ 'images' => array( 'additional_image_link', true ),
527
+ 'images_1' => array( 'additional_image_link', true ),
528
+ 'images_2' => array( 'additional_image_link', true ),
529
+ 'images_3' => array( 'additional_image_link', true ),
530
+ 'images_4' => array( 'additional_image_link', true ),
531
+ 'images_5' => array( 'additional_image_link', true ),
532
+ 'images_6' => array( 'additional_image_link', true ),
533
+ 'images_7' => array( 'additional_image_link', true ),
534
+ 'images_8' => array( 'additional_image_link', true ),
535
+ 'images_9' => array( 'additional_image_link', true ),
536
+ 'images_10' => array( 'additional_image_link', true ),
537
+ 'condition' => array( 'condition', false ),
538
+ 'availability' => array( 'availability', false ),
539
+ 'availability_date' => array( 'availability_date', false ),
540
+ 'inventory' => array( 'inventory', false ),
541
+ 'price' => array( 'price', true ),
542
+ 'sale_price' => array( 'sale_price', true ),
543
+ 'sale_price_effective_date' => array( 'sale_price_effective_date', true ),
544
+ 'brand' => array( 'brand', true ),
545
+ 'sku' => array( 'mpn', true ),
546
+ 'upc' => array( 'gtin', true ),
547
+ 'identifier_exists' => array( 'identifier_exists', true ),
548
+ 'item_group_id' => array( 'item_group_id', false ),
549
+ 'color' => array( 'color', true ),
550
+ 'gender' => array( 'gender', true ),
551
+ 'age_group' => array( 'age_group', true ),
552
+ 'material' => array( 'material', true ),
553
+ 'pattern' => array( 'pattern', true ),
554
+ 'size' => array( 'size', true ),
555
+ 'size_type' => array( 'size_type', true ),
556
+ 'size_system' => array( 'size_system', true ),
557
+ 'tax' => array( 'tax', true ),
558
+ 'tax_country' => array( 'tax_country', true ),
559
+ 'tax_region' => array( 'tax_region', true ),
560
+ 'tax_rate' => array( 'tax_rate', true ),
561
+ 'tax_ship' => array( 'tax_ship', true ),
562
+ 'tax_category' => array( 'tax_category', true ),
563
+ 'free_shipping_label' => array( 'free_shipping_label', true ),
564
+ 'free_shipping_limit' => array( 'free_shipping_limit', true ),
565
+ 'average_review_rating' => array( 'average_review_rating', true ),
566
+ 'number_of_ratings' => array( 'number_of_ratings', true ),
567
+ 'number_of_reviews' => array( 'number_of_reviews', true ),
568
+ 'weight' => array( 'shipping_weight', false ),
569
+ 'length' => array( 'shipping_length', false ),
570
+ 'width' => array( 'shipping_width', false ),
571
+ 'height' => array( 'shipping_height', false ),
572
+ 'ships_from_country' => array( 'ships_from_country', false ),
573
+ 'shipping_label' => array( 'shipping_label', false ),
574
+ 'shipping_country' => array( 'shipping_country', false ),
575
+ 'shipping_service' => array( 'shipping_service', false ),
576
+ 'shipping_price' => array( 'shipping_price', false ),
577
+ 'shipping_region' => array( 'shipping_region', false ),
578
+ 'multipack' => array( 'multipack', true ),
579
+ 'is_bundle' => array( 'is_bundle', true ),
580
+ 'adult' => array( 'adult', true ),
581
+ 'adwords_redirect' => array( 'adwords_redirect', true ),
582
+ 'custom_label_0' => array( 'custom_label_0', true ),
583
+ 'custom_label_1' => array( 'custom_label_1', true ),
584
+ 'custom_label_2' => array( 'custom_label_2', true ),
585
+ 'custom_label_3' => array( 'custom_label_3', true ),
586
+ 'custom_label_4' => array( 'custom_label_4', true ),
587
+ 'excluded_destination' => array( 'excluded_destination', true ),
588
+ 'included_destination' => array( 'included_destination', true ),
589
+ 'expiration_date' => array( 'expiration_date', true ),
590
+ 'unit_pricing_measure' => array( 'unit_pricing_measure', true ),
591
+ 'unit_pricing_base_measure' => array( 'unit_pricing_base_measure', true ),
592
+ 'energy_efficiency_class' => array( 'energy_efficiency_class', true ),
593
+ 'loyalty_points' => array( 'loyalty_points', true ),
594
+ 'installment' => array( 'installment', true ),
595
+ 'promotion_id' => array( 'promotion_id', true ),
596
+ 'cost_of_goods_sold' => array( 'cost_of_goods_sold', true ),
597
+ ],
598
+ 'JSON' => [],
599
+ ],
600
+ 'skroutz' => [
601
+ 'XML' => [
602
+ 'id' => array( 'id', false ),
603
+ 'name' => array( 'name', true ),
604
+ 'description' => array( 'description', true ),
605
+ 'link' => array( 'link', true ),
606
+ 'image' => array( 'image', true ),
607
+ 'additionalimage' => array( 'additionalimage', true ),
608
+ 'category' => array( 'category', true ),
609
+ 'price' => array( 'price', false ),
610
+ 'price_with_vat' => array( 'price_with_vat', false ),
611
+ 'manufacturer' => array( 'manufacturer', true ),
612
+ 'mpn' => array( 'mpn', false ),
613
+ 'ean' => array( 'ean', false ),
614
+ 'instock' => array( 'instock', false ),
615
+ 'availability' => array( 'availability', false ),
616
+ 'color' => array( 'color', false ),
617
+ 'size' => array( 'size', false ),
618
+ 'weight' => array( 'weight', false ),
619
+ 'quantity' => array( 'quantity', false ),
620
+ ],
621
+ 'CSV' => [],
622
+ 'JSON' => [],
623
+ ],
624
+ 'google_shopping_action' => [
625
+ 'XML' => [
626
+ 'description' => array( 'description', true ),
627
+ ],
628
+ 'CSV' => [],
629
+ 'JSON' => [],
630
+ ],
631
+ 'google_local' => [
632
+ 'XML' => [
633
+ 'description' => array( 'description', true ),
634
+ ],
635
+ 'CSV' => [],
636
+ 'JSON' => [],
637
+ ],
638
+
639
+ ];
640
+
641
+ return $data[ $template ][ strtoupper( $file_type ) ];
642
+ }
643
+
644
+ public static function replace_attribute( $attribute, $config ) {
645
+ $feedType = ( 'xml' === $config->feedType ) ? 'xml' : 'csv';
646
+ $data = self::data( $config->provider, $feedType );
647
+ if ( isset( $data[ $attribute ] ) ) {
648
+ return $data[ $attribute ][0];
649
+ }
650
+
651
+ return $attribute;
652
+ }
653
+ }
V5/Merchant/MerchantAttributesFactory.php ADDED
@@ -0,0 +1,1174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Merchant;
4
+ class MerchantAttributesFactory {
5
+
6
+ public static function get( $template = null ) {
7
+ $data = self::data();
8
+
9
+ if ( $template === null ) {
10
+ return $data;
11
+ }
12
+
13
+ if ( in_array( $template, [ 'pinterest', 'adroll', 'smartly.io' ] ) ) {
14
+ $template = 'google';
15
+ } elseif ( in_array( $template, [ 'connexity', 'shopzilla' ] ) ) {
16
+ $template = 'become';
17
+ } elseif ( $template === 'fruugo.au' ) {
18
+ $template = 'fruugo';
19
+ } elseif ( $template === 'shopalike.fr' ) {
20
+ $template = 'kijiji.ca';
21
+ }
22
+
23
+
24
+ if ( isset( $data[ $template ] ) ) {
25
+ return $data[ $template ];
26
+ }
27
+
28
+ return false;
29
+ }
30
+
31
+ private static function data() {
32
+ return [
33
+ 'google' => [
34
+ 1 => [
35
+ 'optionGroup' => 'Basic Information',
36
+ 'options' => [
37
+ 'id' => 'Product Id[id]',
38
+ 'webitemid' => 'Product WebItemId[webitemid]',
39
+ 'region_id' => 'Region Id[region_id]',
40
+ 'title' => 'Product Title[title]',
41
+ 'description' => 'Product Description[description]',
42
+ 'link' => 'Product URL[link]',
43
+ 'canonical_link' => 'Canonical Link[canonical_link]',
44
+ 'mobile_link' => 'Product URL[mobile_link]',
45
+ 'product_type' => 'Product Categories[product_type] ',
46
+ 'current_category' => 'Google Product Category[google_product_category]',
47
+ 'image' => 'Main Image[image_link]',
48
+ 'images' => 'Additional Images [additional_image_link]',
49
+ 'images_1' => 'Additional Image 1 [additional_image_link]',
50
+ 'images_2' => 'Additional Image 2 [additional_image_link]',
51
+ 'images_3' => 'Additional Image 3 [additional_image_link]',
52
+ 'images_4' => 'Additional Image 4 [additional_image_link]',
53
+ 'images_5' => 'Additional Image 5 [additional_image_link]',
54
+ 'images_6' => 'Additional Image 6 [additional_image_link]',
55
+ 'images_7' => 'Additional Image 7 [additional_image_link]',
56
+ 'images_8' => 'Additional Image 8 [additional_image_link]',
57
+ 'images_9' => 'Additional Image 9 [additional_image_link]',
58
+ 'images_10' => 'Additional Image 10 [additional_image_link]',
59
+ 'condition' => 'Condition[condition]',
60
+ ],
61
+ ],
62
+ 2 => [
63
+ 'optionGroup' => 'Availability & Price',
64
+ 'options' => [
65
+ 'availability' => 'Stock Status[availability]',
66
+ 'availability_date' => 'Availability Date[availability_date]',
67
+ 'inventory' => 'Facebook Inventory[inventory]',
68
+ 'override' => 'Facebook Override[override]',
69
+ 'price' => 'Regular Price[price]',
70
+ 'sale_price' => 'Sale Price[sale_price]',
71
+ 'cost_of_goods_sold' => 'Cost of Goods Sold[cost_of_goods_sold]',
72
+ 'sale_price_effective_date' => 'Sale Price Effective Date[sale_price_effective_date]',
73
+ ],
74
+ ],
75
+ 3 => [
76
+ 'optionGroup' => 'Unique Product Identifiers',
77
+ 'options' => [
78
+ 'brand' => 'Manufacturer[brand]',
79
+ 'upc' => 'GTIN[gtin]',
80
+ 'sku' => 'MPN[mpn]',
81
+ 'identifier_exists' => 'Identifier Exist[identifier_exists]',
82
+ ],
83
+ ],
84
+ 4 => [
85
+ 'optionGroup' => 'Detailed Product Attributes',
86
+ 'options' => [
87
+ 'item_group_id' => 'Item Group Id[item_group_id]',
88
+ 'external_seller_id' => 'External seller ID[external_seller_id]',
89
+ 'color' => 'Color[color]',
90
+ 'gender' => 'Gender[gender]',
91
+ 'age_group' => 'Age Group[age_group]',
92
+ 'material' => 'Material[material]',
93
+ 'pattern' => 'Pattern[pattern]',
94
+ 'size' => 'Size of the item[size]',
95
+ 'size_type' => 'Size Type[size_type]',
96
+ 'size_system' => 'Size System[size_system]',
97
+ 'product_length' => 'Product Length[product_length]',
98
+ 'product_width' => 'Product Width[product_width]',
99
+ 'product_height' => 'Product Height[product_height]',
100
+ 'product_weight' => 'Product Weight[product_weight]',
101
+ 'product_highlight_1' => 'Product Highlight 1[product_highlight]',
102
+ 'product_highlight_2' => 'Product Highlight 2[product_highlight]',
103
+ 'product_highlight_3' => 'Product Highlight 3[product_highlight]',
104
+ 'product_highlight_4' => 'Product Highlight 4[product_highlight]',
105
+ 'product_highlight_5' => 'Product Highlight 5[product_highlight]',
106
+ 'product_highlight_6' => 'Product Highlight 6[product_highlight]',
107
+ 'product_highlight_7' => 'Product Highlight 7[product_highlight]',
108
+ 'product_highlight_8' => 'Product Highlight 8[product_highlight]',
109
+ 'product_highlight_9' => 'Product Highlight 9[product_highlight]',
110
+ 'product_highlight_10' => 'Product Highlight 10[product_highlight]',
111
+ 'section_name' => 'Section Name (Product Detail)[section_name]',
112
+ 'attribute_name' => 'Attribute Name (Product Detail)[attribute_name]',
113
+ 'attribute_value' => 'Attribute Value (Product Detail)[attribute_value]',
114
+ ],
115
+ ],
116
+ 5 => [
117
+ 'optionGroup' => 'Tax & Shipping',
118
+ 'options' => [
119
+ 'tax' => 'Tax[tax]',
120
+ 'tax_category' => 'Tax[tax_category]',
121
+ 'shipping' => 'Shipping',
122
+ 'location_id' => 'location_id',
123
+ 'location_group_name' => 'location_group_name',
124
+ 'min_handling_time' => 'Min Handling Time[min_handling_time]',
125
+ 'max_handling_time' => 'Max Handling Time[max_handling_time]',
126
+ 'min_transit_time' => 'Min Transit Time[min_transit_time]',
127
+ 'max_transit_time' => 'Max Transit Time[max_transit_time]',
128
+ 'weight' => 'Shipping Weight[shipping_weight]',
129
+ 'length' => 'Shipping Length[shipping_length]',
130
+ 'width' => 'Shipping Width[shipping_width]',
131
+ 'height' => 'Shipping Height[shipping_height]',
132
+ 'ships_from_country' => 'Shipping Country[ships_from_country]',
133
+ 'shipping_label' => 'Shipping Label[shipping_label]',
134
+ 'material_1' => 'The primary material',
135
+ 'material_2' => 'The secondary material',
136
+ 'material_3' => 'The tertiary material',
137
+ ],
138
+ ],
139
+ 6 => [
140
+ 'optionGroup' => 'Product Combinations',
141
+ 'options' => [
142
+ 'multipack' => 'Multipack[multipack]',
143
+ 'is_bundle' => 'Is Bundle[is_bundle]',
144
+ ],
145
+ ],
146
+ 7 => [
147
+ 'optionGroup' => 'Adult Products',
148
+ 'options' => [
149
+ 'adult' => 'Adult[adult]',
150
+ ],
151
+ ],
152
+ 8 => [
153
+ 'optionGroup' => 'Ads Attributes',
154
+ 'options' => [
155
+ 'ads_redirect' => 'Ads Redirect[ads_redirect]',
156
+ ],
157
+ ],
158
+ 9 => [
159
+ 'optionGroup' => 'Custom Label Attributes',
160
+ 'options' => [
161
+ 'custom_label_0' => 'Custom label 0 [custom_label_0]',
162
+ 'custom_label_1' => 'Custom label 1 [custom_label_1]',
163
+ 'custom_label_2' => 'Custom label 2 [custom_label_2]',
164
+ 'custom_label_3' => 'Custom label 3 [custom_label_3]',
165
+ 'custom_label_4' => 'Custom label 4 [custom_label_4]',
166
+ ],
167
+ ],
168
+ 10 => [
169
+ 'optionGroup' => 'Additional Attributes',
170
+ 'options' => [
171
+ 'excluded_destination' => 'Excluded Destination[excluded_destination]',
172
+ 'shopping_ads_excluded_country' => 'Shopping Ads Excluded Country[shopping_ads_excluded_country]',
173
+ 'included_destination' => 'Included Destination[included_destination]',
174
+ 'expiration_date' => 'Expiration Date [expiration_date]',
175
+ 'transit_time_label' => 'Transit Time [transit_time_label]',
176
+ ],
177
+ ],
178
+ 11 => [
179
+ 'optionGroup' => 'Unit Prices, Subscription, and Installment',
180
+ 'options' => [
181
+ 'unit_pricing_measure' => 'Unit Pricing Measure[unit_pricing_measure]',
182
+ 'unit_pricing_base_measure' => 'Unit Pricing Base Measure[unit_pricing_base_measure]',
183
+ 'installment_months' => 'Installment Months[months]',
184
+ 'installment_amount' => 'Installment Amount[amount]',
185
+ 'subscription_period' => 'Subscription Period[period]',
186
+ 'subscription_period_length' => 'Subscription Period Length[period_length]',
187
+ 'subscription_amount' => 'Subscription Amount[amount]',
188
+ ],
189
+ ],
190
+ 12 => [
191
+ 'optionGroup' => 'Energy Labels',
192
+ 'options' => [
193
+ 'energy_efficiency_class' => 'Energy Efficiency Class[energy_efficiency_class]',
194
+ 'min_energy_efficiency_class' => 'Min Energy Efficiency Class[energy_efficiency_class]',
195
+ 'max_energy_efficiency_class' => 'Max Energy Efficiency Class[energy_efficiency_class]',
196
+ ],
197
+ ],
198
+ 13 => [
199
+ 'optionGroup' => 'Loyalty Points (Japan Only)',
200
+ 'options' => [
201
+ 'loyalty_points' => 'loyalty_points[loyalty_points]',
202
+ ],
203
+ ],
204
+ 14 => [
205
+ 'optionGroup' => 'Multiple Installments (Brazil Only)',
206
+ 'options' => [
207
+ 'installment' => 'Installment[installment]',
208
+ ],
209
+ ],
210
+ 15 => [
211
+ 'optionGroup' => 'Merchant Promotions Attributes',
212
+ 'options' => [
213
+ 'promotion_id' => 'Promotion Id[promotion_id]',
214
+ 'product_applicability' => 'Product Applicability[product_applicability]',
215
+ 'offer_type' => 'Offer Type[offer_type]',
216
+ 'long_title' => 'Long Title[long_title]',
217
+ 'promotion_effective_dates' => 'Promotion Effective Dates[promotion_effective_dates]',
218
+ 'redemption_channel' => 'Redemption Channel[redemption_channel]',
219
+ 'promotion_destination' => 'Promotion Destination[promotion_destination]',
220
+ 'percent_off' => 'Percent Off[percent_off]',
221
+ 'money_off_amount' => 'Money Off Amount[money_off_amount]',
222
+ 'get_this_quantity_discounted' => 'Get Quantity Discounted[get_this_quantity_discounted]',
223
+ 'free_shipping' => 'Free Shipping[free_shipping]',
224
+ 'free_gift_value' => 'Free Gift Value[free_gift_value]',
225
+ 'free_gift_description' => 'Free Gift Description[free_gift_description]',
226
+ 'free_gift_item_id' => 'Free Gift Item ID[free_gift_item_id]',
227
+ 'promotion_display_dates' => 'Promotion Display Dates[promotion_display_dates]',
228
+ 'generic_redemption_code' => 'Generic Redemption Code[generic_redemption_code]',
229
+ 'fine_print' => 'Fine Print[fine_print]',
230
+ 'promotion_price' => 'Promotion Price[promotion_price]',
231
+ 'coupon_value_type' => 'Coupon Value Type[coupon_value_type]',
232
+ 'limit_quantity' => 'Limit Quantity[limit_quantity]',
233
+ 'limit_value' => 'Limit Value[limit_value]',
234
+ 'minimum_purchase_amount' => 'Minimum Purchase Amount[minimum_purchase_amount]',
235
+ 'item_id_exclusion' => 'Item ID Exclusion[item_id_exclusion]',
236
+ 'product_type_exclusion' => 'Product Type Exclusion[product_type_exclusion]',
237
+ 'brand_exclusion' => 'Brand Exclusion[brand_exclusion]',
238
+ 'item_group_id_exclusion' => 'Item Group Exclusion[item_group_id_exclusion]',
239
+ ],
240
+ ],
241
+ 16 => [
242
+ 'optionGroup' => 'Shopping Action Attributes',
243
+ 'options' => [
244
+ 'sell_on_google_quantity' => 'Number of Product Sold On Google [sell_on_google_quantity]',
245
+ 'return_address_label' => 'Return Address [return_address_label]',
246
+ 'return_policy_label' => 'Return Policy [return_policy_label]',
247
+ 'google_funded_promotion_eligibility' => 'Google Funded Promotion Eligibility [google_funded_promotion_eligibility]',
248
+ ],
249
+ ],
250
+ 17 => [
251
+ 'optionGroup' => 'Local Inventory / Product Inventory',
252
+ 'options' => [
253
+ 'store_code' => 'Store Code [store_code]',
254
+ 'quantity' => 'Quantity [quantity]',
255
+ 'pickup_method' => 'Pickup Method [pickup_method]',
256
+ 'pickup_sla' => 'Pickup SLA [pickup_sla]',
257
+ 'pickup_link_template' => 'Pickup Link Template [pickup_link_template]',
258
+ 'link_template' => 'Link Template [link_template]',
259
+ 'mobile_link_template' => 'Mobile Link Template [mobile_link_template]',
260
+ 'mobile_pickup_link_template' => 'Mobile Pickup Link Template [mobile_pickup_link_template]',
261
+ ],
262
+ ],
263
+ 18 => [
264
+ 'optionGroup' => 'Pinterest Catalog Attributes',
265
+ 'options' => [
266
+ 'free_shipping_label' => 'Free Shipping Label[free_shipping_label]',
267
+ 'free_shipping_limit' => 'Free Shipping Limit[free_shipping_limit]',
268
+ 'average_review_rating' => 'Average Review Rating[average_review_rating]',
269
+ 'number_of_ratings' => 'Number of Ratings[number_of_ratings]',
270
+ 'number_of_reviews' => 'Number of Reviews[number_of_reviews]',
271
+ ],
272
+ ],
273
+ ],
274
+ 'facebook' => [
275
+ 1 => [
276
+ 'optionGroup' => 'Basic Information',
277
+ 'options' => [
278
+ 'id' => 'Product Id[id]',
279
+ 'title' => 'Product Title[title]',
280
+ 'description' => 'Product Description[description]',
281
+ 'link' => 'Product URL[link]',
282
+ 'mobile_link' => 'Product URL[mobile_link]',
283
+ 'product_type' => 'Product Categories[product_type] ',
284
+ 'fb_product_category' => 'Facebook Product Category[fb_product_category]',
285
+ 'current_category' => 'Google Product Category[google_product_category]',
286
+ 'image' => 'Main Image[image_link]',
287
+ 'images' => 'Additional Images [additional_image_link]',
288
+ 'images_1' => 'Additional Image 1 [additional_image_link]',
289
+ 'images_2' => 'Additional Image 2 [additional_image_link]',
290
+ 'images_3' => 'Additional Image 3 [additional_image_link]',
291
+ 'images_4' => 'Additional Image 4 [additional_image_link]',
292
+ 'images_5' => 'Additional Image 5 [additional_image_link]',
293
+ 'images_6' => 'Additional Image 6 [additional_image_link]',
294
+ 'images_7' => 'Additional Image 7 [additional_image_link]',
295
+ 'images_8' => 'Additional Image 8 [additional_image_link]',
296
+ 'images_9' => 'Additional Image 9 [additional_image_link]',
297
+ 'images_10' => 'Additional Image 10 [additional_image_link]',
298
+ 'condition' => 'Condition[condition]',
299
+ ],
300
+ ],
301
+ 2 => [
302
+ 'optionGroup' => 'Availability & Price',
303
+ 'options' => [
304
+ 'availability' => 'Stock Status[availability]',
305
+ 'availability_date' => 'Availability Date[availability_date]',
306
+ 'price' => 'Regular Price[price]',
307
+ 'sale_price' => 'Sale Price[sale_price]',
308
+ 'sale_price_effective_date' => 'Sale Price Effective Date[sale_price_effective_date]',
309
+ ],
310
+ ],
311
+ 3 => [
312
+ 'optionGroup' => 'Unique Product Identifiers',
313
+ 'options' => [
314
+ 'brand' => 'Manufacturer[brand]',
315
+ 'gtin' => 'GTIN[gtin]',
316
+ 'mpn' => 'MPN[mpn]',
317
+ 'identifier_exists' => 'Identifier Exist[identifier_exists]',
318
+ ],
319
+ ],
320
+ 4 => [
321
+ 'optionGroup' => 'Detailed Product Attributes',
322
+ 'options' => [
323
+ 'item_group_id' => 'Item Group Id[item_group_id]',
324
+ 'color' => 'Color[color]',
325
+ 'gender' => 'Gender[gender]',
326
+ 'age_group' => 'Age Group[age_group]',
327
+ 'material' => 'Material[material]',
328
+ 'pattern' => 'Pattern[pattern]',
329
+ 'size' => 'Size of the item[size]',
330
+ ],
331
+ ],
332
+ 5 => [
333
+ 'optionGroup' => 'Tax & Shipping',
334
+ 'options' => [
335
+ 'tax' => 'Tax[tax]',
336
+ 'tax_country' => 'Tax Country[tax_country]',
337
+ 'tax_region' => 'Tax Region[tax_region]',
338
+ 'tax_rate' => 'Tax Rate[tax_rate]',
339
+ 'tax_ship' => 'Tax Ship[tax_ship]',
340
+ 'tax_category' => 'Tax[tax_category]',
341
+ 'shipping' => 'Shipping',
342
+ 'shipping_weight' => 'Shipping Weight[shipping_weight]',
343
+ ],
344
+ ],
345
+ 6 => [
346
+ 'optionGroup' => 'Custom Label Attributes',
347
+ 'options' => [
348
+ 'custom_label_0' => 'Custom label 0 [custom_label_0]',
349
+ 'custom_label_1' => 'Custom label 1 [custom_label_1]',
350
+ 'custom_label_2' => 'Custom label 2 [custom_label_2]',
351
+ 'custom_label_3' => 'Custom label 3 [custom_label_3]',
352
+ 'custom_label_4' => 'Custom label 4 [custom_label_4]',
353
+ ],
354
+ ],
355
+ 7 => [
356
+ 'optionGroup' => 'Additional Attributes',
357
+ 'options' => [
358
+ 'inventory' => 'Facebook Inventory[inventory]',
359
+ 'override' => 'Facebook Override[override]',
360
+ 'status' => 'Status [status]',
361
+ 'video' => 'Video [video]',
362
+ 'unit_price_value' => 'Unit Price > Value [unit_price_value]',
363
+ 'unit_price_currency' => 'Unit Price > Currency [unit_price_currency]',
364
+ 'unit_price_unit' => 'Unit Price > Unit [unit_price_unit]',
365
+ 'quantity_to_sell_on_facebook' => 'Quantity to Sell on Facebook [quantity_to_sell_on_facebook]',
366
+ 'commerce_tax_category' => 'Commerce Tax Category [commerce_tax_category]',
367
+ 'expiration_date' => 'Expiration Date[expiration_date]',
368
+ 'marked_for_product_launch' => 'Marked for Product Launce [marked_for_product_launch]',
369
+ 'rich_text_description' => 'Rich Text Description [rich_text_description]',
370
+ 'visibility' => 'Visibility [visibility]',
371
+ 'additional_variant_label' => 'Additional Variant Attribute > Label [Variant Label]',
372
+ 'additional_variant_value' => 'Additional Variant Attribute > Value [Variant Value]',
373
+ 'applink' => 'Applink [applink]',
374
+ 'origin_country' => 'Origin Country [origin_country]',
375
+ 'importer_name' => 'Importer Name [importer_name]',
376
+ 'importer_address' => 'Importer Address [importer_address]',
377
+ 'manufacturer_info' => 'Manufacturer Info [manufacturer_info]',
378
+ 'return_policy_info' => 'Return Policy Info [return_policy_info]',
379
+ ],
380
+ ],
381
+ ],
382
+ 'google_dynamic_ads' => [
383
+ 1 => [
384
+ 'optionGroup' => 'Basic Information',
385
+ 'options' => [
386
+ 'Page URL' => 'Page URL[Page URL]',
387
+ 'Custom Label' => 'Custom Label [Custom Label]',
388
+ ],
389
+ ],
390
+ ],
391
+ 'bing' => [
392
+ 1 => [
393
+ 'optionGroup' => 'Basic Information',
394
+ 'options' => [
395
+ 'id' => 'Product Id[id]',
396
+ 'title' => 'Product Title[title]',
397
+ 'link' => 'Product URL[link]',
398
+ 'price' => 'Product Price[price]',
399
+ 'description' => 'Product Description[description]',
400
+ 'image_link' => 'Image[image_link]',
401
+ 'shipping' => 'Shipping [shipping]',
402
+ 'shipping_country' => 'Shipping Country[shipping]',
403
+ 'shipping_service' => 'Shipping Service[shipping]',
404
+ 'shipping_price' => 'Shipping Price[shipping]',
405
+ 'gtin' => 'GTIN[gtin]',
406
+ 'mpn' => 'MPN[mpn]',
407
+ 'brand' => 'Brand[brand]',
408
+ 'identifier_exists' => 'Identifier Exists[identifier_exists]',
409
+ ],
410
+ ],
411
+ 2 => [
412
+ 'optionGroup' => 'Apparel Products',
413
+ 'options' => [
414
+ 'gender' => 'Gender[gender]',
415
+ 'age_group' => 'Age Group[age_group]',
416
+ 'color' => 'Color[color]',
417
+ 'size' => 'Size[size]',
418
+ 'size_type' => 'Size Type[size_type]',
419
+ 'size_system' => 'Size System[size_system]',
420
+ ],
421
+ ],
422
+ 3 => [
423
+ 'optionGroup' => 'Product Variants',
424
+ 'options' => [
425
+ 'item_group_id' => 'Item Group ID[item_group_id]',
426
+ 'material' => 'Material[material]',
427
+ 'pattern' => 'Pattern[pattern]',
428
+ 'additional_image_link' => 'Additional Image Link[additional_image_link]',
429
+ ],
430
+ ],
431
+ 4 => [
432
+ 'optionGroup' => 'Other Information',
433
+ 'options' => [
434
+ 'adult' => 'Adult[adult]',
435
+ 'availability' => 'Availability[availability]',
436
+ 'product_category' => 'Product Category[product_category]',
437
+ 'condition' => 'Condition[condition]',
438
+ 'expiration_date' => 'Expiration Date[expiration_date]',
439
+ 'multipack' => 'Multipack[multipack]',
440
+ 'product_type' => 'Product Type[product_type]',
441
+ 'mobile_link' => 'Mobile Link[mobile_link]',
442
+ 'unit_pricing_measure' => 'Unit Pricing Measure[unit_pricing_measure]',
443
+ 'unit_pricing_base_measure' => 'Unit Pricing Base Measure[unit_pricing_base_measure]',
444
+ 'installment' => 'Installment[installment]',
445
+ 'energy_efficiency_class' => 'Energy Efficiency Class[energy_efficiency_class]',
446
+ 'min_energy_efficiency_class' => 'Min Energy Efficiency Class[min_energy_efficiency_class]',
447
+ 'max_energy_efficiency_class' => 'Max Energy Efficiency Class[max_energy_efficiency_class]',
448
+ 'seller_name' => 'Seller Name[seller_name]',
449
+ 'ads_redirect' => 'Ads Redirect[ads_redirect]',
450
+ 'custom_label_0' => 'Custom Label 0[custom_label_0]',
451
+ 'custom_label_1' => 'Custom Label 1[custom_label_1]',
452
+ 'custom_label_2' => 'Custom Label 2[custom_label_2]',
453
+ 'custom_label_3' => 'Custom Label 3[custom_label_3]',
454
+ 'custom_label_4' => 'Custom Label 4[custom_label_4]',
455
+ ],
456
+ ],
457
+ 5 => [
458
+ 'optionGroup' => 'Sales & Promotions',
459
+ 'options' => [
460
+ 'sale_price' => 'Sale Price[sale_price]',
461
+ 'sale_price_effective_date' => 'Sale Price Effective Date[sale_price_effective_date]',
462
+ 'promotion_ID' => 'Promotion ID[promotion_ID]',
463
+ ],
464
+ ],
465
+ 6 => [
466
+ 'optionGroup' => 'Local Product Inventory',
467
+ 'options' => [
468
+ 'store_code' => 'Store Code[store_code]',
469
+ 'itemid' => 'Item ID[itemid]',
470
+ 'quantity' => 'Quantity[quantity]',
471
+ 'weeks_of_supply' => 'Weeks Of Supply[weeks_of_supply]',
472
+ 'pick_up_method' => 'Pick Up Method[pick_up_method]',
473
+ 'pick_up_sla' => 'Pick Up SLA[pick_up_sla]',
474
+ ],
475
+ ],
476
+ ],
477
+ 'pinterest_rss' => [
478
+ 1 => [
479
+ 'optionGroup' => 'Basic Information',
480
+ 'options' => [
481
+ 'title' => 'Product Title[title]',
482
+ 'description' => 'Product Description[description]',
483
+ 'link' => 'Product URL[link]',
484
+ 'image' => 'Main Image[image]',
485
+ 'pubDate' => 'Publish Date[pubDate]',
486
+ 'guid' => 'GUID[guid]',
487
+ ],
488
+ ],
489
+ ],
490
+ 'googlereview' => [
491
+ 1 => [
492
+ 'optionGroup' => 'Basic Information',
493
+ 'options' => [
494
+ 'product_name' => 'Product Title [product_name]',
495
+ 'product_url' => 'Product URL [product_url]',
496
+ 'review_temp_gtin' => 'GTIN [gtin]',
497
+ 'review_temp_mpn' => 'MPN [mpn]',
498
+ 'review_temp_sku' => 'SKU [sku]',
499
+ 'review_temp_brand' => 'Brand [brand]',
500
+ ],
501
+ ],
502
+ ],
503
+ 'wine_searcher' => [
504
+ 1 => [
505
+ 'optionGroup' => 'Basic Information',
506
+ 'options' => [
507
+ 'name' => 'Product Title[name]',
508
+ 'description' => 'Product description[description]',
509
+ 'vintage' => 'Vintage[vintage]',
510
+ 'link' => 'Product URL[link]',
511
+ 'unit-size' => 'Unit Size[unit-size]',
512
+ 'price' => 'Price[price]',
513
+ 'url' => 'URL[url] ',
514
+ 'min-order' => 'Minimum Order[min-order]',
515
+ 'tax' => 'Tax[tax]',
516
+ 'offer-type' => 'Offer Type[offer-type]',
517
+ 'delivery-time' => 'Delivery Time[delivery-time]',
518
+ 'stock-level' => 'Stock Level[stock-level]',
519
+ ],
520
+ ],
521
+ ],
522
+ 'tiktok' => [
523
+ 1 => [
524
+ 'optionGroup' => 'Basic Information',
525
+ 'options' => [
526
+ 'sku_id' => 'SKU ID[id]',
527
+ 'title' => 'Product Title[title]',
528
+ 'description' => 'Product description[description]',
529
+ 'availability' => 'Availability[availability]',
530
+ 'condition' => 'Condition[condition]',
531
+ 'price' => 'Price[price]',
532
+ 'sale_price' => 'Sale Price[sale_price]',
533
+ 'shipping' => 'Shipping[shipping]',
534
+ 'tax ' => 'Tax[tax]',
535
+ 'shipping_weight' => 'Shipping Weight[shipping_weight]',
536
+ 'link' => 'Product URL[link]',
537
+ 'image_link' => 'Product Image[image_link]',
538
+ 'additional_image_link' => 'Additional Image [additional_image_link]',
539
+ 'item_group_id' => 'Parent ID[item_group_id]',
540
+ 'brand' => 'Product Brand[brand]',
541
+ 'gtin' => 'Gtin[gtin]',
542
+ 'mpn' => 'MPN[mpn]',
543
+ 'google_product_category' => 'Google Product Category[google_product_category]',
544
+ 'video_link' => 'Video Link[video_link]',
545
+ 'age_group' => 'Age Group[age_group]',
546
+ 'color' => 'Color[color]',
547
+ 'size' => 'Size[size]',
548
+ 'gender' => 'Gender[gender]',
549
+ 'material' => 'Material[material]',
550
+ 'pattern' => 'Pattern[pattern]',
551
+ 'product_type' => 'Product Type[product_type]',
552
+ 'ios_url' => 'IOS URL[ios_url]',
553
+ 'ios_app_store_id' => 'IOS App Store ID[ios_app_store_id]',
554
+ 'ios_app_name' => 'IOS App Name[ios_app_name]',
555
+ 'iPhone_url' => 'iPhone URL[iPhone_url]',
556
+ 'iPhone_app_store_id' => 'iPhone App Store ID[iPhone_app_store_id]',
557
+ 'iPhone_app_name' => 'iPhone App Name[iPhone_app_name]',
558
+ 'iPad_url' => 'iPad URL[iPad_url]',
559
+ 'iPad_app_store_id' => 'iPad App Store ID[iPad_app_store_id]',
560
+ 'iPad_app_name' => 'iPad App Name[iPad_app_name]',
561
+ 'android_url' => 'Android URL[android_url]',
562
+ 'android_package' => 'Android Package[android_package]',
563
+ 'android_app_name' => 'Android App Name[android_app_name]',
564
+ 'custom_label_0' => 'custom_label_0[custom_label_0]',
565
+ 'custom_label_1' => 'custom_label_1[custom_label_1]',
566
+ 'custom_label_2' => 'custom_label_2[custom_label_2]',
567
+ 'custom_label_3' => 'custom_label_3[custom_label_3]',
568
+ 'custom_label_4' => 'custom_label_4[custom_label_4]',
569
+ 'merchant_brand' => 'Merchant Brand[merchant_brand]',
570
+ 'productHisEval' => 'Purchase Count:FeedBack[productHisEval]',
571
+ 'sale_price_effective_date' => 'Sale Price Effective Date[sale_price_effective_date]',
572
+ ],
573
+ ],
574
+ ],
575
+ 'modalova' => [
576
+ 1 => [
577
+ 'optionGroup' => 'Basic Information',
578
+ 'options' => [
579
+ 'id' => 'Product ID[id]',
580
+ 'title' => 'Product Title[title]',
581
+ 'slug' => 'Product URL Slug[slug]',
582
+ 'description' => 'Product description[description]',
583
+ 'short_description' => 'Product Short description[short_description]',
584
+ 'link' => 'Product URL[link]',
585
+ 'sku' => 'SKU[sku]',
586
+ 'brand' => 'Product Brand[brand]',
587
+ 'main_image' => 'Product Image[main_image]',
588
+ 'featured_image' => 'Featured Image[featured_image]',
589
+ 'images' => 'Images[images]',
590
+ 'price' => 'Price[price]',
591
+ 'sale_price' => 'Sale Price[sale_price]',
592
+ 'availability' => 'Availability[availability]',
593
+ 'tags' => 'Tags[tags]',
594
+ 'color' => 'Color[color]',
595
+ 'size' => 'Size[size]',
596
+ 'quantity' => 'Quantity[quantity]',
597
+ 'parent_id' => 'Parent ID[parent_id]',
598
+ 'condition' => 'Condition[condition]',
599
+ 'category' => 'Category[category]',
600
+ 'parent_category' => 'Parent Category[parent_category]',
601
+ 'child_category' => 'Child Category[child_category]',
602
+ 'category_path' => 'Category Path[category_path]',
603
+ 'created_at' => 'Created At[created_at]',
604
+ 'updated_at' => 'Updated At[updated_at]',
605
+ ],
606
+ ],
607
+ ],
608
+ 'catchdotcom' => [
609
+ 1 => [
610
+ 'optionGroup' => 'Basic Information',
611
+ 'options' => [
612
+ 'product-id' => 'Product ID [product-id]',
613
+ 'title' => 'Product title [title]',
614
+ 'product-description' => 'Product Description[product-description]',
615
+ 'product-id-type' => 'Product ID Type[product-id-type]',
616
+ 'internal-sku' => 'Internal SKU[internal-sku]',
617
+ 'category' => 'Product Category[category]',
618
+ 'image-1' => 'Image 1 [image-1]',
619
+ 'images-2' => 'Image 2 [image-2]',
620
+ 'images-3' => 'Image 3 [image-3]',
621
+ 'images-4' => 'Image 4 [image-4]',
622
+ 'images-5' => 'Image 5 [image-5]',
623
+ 'images-6' => 'Image 6 [image-6]',
624
+ 'image-size-chart' => 'Image Size Chart[image-size-chart]',
625
+ 'brand' => 'Brand[brand]',
626
+ 'adult' => 'Adult[adult]',
627
+ 'keywords' => 'Keywords[keywords]',
628
+ 'sku' => 'Offer SKU[sku]',
629
+ 'inventory' => 'Facebook Inventory[inventory]',
630
+ 'override' => 'Facebook Override[override]',
631
+ 'price' => 'Regular Price[price]',
632
+ 'quantity' => 'Offer Quantity[quantity]',
633
+ 'min-quantity-alert' => 'Minimum Quantity Alert[min-quantity-alert]',
634
+ 'state' => 'Offer State[state]',
635
+ 'logistic-class' => 'Logistic Class[logistic-class]',
636
+ 'discount-price' => 'Discount Price[discount-price]',
637
+ 'leadtime-to-ship' => 'Lead Time to Ship[leadtime-to-ship]',
638
+ 'club-catch-eligible' => 'Club Catch eligible[club-catch-eligible]',
639
+ 'tax-au' => 'GST %[tax-au]',
640
+ ],
641
+ ],
642
+ ],
643
+ 'fashionchick' => [
644
+ 1 => [
645
+ 'optionGroup' => 'Basic Information',
646
+ 'options' => [
647
+ 'Product ID' => 'Product ID [Product ID]',
648
+ 'Titel' => 'Product Titel [Titel]',
649
+ 'Omschrijving' => 'Product Description [Omschrijving]',
650
+ 'Url' => 'Product URL [Url]',
651
+ 'Image' => 'Image [Image]',
652
+ 'Category' => 'Product Category [Category (pad)]',
653
+ 'Prijs' => 'Regular Price [Prijs]',
654
+ 'Merk' => 'Brand [Merk]',
655
+ 'Cluster ID' => 'Cluster ID [Cluster ID]',
656
+ 'internal-sku' => 'Internal SKU [internal-sku]',
657
+ 'sku' => 'Offer SKU[sku]',
658
+ 'Delivery Time' => 'Delivery Time [Delivery Time]',
659
+ 'Shipping Costs' => 'Shipping Costs [Shipping Costs]',
660
+ 'Old price' => 'Old price [Old price]',
661
+ 'Product maten' => 'Product sizes [Product maten]',
662
+ 'Stock' => 'Stock [Stock]',
663
+ 'Voorraad aantal' => 'Stock quantity [Voorraad aantal]',
664
+ 'Materiaal' => 'Material [Materiaal]',
665
+ 'Geslacht' => 'Gender [Geslacht]',
666
+ 'Kleur' => 'Color [Kleur]',
667
+ ],
668
+ ],
669
+ ],
670
+ 'goedgeplaatst' => [
671
+ 1 => [
672
+ 'optionGroup' => 'Basic Information',
673
+ 'options' => [
674
+ 'title' => 'Product Title [title]',
675
+ 'description' => 'Product Description [description]',
676
+ 'type' => 'Product Type [type]',
677
+ 'price' => 'Price [price]',
678
+ 'images' => 'Images [images]',
679
+ 'categoryId' => 'Category ID [categoryId]',
680
+ 'externalAdId' => 'External Ad ID [externalAdId]',
681
+ 'priceRetail' => 'Retail Price [priceRetail]',
682
+ 'priceOther' => 'Other Price [priceOther]',
683
+ 'bid' => 'Bid [bid]',
684
+ 'showContact' => 'Show Contact [showContact]',
685
+ 'website' => 'Website [website]',
686
+ 'name' => 'Name [name]',
687
+ 'phone' => 'Phone [phone]',
688
+ 'address' => 'Address [address]',
689
+ 'houseNumber' => 'House Number [houseNumber]',
690
+ 'postalCode' => 'Postal Code [postalCode]',
691
+ 'city' => 'City [city]',
692
+ 'country' => 'Country [country]',
693
+ 'autoReplace' => 'Auto Replace [autoReplace]',
694
+ 'directForwardToMp' => 'Direct Forward Mp [directForwardToMp]',
695
+ 'priceBidMinimal' => 'Price Bid Minimal [priceBidMinimal]',
696
+ 'priceBidAsking' => 'Price Bid Asking [priceBidAsking]',
697
+ ],
698
+ ],
699
+ ],
700
+ 'skroutz' => [
701
+ 1 => [
702
+ 'optionGroup' => 'Required Information',
703
+ 'options' => [
704
+ 'id' => 'Unique ID',
705
+ 'name' => 'Product Title',
706
+ 'description' => 'Product Description',
707
+ 'link' => 'Product Link',
708
+ 'image' => 'Image Link',
709
+ 'category' => 'Category Name',
710
+ 'price' => 'Price',
711
+ 'price_with_vat' => 'Price With Tax',
712
+ 'manufacturer' => 'Manufacturer',
713
+ 'mpn' => 'MPN / ISBN',
714
+ 'availability' => 'Availability',
715
+ ],
716
+ ],
717
+ 2 => [
718
+ 'optionGroup' => 'Additional Information',
719
+ 'options' => [
720
+ 'instock' => 'Stock Status [InStock]',
721
+ 'ean' => 'EAN / Barcode',
722
+ 'additionalimage' => 'Additional Image Link',
723
+ 'color' => 'Color',
724
+ 'size' => 'Size',
725
+ 'weight' => 'Weight',
726
+ 'quantity' => 'Quantity',
727
+ ],
728
+ ],
729
+ ],
730
+ 'daisycon' => [
731
+ 1 => [
732
+ 'optionGroup' => 'Required Attributes',
733
+ 'option' => [
734
+ 'sku' => 'Unique Product ID [SKU]',
735
+ 'description' => 'Description',
736
+ 'link' => 'Product URL',
737
+ 'price' => 'Price[Current/Sale Price]',
738
+ 'title' => 'Product Title',
739
+ ],
740
+ ],
741
+ 2 => [
742
+ 'optionGroup' => 'Highly Recommended Attributes',
743
+ 'option' => [
744
+ 'image_link_1' => 'Main Image',
745
+ 'brand' => 'Brand of the product',
746
+ 'category' => 'Main category',
747
+ 'category_path' => 'Category path',
748
+ 'delivery_time' => 'Delivery time in days',
749
+ 'ean' => 'EAN',
750
+ 'google_category_id' => 'Google category ID',
751
+ 'in_stock' => 'Stock status',
752
+ 'in_stock_amount' => 'Amount of items in stock',
753
+ 'price_old' => 'Old price [Regular Price (in case of discount prices)]',
754
+ ],
755
+ ],
756
+ 3 => [
757
+ 'optionGroup' => 'Recommended Attributes',
758
+ 'option' => [
759
+ 'color_primary' => 'Primary color of the product',
760
+ 'condition' => 'Product Condition',
761
+ 'gender_target' => 'Gender Target',
762
+ 'price_shipping' => 'Shipping costs',
763
+ 'image_link_2' => 'Image 2',
764
+ 'image_link_3' => 'Image 3',
765
+ 'image_link_4' => 'Image 4',
766
+ 'image_link_5' => 'Image 5',
767
+ 'image_link_6' => 'Image 6',
768
+ 'image_link_7' => 'Image 7',
769
+ 'image_link_8' => 'Image 8',
770
+ 'image_link_9' => 'Image 9',
771
+ ],
772
+ ],
773
+ 4 => [
774
+ 'optionGroup' => 'Optional Attributes',
775
+ 'option' => [
776
+ 'additional_costs' => 'Additional costs',
777
+ 'brand_logo' => 'Brand Logo URL',
778
+ 'delivery_description' => 'Description of the delivery method',
779
+ 'keywords' => 'Keywords [Tags]',
780
+ 'model' => 'Model name/number',
781
+ 'material_1' => 'The primary material',
782
+ 'material_2' => 'The secondary material',
783
+ 'material_3' => 'The tertiary material',
784
+ 'priority' => 'Priority of the product',
785
+ 'size' => 'General Size field',
786
+ 'size_description' => 'Description for the “size” field',
787
+ 'terms_conditions' => 'Full terms and conditions',
788
+ ],
789
+ ],
790
+ ],
791
+ 'daisycon_automotive' => [
792
+ 1 => [
793
+ 'optionGroup' => 'Required Attributes',
794
+ 'option' => [
795
+ 'description' => "Description of the product",
796
+ 'link' => "URL to the page of the product",
797
+ 'price' => "Price [Current/Sale Price]",
798
+ 'sku' => "Unique Product ID [SKU]",
799
+ 'title' => "Complete name of the product",
800
+ ],
801
+ ],
802
+ 2 => [
803
+ 'optionGroup' => 'Highly Recommended Attributes',
804
+ 'option' => [
805
+ 'brand' => "Brand of the product",
806
+ 'category' => "Main category",
807
+ 'category_path' => "Category path",
808
+ 'color_primary' => "Primary color of the product",
809
+ 'delivery_time' => "Delivery time in days",
810
+ 'ean' => "EAN",
811
+ 'google_category_id' => "Google category ID",
812
+ 'in_stock' => "Stock status",
813
+ 'in_stock_amount' => "Amount of items in stock",
814
+ 'price_old' => "Old price [Regular Price]",
815
+ 'image_link_1' => "Main Image",
816
+ ],
817
+ ],
818
+ 3 => [
819
+ 'optionGroup' => 'Recommended Attributes',
820
+ 'option' => [
821
+ 'condition' => "Product Condition",
822
+ 'price_shipping' => "Shipping costs",
823
+ 'image_link_2' => "Image 2",
824
+ 'image_link_3' => "Image 3",
825
+ 'image_link_4' => "Image 4",
826
+ 'image_link_5' => "Image 5",
827
+ 'image_link_6' => "Image 6",
828
+ 'image_link_7' => "Image 7",
829
+ 'image_link_8' => "Image 8",
830
+ 'image_link_9' => "Image 9",
831
+ ],
832
+ ],
833
+ 4 => [
834
+ 'optionGroup' => 'Optional Attributes',
835
+ 'option' => [
836
+ 'additional_costs' => "Additional costs",
837
+ 'brake_system' => "Brake system type",
838
+ 'brand_logo' => "Brand Logo URL",
839
+ 'delivery_description' => "Description of the delivery method",
840
+ 'fuel_type' => "Fuel type",
841
+ 'gear_system' => "Gear system type",
842
+ 'gender_target' => "Gender Target",
843
+ 'has_airco' => "Is there an airco present",
844
+ 'keywords' => "Keywords [Tags]",
845
+ 'model' => "Model name/number",
846
+ 'material_1' => "The primary material",
847
+ 'material_2' => "The secondary material",
848
+ 'material_3' => "The tertiary material",
849
+ 'priority' => "Priority of the product",
850
+ 'rental_location_city' => "City of a rental car's pick up location (if applicable)",
851
+ 'rental_location_country' => "Country of a rental car's pick up location (if applicable)",
852
+ 'rental_location_region' => "Region of a rental car's pick up location (if applicable)",
853
+ 'size' => "General field for size",
854
+ 'size_description' => "Description for the “size” field",
855
+ 'tire_size' => "The measurements of the tire size of the product.",
856
+ 'year_built' => "Year in which the product is fabricated",
857
+ 'terms_conditions' => "Full terms and conditions",
858
+ ],
859
+ ],
860
+ ],
861
+ 'daisycon_books' => [
862
+ 1 => [
863
+ 'optionGroup' => 'Required Attributes',
864
+ 'option' => [
865
+ 'description' => "Description of the product",
866
+ 'link' => "URL to the page of the product",
867
+ 'price' => "Price [Current/Sale Price]",
868
+ 'sku' => "Unique Product ID [SKU]",
869
+ 'title' => "Complete name of the product",
870
+ ],
871
+ ],
872
+ 2 => [
873
+ 'optionGroup' => 'Highly Recommended Attributes',
874
+ 'option' => [
875
+ 'author' => "Name of the author",
876
+ 'category' => "Main category",
877
+ 'category_path' => "Category path",
878
+ 'delivery_time' => "Delivery time in days",
879
+ 'ean' => "EAN",
880
+ 'google_category_id' => "Google category ID",
881
+ 'in_stock' => "Stock status",
882
+ 'in_stock_amount' => "Amount of items in stock",
883
+ 'isbn' => "ISBN of the book/magazine",
884
+ 'price_old' => "Old price [Regular Price]",
885
+ 'image_link_1' => "Main Image",
886
+ ],
887
+ ],
888
+ 3 => [
889
+ 'optionGroup' => 'Recommended Attributes',
890
+ 'option' => [
891
+ 'book_publisher' => "Publisher of the book",
892
+ 'book_type' => "Type of book",
893
+ 'price_shipping' => "Shipping costs",
894
+ 'image_link_2' => "Image 2",
895
+ 'image_link_3' => "Image 3",
896
+ 'image_link_4' => "Image 4",
897
+ 'image_link_5' => "Image 5",
898
+ 'image_link_6' => "Image 6",
899
+ 'image_link_7' => "Image 7",
900
+ 'image_link_8' => "Image 8",
901
+ 'image_link_9' => "Image 9",
902
+ ],
903
+ ],
904
+ 4 => [
905
+ 'optionGroup' => 'Low Priority Attributes',
906
+ 'option' => [
907
+ 'condition' => "Product Condition",
908
+ 'gender_target' => "Gender to which the product is aimed",
909
+ 'number_of_pages' => "Number of pages",
910
+ 'release_date' => "Date of publication",
911
+ ],
912
+ ],
913
+ 5 => [
914
+ 'optionGroup' => 'Optional Attributes',
915
+ 'option' => [
916
+ 'additional_costs' => "Additional costs",
917
+ 'book_edition' => "Edition of the book",
918
+ 'brand' => "Brand of the product",
919
+ 'brand_logo' => "URL to an image of the brand logo",
920
+ 'color_primary' => "Primary color of the product",
921
+ 'delivery_description' => "Description of the delivery method",
922
+ 'file_size' => "Total file size in kbps",
923
+ 'file_type' => "File type (for example: epub)",
924
+ 'keywords' => "Keywords for this product",
925
+ 'language' => "Language of the product",
926
+ 'model' => "Model name/number",
927
+ 'priority' => "Priority of the product",
928
+ 'size' => "General field for size",
929
+ 'size_description' => "Description for the “size” field",
930
+ 'size_length' => "Magazine length in mm",
931
+ 'size_width' => "Magazine width in mm",
932
+ 'weight' => "Weight in grams",
933
+ 'material_1' => "The primary material",
934
+ 'material_2' => "The secondary material",
935
+ 'material_3' => "The tertiary material",
936
+ 'terms_conditions' => "Full terms and conditions",
937
+ ],
938
+ ],
939
+ ],
940
+ 'daisycon_cosmetics' => [
941
+ 1 => [
942
+ 'optionGroup' => 'Required Attributes',
943
+ 'option' => [
944
+ 'description' => "Description of the product",
945
+ 'link' => "URL to the page of the product",
946
+ 'price' => "Price [Current/Sale Price]",
947
+ 'sku' => "Unique Product ID [SKU]",
948
+ 'title' => "Complete name of the product",
949
+ ],
950
+ ],
951
+ 2 => [
952
+ 'optionGroup' => 'Highly Recommended Attributes',
953
+ 'option' => [
954
+ 'allergic_info' => "Allergy information",
955
+ 'amount_content' => "Amount of content, for example: 120(in combination with amount_description)",
956
+ 'amount_description' => "The unit in which the amount is specified for example: ml",
957
+ 'category' => "Main category",
958
+ 'category_path' => "Category path",
959
+ 'delivery_time' => "Delivery time in days",
960
+ 'ean' => "EAN",
961
+ 'google_category_id' => "Google category ID",
962
+ 'in_stock' => "Stock status",
963
+ 'in_stock_amount' => "Amount of items in stock",
964
+ 'price_old' => "Old price [Regular Price]",
965
+ 'image_link_1' => "Main Image",
966
+ ],
967
+ ],
968
+ 3 => [
969
+ 'optionGroup' => 'Recommended Attributes',
970
+ 'option' => [
971
+ 'description_ingredients' => "Description of the ingredients",
972
+ 'gender_target' => "Gender to which the product is aimed",
973
+ 'price_shipping' => "Shipping costs",
974
+ 'skin_type' => "Skintype for which the product is made",
975
+ 'image_link_2' => "Image 2",
976
+ 'image_link_3' => "Image 3",
977
+ 'image_link_4' => "Image 4",
978
+ 'image_link_5' => "Image 5",
979
+ 'image_link_6' => "Image 6",
980
+ 'image_link_7' => "Image 7",
981
+ 'image_link_8' => "Image 8",
982
+ 'image_link_9' => "Image 9",
983
+ ],
984
+ ],
985
+ 4 => [
986
+ 'optionGroup' => 'Low Priority Attributes',
987
+ 'option' => [
988
+ 'color_primary' => "Primary color of the product",
989
+ ],
990
+ ],
991
+ 5 => [
992
+ 'optionGroup' => 'Optional Attributes',
993
+ 'option' => [
994
+ 'additional_costs' => "Additional costs",
995
+ 'brand_logo' => "URL to an image of the brand logo",
996
+ 'condition' => "Product Condition",
997
+ 'delivery_description' => "Description of the delivery method",
998
+ 'keywords' => "Keywords for this product",
999
+ 'made_in_country' => "Country in which the product is fabricated",
1000
+ 'model' => "Model name/number",
1001
+ 'priority' => "Priority of the product",
1002
+ 'size' => "General field for size",
1003
+ 'size_description' => "Description for the “size” field",
1004
+ 'weight' => "Weight in grams",
1005
+ 'material_1' => "The primary material",
1006
+ 'material_2' => "The secondary material",
1007
+ 'material_3' => "The tertiary material",
1008
+ 'terms_conditions' => "Full terms and conditions",
1009
+ ],
1010
+ ],
1011
+ ],
1012
+ 'daisycon_daily_offers' => [
1013
+ 1 => [
1014
+ 'optionGroup' => 'Required Attributes',
1015
+ 'option' => [
1016
+ 'description' => "Description of the product",
1017
+ 'link' => "URL to the page of the product",
1018
+ 'price' => "Price [Current/Sale Price]",
1019
+ 'sku' => "Unique Product ID [SKU]",
1020
+ 'title' => "Complete name of the product",
1021
+ ],
1022
+ ],
1023
+ 2 => [
1024
+ 'optionGroup' => 'Highly Recommended Attributes',
1025
+ 'option' => [
1026
+ 'brand' => "Brand of the product",
1027
+ 'category' => "Main category",
1028
+ 'category_path' => "Category path",
1029
+ 'delivery_time' => "Delivery time in days",
1030
+ 'ean' => "EAN",
1031
+ 'in_stock' => "Stock status",
1032
+ 'in_stock_amount' => "Amount of items in stock",
1033
+ 'price_old' => "Old price [Regular Price]",
1034
+ 'image_link_1' => "Main Image",
1035
+ ],
1036
+ ],
1037
+ 3 => [
1038
+ 'optionGroup' => 'Recommended Attributes',
1039
+ 'option' => [
1040
+ 'google_category_id' => "Google category ID",
1041
+ 'price_shipping' => "Shipping costs",
1042
+ 'image_link_2' => "Image 2",
1043
+ 'image_link_3' => "Image 3",
1044
+ 'image_link_4' => "Image 4",
1045
+ 'image_link_5' => "Image 5",
1046
+ 'image_link_6' => "Image 6",
1047
+ 'image_link_7' => "Image 7",
1048
+ 'image_link_8' => "Image 8",
1049
+ 'image_link_9' => "Image 9",
1050
+ ],
1051
+ ],
1052
+ 4 => [
1053
+ 'optionGroup' => 'Optional Attributes',
1054
+ 'option' => [
1055
+ 'additional_costs' => "Additional costs",
1056
+ 'brand_logo' => "URL to an image of the brand logo",
1057
+ 'color_primary' => "Primary color of the product",
1058
+ 'condition' => "Product Condition",
1059
+ 'delivery_description' => "Description of the delivery method",
1060
+ 'discount_amount' => "Amount of discount in euro's",
1061
+ 'discount_percentage' => "Amount of discount in percent",
1062
+ 'gender_target' => "Gender to which the product is aimed",
1063
+ 'keywords' => "Keywords for this product",
1064
+ 'model' => "Model name/number",
1065
+ 'offer_datetime_end' => "End (time and) date of the daily offer",
1066
+ 'offer_datetime_start' => "Start (time and) date of the daily offer",
1067
+ 'size' => "General field for size",
1068
+ 'size_description' => "Description for the “size” field",
1069
+ 'material_1' => "The primary material",
1070
+ 'material_2' => "The secondary material",
1071
+ 'material_3' => "The tertiary material",
1072
+ 'terms_conditions' => "Full terms and conditions",
1073
+ ],
1074
+ ],
1075
+ ],
1076
+ 'daisycon_electronics' => [
1077
+ 1 => [
1078
+ 'optionGroup' => 'Required Attributes',
1079
+ 'option' => [
1080
+ 'description' => "Description of the product",
1081
+ 'link' => "URL to the page of the product",
1082
+ 'price' => "Price [Current/Sale Price]",
1083
+ 'sku' => "Unique Product ID [SKU]",
1084
+ 'title' => "Complete name of the product",
1085
+ ],
1086
+ ],
1087
+ 2 => [
1088
+ 'optionGroup' => 'Highly Recommended Attributes',
1089
+ 'option' => [
1090
+ 'brand' => "Brand of the product",
1091
+ 'category' => "Main category",
1092
+ 'category_path' => "Category path",
1093
+ 'delivery_time' => "Delivery time in days",
1094
+ 'ean' => "EAN",
1095
+ 'google_category_id' => "Google category ID",
1096
+ 'in_stock' => "Stock status",
1097
+ 'in_stock_amount' => "Amount of items in stock",
1098
+ 'model' => "Model name/number",
1099
+ 'price_old' => "Old price [Regular Price]",
1100
+ 'image_link_1' => "Main Image",
1101
+ ],
1102
+ ],
1103
+ 3 => [
1104
+ 'optionGroup' => 'Recommended Attributes',
1105
+ 'option' => [
1106
+ 'color_primary' => "Primary color of the product",
1107
+ 'price_shipping' => "Shipping costs",
1108
+ 'image_link_2' => "Image 2",
1109
+ 'image_link_3' => "Image 3",
1110
+ 'image_link_4' => "Image 4",
1111
+ 'image_link_5' => "Image 5",
1112
+ 'image_link_6' => "Image 6",
1113
+ 'image_link_7' => "Image 7",
1114
+ 'image_link_8' => "Image 8",
1115
+ 'image_link_9' => "Image 9",
1116
+ ],
1117
+ ],
1118
+ 4 => [
1119
+ 'optionGroup' => 'Low Priority Attributes',
1120
+ 'option' => [
1121
+ 'condition' => "Product Condition",
1122
+ ],
1123
+ ],
1124
+ 5 => [
1125
+ 'optionGroup' => 'Optional Attributes',
1126
+ 'option' => [
1127
+ 'additional_costs' => "Additional costs",
1128
+ 'audio_surround' => "Has audio surround sound",
1129
+ 'batteries_included' => "Specifies is batteries are included at the purchase of the product",
1130
+ 'brand_logo' => "URL to an image of the brand logo",
1131
+ 'connection_type' => "Connection type, for example: USB",
1132
+ 'delivery_description' => "Description of the delivery method",
1133
+ 'device_max_content' => "Maximum content of the product, for example: 7KG or 3L",
1134
+ 'device_max_temperature' => "Maximum temperature the device can reach in Celsius",
1135
+ 'device_serve_amount' => "Amount of portions/persons the product can serve.",
1136
+ 'device_watt' => "Maximum wattage of the product for example: 450",
1137
+ 'dishwasher_safe' => "Product is dishwasher proof",
1138
+ 'disposal_fee' => "Disposal fee of the product in euro’s",
1139
+ 'file_types_supported' => "Supported filetypes",
1140
+ 'gender_target' => "Gender to which the product is aimed",
1141
+ 'has_alarm' => "Product has an alarm",
1142
+ 'has_grill' => "Product has a grill option, or a grill is present",
1143
+ 'has_microwave' => "Product has a microwave option or a microwave is present",
1144
+ 'has_oven' => "Product has an oven option or an oven is present",
1145
+ 'has_radio' => "Product has a radio option or a radio is pressent",
1146
+ 'has_remote_control' => "Product has a remote",
1147
+ 'has_timer' => "Product has a timer",
1148
+ 'has_wifi' => "Product has a wifi connection or wifi is present",
1149
+ 'keywords' => "Keywords for this product",
1150
+ 'made_in_country' => "Country in which the product is fabricated",
1151
+ 'partnumber' => "Part Number [MPN]",
1152
+ 'power_type' => "Type of energysource, for example: gas, electric, ceramic",
1153
+ 'price_suggested_retail' => "Suggested price",
1154
+ 'priority' => "Priority of the product",
1155
+ 'resolution_record' => "Camera recording resolution of the product (for example: 1280x768, 350dpi or 10MP)",
1156
+ 'resolution_screen' => "Screenresolution of the product (For example: 1280x768 or 350dpi)",
1157
+ 'screen_size' => "Screensize in inches",
1158
+ 'screen_type' => "Screentype of the product (for example: LED/3D/etc.)",
1159
+ 'size' => "General field for size",
1160
+ 'size_description' => "Description for the “size” field",
1161
+ 'size_length' => "Product length in mm",
1162
+ 'size_width' => "Product width in mm",
1163
+ 'specs' => "All specifications/functionalities of the product",
1164
+ 'terms_conditions' => "Full terms and conditions",
1165
+ 'material_1' => "The primary material",
1166
+ 'material_2' => "The secondary material",
1167
+ 'material_3' => "The tertiary material",
1168
+ ],
1169
+ ],
1170
+ ],
1171
+ 'name' => [],
1172
+ ];
1173
+ }
1174
+ }
V5/Merchant/Merchants.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Merchant;
3
+ use CTXFeed\V5\Common\DropDown;
4
+
5
+ class Merchants
6
+ {
7
+
8
+ public static function get_template_config()
9
+ {
10
+
11
+ }
12
+
13
+ public static function get_template_info()
14
+ {
15
+
16
+ }
17
+
18
+
19
+ private static function get_merchants()
20
+ {
21
+
22
+ }
23
+ }
V5/Merchant/TemplateConfig.php ADDED
@@ -0,0 +1,10379 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Merchant;
3
+ class TemplateConfig {
4
+
5
+ private static $template;
6
+ private static $brand;
7
+ private static $currency;
8
+
9
+ public function __construct( $merchant = null, $currency = null, $brand = null ) {
10
+ self::$template = ! empty( $merchant ) ? $merchant : 'default';
11
+ self::$brand = ! empty( $brand ) ? $brand : self::default_brand();
12
+ self::$currency = ! empty( $currency ) ? $currency : get_woocommerce_currency();
13
+ }
14
+
15
+
16
+ /**
17
+ * Guess Brand name from Site URL
18
+ *
19
+ * @return string
20
+ */
21
+ public static function default_brand() {
22
+ $brand = apply_filters( 'woo_feed_pre_get_default_brand_name', null );
23
+ if ( ! is_null( $brand ) ) {
24
+ return $brand;
25
+ }
26
+ $brand = '';
27
+ $url = filter_var( site_url(), FILTER_SANITIZE_URL );
28
+ if ( false !== $url ) {
29
+ $url = wp_parse_url( $url );
30
+ if ( array_key_exists( 'host', $url ) ) {
31
+ if ( strpos( $url['host'], "." ) !== false ) {
32
+ $arr = explode( '.', $url['host'] );
33
+ $brand = $arr[ count( $arr ) - 2 ];
34
+ $brand = ucfirst( $brand );
35
+ } else {
36
+ $brand = $url['host'];
37
+ $brand = ucfirst( $brand );
38
+ }
39
+ }
40
+ }
41
+
42
+ return apply_filters( 'woo_feed_get_default_brand_name', $brand );
43
+ }
44
+
45
+ public static function get() {
46
+ $config = array(
47
+ 'default' => array(
48
+ 'mattributes' => array(
49
+ 'id',
50
+ 'title',
51
+ 'description',
52
+ 'link',
53
+ 'image_link',
54
+ 'price',
55
+ 'categories',
56
+ 'brand',
57
+ ),
58
+ 'prefix' => array( '', '', '', '', '', '', '', '' ),
59
+ 'type' => array(
60
+ 'attribute',
61
+ 'attribute',
62
+ 'attribute',
63
+ 'attribute',
64
+ 'attribute',
65
+ 'attribute',
66
+ 'attribute',
67
+ 'attribute',
68
+ ),
69
+ 'attributes' => array(
70
+ 'id',
71
+ 'title',
72
+ 'description',
73
+ 'link',
74
+ 'image',
75
+ 'price',
76
+ 'product_type',
77
+ '',
78
+ ),
79
+ 'default' => array( '', '', '', '', '', '', '', self::$brand ),
80
+ 'suffix' => array( '', '', '', '', '', '', '', '' ),
81
+ 'output_type' => array( '1', '1', '11', '1', '1', '1', '1', '1' ),
82
+ 'limit' => array( '', '', '', '', '', '', '', '' ),
83
+ ),
84
+ 'google' => array(
85
+ 'mattributes' => array(
86
+ 'id',
87
+ 'title',
88
+ 'description',
89
+ 'item_group_id',
90
+ 'link',
91
+ 'product_type',
92
+ 'current_category',
93
+ 'image',
94
+ 'condition',
95
+ 'availability',
96
+ 'price',
97
+ 'sale_price',
98
+ 'sku',
99
+ 'brand',
100
+ 'canonical_link',
101
+ 'images_1',
102
+ 'images_2',
103
+ 'images_3',
104
+ 'images_4',
105
+ 'images_5'
106
+ ),
107
+ 'prefix' => array(
108
+ '',
109
+ '',
110
+ '',
111
+ '',
112
+ '',
113
+ '',
114
+ '',
115
+ '',
116
+ '',
117
+ '',
118
+ '',
119
+ '',
120
+ '',
121
+ '',
122
+ '',
123
+ '',
124
+ '',
125
+ '',
126
+ '',
127
+ ''
128
+ ),
129
+ 'type' => array(
130
+ 'attribute',
131
+ 'attribute',
132
+ 'attribute',
133
+ 'attribute',
134
+ 'attribute',
135
+ 'attribute',
136
+ 'pattern',
137
+ 'attribute',
138
+ 'pattern',
139
+ 'attribute',
140
+ 'attribute',
141
+ 'attribute',
142
+ 'attribute',
143
+ 'pattern',
144
+ 'attribute',
145
+ 'attribute',
146
+ 'attribute',
147
+ 'attribute',
148
+ 'attribute',
149
+ 'attribute'
150
+ ),
151
+ 'attributes' => array(
152
+ 'id',
153
+ 'title',
154
+ 'description',
155
+ 'item_group_id',
156
+ 'link',
157
+ 'product_type',
158
+ '',
159
+ 'image',
160
+ '',
161
+ 'availability',
162
+ 'price',
163
+ 'current_price',
164
+ 'sku',
165
+ '',
166
+ 'canonical_link',
167
+ 'image_1',
168
+ 'image_2',
169
+ 'image_3',
170
+ 'image_4',
171
+ 'image_5'
172
+ ),
173
+ 'default' => array(
174
+ '',
175
+ '',
176
+ '',
177
+ '',
178
+ '',
179
+ '',
180
+ '',
181
+ '',
182
+ 'new',
183
+ '',
184
+ '',
185
+ '',
186
+ '',
187
+ self::$brand,
188
+ '',
189
+ '',
190
+ '',
191
+ '',
192
+ '',
193
+ ''
194
+ ),
195
+ 'suffix' => array(
196
+ '',
197
+ '',
198
+ '',
199
+ '',
200
+ '',
201
+ '',
202
+ '',
203
+ '',
204
+ '',
205
+ '',
206
+ ' ' . self::$currency,
207
+ ' ' . self::$currency,
208
+ '',
209
+ '',
210
+ '',
211
+ '',
212
+ '',
213
+ '',
214
+ '',
215
+ ''
216
+ ),
217
+ 'output_type' => array(
218
+ '1',
219
+ '1',
220
+ '11',
221
+ '1',
222
+ '1',
223
+ '1',
224
+ '1',
225
+ '1',
226
+ '1',
227
+ '1',
228
+ '6',
229
+ '6',
230
+ '1',
231
+ '1',
232
+ '1',
233
+ '1',
234
+ '1',
235
+ '1',
236
+ '1',
237
+ '1'
238
+ ),
239
+ 'limit' => array(
240
+ '',
241
+ '',
242
+ '',
243
+ '',
244
+ '',
245
+ '',
246
+ '',
247
+ '',
248
+ '',
249
+ '',
250
+ '',
251
+ '',
252
+ '',
253
+ '',
254
+ '',
255
+ '',
256
+ '',
257
+ '',
258
+ '',
259
+ ''
260
+ ),
261
+ ),
262
+ 'facebook' => array(
263
+ 'mattributes' => array(
264
+ 'id',
265
+ 'title',
266
+ 'description',
267
+ 'item_group_id',
268
+ 'link',
269
+ 'product_type',
270
+ 'fb_product_category',
271
+ 'image',
272
+ 'condition',
273
+ 'availability',
274
+ 'price',
275
+ 'sale_price',
276
+ 'brand',
277
+ 'images_1',
278
+ 'images_2',
279
+ 'images_3',
280
+ 'images_4',
281
+ 'images_5'
282
+ ),
283
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' ),
284
+ 'type' => array(
285
+ 'attribute',
286
+ 'attribute',
287
+ 'attribute',
288
+ 'attribute',
289
+ 'attribute',
290
+ 'attribute',
291
+ 'pattern',
292
+ 'attribute',
293
+ 'pattern',
294
+ 'attribute',
295
+ 'attribute',
296
+ 'attribute',
297
+ 'pattern',
298
+ 'attribute',
299
+ 'attribute',
300
+ 'attribute',
301
+ 'attribute',
302
+ 'attribute'
303
+ ),
304
+ 'attributes' => array(
305
+ 'id',
306
+ 'title',
307
+ 'description',
308
+ 'item_group_id',
309
+ 'link',
310
+ 'product_type',
311
+ '',
312
+ 'image',
313
+ '',
314
+ 'availability',
315
+ 'price',
316
+ 'current_price',
317
+ '',
318
+ 'image_1',
319
+ 'image_2',
320
+ 'image_3',
321
+ 'image_4',
322
+ 'image_5'
323
+ ),
324
+ 'default' => array(
325
+ '',
326
+ '',
327
+ '',
328
+ '',
329
+ '',
330
+ '',
331
+ '',
332
+ '',
333
+ 'new',
334
+ '',
335
+ '',
336
+ '',
337
+ self::$brand,
338
+ '',
339
+ '',
340
+ '',
341
+ '',
342
+ ''
343
+ ),
344
+ 'suffix' => array(
345
+ '',
346
+ '',
347
+ '',
348
+ '',
349
+ '',
350
+ '',
351
+ '',
352
+ '',
353
+ '',
354
+ '',
355
+ ' ' . self::$currency,
356
+ ' ' . self::$currency,
357
+ '',
358
+ '',
359
+ '',
360
+ '',
361
+ '',
362
+ ''
363
+ ),
364
+ 'output_type' => array(
365
+ '1',
366
+ '1',
367
+ '11',
368
+ '1',
369
+ '1',
370
+ '1',
371
+ '1',
372
+ '1',
373
+ '1',
374
+ '1',
375
+ '6',
376
+ '6',
377
+ '1',
378
+ '1',
379
+ '1',
380
+ '1',
381
+ '1',
382
+ '1'
383
+ ),
384
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' ),
385
+ ),
386
+ 'pinterest_rss' => array(
387
+ 'mattributes' => array( 'title', 'description', 'link', 'image', 'pubDate', 'guid' ),
388
+ 'prefix' => array( '', '', '', '', '', '' ),
389
+ 'type' => array( 'attribute', 'attribute', 'attribute', 'attribute', 'attribute', 'attribute' ),
390
+ 'attributes' => array( 'title', 'description', 'link', 'image', 'date_created', 'link' ),
391
+ 'default' => array( '', '', '', '', '', '' ),
392
+ 'suffix' => array( '', '', '', '', '', '' ),
393
+ 'output_type' => array( '1', '11', '1', '1', '1', '1' ),
394
+ 'limit' => array( '', '', '', '', '', '' ),
395
+ ),
396
+ 'bol' => array(
397
+ 'mattributes' => array(
398
+ 'EAN',
399
+ 'Internal Reference',
400
+ 'Name',
401
+ 'Product Classification',
402
+ 'Description',
403
+ 'Cover Image URL',
404
+ 'Brand',
405
+ ),
406
+ 'prefix' => array( '', '', '', '', '', '', '' ),
407
+ 'type' => array(
408
+ 'attribute',
409
+ 'attribute',
410
+ 'attribute',
411
+ 'attribute',
412
+ 'attribute',
413
+ 'attribute',
414
+ 'pattern',
415
+ ),
416
+ 'attributes' => array(
417
+ 'sku',
418
+ 'id',
419
+ 'title',
420
+ 'product_type',
421
+ 'description',
422
+ 'image',
423
+ '',
424
+ ),
425
+ 'default' => array( '', '', '', '', '', '', self::$brand ),
426
+ 'suffix' => array( '', '', '', '', '', '', '' ),
427
+ 'output_type' => array( '1', '1', '1', '1', '1, 2, 11', '1', '' ),
428
+ 'limit' => array( '', '', '', '', '', '', '' ),
429
+ ),
430
+ 'adform' => array(
431
+ 'mattributes' => array(
432
+ 'product_id',
433
+ 'product_name',
434
+ 'product_category_id',
435
+ 'product_deeplink',
436
+ 'product_image',
437
+ 'product_price',
438
+ ),
439
+ 'prefix' => array( '', '', '', '', '', '' ),
440
+ 'type' => array(
441
+ 'attribute',
442
+ 'attribute',
443
+ 'attribute',
444
+ 'attribute',
445
+ 'attribute',
446
+ 'attribute',
447
+ ),
448
+ 'attributes' => array( 'id', 'title', 'product_type', 'link', 'image', 'price' ),
449
+ 'default' => array( '', '', '', '', '', '' ),
450
+ 'suffix' => array( '', '', '', '', '', '' ),
451
+ 'output_type' => array( '1', '1', '1', '1', '1', '1' ),
452
+ 'limit' => array( '', '', '', '', '', '' ),
453
+ ),
454
+ 'avantlink' => array(
455
+ 'mattributes' => array(
456
+ 'SKU',
457
+ 'Brand Name',
458
+ 'Product Name',
459
+ 'Long Description',
460
+ 'Category',
461
+ 'Standardized Categorization',
462
+ 'Image URL',
463
+ 'Buy Link',
464
+ 'Retail Price',
465
+ 'Sale Price',
466
+ 'UPC',
467
+ ),
468
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '' ),
469
+ 'type' => array(
470
+ 'attribute',
471
+ 'pattern',
472
+ 'attribute',
473
+ 'attribute',
474
+ 'attribute',
475
+ 'attribute',
476
+ 'attribute',
477
+ 'attribute',
478
+ 'attribute',
479
+ 'attribute',
480
+ 'attribute',
481
+ ),
482
+ 'attributes' => array(
483
+ 'sku',
484
+ '',
485
+ 'title',
486
+ 'description',
487
+ 'product_type',
488
+ '',
489
+ 'image',
490
+ 'link',
491
+ 'price',
492
+ 'sale_price',
493
+ '',
494
+ ),
495
+ 'default' => array(
496
+ '',
497
+ self::$brand,
498
+ '',
499
+ '',
500
+ '',
501
+ '',
502
+ '',
503
+ '',
504
+ '',
505
+ '',
506
+ '',
507
+ ),
508
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '', '' ),
509
+ 'output_type' => array( '1', '1', '1', '11', '1', '1', '1', '1', '1', '1', '1' ),
510
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '' ),
511
+ ),
512
+ 'become' => array(
513
+ 'mattributes' => array(
514
+ 'Unique ID',
515
+ 'Title',
516
+ 'Description',
517
+ 'Category',
518
+ 'Product URL',
519
+ 'Image URL',
520
+ 'Condition',
521
+ 'Availability',
522
+ 'Current Price',
523
+ ),
524
+ 'prefix' => array( '', '', '', '', '', '', '', '', '' ),
525
+ 'type' => array(
526
+ 'attribute',
527
+ 'attribute',
528
+ 'attribute',
529
+ 'attribute',
530
+ 'attribute',
531
+ 'attribute',
532
+ 'attribute',
533
+ 'attribute',
534
+ 'attribute',
535
+ ),
536
+ 'attributes' => array(
537
+ 'id',
538
+ 'title',
539
+ 'description',
540
+ 'product_type',
541
+ 'link',
542
+ 'image',
543
+ 'condition',
544
+ 'availability',
545
+ 'price',
546
+ ),
547
+ 'default' => array( '', '', '', '', '', '', '', '', '' ),
548
+ 'suffix' => array( '', '', '', '', '', '', '', '', '' ),
549
+ 'output_type' => array( '1', '1', '11', '1', '1', '1', '1', '1', '6' ),
550
+ 'limit' => array( '', '', '', '', '', '', '', '', '' ),
551
+ ),
552
+ 'bonanza' => array(
553
+ 'mattributes' => array(
554
+ 'id',
555
+ 'title',
556
+ 'description',
557
+ 'price',
558
+ 'images',
559
+ 'category',
560
+ 'booth_category',
561
+ 'shipping_price',
562
+ 'shipping_type',
563
+ 'shipping_service',
564
+ 'shipping_lbs',
565
+ 'shipping_oz',
566
+ 'shipping_carrier',
567
+ 'shipping_package',
568
+ 'sku',
569
+ 'worldwide_shipping_price',
570
+ 'worldwide_shipping_type',
571
+ 'worldwide_shipping_carrier',
572
+ 'quantity',
573
+ 'trait',
574
+ 'force_update',
575
+ ),
576
+ 'prefix' => array(
577
+ '',
578
+ '',
579
+ '',
580
+ '',
581
+ '',
582
+ '',
583
+ '',
584
+ '',
585
+ '',
586
+ '',
587
+ '',
588
+ '',
589
+ '',
590
+ '',
591
+ '',
592
+ '',
593
+ '',
594
+ '',
595
+ '',
596
+ '',
597
+ '',
598
+ ),
599
+ 'type' => array(
600
+ 'attribute',
601
+ 'attribute',
602
+ 'attribute',
603
+ 'attribute',
604
+ 'attribute',
605
+ 'pattern',
606
+ 'attribute',
607
+ 'pattern',
608
+ 'pattern',
609
+ 'pattern',
610
+ 'pattern',
611
+ 'pattern',
612
+ 'pattern',
613
+ 'pattern',
614
+ 'attribute',
615
+ 'pattern',
616
+ 'pattern',
617
+ 'pattern',
618
+ 'attribute',
619
+ 'pattern',
620
+ 'pattern',
621
+ ),
622
+ 'attributes' => array(
623
+ 'id',
624
+ 'title',
625
+ 'description',
626
+ 'price',
627
+ 'image',
628
+ '',
629
+ 'product_type',
630
+ '',
631
+ '',
632
+ '',
633
+ '',
634
+ '',
635
+ '',
636
+ '',
637
+ 'sku',
638
+ '',
639
+ '',
640
+ '',
641
+ 'quantity',
642
+ '',
643
+ '',
644
+ ),
645
+ 'default' => array(
646
+ '',
647
+ '',
648
+ '',
649
+ '',
650
+ '',
651
+ '',
652
+ '',
653
+ '',
654
+ '',
655
+ '',
656
+ '',
657
+ '',
658
+ '',
659
+ '',
660
+ '',
661
+ '',
662
+ '',
663
+ '',
664
+ '',
665
+ '',
666
+ '',
667
+ ),
668
+ 'suffix' => array(
669
+ '',
670
+ '',
671
+ '',
672
+ '',
673
+ '',
674
+ '',
675
+ '',
676
+ '',
677
+ '',
678
+ '',
679
+ '',
680
+ '',
681
+ '',
682
+ '',
683
+ '',
684
+ '',
685
+ '',
686
+ '',
687
+ '',
688
+ '',
689
+ '',
690
+ ),
691
+ 'output_type' => array(
692
+ '1',
693
+ '1',
694
+ '11',
695
+ '1',
696
+ '1',
697
+ '1',
698
+ '1',
699
+ '1',
700
+ '1',
701
+ '1',
702
+ '1',
703
+ '1',
704
+ '1',
705
+ '1',
706
+ '1',
707
+ '1',
708
+ '1',
709
+ '1',
710
+ '1',
711
+ '1',
712
+ '1',
713
+ ),
714
+ 'limit' => array(
715
+ '',
716
+ '',
717
+ '',
718
+ '',
719
+ '',
720
+ '',
721
+ '',
722
+ '',
723
+ '',
724
+ '',
725
+ '',
726
+ '',
727
+ '',
728
+ '',
729
+ '',
730
+ '',
731
+ '',
732
+ '',
733
+ '',
734
+ '',
735
+ '',
736
+ ),
737
+ ),
738
+ 'criteo' => array(
739
+ 'mattributes' => array(
740
+ 'ID',
741
+ 'title',
742
+ 'description',
743
+ 'google_product_category',
744
+ 'link',
745
+ 'image_link',
746
+ 'additional_image_link',
747
+ 'availability',
748
+ 'price',
749
+ 'sale_price',
750
+ 'gtin',
751
+ 'mpn',
752
+ 'brand',
753
+ 'product_type',
754
+ 'product_type_key',
755
+ 'number_of_reviews',
756
+ 'product_rating',
757
+ 'filters',
758
+ 'adult',
759
+ ),
760
+ 'prefix' => array(
761
+ '',
762
+ '',
763
+ '',
764
+ '',
765
+ '',
766
+ '',
767
+ '',
768
+ '',
769
+ '',
770
+ '',
771
+ '',
772
+ '',
773
+ '',
774
+ '',
775
+ '',
776
+ '',
777
+ '',
778
+ '',
779
+ '',
780
+ ),
781
+ 'type' => array(
782
+ 'attribute',
783
+ 'attribute',
784
+ 'attribute',
785
+ 'attribute',
786
+ 'attribute',
787
+ 'attribute',
788
+ 'attribute',
789
+ 'attribute',
790
+ 'attribute',
791
+ 'attribute',
792
+ 'attribute',
793
+ 'attribute',
794
+ 'pattern',
795
+ 'attribute',
796
+ 'attribute',
797
+ 'attribute',
798
+ 'attribute',
799
+ 'attribute',
800
+ 'attribute',
801
+ ),
802
+ 'attributes' => array(
803
+ 'id',
804
+ 'title',
805
+ 'description',
806
+ 'product_type',
807
+ 'link',
808
+ 'image',
809
+ 'images',
810
+ 'availability',
811
+ 'price',
812
+ 'sale_price',
813
+ '',
814
+ '',
815
+ '',
816
+ '',
817
+ '',
818
+ '',
819
+ '',
820
+ '',
821
+ '',
822
+ ),
823
+ 'default' => array(
824
+ '',
825
+ '',
826
+ '',
827
+ '',
828
+ '',
829
+ '',
830
+ '',
831
+ '',
832
+ '',
833
+ '',
834
+ '',
835
+ '',
836
+ self::$brand,
837
+ '',
838
+ '',
839
+ '',
840
+ '',
841
+ '',
842
+ '',
843
+ ),
844
+ 'suffix' => array(
845
+ '',
846
+ '',
847
+ '',
848
+ '',
849
+ '',
850
+ '',
851
+ '',
852
+ '',
853
+ '',
854
+ '',
855
+ '',
856
+ '',
857
+ '',
858
+ '',
859
+ '',
860
+ '',
861
+ '',
862
+ '',
863
+ '',
864
+ ),
865
+ 'output_type' => array(
866
+ '1',
867
+ '1',
868
+ '11',
869
+ '1',
870
+ '1',
871
+ '1',
872
+ '1',
873
+ '1',
874
+ '1',
875
+ '1',
876
+ '1',
877
+ '1',
878
+ '1',
879
+ '1',
880
+ '1',
881
+ '1',
882
+ '1',
883
+ '1',
884
+ '1',
885
+ ),
886
+ 'limit' => array(
887
+ '240',
888
+ '150',
889
+ '5000',
890
+ '',
891
+ '1024',
892
+ '2000',
893
+ '2000',
894
+ '25',
895
+ '14',
896
+ '50',
897
+ '50',
898
+ '70',
899
+ '70',
900
+ '500',
901
+ '500',
902
+ '8',
903
+ '8',
904
+ '2000',
905
+ '',
906
+ ),
907
+ ),
908
+ 'crowdfox' => array(
909
+ 'mattributes' => array(
910
+ 'sku ',
911
+ 'image',
912
+ 'name',
913
+ 'price',
914
+ 'ean',
915
+ 'dlv_time',
916
+ 'dlv_cost',
917
+ 'obl_info',
918
+ 'brand',
919
+ 'mpn',
920
+ 'link',
921
+ 'desc',
922
+ 'sell_max',
923
+ 'shop_cat',
924
+ ),
925
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '', '', '', '' ),
926
+ 'type' => array(
927
+ 'attribute',
928
+ 'attribute',
929
+ 'attribute',
930
+ 'attribute',
931
+ 'attribute',
932
+ 'pattern',
933
+ 'pattern',
934
+ 'attribute',
935
+ 'pattern',
936
+ 'attribute',
937
+ 'attribute',
938
+ 'attribute',
939
+ 'attribute',
940
+ 'attribute',
941
+ ),
942
+ 'attributes' => array(
943
+ 'sku',
944
+ 'image',
945
+ 'title',
946
+ 'price',
947
+ '',
948
+ '',
949
+ '',
950
+ '',
951
+ '',
952
+ '',
953
+ 'link',
954
+ 'description',
955
+ 'quantity',
956
+ 'product_type',
957
+ ),
958
+ 'default' => array(
959
+ '',
960
+ '',
961
+ '',
962
+ '',
963
+ '',
964
+ '',
965
+ '',
966
+ '',
967
+ self::$brand,
968
+ '',
969
+ '',
970
+ '',
971
+ '',
972
+ '',
973
+ ),
974
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '', '', '', '', '' ),
975
+ 'output_type' => array(
976
+ '1',
977
+ '1',
978
+ '1',
979
+ '1',
980
+ '1',
981
+ '1',
982
+ '1',
983
+ '1',
984
+ '1',
985
+ '1',
986
+ '1',
987
+ '11',
988
+ '1',
989
+ '1',
990
+ ),
991
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '', '', '', '' ),
992
+ ),
993
+ 'fruugo' => array(
994
+ 'mattributes' => array(
995
+ 'ProductId',
996
+ 'SkuId',
997
+ 'EAN',
998
+ 'Brand',
999
+ 'Category',
1000
+ 'Imageurl1',
1001
+ 'StockStatus',
1002
+ 'StockQuantity',
1003
+ 'Title',
1004
+ 'Description',
1005
+ 'NormalPriceWithoutVAT',
1006
+ 'DiscountPriceWithoutVAT',
1007
+ 'VatRate',
1008
+ 'Currency',
1009
+ 'Country',
1010
+ ),
1011
+ 'prefix' => array(
1012
+ '',
1013
+ '',
1014
+ '',
1015
+ '',
1016
+ '',
1017
+ '',
1018
+ '',
1019
+ '',
1020
+ '',
1021
+ '',
1022
+ '',
1023
+ '',
1024
+ '',
1025
+ '',
1026
+ '',
1027
+ ),
1028
+ 'type' => array(
1029
+ 'attribute',
1030
+ 'attribute',
1031
+ 'attribute',
1032
+ 'pattern',
1033
+ 'attribute',
1034
+ 'attribute',
1035
+ 'attribute',
1036
+ 'attribute',
1037
+ 'attribute',
1038
+ 'attribute',
1039
+ 'attribute',
1040
+ 'attribute',
1041
+ 'attribute',
1042
+ 'pattern',
1043
+ 'attribute',
1044
+ ),
1045
+ 'attributes' => array(
1046
+ 'id',
1047
+ 'sku',
1048
+ '',
1049
+ '',
1050
+ 'product_type',
1051
+ 'image',
1052
+ 'availability',
1053
+ 'quantity',
1054
+ 'title',
1055
+ 'description',
1056
+ 'price',
1057
+ 'sale_price',
1058
+ '',
1059
+ '',
1060
+ '',
1061
+ ),
1062
+ 'default' => array(
1063
+ '',
1064
+ '',
1065
+ '',
1066
+ self::$brand,
1067
+ '',
1068
+ '',
1069
+ '',
1070
+ '',
1071
+ '',
1072
+ '',
1073
+ '',
1074
+ '',
1075
+ '',
1076
+ ' ' . self::$currency,
1077
+ '',
1078
+ ),
1079
+ 'suffix' => array(
1080
+ '',
1081
+ '',
1082
+ '',
1083
+ '',
1084
+ '',
1085
+ '',
1086
+ '',
1087
+ '',
1088
+ '',
1089
+ '',
1090
+ '',
1091
+ '',
1092
+ '',
1093
+ '',
1094
+ '',
1095
+ ),
1096
+ 'output_type' => array(
1097
+ '1',
1098
+ '1',
1099
+ '1',
1100
+ '1',
1101
+ '1',
1102
+ '1',
1103
+ '1',
1104
+ '1',
1105
+ '1',
1106
+ '11',
1107
+ '1',
1108
+ '1',
1109
+ '1',
1110
+ '1',
1111
+ '1',
1112
+ ),
1113
+ 'limit' => array(
1114
+ '',
1115
+ '',
1116
+ '',
1117
+ '',
1118
+ '',
1119
+ '',
1120
+ '',
1121
+ '',
1122
+ '',
1123
+ '',
1124
+ '',
1125
+ '',
1126
+ '',
1127
+ '',
1128
+ '',
1129
+ ),
1130
+ ),
1131
+ 'jet' => array(
1132
+ 'mattributes' => array(
1133
+ 'Merchant SKU ID',
1134
+ 'Unique ID',
1135
+ 'Multi-pack Quantity',
1136
+ 'Product Title',
1137
+ 'Description',
1138
+ 'Image',
1139
+ 'Product Price',
1140
+ 'Jet Category',
1141
+ 'Brand',
1142
+ ),
1143
+ 'prefix' => array( '', '', '', '', '', '', '', '', '' ),
1144
+ 'type' => array(
1145
+ 'attribute',
1146
+ 'attribute',
1147
+ 'pattern',
1148
+ 'attribute',
1149
+ 'attribute',
1150
+ 'attribute',
1151
+ 'attribute',
1152
+ 'pattern',
1153
+ 'pattern',
1154
+ ),
1155
+ 'attributes' => array(
1156
+ 'sku',
1157
+ 'id',
1158
+ '',
1159
+ 'title',
1160
+ 'description',
1161
+ 'image',
1162
+ 'price',
1163
+ '',
1164
+ '',
1165
+ ),
1166
+ 'default' => array( '', '', '', '', '', '', '', '', self::$brand ),
1167
+ 'suffix' => array( '', '', '', '', '', '', '', '', '' ),
1168
+ 'output_type' => array( '1', '1', '1', '1', '11', '1', '1', '1', '1' ),
1169
+ 'limit' => array( '', '', '', '', '', '', '', '', '' ),
1170
+ ),
1171
+ 'kelkoo' => array(
1172
+ 'mattributes' => array(
1173
+ 'title',
1174
+ 'product-url',
1175
+ 'price',
1176
+ 'merchant-category',
1177
+ 'ean',
1178
+ 'delivery-cost',
1179
+ 'brand',
1180
+ 'description',
1181
+ 'image-url',
1182
+ 'availability',
1183
+ 'mpn',
1184
+ ),
1185
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '' ),
1186
+ 'type' => array(
1187
+ 'attribute',
1188
+ 'attribute',
1189
+ 'attribute',
1190
+ 'attribute',
1191
+ 'attribute',
1192
+ 'attribute',
1193
+ 'pattern',
1194
+ 'attribute',
1195
+ 'attribute',
1196
+ 'attribute',
1197
+ 'attribute',
1198
+ ),
1199
+ 'attributes' => array(
1200
+ 'title',
1201
+ 'link',
1202
+ 'price',
1203
+ '',
1204
+ '',
1205
+ '',
1206
+ '',
1207
+ 'description',
1208
+ 'image',
1209
+ 'availability',
1210
+ '',
1211
+ ),
1212
+ 'default' => array(
1213
+ '',
1214
+ '',
1215
+ '',
1216
+ '',
1217
+ '',
1218
+ '',
1219
+ self::$brand,
1220
+ '',
1221
+ '',
1222
+ '',
1223
+ '',
1224
+ ),
1225
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '', '' ),
1226
+ 'output_type' => array( '1', '1', '1', '1', '1', '1', '1', '11', '1', '1', '1' ),
1227
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '' ),
1228
+ ),
1229
+ 'kieskeurig.nl' => array(
1230
+ 'mattributes' => array(
1231
+ 'id',
1232
+ 'productgroep',
1233
+ 'merk',
1234
+ 'type',
1235
+ 'toevoeging-type',
1236
+ 'extra-productbeschrijving',
1237
+ 'partnumber',
1238
+ 'ean-code',
1239
+ 'prijs',
1240
+ 'verzendkosten',
1241
+ 'afhaalkosten',
1242
+ 'levertijd',
1243
+ 'deeplink',
1244
+ 'imagelink',
1245
+ 'voorraad',
1246
+ ),
1247
+ 'prefix' => array(
1248
+ '',
1249
+ '',
1250
+ '',
1251
+ '',
1252
+ '',
1253
+ '',
1254
+ '',
1255
+ '',
1256
+ '',
1257
+ '',
1258
+ '',
1259
+ '',
1260
+ '',
1261
+ '',
1262
+ '',
1263
+ ),
1264
+ 'type' => array(
1265
+ 'attribute',
1266
+ 'attribute',
1267
+ 'attribute',
1268
+ 'attribute',
1269
+ 'attribute',
1270
+ 'attribute',
1271
+ 'attribute',
1272
+ 'attribute',
1273
+ 'attribute',
1274
+ 'attribute',
1275
+ 'attribute',
1276
+ 'attribute',
1277
+ 'attribute',
1278
+ 'attribute',
1279
+ 'attribute',
1280
+ ),
1281
+ 'attributes' => array(
1282
+ 'id',
1283
+ 'product_type',
1284
+ 'title',
1285
+ 'type',
1286
+ '',
1287
+ 'description',
1288
+ '',
1289
+ '',
1290
+ 'price',
1291
+ '',
1292
+ '',
1293
+ '',
1294
+ 'link',
1295
+ 'image',
1296
+ 'quantity',
1297
+ ),
1298
+ 'default' => array(
1299
+ '',
1300
+ '',
1301
+ '',
1302
+ '',
1303
+ '',
1304
+ '',
1305
+ '',
1306
+ '',
1307
+ '',
1308
+ '',
1309
+ '',
1310
+ '',
1311
+ '',
1312
+ '',
1313
+ '',
1314
+ ),
1315
+ 'suffix' => array(
1316
+ '',
1317
+ '',
1318
+ '',
1319
+ '',
1320
+ '',
1321
+ '',
1322
+ '',
1323
+ '',
1324
+ '',
1325
+ '',
1326
+ '',
1327
+ '',
1328
+ '',
1329
+ '',
1330
+ '',
1331
+ ),
1332
+ 'output_type' => array(
1333
+ '1',
1334
+ '1',
1335
+ '1',
1336
+ '1',
1337
+ '1',
1338
+ '11',
1339
+ '1',
1340
+ '1',
1341
+ '1',
1342
+ '1',
1343
+ '1',
1344
+ '1',
1345
+ '1',
1346
+ '1',
1347
+ '1',
1348
+ ),
1349
+ 'limit' => array(
1350
+ '',
1351
+ '',
1352
+ '',
1353
+ '',
1354
+ '',
1355
+ '',
1356
+ '',
1357
+ '',
1358
+ '',
1359
+ '',
1360
+ '',
1361
+ '',
1362
+ '',
1363
+ '',
1364
+ '',
1365
+ ),
1366
+ ),
1367
+ 'kijiji.ca' => array(
1368
+ 'mattributes' => array(
1369
+ 'id',
1370
+ 'title',
1371
+ 'description',
1372
+ 'link',
1373
+ 'image_link',
1374
+ 'price',
1375
+ 'categories',
1376
+ 'brand',
1377
+ ),
1378
+ 'prefix' => array( '', '', '', '', '', '', '', '' ),
1379
+ 'type' => array(
1380
+ 'attribute',
1381
+ 'attribute',
1382
+ 'attribute',
1383
+ 'attribute',
1384
+ 'attribute',
1385
+ 'attribute',
1386
+ 'attribute',
1387
+ 'pattern',
1388
+ ),
1389
+ 'attributes' => array(
1390
+ 'id',
1391
+ 'title',
1392
+ 'description',
1393
+ 'link',
1394
+ 'image',
1395
+ 'price',
1396
+ 'product_type',
1397
+ '',
1398
+ ),
1399
+ 'default' => array( '', '', '', '', '', '', '', self::$brand ),
1400
+ 'suffix' => array( '', '', '', '', '', '', '', '' ),
1401
+ 'output_type' => array( '1', '1', '11', '1', '1', '1', '1', '1' ),
1402
+ 'limit' => array( '', '', '', '', '', '', '', '' ),
1403
+ ),
1404
+ 'leguide' => array(
1405
+ 'mattributes' => array(
1406
+ 'category',
1407
+ 'unique_id',
1408
+ 'title',
1409
+ 'description',
1410
+ 'price',
1411
+ 'product_URL',
1412
+ 'landing_URL',
1413
+ 'image_URL',
1414
+ 'EAN',
1415
+ 'delivery_charge',
1416
+ 'delivery_time',
1417
+ 'availability',
1418
+ 'guarantee',
1419
+ ),
1420
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '', '', '' ),
1421
+ 'type' => array(
1422
+ 'attribute',
1423
+ 'attribute',
1424
+ 'attribute',
1425
+ 'attribute',
1426
+ 'attribute',
1427
+ 'attribute',
1428
+ 'attribute',
1429
+ 'attribute',
1430
+ 'attribute',
1431
+ 'pattern',
1432
+ 'pattern',
1433
+ 'pattern',
1434
+ 'pattern',
1435
+ ),
1436
+ 'attributes' => array(
1437
+ 'product_type',
1438
+ 'id',
1439
+ 'title',
1440
+ 'description',
1441
+ 'price',
1442
+ 'link',
1443
+ '',
1444
+ 'image',
1445
+ 'sku',
1446
+ '',
1447
+ '',
1448
+ '',
1449
+ '',
1450
+ ),
1451
+ 'default' => array( '', '', '', '', '', '', '', '', '', '', '', '', '' ),
1452
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '', '', '', '' ),
1453
+ 'output_type' => array(
1454
+ '1',
1455
+ '1',
1456
+ '1',
1457
+ '11',
1458
+ '1',
1459
+ '1',
1460
+ '1',
1461
+ '1',
1462
+ '1',
1463
+ '1',
1464
+ '1',
1465
+ '1',
1466
+ '1',
1467
+ ),
1468
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '', '', '' ),
1469
+ ),
1470
+ 'modina.de' => array(
1471
+ 'mattributes' => array(
1472
+ 'id',
1473
+ 'brand',
1474
+ 'title',
1475
+ 'description',
1476
+ 'productLink',
1477
+ 'imageLink',
1478
+ 'imageLinkAdditional',
1479
+ 'price',
1480
+ 'priceOld',
1481
+ 'shippingCost',
1482
+ 'shippingDuration',
1483
+ 'availability',
1484
+ 'gtin',
1485
+ 'mpn',
1486
+ 'category',
1487
+ 'subcategory',
1488
+ 'color',
1489
+ 'gender',
1490
+ 'material',
1491
+ 'pattern',
1492
+ 'size',
1493
+ ),
1494
+ 'prefix' => array(
1495
+ '',
1496
+ '',
1497
+ '',
1498
+ '',
1499
+ '',
1500
+ '',
1501
+ '',
1502
+ '',
1503
+ '',
1504
+ '',
1505
+ '',
1506
+ '',
1507
+ '',
1508
+ '',
1509
+ '',
1510
+ '',
1511
+ '',
1512
+ '',
1513
+ '',
1514
+ '',
1515
+ '',
1516
+ ),
1517
+ 'type' => array(
1518
+ 'attribute',
1519
+ 'pattern',
1520
+ 'attribute',
1521
+ 'attribute',
1522
+ 'attribute',
1523
+ 'attribute',
1524
+ 'attribute',
1525
+ 'attribute',
1526
+ 'attribute',
1527
+ 'attribute',
1528
+ 'attribute',
1529
+ 'attribute',
1530
+ 'attribute',
1531
+ 'attribute',
1532
+ 'attribute',
1533
+ 'attribute',
1534
+ 'attribute',
1535
+ 'attribute',
1536
+ 'attribute',
1537
+ 'attribute',
1538
+ 'attribute',
1539
+ ),
1540
+ 'attributes' => array(
1541
+ 'id',
1542
+ '',
1543
+ 'title',
1544
+ 'description',
1545
+ 'link',
1546
+ 'image',
1547
+ 'images',
1548
+ 'price',
1549
+ '',
1550
+ '',
1551
+ '',
1552
+ 'availability',
1553
+ '',
1554
+ '',
1555
+ 'product_type',
1556
+ '',
1557
+ '',
1558
+ '',
1559
+ '',
1560
+ '',
1561
+ '',
1562
+ ),
1563
+ 'default' => array(
1564
+ '',
1565
+ self::$brand,
1566
+ '',
1567
+ '',
1568
+ '',
1569
+ '',
1570
+ '',
1571
+ '',
1572
+ '',
1573
+ '',
1574
+ '',
1575
+ '',
1576
+ '',
1577
+ '',
1578
+ '',
1579
+ '',
1580
+ '',
1581
+ '',
1582
+ '',
1583
+ '',
1584
+ '',
1585
+ ),
1586
+ 'suffix' => array(
1587
+ '',
1588
+ '',
1589
+ '',
1590
+ '',
1591
+ '',
1592
+ '',
1593
+ '',
1594
+ '',
1595
+ '',
1596
+ '',
1597
+ '',
1598
+ '',
1599
+ '',
1600
+ '',
1601
+ '',
1602
+ '',
1603
+ '',
1604
+ '',
1605
+ '',
1606
+ '',
1607
+ '',
1608
+ ),
1609
+ 'output_type' => array(
1610
+ '1',
1611
+ '1',
1612
+ '1',
1613
+ '11',
1614
+ '1',
1615
+ '1',
1616
+ '1',
1617
+ '1',
1618
+ '1',
1619
+ '1',
1620
+ '1',
1621
+ '1',
1622
+ '1',
1623
+ '1',
1624
+ '1',
1625
+ '1',
1626
+ '1',
1627
+ '1',
1628
+ '1',
1629
+ '1',
1630
+ '1',
1631
+ ),
1632
+ 'limit' => array(
1633
+ '',
1634
+ '',
1635
+ '',
1636
+ '',
1637
+ '',
1638
+ '',
1639
+ '',
1640
+ '',
1641
+ '',
1642
+ '',
1643
+ '',
1644
+ '',
1645
+ '',
1646
+ '',
1647
+ '',
1648
+ '',
1649
+ '',
1650
+ '',
1651
+ '',
1652
+ '',
1653
+ '',
1654
+ ),
1655
+ ),
1656
+ 'myshopping.com.au' => array(
1657
+ 'mattributes' => array(
1658
+ 'Code',
1659
+ 'Id',
1660
+ 'Name',
1661
+ 'Description',
1662
+ 'Category',
1663
+ 'price',
1664
+ 'Product_URL',
1665
+ 'Image_URL',
1666
+ 'Brand',
1667
+ 'InStock',
1668
+ 'MPN',
1669
+ ),
1670
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '' ),
1671
+ 'type' => array(
1672
+ 'pattern',
1673
+ 'attribute',
1674
+ 'attribute',
1675
+ 'attribute',
1676
+ 'attribute',
1677
+ 'attribute',
1678
+ 'attribute',
1679
+ 'attribute',
1680
+ 'attribute',
1681
+ 'pattern',
1682
+ 'attribute',
1683
+ ),
1684
+ 'attributes' => array(
1685
+ '',
1686
+ 'id',
1687
+ 'title',
1688
+ 'description',
1689
+ 'product_type',
1690
+ 'price',
1691
+ 'link',
1692
+ 'image',
1693
+ '',
1694
+ '',
1695
+ 'sku',
1696
+ ),
1697
+ 'default' => array( '', '', '', '', '', '', '', '', '', 'Y', '' ),
1698
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '', '' ),
1699
+ 'output_type' => array( '1', '1', '1', '11', '1', '1', '1', '1', '1', '1', '1' ),
1700
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '' ),
1701
+ ),
1702
+ 'nextag' => array(
1703
+ 'mattributes' => array(
1704
+ 'Manufacturer',
1705
+ 'Product Name',
1706
+ 'Product Description',
1707
+ 'Price',
1708
+ 'Click-Out URL',
1709
+ 'Category',
1710
+ 'Image URL',
1711
+ 'Stock Status',
1712
+ 'Condition',
1713
+ ),
1714
+ 'prefix' => array( '', '', '', '$', '', '', '', '', '' ),
1715
+ 'type' => array(
1716
+ 'pattern',
1717
+ 'attribute',
1718
+ 'attribute',
1719
+ 'attribute',
1720
+ 'attribute',
1721
+ 'attribute',
1722
+ 'attribute',
1723
+ 'attribute',
1724
+ 'attribute',
1725
+ ),
1726
+ 'attributes' => array(
1727
+ '',
1728
+ 'title',
1729
+ 'description',
1730
+ 'price',
1731
+ 'link',
1732
+ 'product_type',
1733
+ 'image',
1734
+ 'availability',
1735
+ 'condition',
1736
+ ),
1737
+ 'default' => array( '', '', '', '', '', '', '', '', '' ),
1738
+ 'suffix' => array( '', '', '', '', '', '', '', '', '' ),
1739
+ 'output_type' => array( '1', '1', '11', '1', '1', '1', '1', '1', '1' ),
1740
+ 'limit' => array( '', '', '', '', '', '', '', '', '' ),
1741
+ ),
1742
+ 'polyvore' => array(
1743
+ 'mattributes' => array(
1744
+ 'title',
1745
+ 'brand',
1746
+ 'url',
1747
+ 'imgurl',
1748
+ 'price',
1749
+ 'currency',
1750
+ 'description',
1751
+ 'subject',
1752
+ ),
1753
+ 'prefix' => array( '', '', '', '', '', '', '', '' ),
1754
+ 'type' => array(
1755
+ 'attribute',
1756
+ 'pattern',
1757
+ 'attribute',
1758
+ 'attribute',
1759
+ 'attribute',
1760
+ 'pattern',
1761
+ 'attribute',
1762
+ 'pattern',
1763
+ ),
1764
+ 'attributes' => array(
1765
+ 'title',
1766
+ '',
1767
+ 'link',
1768
+ 'image',
1769
+ 'price',
1770
+ '',
1771
+ 'description',
1772
+ '',
1773
+ ),
1774
+ 'default' => array(
1775
+ '',
1776
+ self::$brand,
1777
+ '',
1778
+ '',
1779
+ '',
1780
+ ' ' . self::$currency,
1781
+ '',
1782
+ '',
1783
+ ),
1784
+ 'suffix' => array( '', '', '', '', '', '', '', '' ),
1785
+ 'output_type' => array( '1', '1', '1', '1', '1', '1', '11', '1' ),
1786
+ 'limit' => array( '', '', '', '', '', '', '', '' ),
1787
+ ),
1788
+ 'pricegrabber' => array(
1789
+ 'mattributes' => array(
1790
+ 'Retsku',
1791
+ 'Product Title',
1792
+ 'Detailed Description',
1793
+ 'Categorization',
1794
+ 'Product URL',
1795
+ 'Primary Image URL',
1796
+ 'Selling Price',
1797
+ 'Regular Price',
1798
+ 'Condition',
1799
+ 'Availability',
1800
+ 'Manufacturer Name',
1801
+ 'GTIN',
1802
+ ),
1803
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
1804
+ 'type' => array(
1805
+ 'attribute',
1806
+ 'attribute',
1807
+ 'attribute',
1808
+ 'attribute',
1809
+ 'attribute',
1810
+ 'attribute',
1811
+ 'attribute',
1812
+ 'attribute',
1813
+ 'attribute',
1814
+ 'attribute',
1815
+ 'attribute',
1816
+ 'attribute',
1817
+ ),
1818
+ 'attributes' => array(
1819
+ 'sku',
1820
+ 'title',
1821
+ 'description',
1822
+ 'product_type',
1823
+ 'link',
1824
+ 'image',
1825
+ 'sale_price',
1826
+ 'price',
1827
+ 'condition',
1828
+ 'availability',
1829
+ '',
1830
+ '',
1831
+ ),
1832
+ 'default' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
1833
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
1834
+ 'output_type' => array(
1835
+ '1',
1836
+ '1',
1837
+ '11',
1838
+ '1',
1839
+ '1',
1840
+ '1',
1841
+ '1',
1842
+ '1',
1843
+ '1',
1844
+ '1',
1845
+ '1',
1846
+ '1',
1847
+ ),
1848
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
1849
+ ),
1850
+ 'pricerunner' => array(
1851
+ 'mattributes' => array(
1852
+ 'Category',
1853
+ 'SKU',
1854
+ 'Price',
1855
+ 'Product URL',
1856
+ 'Product name',
1857
+ 'Manufacturer SKU',
1858
+ 'Manufacturer',
1859
+ 'EAN',
1860
+ 'Description',
1861
+ 'Graphic URL',
1862
+ 'In Stock',
1863
+ 'Stock Level',
1864
+ 'Shipping Cost',
1865
+ 'Delivery time'
1866
+ ),
1867
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '', '', '', '' ),
1868
+ 'type' => array(
1869
+ 'attribute',
1870
+ 'attribute',
1871
+ 'attribute',
1872
+ 'attribute',
1873
+ 'attribute',
1874
+ 'attribute',
1875
+ 'pattern',
1876
+ 'attribute',
1877
+ 'attribute',
1878
+ 'attribute',
1879
+ 'attribute',
1880
+ 'attribute',
1881
+ 'pattern',
1882
+ 'pattern'
1883
+ ),
1884
+ 'attributes' => array(
1885
+ 'product_type',
1886
+ 'id',
1887
+ 'price',
1888
+ 'link',
1889
+ 'title',
1890
+ 'sku',
1891
+ '',
1892
+ 'sku',
1893
+ 'description',
1894
+ 'image',
1895
+ 'availability',
1896
+ 'quantity',
1897
+ '',
1898
+ ''
1899
+ ),
1900
+ 'default' => array( '', '', '', '', '', '', '', '', '', '', '', '', '10.00', '5-7 days' ),
1901
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '', '', '', '', '' ),
1902
+ 'output_type' => array( '1', '1', '1', '1', '1', '1', '1', '1', '11', '1', '1', '1', '1', '1' ),
1903
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '', '', '', '' ),
1904
+ ),
1905
+ 'prisjakt' => array(
1906
+ 'mattributes' => array(
1907
+ 'Produktnamn',
1908
+ 'Art.nr.',
1909
+ 'Kategori',
1910
+ 'Pris inkl.moms',
1911
+ 'Produkt-URL',
1912
+ 'Tillverkare',
1913
+ 'Tillverkar-SKU',
1914
+ 'Frakt',
1915
+ 'Bild-URL',
1916
+ 'Lagerstatus',
1917
+ ),
1918
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '' ),
1919
+ 'type' => array(
1920
+ 'attribute',
1921
+ 'attribute',
1922
+ 'attribute',
1923
+ 'attribute',
1924
+ 'attribute',
1925
+ 'pattern',
1926
+ 'attribute',
1927
+ 'pattern',
1928
+ 'attribute',
1929
+ 'attribute',
1930
+ ),
1931
+ 'attributes' => array(
1932
+ 'title',
1933
+ 'id',
1934
+ 'product_type',
1935
+ 'price',
1936
+ 'link',
1937
+ '',
1938
+ 'sku',
1939
+ '',
1940
+ 'image',
1941
+ 'condition',
1942
+ ),
1943
+ 'default' => array( '', '', '', '', '', '', '', '', 'mens, womens', '' ),
1944
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '' ),
1945
+ 'output_type' => array( '1', '1', '1', '1', '1', '1', '1', '1', '1', '1' ),
1946
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '' ),
1947
+ ),
1948
+ 'real' => array(
1949
+ 'mattributes' => array(
1950
+ 'ean',
1951
+ 'category',
1952
+ 'title',
1953
+ 'description',
1954
+ 'picture',
1955
+ 'manufacturer',
1956
+ ),
1957
+ 'prefix' => array( '', '', '', '', '', '' ),
1958
+ 'type' => array(
1959
+ 'attribute',
1960
+ 'attribute',
1961
+ 'attribute',
1962
+ 'attribute',
1963
+ 'attribute',
1964
+ 'pattern',
1965
+ ),
1966
+ 'attributes' => array(
1967
+ 'sku',
1968
+ 'product_type',
1969
+ 'title',
1970
+ 'description',
1971
+ 'image',
1972
+ '',
1973
+ ),
1974
+ 'default' => array( '', '', '', '', '', self::$brand ),
1975
+ 'suffix' => array( '', '', '', '', '', '' ),
1976
+ 'output_type' => array( '1', '1', '1', '11', '1', '1' ),
1977
+ 'limit' => array( '', '', '', '', '', '' ),
1978
+ ),
1979
+ 'shareasale' => array(
1980
+ 'mattributes' => array(
1981
+ 'ProductID',
1982
+ 'Name',
1983
+ 'MerchantID',
1984
+ 'Merchant',
1985
+ 'Link',
1986
+ 'Thumbnail',
1987
+ 'BigImage',
1988
+ 'Price',
1989
+ 'RetailPrice',
1990
+ 'Category',
1991
+ 'Subcategory',
1992
+ 'Description',
1993
+ ),
1994
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
1995
+ 'type' => array(
1996
+ 'attribute',
1997
+ 'attribute',
1998
+ 'attribute',
1999
+ 'attribute',
2000
+ 'attribute',
2001
+ 'attribute',
2002
+ 'attribute',
2003
+ 'attribute',
2004
+ 'attribute',
2005
+ 'attribute',
2006
+ 'attribute',
2007
+ 'attribute',
2008
+ ),
2009
+ 'attributes' => array(
2010
+ 'id',
2011
+ 'title',
2012
+ '',
2013
+ '',
2014
+ 'link',
2015
+ 'image',
2016
+ 'feature_image',
2017
+ 'sale_price',
2018
+ 'price',
2019
+ 'product_type',
2020
+ '',
2021
+ 'description',
2022
+ ),
2023
+ 'default' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
2024
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
2025
+ 'output_type' => array(
2026
+ '1',
2027
+ '1',
2028
+ '1',
2029
+ '1',
2030
+ '1',
2031
+ '1',
2032
+ '1',
2033
+ '6',
2034
+ '6',
2035
+ '1',
2036
+ '1',
2037
+ '11',
2038
+ ),
2039
+ 'limit' => array(
2040
+ '8',
2041
+ '255',
2042
+ '8',
2043
+ '255',
2044
+ '255',
2045
+ '255',
2046
+ '255',
2047
+ '',
2048
+ '',
2049
+ '50',
2050
+ '50',
2051
+ '',
2052
+ ),
2053
+ ),
2054
+ 'shopbot' => array(
2055
+ 'mattributes' => array(
2056
+ 'ID',
2057
+ 'Product Name',
2058
+ 'URL',
2059
+ 'Category',
2060
+ 'Photo URL',
2061
+ 'Price',
2062
+ 'Original Price',
2063
+ 'Description',
2064
+ 'MPN',
2065
+ 'Brand',
2066
+ 'Shipment Cost',
2067
+ 'Stock',
2068
+ 'Promotional Phrase',
2069
+ 'Model',
2070
+ 'Color',
2071
+ 'Product Type',
2072
+ ),
2073
+ 'prefix' => array(
2074
+ '',
2075
+ '',
2076
+ '',
2077
+ '',
2078
+ '',
2079
+ '',
2080
+ '',
2081
+ '',
2082
+ '',
2083
+ '',
2084
+ '',
2085
+ '',
2086
+ '',
2087
+ '',
2088
+ '',
2089
+ '',
2090
+ ),
2091
+ 'type' => array(
2092
+ 'attribute',
2093
+ 'attribute',
2094
+ 'attribute',
2095
+ 'attribute',
2096
+ 'attribute',
2097
+ 'attribute',
2098
+ 'attribute',
2099
+ 'attribute',
2100
+ 'attribute',
2101
+ 'pattern',
2102
+ 'attribute',
2103
+ 'attribute',
2104
+ 'attribute',
2105
+ 'attribute',
2106
+ 'attribute',
2107
+ 'attribute',
2108
+ ),
2109
+ 'attributes' => array(
2110
+ 'id',
2111
+ 'title',
2112
+ 'link',
2113
+ 'product_type',
2114
+ 'image',
2115
+ 'sale_price',
2116
+ 'price',
2117
+ 'description',
2118
+ 'sku',
2119
+ '',
2120
+ '',
2121
+ 'quantity',
2122
+ '',
2123
+ '',
2124
+ '',
2125
+ '',
2126
+ ),
2127
+ 'default' => array(
2128
+ '',
2129
+ '',
2130
+ '',
2131
+ '',
2132
+ '',
2133
+ '',
2134
+ '',
2135
+ '',
2136
+ 'mens, womens',
2137
+ self::$brand,
2138
+ '',
2139
+ '',
2140
+ '',
2141
+ '',
2142
+ '',
2143
+ '',
2144
+ ),
2145
+ 'suffix' => array(
2146
+ '',
2147
+ '',
2148
+ '',
2149
+ '',
2150
+ '',
2151
+ '',
2152
+ '',
2153
+ '',
2154
+ '',
2155
+ '',
2156
+ '',
2157
+ '',
2158
+ '',
2159
+ '',
2160
+ '',
2161
+ '',
2162
+ ),
2163
+ 'output_type' => array(
2164
+ '1',
2165
+ '1',
2166
+ '1',
2167
+ '1',
2168
+ '1',
2169
+ '1',
2170
+ '1',
2171
+ '11',
2172
+ '1',
2173
+ '1',
2174
+ '1',
2175
+ '1',
2176
+ '1',
2177
+ '1',
2178
+ '1',
2179
+ '1',
2180
+ ),
2181
+ 'limit' => array(
2182
+ '',
2183
+ '',
2184
+ '',
2185
+ '',
2186
+ '',
2187
+ '',
2188
+ '',
2189
+ '',
2190
+ '',
2191
+ '',
2192
+ '',
2193
+ '',
2194
+ '',
2195
+ '',
2196
+ '',
2197
+ '',
2198
+ ),
2199
+ ),
2200
+ 'shopmania' => array(
2201
+ 'mattributes' => array(
2202
+ 'Category',
2203
+ 'Manufacturer',
2204
+ 'Model',
2205
+ 'MPC',
2206
+ 'Name',
2207
+ 'Description',
2208
+ 'URL',
2209
+ 'Image',
2210
+ 'Price',
2211
+ 'Currency',
2212
+ 'Shipping',
2213
+ 'Availability',
2214
+ 'GTIN',
2215
+ ),
2216
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '', '', '' ),
2217
+ 'type' => array(
2218
+ 'attribute',
2219
+ 'attribute',
2220
+ 'attribute',
2221
+ 'attribute',
2222
+ 'attribute',
2223
+ 'attribute',
2224
+ 'attribute',
2225
+ 'attribute',
2226
+ 'attribute',
2227
+ 'attribute',
2228
+ 'attribute',
2229
+ 'attribute',
2230
+ 'attribute',
2231
+ ),
2232
+ 'attributes' => array(
2233
+ 'product_type',
2234
+ '',
2235
+ '',
2236
+ '',
2237
+ 'title',
2238
+ 'description',
2239
+ 'link',
2240
+ 'image',
2241
+ 'price',
2242
+ '',
2243
+ '',
2244
+ 'availability',
2245
+ '',
2246
+ ),
2247
+ 'default' => array( '', '', '', '', '', '', '', '', '', '', '', '', '' ),
2248
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '', '', '', '' ),
2249
+ 'output_type' => array(
2250
+ '1',
2251
+ '1',
2252
+ '1',
2253
+ '1',
2254
+ '1',
2255
+ '11',
2256
+ '1',
2257
+ '1',
2258
+ '1',
2259
+ '1',
2260
+ '1',
2261
+ '1',
2262
+ '1',
2263
+ ),
2264
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '', '', '' ),
2265
+ ),
2266
+ 'shopping' => array(
2267
+ 'mattributes' => array(
2268
+ 'Unique Merchant SKU',
2269
+ 'Product Name',
2270
+ 'Product URL',
2271
+ 'Image URL',
2272
+ 'Current Price',
2273
+ 'Stock Availability',
2274
+ 'Condition',
2275
+ 'MPN',
2276
+ 'UPC',
2277
+ ),
2278
+ 'prefix' => array( '', '', '', '', '', '', '', '', '' ),
2279
+ 'type' => array(
2280
+ 'attribute',
2281
+ 'attribute',
2282
+ 'attribute',
2283
+ 'attribute',
2284
+ 'attribute',
2285
+ 'attribute',
2286
+ 'attribute',
2287
+ 'attribute',
2288
+ 'attribute',
2289
+ ),
2290
+ 'attributes' => array(
2291
+ 'sku',
2292
+ 'title',
2293
+ 'link',
2294
+ 'image',
2295
+ 'price',
2296
+ 'availability',
2297
+ 'condition',
2298
+ '',
2299
+ '',
2300
+ ),
2301
+ 'default' => array( '', '', '', '', '', '', '', '', '' ),
2302
+ 'suffix' => array( '', '', '', '', '', '', '', '', '' ),
2303
+ 'output_type' => array( '1', '1', '1', '1', '1', '1', '1', '1', '1' ),
2304
+ 'limit' => array( '', '', '', '', '', '', '', '', '' ),
2305
+ ),
2306
+ 'spartoo.fi' => array(
2307
+ 'mattributes' => array(
2308
+ 'SKU',
2309
+ 'Parent / Child',
2310
+ 'Parent SKU',
2311
+ 'Product name',
2312
+ 'Manufacturer name',
2313
+ 'Gender',
2314
+ 'Product_description',
2315
+ 'Product price',
2316
+ 'Discount price',
2317
+ 'Quantity',
2318
+ 'Category',
2319
+ 'Products selection',
2320
+ 'Photo 1',
2321
+ 'Photo 2',
2322
+ 'Photo 3',
2323
+ 'Photo 4',
2324
+ 'Photo 5',
2325
+ 'Photo 6',
2326
+ 'Photo 7',
2327
+ 'Photo 8',
2328
+ 'Color id',
2329
+ 'Color name',
2330
+ 'Size name',
2331
+ 'ean',
2332
+ ),
2333
+ 'prefix' => array(
2334
+ '',
2335
+ '',
2336
+ '',
2337
+ '',
2338
+ '',
2339
+ '',
2340
+ '',
2341
+ '',
2342
+ '',
2343
+ '',
2344
+ '',
2345
+ '',
2346
+ '',
2347
+ '',
2348
+ '',
2349
+ '',
2350
+ '',
2351
+ '',
2352
+ '',
2353
+ '',
2354
+ '',
2355
+ '',
2356
+ '',
2357
+ '',
2358
+ ),
2359
+ 'type' => array(
2360
+ 'attribute',
2361
+ 'attribute',
2362
+ 'attribute',
2363
+ 'attribute',
2364
+ 'attribute',
2365
+ 'attribute',
2366
+ 'attribute',
2367
+ 'attribute',
2368
+ 'attribute',
2369
+ 'attribute',
2370
+ 'attribute',
2371
+ 'attribute',
2372
+ 'attribute',
2373
+ 'attribute',
2374
+ 'attribute',
2375
+ 'attribute',
2376
+ 'attribute',
2377
+ 'attribute',
2378
+ 'attribute',
2379
+ 'attribute',
2380
+ 'attribute',
2381
+ 'attribute',
2382
+ 'attribute',
2383
+ 'attribute',
2384
+ ),
2385
+ 'attributes' => array(
2386
+ 'sku',
2387
+ 'type',
2388
+ 'parent_sku',
2389
+ 'title',
2390
+ '',
2391
+ '',
2392
+ 'description',
2393
+ 'price',
2394
+ 'sale_price',
2395
+ 'quantity',
2396
+ 'product_type',
2397
+ '',
2398
+ 'image_1',
2399
+ 'image_2',
2400
+ 'image_3',
2401
+ 'image_4',
2402
+ 'image_5',
2403
+ 'image_6',
2404
+ 'image_7',
2405
+ 'image_8',
2406
+ '',
2407
+ '',
2408
+ '',
2409
+ '',
2410
+ ),
2411
+ 'default' => array(
2412
+ '',
2413
+ '',
2414
+ '',
2415
+ '',
2416
+ '',
2417
+ '',
2418
+ '',
2419
+ '',
2420
+ '',
2421
+ '',
2422
+ '',
2423
+ '',
2424
+ '',
2425
+ '',
2426
+ '',
2427
+ '',
2428
+ '',
2429
+ '',
2430
+ '',
2431
+ '',
2432
+ '',
2433
+ '',
2434
+ '',
2435
+ '',
2436
+ ),
2437
+ 'suffix' => array(
2438
+ '',
2439
+ '',
2440
+ '',
2441
+ '',
2442
+ '',
2443
+ '',
2444
+ '',
2445
+ '',
2446
+ '',
2447
+ '',
2448
+ '',
2449
+ '',
2450
+ '',
2451
+ '',
2452
+ '',
2453
+ '',
2454
+ '',
2455
+ '',
2456
+ '',
2457
+ '',
2458
+ '',
2459
+ '',
2460
+ '',
2461
+ '',
2462
+ ),
2463
+ 'output_type' => array(
2464
+ '1',
2465
+ '1',
2466
+ '1',
2467
+ '1',
2468
+ '1',
2469
+ '1',
2470
+ '11',
2471
+ '1',
2472
+ '1',
2473
+ '1',
2474
+ '1',
2475
+ '1',
2476
+ '1',
2477
+ '1',
2478
+ '1',
2479
+ '1',
2480
+ '1',
2481
+ '1',
2482
+ '1',
2483
+ '1',
2484
+ '1',
2485
+ '1',
2486
+ '1',
2487
+ '1',
2488
+ ),
2489
+ 'limit' => array(
2490
+ '',
2491
+ '',
2492
+ '',
2493
+ '',
2494
+ '',
2495
+ '',
2496
+ '',
2497
+ '',
2498
+ '',
2499
+ '',
2500
+ '',
2501
+ '',
2502
+ '',
2503
+ '',
2504
+ '',
2505
+ '',
2506
+ '',
2507
+ '',
2508
+ '',
2509
+ '',
2510
+ '',
2511
+ '',
2512
+ '',
2513
+ '',
2514
+ ),
2515
+ ),
2516
+ 'trovaprezzi' => array(
2517
+ 'mattributes' => array(
2518
+ 'Code',
2519
+ 'Name',
2520
+ 'Description',
2521
+ 'Link',
2522
+ 'Price',
2523
+ 'Categories',
2524
+ 'Image',
2525
+ 'Stock',
2526
+ 'Availability',
2527
+ 'ShippingCost',
2528
+ 'SKU',
2529
+ 'Brand',
2530
+ ),
2531
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
2532
+ 'type' => array(
2533
+ 'attribute',
2534
+ 'attribute',
2535
+ 'attribute',
2536
+ 'attribute',
2537
+ 'attribute',
2538
+ 'attribute',
2539
+ 'attribute',
2540
+ 'attribute',
2541
+ 'attribute',
2542
+ 'pattern',
2543
+ 'attribute',
2544
+ 'pattern',
2545
+ ),
2546
+ 'attributes' => array(
2547
+ 'id',
2548
+ 'title',
2549
+ 'short_description',
2550
+ 'link',
2551
+ 'current_price',
2552
+ 'product_type',
2553
+ 'image',
2554
+ 'wf_cattr__stock',
2555
+ 'availability',
2556
+ '',
2557
+ 'sku',
2558
+ '',
2559
+ ),
2560
+ 'default' => array( '', '', '', '', '', '', '', '', '', '0', '', '' ),
2561
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
2562
+ 'output_type' => array(
2563
+ '1',
2564
+ '1',
2565
+ '2, 11',
2566
+ '1',
2567
+ '6',
2568
+ '1',
2569
+ '1',
2570
+ '5',
2571
+ '1',
2572
+ '6',
2573
+ '1',
2574
+ '1',
2575
+ ),
2576
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
2577
+ ),
2578
+ 'twenga' => array(
2579
+ 'mattributes' => array(
2580
+ 'merchant_ref',
2581
+ 'merchant_id',
2582
+ 'upc_ean',
2583
+ 'manufacturer_id',
2584
+ 'product_url',
2585
+ 'image_url',
2586
+ 'price',
2587
+ 'regular_price',
2588
+ 'shipping_cost',
2589
+ 'designation',
2590
+ 'description',
2591
+ 'category',
2592
+ 'brand',
2593
+ 'in_stock',
2594
+ 'availability',
2595
+ 'stock_detail',
2596
+ 'unit_price',
2597
+ 'merchant_margin',
2598
+ 'ecotax',
2599
+ 'item_display',
2600
+ 'condition',
2601
+ 'merchant_ref',
2602
+ ),
2603
+ 'prefix' => array(
2604
+ '',
2605
+ '',
2606
+ '',
2607
+ '',
2608
+ '',
2609
+ '',
2610
+ '',
2611
+ '',
2612
+ '',
2613
+ '',
2614
+ '',
2615
+ '',
2616
+ '',
2617
+ '',
2618
+ '',
2619
+ '',
2620
+ '',
2621
+ '',
2622
+ '',
2623
+ '',
2624
+ '',
2625
+ '',
2626
+ ),
2627
+ 'type' => array(
2628
+ 'attribute',
2629
+ 'attribute',
2630
+ 'pattern',
2631
+ 'attribute',
2632
+ 'attribute',
2633
+ 'pattern',
2634
+ 'attribute',
2635
+ 'pattern',
2636
+ 'pattern',
2637
+ 'pattern',
2638
+ 'attribute',
2639
+ 'attribute',
2640
+ 'pattern',
2641
+ 'attribute',
2642
+ 'attribute',
2643
+ 'pattern',
2644
+ 'pattern',
2645
+ 'pattern',
2646
+ 'pattern',
2647
+ 'pattern',
2648
+ 'pattern',
2649
+ 'attribute',
2650
+ ),
2651
+ 'attributes' => array(
2652
+ 'sku',
2653
+ 'id',
2654
+ '',
2655
+ 'sku',
2656
+ 'link',
2657
+ 'image',
2658
+ 'sale_price',
2659
+ 'price',
2660
+ '',
2661
+ '',
2662
+ 'description',
2663
+ 'product_type',
2664
+ '',
2665
+ 'availability',
2666
+ 'quantity',
2667
+ '',
2668
+ '',
2669
+ '',
2670
+ '',
2671
+ '',
2672
+ '',
2673
+ 'sku',
2674
+ ),
2675
+ 'default' => array(
2676
+ '',
2677
+ '',
2678
+ '',
2679
+ '',
2680
+ '',
2681
+ '',
2682
+ '',
2683
+ '',
2684
+ '',
2685
+ '',
2686
+ '',
2687
+ '',
2688
+ self::$brand,
2689
+ '',
2690
+ '',
2691
+ '',
2692
+ '',
2693
+ '',
2694
+ '',
2695
+ '',
2696
+ '',
2697
+ '',
2698
+ ),
2699
+ 'suffix' => array(
2700
+ '',
2701
+ '',
2702
+ '',
2703
+ '',
2704
+ '',
2705
+ '',
2706
+ '',
2707
+ '',
2708
+ '',
2709
+ '',
2710
+ '',
2711
+ '',
2712
+ '',
2713
+ '',
2714
+ '',
2715
+ '',
2716
+ '',
2717
+ '',
2718
+ '',
2719
+ '',
2720
+ '',
2721
+ '',
2722
+ ),
2723
+ 'output_type' => array(
2724
+ '1',
2725
+ '1',
2726
+ '1',
2727
+ '1',
2728
+ '1',
2729
+ '1',
2730
+ '1',
2731
+ '1',
2732
+ '1',
2733
+ '1',
2734
+ '11',
2735
+ '1',
2736
+ '1',
2737
+ '1',
2738
+ '1',
2739
+ '1',
2740
+ '1',
2741
+ '1',
2742
+ '1',
2743
+ '1',
2744
+ '1',
2745
+ '1',
2746
+ ),
2747
+ 'limit' => array(
2748
+ '',
2749
+ '',
2750
+ '',
2751
+ '',
2752
+ '',
2753
+ '',
2754
+ '',
2755
+ '',
2756
+ '',
2757
+ '',
2758
+ '',
2759
+ '',
2760
+ '',
2761
+ '',
2762
+ '',
2763
+ '',
2764
+ '',
2765
+ '',
2766
+ '',
2767
+ '',
2768
+ '',
2769
+ '',
2770
+ ),
2771
+ ),
2772
+ 'vertaa.fi' => array(
2773
+ 'mattributes' => array(
2774
+ 'Product category',
2775
+ 'Product name',
2776
+ 'Product brand',
2777
+ 'Product price',
2778
+ 'Product URL',
2779
+ 'Delivery time',
2780
+ 'Shipping method',
2781
+ 'Delivery price',
2782
+ 'Service country code',
2783
+ ),
2784
+ 'prefix' => array( '', '', '', '', '', '', '', '', '' ),
2785
+ 'type' => array(
2786
+ 'attribute',
2787
+ 'attribute',
2788
+ 'pattern',
2789
+ 'attribute',
2790
+ 'attribute',
2791
+ 'attribute',
2792
+ 'attribute',
2793
+ 'attribute',
2794
+ 'attribute',
2795
+ ),
2796
+ 'attributes' => array(
2797
+ 'product_type',
2798
+ 'title',
2799
+ '',
2800
+ 'price',
2801
+ 'link',
2802
+ '',
2803
+ '',
2804
+ '',
2805
+ '',
2806
+ ),
2807
+ 'default' => array( '', '', self::$brand, '', '', '', '', '', '' ),
2808
+ 'suffix' => array( '', '', '', '', '', '', '', '', '' ),
2809
+ 'output_type' => array( '1', '1', '1', '1', '1', '1', '1', '1', '1' ),
2810
+ 'limit' => array( '', '', '', '', '', '', '', '', '' ),
2811
+ ),
2812
+ 'walmart' => array(
2813
+ 'mattributes' => array(
2814
+ 'Product Name',
2815
+ 'SKU',
2816
+ 'Product Tax Code',
2817
+ 'Product ID Type',
2818
+ 'Product ID',
2819
+ 'Product Identifiers',
2820
+ 'Description',
2821
+ 'Brand',
2822
+ 'Price',
2823
+ 'Shipping Weight',
2824
+ ),
2825
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '' ),
2826
+ 'type' => array(
2827
+ 'attribute',
2828
+ 'attribute',
2829
+ 'attribute',
2830
+ 'attribute',
2831
+ 'attribute',
2832
+ 'attribute',
2833
+ 'attribute',
2834
+ 'pattern',
2835
+ 'attribute',
2836
+ 'attribute',
2837
+ ),
2838
+ 'attributes' => array(
2839
+ 'title',
2840
+ 'sku',
2841
+ '',
2842
+ '',
2843
+ 'id',
2844
+ '',
2845
+ 'description',
2846
+ '',
2847
+ 'price',
2848
+ '',
2849
+ ),
2850
+ 'default' => array( '', '', '', '', '', '', '', self::$brand, '', '' ),
2851
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '' ),
2852
+ 'output_type' => array( '1', '1', '1', '1', '1', '1', '11', '1', '1', '1' ),
2853
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '' ),
2854
+ ),
2855
+ 'wish' => array(
2856
+ 'mattributes' => array(
2857
+ 'Main Image URL',
2858
+ 'Price',
2859
+ 'Product Name',
2860
+ 'Quantity',
2861
+ 'Shipping',
2862
+ 'Tags',
2863
+ 'Parent Unique Id',
2864
+ 'Unique ID/SKU',
2865
+ 'Description',
2866
+ ),
2867
+ 'prefix' => array( '', '', '', '', '', '', '', '', '' ),
2868
+ 'type' => array(
2869
+ 'attribute',
2870
+ 'attribute',
2871
+ 'attribute',
2872
+ 'attribute',
2873
+ 'attribute',
2874
+ 'attribute',
2875
+ 'attribute',
2876
+ 'attribute',
2877
+ 'attribute',
2878
+ ),
2879
+ 'attributes' => array(
2880
+ 'image',
2881
+ 'price',
2882
+ 'title',
2883
+ 'quantity',
2884
+ '',
2885
+ 'tags',
2886
+ 'item_group_id',
2887
+ 'id',
2888
+ 'description',
2889
+ ),
2890
+ 'default' => array( '', '', '', '', '', '', '', '', '' ),
2891
+ 'suffix' => array( '', '', '', '', '', '', '', '', '' ),
2892
+ 'output_type' => array( '1', '1', '1', '1', '1', '1', '1', '1', '11' ),
2893
+ 'limit' => array( '', '', '', '', '', '', '', '', '' ),
2894
+ ),
2895
+ 'yahoo_nfa' => array(
2896
+ 'mattributes' => array(
2897
+ 'id',
2898
+ 'title',
2899
+ 'description',
2900
+ 'image_link',
2901
+ 'link',
2902
+ 'availability',
2903
+ 'condition',
2904
+ 'price',
2905
+ 'gtin',
2906
+ ),
2907
+ 'prefix' => array( '', '', '', '', '', '', '', '', '' ),
2908
+ 'type' => array(
2909
+ 'attribute',
2910
+ 'attribute',
2911
+ 'attribute',
2912
+ 'attribute',
2913
+ 'attribute',
2914
+ 'attribute',
2915
+ 'attribute',
2916
+ 'attribute',
2917
+ 'attribute',
2918
+ ),
2919
+ 'attributes' => array(
2920
+ 'id',
2921
+ 'title',
2922
+ 'description',
2923
+ 'image',
2924
+ 'link',
2925
+ 'availability',
2926
+ 'condition',
2927
+ 'price',
2928
+ '',
2929
+ ),
2930
+ 'default' => array( '', '', '', '', '', '', '', '', '' ),
2931
+ 'suffix' => array( '', '', '', '', '', '', '', '', '' ),
2932
+ 'output_type' => array( '1', '1', '11', '1', '1', '1', '1', '1', '1' ),
2933
+ 'limit' => array( '', '', '', '', '', '', '', '', '' ),
2934
+ ),
2935
+ 'zap.co.il' => array(
2936
+ 'mattributes' => array(
2937
+ 'PRODUCT_URL',
2938
+ 'PRODUCT_NAME',
2939
+ 'DETAILS',
2940
+ 'PRODUCTCODE',
2941
+ 'CURRENCY',
2942
+ 'PRICE',
2943
+ 'SHIPMENT_COST',
2944
+ 'DELIVERY_TIME',
2945
+ 'IMAGE',
2946
+ ),
2947
+ 'prefix' => array( '', '', '', '', '', '', '', '', '' ),
2948
+ 'type' => array(
2949
+ 'attribute',
2950
+ 'attribute',
2951
+ 'attribute',
2952
+ 'attribute',
2953
+ 'attribute',
2954
+ 'attribute',
2955
+ 'attribute',
2956
+ 'attribute',
2957
+ 'attribute',
2958
+ ),
2959
+ 'attributes' => array(
2960
+ 'link',
2961
+ 'title',
2962
+ 'description',
2963
+ 'id',
2964
+ '',
2965
+ 'price',
2966
+ '',
2967
+ '',
2968
+ 'image',
2969
+ ),
2970
+ 'default' => array( '', '', '', '', '', '', '', '', '' ),
2971
+ 'suffix' => array( '', '', '', '', '', '', '', '', '' ),
2972
+ 'output_type' => array( '1', '1', '11', '1', '1', '1', '1', '1', '1' ),
2973
+ 'limit' => array( '', '', '', '', '', '', '', '', '' ),
2974
+ ),
2975
+ 'adwords' => array(
2976
+ 'mattributes' => array(
2977
+ 'ID',
2978
+ 'ID2',
2979
+ 'Item title',
2980
+ 'Final URL',
2981
+ 'Image URL',
2982
+ 'Item subtitle',
2983
+ 'Item description',
2984
+ 'Item category',
2985
+ 'Price',
2986
+ 'Sale price',
2987
+ 'Contextual keywords',
2988
+ 'Item address'
2989
+ ),
2990
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
2991
+ 'type' => array(
2992
+ 'attribute',
2993
+ 'attribute',
2994
+ 'attribute',
2995
+ 'attribute',
2996
+ 'attribute',
2997
+ 'attribute',
2998
+ 'attribute',
2999
+ 'attribute',
3000
+ 'attribute',
3001
+ 'attribute',
3002
+ 'pattern',
3003
+ 'pattern'
3004
+ ),
3005
+ 'attributes' => array(
3006
+ 'id',
3007
+ 'id',
3008
+ 'title',
3009
+ 'link',
3010
+ 'image',
3011
+ 'short_description',
3012
+ 'description',
3013
+ 'product_type',
3014
+ 'price',
3015
+ 'sale_price',
3016
+ '',
3017
+ ''
3018
+ ),
3019
+ 'default' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
3020
+ 'suffix' => array(
3021
+ '',
3022
+ '',
3023
+ '',
3024
+ '',
3025
+ '',
3026
+ '',
3027
+ '',
3028
+ '',
3029
+ ' ' . self::$currency,
3030
+ ' ' . self::$currency,
3031
+ '',
3032
+ ''
3033
+ ),
3034
+ 'output_type' => array( '1', '1', '1', '1', '1', '1', '11', '1', '6', '6', '1', '1' ),
3035
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
3036
+ ),
3037
+ 'adwords_local_product' => array(
3038
+ 'mattributes' => array(
3039
+ 'Rank',
3040
+ 'Product Item Id',
3041
+ 'Title',
3042
+ 'Description',
3043
+ 'Item URL',
3044
+ 'Image URL',
3045
+ 'Price',
3046
+ 'Store code'
3047
+ ),
3048
+ 'prefix' => array( '', '', '', '', '', '', '', '' ),
3049
+ 'type' => array(
3050
+ 'attribute',
3051
+ 'attribute',
3052
+ 'attribute',
3053
+ 'attribute',
3054
+ 'attribute',
3055
+ 'attribute',
3056
+ 'attribute',
3057
+ 'pattern'
3058
+ ),
3059
+ 'attributes' => array( 'id', 'id', 'title', 'description', 'link', 'image', 'current_price', '' ),
3060
+ 'default' => array( '', '', '', '', '', '', '', '' ),
3061
+ 'suffix' => array( '', '', '', '', '', '', ' ' . self::$currency, '' ),
3062
+ 'output_type' => array( '1', '1', '1', '11', '1', '1', '6', '1' ),
3063
+ 'limit' => array( '', '', '', '', '', '', '', '' ),
3064
+ ),
3065
+ 'bing' => array(
3066
+ 'mattributes' => array(
3067
+ 'id',
3068
+ 'title',
3069
+ 'link',
3070
+ 'price',
3071
+ 'sale_price',
3072
+ 'description',
3073
+ 'image_link',
3074
+ 'mpn',
3075
+ 'brand',
3076
+ 'product_type',
3077
+ 'availability',
3078
+ 'item_group_id',
3079
+ 'shipping'
3080
+ ),
3081
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '', '', '' ),
3082
+ 'type' => array(
3083
+ 'attribute',
3084
+ 'attribute',
3085
+ 'attribute',
3086
+ 'attribute',
3087
+ 'attribute',
3088
+ 'attribute',
3089
+ 'attribute',
3090
+ 'attribute',
3091
+ 'pattern',
3092
+ 'attribute',
3093
+ 'attribute',
3094
+ 'attribute',
3095
+ 'attribute'
3096
+ ),
3097
+ 'attributes' => array(
3098
+ 'id',
3099
+ 'title',
3100
+ 'link',
3101
+ 'price',
3102
+ 'current_price',
3103
+ 'description',
3104
+ 'image',
3105
+ 'sku',
3106
+ '',
3107
+ 'product_type',
3108
+ 'availability',
3109
+ 'item_group_id',
3110
+ 'shipping'
3111
+ ),
3112
+ 'default' => array( '', '', '', '', '', '', '', '', self::$brand, '', '', '', '' ),
3113
+ 'suffix' => array(
3114
+ '',
3115
+ '',
3116
+ '',
3117
+ ' ' . self::$currency,
3118
+ ' ' . self::$currency,
3119
+ '',
3120
+ '',
3121
+ '',
3122
+ '',
3123
+ '',
3124
+ '',
3125
+ '',
3126
+ ''
3127
+ ),
3128
+ 'output_type' => array( '1', '1', '1', '6', '6', '11', '1', '1', '1', '1', '1', '1', '1' ),
3129
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '', '', '' ),
3130
+ ),
3131
+ 'bing_local_inventory' => array(
3132
+ 'mattributes' => array(
3133
+ 'store_code',
3134
+ 'itemid',
3135
+ 'quantity',
3136
+ 'weeks_of_supply',
3137
+ 'pick_up_method',
3138
+ 'pick_up_sla'
3139
+ ),
3140
+ 'prefix' => array( '', '', '', '', '', '' ),
3141
+ 'type' => array( 'pattern', 'attribute', 'attribute', 'pattern', 'pattern', 'pattern' ),
3142
+ 'attributes' => array( '', 'id', 'quantity', '', '', '' ),
3143
+ 'default' => array( '', '', '', '', '', '' ),
3144
+ 'suffix' => array( '', '', '', '', '', '' ),
3145
+ 'output_type' => array( '1', '1', '1', '1', '1', '1' ),
3146
+ 'limit' => array( '', '', '', '', '', '' ),
3147
+ ),
3148
+ 'google_local_inventory' => array(
3149
+ 'mattributes' => array(
3150
+ 'store_code',
3151
+ 'id',
3152
+ 'quantity',
3153
+ 'price',
3154
+ 'sale_price',
3155
+ 'sale_price_effective_date',
3156
+ 'availability',
3157
+ 'pickup_method',
3158
+ 'pickup_sla'
3159
+ ),
3160
+ 'prefix' => array( '', '', '', '', '', '', '', '', '' ),
3161
+ 'type' => array(
3162
+ 'pattern',
3163
+ 'attribute',
3164
+ 'attribute',
3165
+ 'attribute',
3166
+ 'attribute',
3167
+ 'attribute',
3168
+ 'attribute',
3169
+ 'pattern',
3170
+ 'pattern'
3171
+ ),
3172
+ 'attributes' => array(
3173
+ '',
3174
+ 'id',
3175
+ 'quantity',
3176
+ 'price',
3177
+ 'sale_price',
3178
+ 'sale_price_effective_date',
3179
+ 'availability',
3180
+ '',
3181
+ ''
3182
+ ),
3183
+ 'default' => array( ' ', '', '', '', '', '', '', '', '' ),
3184
+ 'suffix' => array( '', '', '', ' ' . self::$currency, ' ' . self::$currency, '', '', '', '' ),
3185
+ 'output_type' => array( '1', '1', '1', '6', '6', '1', '1', '1', '1' ),
3186
+ 'limit' => array( '', '', '', '', '', '', '', '', '' ),
3187
+ ),
3188
+ 'google_local' => array(
3189
+ 'mattributes' => array(
3190
+ 'store_code',
3191
+ 'id',
3192
+ 'title',
3193
+ 'description',
3194
+ 'image',
3195
+ 'upc',
3196
+ 'brand',
3197
+ 'condition',
3198
+ 'price',
3199
+ 'sale_price',
3200
+ 'sale_price_effective_date',
3201
+ 'energy_efficiency_class',
3202
+ 'min_energy_efficiency_class',
3203
+ 'max_energy_efficiency_class'
3204
+ ),
3205
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '', '', '', '' ),
3206
+ 'type' => array(
3207
+ 'pattern',
3208
+ 'attribute',
3209
+ 'attribute',
3210
+ 'attribute',
3211
+ 'attribute',
3212
+ 'attribute',
3213
+ 'pattern',
3214
+ 'pattern',
3215
+ 'attribute',
3216
+ 'attribute',
3217
+ 'attribute',
3218
+ 'pattern',
3219
+ 'pattern',
3220
+ 'pattern'
3221
+ ),
3222
+ 'attributes' => array(
3223
+ '',
3224
+ 'id',
3225
+ 'title',
3226
+ 'description',
3227
+ 'image',
3228
+ 'sku',
3229
+ '',
3230
+ '',
3231
+ 'price',
3232
+ 'sale_price',
3233
+ 'sale_price_effective_date',
3234
+ '',
3235
+ '',
3236
+ ''
3237
+ ),
3238
+ 'default' => array( '', '', '', '', '', '', self::$brand, 'new', '', '', '', '', '', '' ),
3239
+ 'suffix' => array(
3240
+ '',
3241
+ '',
3242
+ '',
3243
+ '',
3244
+ '',
3245
+ '',
3246
+ '',
3247
+ '',
3248
+ ' ' . self::$currency,
3249
+ ' ' . self::$currency,
3250
+ '',
3251
+ '',
3252
+ '',
3253
+ ''
3254
+ ),
3255
+ 'output_type' => array( '1', '1', '1', '11', '1', '1', '1', '1', '6', '6', '1', '1', '1', '1' ),
3256
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '', '', '', '' ),
3257
+ ),
3258
+ 'google_promotions' => array(
3259
+ 'mattributes' => array(
3260
+ 'promotion_id',
3261
+ 'product_applicability',
3262
+ 'offer_type',
3263
+ 'long_title',
3264
+ 'promotion_effective_dates',
3265
+ 'redemption_channel',
3266
+ 'promotion_destination',
3267
+ 'money_off_amount'
3268
+ ),
3269
+ 'prefix' => array( '', '', '', '', '', '', '', '' ),
3270
+ 'type' => array(
3271
+ 'pattern',
3272
+ 'pattern',
3273
+ 'pattern',
3274
+ 'pattern',
3275
+ 'pattern',
3276
+ 'pattern',
3277
+ 'pattern',
3278
+ 'pattern'
3279
+ ),
3280
+ 'attributes' => array( '', '', '', '', '', '', '', '' ),
3281
+ 'default' => array( '', '', '', '', '', '', '', '' ),
3282
+ 'suffix' => array( '', '', '', '', '', '', '', '' ),
3283
+ 'output_type' => array( '1', '1', '1', '1', '1', '1', '1', '1' ),
3284
+ 'limit' => array( '', '', '', '', '', '', '', '' ),
3285
+ ),
3286
+ 'google_dynamic_ads' => array(
3287
+ 'mattributes' => array( 'Page URL', 'Custom Label' ),
3288
+ 'prefix' => array( '', '' ),
3289
+ 'type' => array( 'attribute', 'pattern' ),
3290
+ 'attributes' => array( 'link', '' ),
3291
+ 'default' => array( '', '' ),
3292
+ 'suffix' => array( '', '' ),
3293
+ 'output_type' => array( '1', '1' ),
3294
+ 'limit' => array( '', '' ),
3295
+ ),
3296
+ 'snapchat' => array(
3297
+ 'mattributes' => array(
3298
+ 'id',
3299
+ 'title',
3300
+ 'description',
3301
+ 'item_group_id',
3302
+ 'link',
3303
+ 'product_type',
3304
+ 'current_category',
3305
+ 'image',
3306
+ 'condition',
3307
+ 'availability',
3308
+ 'price',
3309
+ 'sale_price',
3310
+ 'sku',
3311
+ 'brand',
3312
+ 'canonical_link'
3313
+ ),
3314
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' ),
3315
+ 'type' => array(
3316
+ 'attribute',
3317
+ 'attribute',
3318
+ 'attribute',
3319
+ 'attribute',
3320
+ 'attribute',
3321
+ 'attribute',
3322
+ 'pattern',
3323
+ 'attribute',
3324
+ 'attribute',
3325
+ 'attribute',
3326
+ 'attribute',
3327
+ 'attribute',
3328
+ 'attribute',
3329
+ 'pattern',
3330
+ 'attribute'
3331
+ ),
3332
+ 'attributes' => array(
3333
+ 'id',
3334
+ 'title',
3335
+ 'description',
3336
+ 'item_group_id',
3337
+ 'link',
3338
+ 'product_type',
3339
+ '',
3340
+ 'image',
3341
+ 'condition',
3342
+ 'availability',
3343
+ 'price',
3344
+ 'current_price',
3345
+ 'sku',
3346
+ '',
3347
+ 'canonical_link'
3348
+ ),
3349
+ 'default' => array( '', '', '', '', '', '', '', '', '', '', '', '', '', self::$brand, '', '' ),
3350
+ 'suffix' => array(
3351
+ '',
3352
+ '',
3353
+ '',
3354
+ '',
3355
+ '',
3356
+ '',
3357
+ '',
3358
+ '',
3359
+ '',
3360
+ '',
3361
+ ' ' . self::$currency,
3362
+ ' ' . self::$currency,
3363
+ '',
3364
+ '',
3365
+ ''
3366
+ ),
3367
+ 'output_type' => array( '1', '1', '11', '1', '1', '1', '1', '1', '1', '1', '6', '6', '1', '1', '1' ),
3368
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' ),
3369
+ ),
3370
+ 'idealo' => array(
3371
+ 'mattributes' => array(
3372
+ 'sku',
3373
+ 'title',
3374
+ 'description',
3375
+ 'price',
3376
+ 'imageUrls',
3377
+ 'deliveryTime',
3378
+ 'categoryPath',
3379
+ 'url',
3380
+ 'brand',
3381
+ 'checkout',
3382
+ 'eans',
3383
+ 'fulfillmentType',
3384
+ 'checkoutLimitPerPeriod',
3385
+ 'size',
3386
+ 'colour'
3387
+ ),
3388
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' ),
3389
+ 'type' => array(
3390
+ 'attribute',
3391
+ 'attribute',
3392
+ 'attribute',
3393
+ 'attribute',
3394
+ 'attribute',
3395
+ 'pattern',
3396
+ 'attribute',
3397
+ 'attribute',
3398
+ 'pattern',
3399
+ 'pattern',
3400
+ 'pattern',
3401
+ 'pattern',
3402
+ 'pattern',
3403
+ 'attribute',
3404
+ 'attribute'
3405
+ ),
3406
+ 'attributes' => array(
3407
+ 'sku',
3408
+ 'title',
3409
+ 'description',
3410
+ 'current_price',
3411
+ 'images',
3412
+ '',
3413
+ 'product_type',
3414
+ 'link',
3415
+ '',
3416
+ '',
3417
+ '',
3418
+ '',
3419
+ '',
3420
+ 'wf_attr_pa_size',
3421
+ 'wf_attr_pa_color'
3422
+ ),
3423
+ 'default' => array( '', '', '', '', '', '1-3 working days', '', '', '', '', '', '', '', '', '' ),
3424
+ 'suffix' => array( '', '', '', ' USD', '', '', '', '', '', '', '', '', '', '', '' ),
3425
+ 'output_type' => array( '1', '1', '11', '6', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1' ),
3426
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' ),
3427
+ ),
3428
+ 'pricespy' => array(
3429
+ 'mattributes' => array(
3430
+ 'Product-name',
3431
+ 'Your-item-number',
3432
+ 'category',
3433
+ 'price-including-gst',
3434
+ 'Product-URL',
3435
+ 'manufacturer',
3436
+ 'manufacturer-SKU',
3437
+ 'shipping',
3438
+ 'image-URL',
3439
+ 'stock status',
3440
+ ),
3441
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '' ),
3442
+ 'type' => array(
3443
+ 'attribute',
3444
+ 'attribute',
3445
+ 'attribute',
3446
+ 'attribute',
3447
+ 'attribute',
3448
+ 'pattern',
3449
+ 'attribute',
3450
+ 'pattern',
3451
+ 'attribute',
3452
+ 'attribute',
3453
+ ),
3454
+ 'attributes' => array(
3455
+ 'title',
3456
+ 'id',
3457
+ 'product_type',
3458
+ 'price',
3459
+ 'link',
3460
+ '',
3461
+ 'sku',
3462
+ '',
3463
+ 'image',
3464
+ 'condition',
3465
+ ),
3466
+ 'default' => array( '', '', '', '', '', '', '', '', 'mens, womens', '' ),
3467
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '' ),
3468
+ 'output_type' => array( '1', '1', '1', '1', '1', '1', '1', '1', '1', '1' ),
3469
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '' ),
3470
+ ),
3471
+ 'yandex_csv' => array(
3472
+ 'mattributes' => array(
3473
+ 'id',
3474
+ 'available',
3475
+ 'price',
3476
+ 'currencyId',
3477
+ 'category',
3478
+ 'picture',
3479
+ 'name',
3480
+ 'description',
3481
+ ),
3482
+ 'prefix' => array( '', '', '', '', '', '', '', '' ),
3483
+ 'type' => array(
3484
+ 'attribute',
3485
+ 'attribute',
3486
+ 'attribute',
3487
+ 'pattern',
3488
+ 'attribute',
3489
+ 'attribute',
3490
+ 'attribute',
3491
+ 'attribute',
3492
+ ),
3493
+ 'attributes' => array(
3494
+ 'id',
3495
+ 'availability',
3496
+ 'price',
3497
+ '',
3498
+ 'product_type',
3499
+ 'image',
3500
+ 'title',
3501
+ 'description',
3502
+ ),
3503
+ 'default' => array( '', '', '', 'RUR', '', '', '', '' ),
3504
+ 'suffix' => array( '', '', '', '', '', '', '', '' ),
3505
+ 'output_type' => array( '1', '1', '1', '1', '1', '1', '1', '11' ),
3506
+ 'limit' => array( '', '', '', '', '', '', '', '' ),
3507
+ ),
3508
+ 'fyndiq.se' => array(
3509
+ 'mattributes' => array(
3510
+ 'product-id',
3511
+ 'product-title',
3512
+ 'product-description',
3513
+ 'product-market',
3514
+ 'product-currency',
3515
+ 'product-price',
3516
+ 'product-oldprice',
3517
+ 'product-var-percent',
3518
+ 'product-image-1-url',
3519
+ 'product-image-1-identifier',
3520
+ 'article-sku',
3521
+ 'article-quantity',
3522
+ 'article-name',
3523
+ ),
3524
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '', '', '' ),
3525
+ 'type' => array(
3526
+ 'attribute',
3527
+ 'attribute',
3528
+ 'attribute',
3529
+ 'attribute',
3530
+ 'pattern',
3531
+ 'attribute',
3532
+ 'attribute',
3533
+ 'attribute',
3534
+ 'attribute',
3535
+ 'attribute',
3536
+ 'attribute',
3537
+ 'attribute',
3538
+ 'attribute',
3539
+ ),
3540
+ 'attributes' => array(
3541
+ 'id',
3542
+ 'title',
3543
+ 'description',
3544
+ '',
3545
+ '',
3546
+ 'price',
3547
+ '',
3548
+ '',
3549
+ 'image',
3550
+ '',
3551
+ 'sku',
3552
+ 'quantity',
3553
+ '',
3554
+ ),
3555
+ 'default' => array(
3556
+ '',
3557
+ '',
3558
+ '',
3559
+ '',
3560
+ ' ' . self::$currency,
3561
+ '',
3562
+ '',
3563
+ '',
3564
+ '',
3565
+ '',
3566
+ '',
3567
+ '',
3568
+ '',
3569
+ ),
3570
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '', '', '', '' ),
3571
+ 'output_type' => array(
3572
+ '1',
3573
+ '1',
3574
+ '11',
3575
+ '1',
3576
+ '1',
3577
+ '1',
3578
+ '1',
3579
+ '1',
3580
+ '1',
3581
+ '1',
3582
+ '1',
3583
+ '1',
3584
+ '1',
3585
+ ),
3586
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '', '', '' ),
3587
+ ),
3588
+ 'miinto.de' => array(
3589
+ 'mattributes' => array(
3590
+ 'title',
3591
+ 'description',
3592
+ 'gtin',
3593
+ 'item_group_id',
3594
+ 'image_link',
3595
+ 'product_type',
3596
+ 'availability',
3597
+ 'color',
3598
+ 'season_tag',
3599
+ 'brand',
3600
+ 'material',
3601
+ 'washing',
3602
+ 'style_id',
3603
+ 'retail_price_PLN',
3604
+ 'retail_price_DKK',
3605
+ 'retail_price_EUR'
3606
+ ),
3607
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' ),
3608
+ 'type' => array(
3609
+ 'attribute',
3610
+ 'attribute',
3611
+ 'attribute',
3612
+ 'attribute',
3613
+ 'attribute',
3614
+ 'attribute',
3615
+ 'attribute',
3616
+ 'attribute',
3617
+ 'pattern',
3618
+ 'pattern',
3619
+ 'pattern',
3620
+ 'pattern',
3621
+ 'pattern',
3622
+ 'attribute',
3623
+ 'attribute',
3624
+ 'attribute'
3625
+ ),
3626
+ 'attributes' => array(
3627
+ 'title',
3628
+ 'description',
3629
+ 'id',
3630
+ 'item_group_id',
3631
+ 'image',
3632
+ 'product_type',
3633
+ 'availability',
3634
+ 'wf_attr_pa_color',
3635
+ '',
3636
+ '',
3637
+ '',
3638
+ '',
3639
+ '',
3640
+ 'price',
3641
+ 'price',
3642
+ 'price'
3643
+ ),
3644
+ 'default' => array( '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' ),
3645
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '', '', '', '', ' USD', ' USD', ' USD' ),
3646
+ 'output_type' => array(
3647
+ '1',
3648
+ '1',
3649
+ '1',
3650
+ '1',
3651
+ '1',
3652
+ '1',
3653
+ '1',
3654
+ '1',
3655
+ '1',
3656
+ '1',
3657
+ '1',
3658
+ '1',
3659
+ '1',
3660
+ '6',
3661
+ '6',
3662
+ '6'
3663
+ ),
3664
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' ),
3665
+ ),
3666
+ 'miinto.nl' => array(
3667
+ 'mattributes' => array(
3668
+ 'gtin',
3669
+ 'item_group_id',
3670
+ 'brand',
3671
+ 'title',
3672
+ 'product_type',
3673
+ 'gender',
3674
+ 'color',
3675
+ 'size',
3676
+ 'image_link',
3677
+ 'stock_level',
3678
+ 'season_tag',
3679
+ 'description',
3680
+ 'material',
3681
+ 'washing',
3682
+ 'retail_price_currencyCode',
3683
+ ),
3684
+ 'prefix' => array(
3685
+ '',
3686
+ '',
3687
+ '',
3688
+ '',
3689
+ '',
3690
+ '',
3691
+ '',
3692
+ '',
3693
+ '',
3694
+ '',
3695
+ '',
3696
+ '',
3697
+ '',
3698
+ '',
3699
+ '',
3700
+ ),
3701
+ 'type' => array(
3702
+ 'attribute',
3703
+ 'attribute',
3704
+ 'pattern',
3705
+ 'attribute',
3706
+ 'attribute',
3707
+ 'attribute',
3708
+ 'attribute',
3709
+ 'attribute',
3710
+ 'attribute',
3711
+ 'attribute',
3712
+ 'attribute',
3713
+ 'attribute',
3714
+ 'attribute',
3715
+ 'attribute',
3716
+ 'attribute',
3717
+ ),
3718
+ 'attributes' => array(
3719
+ '',
3720
+ 'item_group_id',
3721
+ '',
3722
+ 'title',
3723
+ 'product_type',
3724
+ '',
3725
+ '',
3726
+ '',
3727
+ 'image',
3728
+ 'quantity',
3729
+ '',
3730
+ 'description',
3731
+ '',
3732
+ '',
3733
+ '',
3734
+ ),
3735
+ 'default' => array(
3736
+ '',
3737
+ '',
3738
+ self::$brand,
3739
+ '',
3740
+ '',
3741
+ '',
3742
+ '',
3743
+ '',
3744
+ '',
3745
+ '',
3746
+ '',
3747
+ '',
3748
+ '',
3749
+ '',
3750
+ '',
3751
+ ),
3752
+ 'suffix' => array(
3753
+ '',
3754
+ '',
3755
+ '',
3756
+ '',
3757
+ '',
3758
+ '',
3759
+ '',
3760
+ '',
3761
+ '',
3762
+ '',
3763
+ '',
3764
+ '',
3765
+ '',
3766
+ '',
3767
+ '',
3768
+ ),
3769
+ 'output_type' => array(
3770
+ '1',
3771
+ '1',
3772
+ '1',
3773
+ '1',
3774
+ '1',
3775
+ '1',
3776
+ '1',
3777
+ '1',
3778
+ '1',
3779
+ '1',
3780
+ '1',
3781
+ '11',
3782
+ '1',
3783
+ '1',
3784
+ '1',
3785
+ ),
3786
+ 'limit' => array(
3787
+ '',
3788
+ '',
3789
+ '',
3790
+ '',
3791
+ '',
3792
+ '',
3793
+ '',
3794
+ '',
3795
+ '',
3796
+ '',
3797
+ '',
3798
+ '',
3799
+ '',
3800
+ '',
3801
+ '',
3802
+ ),
3803
+ ),
3804
+ 'skroutz' => array(
3805
+ 'mattributes' => array(
3806
+ 'id',
3807
+ 'name',
3808
+ 'description',
3809
+ 'link',
3810
+ 'image',
3811
+ 'category',
3812
+ 'price_with_vat',
3813
+ 'mpn',
3814
+ 'manufacturer',
3815
+ 'availability',
3816
+ ),
3817
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '' ),
3818
+ 'type' => array(
3819
+ 'attribute',
3820
+ 'attribute',
3821
+ 'attribute',
3822
+ 'attribute',
3823
+ 'attribute',
3824
+ 'attribute',
3825
+ 'attribute',
3826
+ 'attribute',
3827
+ 'pattern',
3828
+ 'pattern',
3829
+ ),
3830
+ 'attributes' => array(
3831
+ 'id',
3832
+ 'title',
3833
+ 'short_description',
3834
+ 'link',
3835
+ 'image',
3836
+ 'product_type',
3837
+ 'current_price_with_tax',
3838
+ 'sku',
3839
+ '',
3840
+ '',
3841
+ ),
3842
+ 'default' => array( '', '', '', '', '', '', '', '', self::$brand, 'Delivery 1 to 3 days' ),
3843
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '' ),
3844
+ 'output_type' => array( '1', '1', '8, 11', '1', '1', '1', '6', '1', '1', '1' ),
3845
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '' ),
3846
+ ),
3847
+ 'bestprice' => array(
3848
+ 'mattributes' => array(
3849
+ 'productId',
3850
+ 'name',
3851
+ 'description',
3852
+ 'link',
3853
+ 'image',
3854
+ 'categoryPath',
3855
+ 'categoryID',
3856
+ 'price',
3857
+ 'mpn',
3858
+ 'manufacturer',
3859
+ 'availability',
3860
+ 'instock',
3861
+ ),
3862
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
3863
+ 'type' => array(
3864
+ 'attribute',
3865
+ 'attribute',
3866
+ 'attribute',
3867
+ 'attribute',
3868
+ 'attribute',
3869
+ 'attribute',
3870
+ 'pattern',
3871
+ 'attribute',
3872
+ 'attribute',
3873
+ 'pattern',
3874
+ 'pattern',
3875
+ 'attribute',
3876
+ ),
3877
+ 'attributes' => array(
3878
+ 'id',
3879
+ 'title',
3880
+ 'description',
3881
+ 'link',
3882
+ 'image',
3883
+ 'product_type',
3884
+ '',
3885
+ 'price',
3886
+ 'sku',
3887
+ '',
3888
+ '',
3889
+ 'availability',
3890
+ ),
3891
+ 'default' => array(
3892
+ '',
3893
+ '',
3894
+ '',
3895
+ '',
3896
+ '',
3897
+ '',
3898
+ '',
3899
+ '',
3900
+ '',
3901
+ self::$brand,
3902
+ 'Delivery up to 30 days',
3903
+ ''
3904
+ ),
3905
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
3906
+ 'output_type' => array( '1', '1', '8, 11', '1', '1', '1', '1', '6', '1', '1', '1', '1' ),
3907
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
3908
+ ),
3909
+ 'googlereview' => array(
3910
+ 'mattributes' => array(
3911
+ 'product_name',
3912
+ 'product_url',
3913
+ 'review_temp_gtin',
3914
+ 'review_temp_mpn',
3915
+ 'review_temp_sku',
3916
+ 'review_temp_brand'
3917
+ ),
3918
+ 'prefix' => array( '', '', '', '', '', '' ),
3919
+ 'type' => array( 'attribute', 'attribute', 'pattern', 'pattern', 'attribute', 'pattern' ),
3920
+ 'attributes' => array( 'title', 'link', '', '', 'sku', '' ),
3921
+ 'default' => array( '', '', '', '', '', self::$brand ),
3922
+ 'suffix' => array( '', '', '', '', '', '' ),
3923
+ 'output_type' => array( '1', '1', '1', '1', '1', '1' ),
3924
+ 'limit' => array( '', '', '', '', '', '' ),
3925
+ ),
3926
+ 'google_shopping_action' => array(
3927
+ 'mattributes' => array(
3928
+ 'id',
3929
+ 'title',
3930
+ 'description',
3931
+ 'item_group_id',
3932
+ 'link',
3933
+ 'product_type',
3934
+ 'current_category',
3935
+ 'image',
3936
+ 'condition',
3937
+ 'availability',
3938
+ 'price',
3939
+ 'sku',
3940
+ 'brand',
3941
+ 'sell_on_google_quantity',
3942
+ 'min_handling_time',
3943
+ 'max_handling_time',
3944
+ 'return_address_label',
3945
+ 'return_policy_label',
3946
+ 'google_funded_promotion_eligibility',
3947
+ ),
3948
+ 'prefix' => array(
3949
+ '',
3950
+ '',
3951
+ '',
3952
+ '',
3953
+ '',
3954
+ '',
3955
+ '',
3956
+ '',
3957
+ '',
3958
+ '',
3959
+ '',
3960
+ '',
3961
+ '',
3962
+ '',
3963
+ '',
3964
+ '',
3965
+ '',
3966
+ '',
3967
+ '',
3968
+ ),
3969
+ 'type' => array(
3970
+ 'attribute',
3971
+ 'attribute',
3972
+ 'attribute',
3973
+ 'attribute',
3974
+ 'attribute',
3975
+ 'attribute',
3976
+ 'pattern',
3977
+ 'attribute',
3978
+ 'attribute',
3979
+ 'attribute',
3980
+ 'attribute',
3981
+ 'attribute',
3982
+ 'pattern',
3983
+ 'attribute',
3984
+ 'pattern',
3985
+ 'pattern',
3986
+ 'pattern',
3987
+ 'pattern',
3988
+ 'pattern',
3989
+ ),
3990
+ 'attributes' => array(
3991
+ 'id',
3992
+ 'title',
3993
+ 'description',
3994
+ 'item_group_id',
3995
+ 'link',
3996
+ 'product_type',
3997
+ '',
3998
+ 'image',
3999
+ 'condition',
4000
+ 'availability',
4001
+ 'price',
4002
+ 'sku',
4003
+ '',
4004
+ 'quantity',
4005
+ '',
4006
+ '',
4007
+ '',
4008
+ '',
4009
+ '',
4010
+ ),
4011
+ 'default' => array(
4012
+ '',
4013
+ '',
4014
+ '',
4015
+ '',
4016
+ '',
4017
+ '',
4018
+ '',
4019
+ '',
4020
+ '',
4021
+ '',
4022
+ '',
4023
+ '',
4024
+ self::$brand,
4025
+ '',
4026
+ '',
4027
+ '',
4028
+ '',
4029
+ '',
4030
+ 'all',
4031
+ ),
4032
+ 'suffix' => array(
4033
+ '',
4034
+ '',
4035
+ '',
4036
+ '',
4037
+ '',
4038
+ '',
4039
+ '',
4040
+ '',
4041
+ '',
4042
+ '',
4043
+ ' ' . self::$currency,
4044
+ '',
4045
+ '',
4046
+ '',
4047
+ '',
4048
+ '',
4049
+ '',
4050
+ '',
4051
+ '',
4052
+ ),
4053
+ 'output_type' => array(
4054
+ '1',
4055
+ '1',
4056
+ '11',
4057
+ '1',
4058
+ '1',
4059
+ '1',
4060
+ '1',
4061
+ '1',
4062
+ '1',
4063
+ '1',
4064
+ '6',
4065
+ '1',
4066
+ '1',
4067
+ '1',
4068
+ '1',
4069
+ '1',
4070
+ '1',
4071
+ '1',
4072
+ '1',
4073
+ ),
4074
+ 'limit' => array(
4075
+ '',
4076
+ '',
4077
+ '',
4078
+ '',
4079
+ '',
4080
+ '',
4081
+ '',
4082
+ '',
4083
+ '',
4084
+ '',
4085
+ '',
4086
+ '',
4087
+ '',
4088
+ '',
4089
+ '',
4090
+ '',
4091
+ '',
4092
+ '',
4093
+ '',
4094
+ ),
4095
+ ),
4096
+ 'daisycon' => array(
4097
+ 'mattributes' => array(
4098
+ 'sku',
4099
+ 'description',
4100
+ 'link',
4101
+ 'price',
4102
+ 'title',
4103
+ 'image_link_1',
4104
+ 'brand',
4105
+ 'category',
4106
+ 'category_path',
4107
+ 'delivery_time',
4108
+ 'ean',
4109
+ 'google_category_id',
4110
+ 'in_stock',
4111
+ 'in_stock_amount',
4112
+ 'price_old',
4113
+ 'color_primary',
4114
+ 'condition',
4115
+ 'gender_target',
4116
+ 'price_shipping',
4117
+ 'brand_logo',
4118
+ 'delivery_description',
4119
+ 'image_link_2',
4120
+ 'keywords',
4121
+ 'size',
4122
+ 'size_description',
4123
+ 'terms_conditions',
4124
+ ),
4125
+ 'prefix' => array(
4126
+ '',
4127
+ '',
4128
+ '',
4129
+ '',
4130
+ '',
4131
+ '',
4132
+ '',
4133
+ '',
4134
+ '',
4135
+ '',
4136
+ '',
4137
+ '',
4138
+ '',
4139
+ '',
4140
+ '',
4141
+ '',
4142
+ '',
4143
+ '',
4144
+ '',
4145
+ '',
4146
+ '',
4147
+ '',
4148
+ '',
4149
+ '',
4150
+ '',
4151
+ '',
4152
+ ),
4153
+ 'type' => array(
4154
+ 'attribute',
4155
+ 'attribute',
4156
+ 'attribute',
4157
+ 'attribute',
4158
+ 'attribute',
4159
+ 'attribute',
4160
+ 'pattern',
4161
+ 'attribute',
4162
+ 'attribute',
4163
+ 'pattern',
4164
+ 'attribute',
4165
+ 'pattern',
4166
+ 'attribute',
4167
+ 'attribute',
4168
+ 'attribute',
4169
+ 'attribute',
4170
+ 'attribute',
4171
+ 'pattern',
4172
+ 'pattern',
4173
+ 'pattern',
4174
+ 'pattern',
4175
+ 'attribute',
4176
+ 'attribute',
4177
+ 'attribute',
4178
+ 'pattern',
4179
+ 'pattern',
4180
+ ),
4181
+ 'attributes' => array(
4182
+ 'sku',
4183
+ 'description',
4184
+ 'link',
4185
+ 'price',
4186
+ 'title',
4187
+ 'image',
4188
+ '',
4189
+ 'primary_category',
4190
+ 'product_type',
4191
+ '',
4192
+ 'sku',
4193
+ '',
4194
+ 'availability',
4195
+ 'wf_cattr__stock',
4196
+ 'price',
4197
+ 'wf_attr_pa_color',
4198
+ 'condition',
4199
+ '',
4200
+ '',
4201
+ '',
4202
+ '',
4203
+ 'image_2',
4204
+ 'tags',
4205
+ 'wf_attr_pa_size',
4206
+ '',
4207
+ '',
4208
+ ),
4209
+ 'default' => array(
4210
+ '',
4211
+ '',
4212
+ '',
4213
+ '',
4214
+ '',
4215
+ '',
4216
+ 'Pxwp',
4217
+ '',
4218
+ '',
4219
+ '',
4220
+ '',
4221
+ '',
4222
+ '',
4223
+ '',
4224
+ '',
4225
+ '',
4226
+ '',
4227
+ '',
4228
+ '',
4229
+ '',
4230
+ '',
4231
+ '',
4232
+ '',
4233
+ '',
4234
+ '',
4235
+ '',
4236
+ ),
4237
+ 'suffix' => array(
4238
+ '',
4239
+ '',
4240
+ '',
4241
+ '',
4242
+ '',
4243
+ '',
4244
+ '',
4245
+ '',
4246
+ '',
4247
+ '',
4248
+ '',
4249
+ '',
4250
+ '',
4251
+ '',
4252
+ '',
4253
+ '',
4254
+ '',
4255
+ '',
4256
+ '',
4257
+ '',
4258
+ '',
4259
+ '',
4260
+ '',
4261
+ '',
4262
+ '',
4263
+ '',
4264
+ ),
4265
+ 'output_type' => array(
4266
+ '1',
4267
+ '11',
4268
+ '1',
4269
+ '1',
4270
+ '1',
4271
+ '1',
4272
+ '1',
4273
+ '1',
4274
+ '1',
4275
+ '1',
4276
+ '1',
4277
+ '1',
4278
+ '1',
4279
+ '1',
4280
+ '1',
4281
+ '1',
4282
+ '1',
4283
+ '1',
4284
+ '1',
4285
+ '1',
4286
+ '1',
4287
+ '1',
4288
+ '1',
4289
+ '1',
4290
+ '1',
4291
+ '1',
4292
+ ),
4293
+ 'limit' => array(
4294
+ '',
4295
+ '',
4296
+ '',
4297
+ '',
4298
+ '',
4299
+ '',
4300
+ '',
4301
+ '',
4302
+ '',
4303
+ '',
4304
+ '',
4305
+ '',
4306
+ '',
4307
+ '',
4308
+ '',
4309
+ '',
4310
+ '',
4311
+ '',
4312
+ '',
4313
+ '',
4314
+ '',
4315
+ '',
4316
+ '',
4317
+ '',
4318
+ '',
4319
+ '',
4320
+ ),
4321
+ ),
4322
+ 'daisycon_automotive' => array(
4323
+ 'mattributes' => array(
4324
+ 'sku',
4325
+ 'title',
4326
+ 'description',
4327
+ 'link',
4328
+ 'price',
4329
+ 'brand',
4330
+ 'category',
4331
+ 'category_path',
4332
+ 'color_primary',
4333
+ 'delivery_time',
4334
+ 'ean',
4335
+ 'google_category_id',
4336
+ 'in_stock',
4337
+ 'in_stock_amount',
4338
+ 'price_old',
4339
+ 'image_link_1',
4340
+ 'condition',
4341
+ 'price_shipping',
4342
+ 'image_link_2',
4343
+ 'brake_system',
4344
+ 'brand_logo',
4345
+ 'delivery_description',
4346
+ 'fuel_type',
4347
+ 'gear_system',
4348
+ 'gender_target',
4349
+ 'has_airco',
4350
+ 'keywords',
4351
+ 'model',
4352
+ 'priority',
4353
+ 'rental_location_city',
4354
+ 'rental_location_country',
4355
+ 'rental_location_region',
4356
+ 'size',
4357
+ 'size_description',
4358
+ 'tire_size',
4359
+ 'year_built',
4360
+ 'terms_conditions'
4361
+ ),
4362
+ 'prefix' => array(
4363
+ '',
4364
+ '',
4365
+ '',
4366
+ '',
4367
+ '',
4368
+ '',
4369
+ '',
4370
+ '',
4371
+ '',
4372
+ '',
4373
+ '',
4374
+ '',
4375
+ '',
4376
+ '',
4377
+ '',
4378
+ '',
4379
+ '',
4380
+ '',
4381
+ '',
4382
+ '',
4383
+ '',
4384
+ '',
4385
+ '',
4386
+ '',
4387
+ '',
4388
+ '',
4389
+ '',
4390
+ '',
4391
+ '',
4392
+ '',
4393
+ '',
4394
+ '',
4395
+ '',
4396
+ '',
4397
+ '',
4398
+ '',
4399
+ ''
4400
+ ),
4401
+ 'type' => array(
4402
+ 'attribute',
4403
+ 'attribute',
4404
+ 'attribute',
4405
+ 'attribute',
4406
+ 'attribute',
4407
+ 'pattern',
4408
+ 'attribute',
4409
+ 'attribute',
4410
+ 'attribute',
4411
+ 'pattern',
4412
+ 'pattern',
4413
+ 'pattern',
4414
+ 'attribute',
4415
+ 'attribute',
4416
+ 'attribute',
4417
+ 'attribute',
4418
+ 'attribute',
4419
+ 'pattern',
4420
+ 'attribute',
4421
+ 'pattern',
4422
+ 'pattern',
4423
+ 'pattern',
4424
+ 'pattern',
4425
+ 'pattern',
4426
+ 'pattern',
4427
+ 'pattern',
4428
+ 'attribute',
4429
+ 'pattern',
4430
+ 'pattern',
4431
+ 'pattern',
4432
+ 'pattern',
4433
+ 'pattern',
4434
+ 'pattern',
4435
+ 'pattern',
4436
+ 'pattern',
4437
+ 'pattern',
4438
+ 'pattern'
4439
+ ),
4440
+ 'attributes' => array(
4441
+ 'sku',
4442
+ 'title',
4443
+ 'description',
4444
+ 'link',
4445
+ 'price',
4446
+ '',
4447
+ 'primary_category',
4448
+ 'product_type',
4449
+ 'wf_attr_pa_color',
4450
+ '',
4451
+ '',
4452
+ '',
4453
+ 'availability',
4454
+ 'quantity',
4455
+ 'price',
4456
+ 'image',
4457
+ 'condition',
4458
+ '',
4459
+ 'image_2',
4460
+ '',
4461
+ '',
4462
+ '',
4463
+ '',
4464
+ '',
4465
+ '',
4466
+ '',
4467
+ 'tags',
4468
+ '',
4469
+ '',
4470
+ '',
4471
+ '',
4472
+ '',
4473
+ '',
4474
+ '',
4475
+ '',
4476
+ '',
4477
+ ''
4478
+ ),
4479
+ 'default' => array(
4480
+ '',
4481
+ '',
4482
+ '',
4483
+ '',
4484
+ '',
4485
+ 'Pxwp',
4486
+ '',
4487
+ '',
4488
+ '',
4489
+ '',
4490
+ '',
4491
+ '',
4492
+ '',
4493
+ '',
4494
+ '',
4495
+ '',
4496
+ '',
4497
+ '',
4498
+ '',
4499
+ '',
4500
+ '',
4501
+ '',
4502
+ '',
4503
+ '',
4504
+ '',
4505
+ '',
4506
+ '',
4507
+ '',
4508
+ '',
4509
+ '',
4510
+ '',
4511
+ '',
4512
+ '',
4513
+ '',
4514
+ '',
4515
+ '',
4516
+ ''
4517
+ ),
4518
+ 'suffix' => array(
4519
+ '',
4520
+ '',
4521
+ '',
4522
+ '',
4523
+ '',
4524
+ '',
4525
+ '',
4526
+ '',
4527
+ '',
4528
+ '',
4529
+ '',
4530
+ '',
4531
+ '',
4532
+ '',
4533
+ '',
4534
+ '',
4535
+ '',
4536
+ '',
4537
+ '',
4538
+ '',
4539
+ '',
4540
+ '',
4541
+ '',
4542
+ '',
4543
+ '',
4544
+ '',
4545
+ '',
4546
+ '',
4547
+ '',
4548
+ '',
4549
+ '',
4550
+ '',
4551
+ '',
4552
+ '',
4553
+ '',
4554
+ '',
4555
+ ''
4556
+ ),
4557
+ 'output_type' => array(
4558
+ '1',
4559
+ '1',
4560
+ '11',
4561
+ '1',
4562
+ '1',
4563
+ '1',
4564
+ '1',
4565
+ '1',
4566
+ '1',
4567
+ '1',
4568
+ '1',
4569
+ '1',
4570
+ '1',
4571
+ '1',
4572
+ '1',
4573
+ '1',
4574
+ '1',
4575
+ '1',
4576
+ '1',
4577
+ '1',
4578
+ '1',
4579
+ '1',
4580
+ '1',
4581
+ '1',
4582
+ '1',
4583
+ '1',
4584
+ '1',
4585
+ '1',
4586
+ '1',
4587
+ '1',
4588
+ '1',
4589
+ '1',
4590
+ '1',
4591
+ '1',
4592
+ '1',
4593
+ '1',
4594
+ '1'
4595
+ ),
4596
+ 'limit' => array(
4597
+ '',
4598
+ '',
4599
+ '',
4600
+ '',
4601
+ '',
4602
+ '',
4603
+ '',
4604
+ '',
4605
+ '',
4606
+ '',
4607
+ '',
4608
+ '',
4609
+ '',
4610
+ '',
4611
+ '',
4612
+ '',
4613
+ '',
4614
+ '',
4615
+ '',
4616
+ '',
4617
+ '',
4618
+ '',
4619
+ '',
4620
+ '',
4621
+ '',
4622
+ '',
4623
+ '',
4624
+ '',
4625
+ '',
4626
+ '',
4627
+ '',
4628
+ '',
4629
+ '',
4630
+ '',
4631
+ '',
4632
+ '',
4633
+ ''
4634
+ ),
4635
+ ),
4636
+ 'daisycon_books' => array(
4637
+ 'mattributes' => array(
4638
+ 'description',
4639
+ 'link',
4640
+ 'price',
4641
+ 'sku',
4642
+ 'title',
4643
+ 'author',
4644
+ 'category',
4645
+ 'category_path',
4646
+ 'delivery_time',
4647
+ 'ean',
4648
+ 'google_category_id',
4649
+ 'in_stock',
4650
+ 'in_stock_amount',
4651
+ 'isbn',
4652
+ 'price_old',
4653
+ 'image_link_1',
4654
+ 'book_publisher',
4655
+ 'book_type',
4656
+ 'price_shipping',
4657
+ 'image_link_2',
4658
+ 'condition',
4659
+ 'gender_target',
4660
+ 'number_of_pages',
4661
+ 'release_date',
4662
+ 'book_edition',
4663
+ 'delivery_description',
4664
+ 'file_size',
4665
+ 'file_type',
4666
+ 'keywords',
4667
+ 'language',
4668
+ 'priority',
4669
+ 'size',
4670
+ 'size_description',
4671
+ 'size_length',
4672
+ 'size_width',
4673
+ 'weight',
4674
+ 'terms_conditions'
4675
+ ),
4676
+ 'prefix' => array(
4677
+ '',
4678
+ '',
4679
+ '',
4680
+ '',
4681
+ '',
4682
+ '',
4683
+ '',
4684
+ '',
4685
+ '',
4686
+ '',
4687
+ '',
4688
+ '',
4689
+ '',
4690
+ '',
4691
+ '',
4692
+ '',
4693
+ '',
4694
+ '',
4695
+ '',
4696
+ '',
4697
+ '',
4698
+ '',
4699
+ '',
4700
+ '',
4701
+ '',
4702
+ '',
4703
+ '',
4704
+ '',
4705
+ '',
4706
+ '',
4707
+ '',
4708
+ '',
4709
+ '',
4710
+ '',
4711
+ '',
4712
+ '',
4713
+ ''
4714
+ ),
4715
+ 'type' => array(
4716
+ 'attribute',
4717
+ 'attribute',
4718
+ 'attribute',
4719
+ 'attribute',
4720
+ 'attribute',
4721
+ 'attribute',
4722
+ 'attribute',
4723
+ 'attribute',
4724
+ 'pattern',
4725
+ 'attribute',
4726
+ 'pattern',
4727
+ 'attribute',
4728
+ 'attribute',
4729
+ 'attribute',
4730
+ 'attribute',
4731
+ 'attribute',
4732
+ 'attribute',
4733
+ 'attribute',
4734
+ 'pattern',
4735
+ 'attribute',
4736
+ 'attribute',
4737
+ 'pattern',
4738
+ 'attribute',
4739
+ 'attribute',
4740
+ 'attribute',
4741
+ 'attribute',
4742
+ 'attribute',
4743
+ 'attribute',
4744
+ 'attribute',
4745
+ 'attribute',
4746
+ 'attribute',
4747
+ 'attribute',
4748
+ 'attribute',
4749
+ 'attribute',
4750
+ 'attribute',
4751
+ 'attribute',
4752
+ 'attribute'
4753
+ ),
4754
+ 'attributes' => array(
4755
+ 'description',
4756
+ 'link',
4757
+ 'current_price',
4758
+ 'sku',
4759
+ 'title',
4760
+ '',
4761
+ 'primary_category',
4762
+ 'product_type',
4763
+ '',
4764
+ '',
4765
+ '',
4766
+ 'availability',
4767
+ 'quantity',
4768
+ '',
4769
+ 'price',
4770
+ 'image',
4771
+ '',
4772
+ '',
4773
+ '',
4774
+ 'image_1',
4775
+ 'condition',
4776
+ '',
4777
+ '',
4778
+ '',
4779
+ '',
4780
+ '',
4781
+ '',
4782
+ '',
4783
+ 'tags',
4784
+ '',
4785
+ '',
4786
+ '',
4787
+ '',
4788
+ 'length',
4789
+ 'width',
4790
+ 'weight',
4791
+ ''
4792
+ ),
4793
+ 'default' => array(
4794
+ '',
4795
+ '',
4796
+ '',
4797
+ '',
4798
+ '',
4799
+ '',
4800
+ '',
4801
+ '',
4802
+ '',
4803
+ '',
4804
+ '',
4805
+ '',
4806
+ '',
4807
+ '',
4808
+ '',
4809
+ '',
4810
+ '',
4811
+ '',
4812
+ '',
4813
+ '',
4814
+ '',
4815
+ '',
4816
+ '',
4817
+ '',
4818
+ '',
4819
+ '',
4820
+ '',
4821
+ '',
4822
+ '',
4823
+ '',
4824
+ '',
4825
+ '',
4826
+ '',
4827
+ '',
4828
+ '',
4829
+ '',
4830
+ ''
4831
+ ),
4832
+ 'suffix' => array(
4833
+ '',
4834
+ '',
4835
+ '',
4836
+ '',
4837
+ '',
4838
+ '',
4839
+ '',
4840
+ '',
4841
+ '',
4842
+ '',
4843
+ '',
4844
+ '',
4845
+ '',
4846
+ '',
4847
+ '',
4848
+ '',
4849
+ '',
4850
+ '',
4851
+ '',
4852
+ '',
4853
+ '',
4854
+ '',
4855
+ '',
4856
+ '',
4857
+ '',
4858
+ '',
4859
+ '',
4860
+ '',
4861
+ '',
4862
+ '',
4863
+ '',
4864
+ '',
4865
+ '',
4866
+ '',
4867
+ '',
4868
+ '',
4869
+ ''
4870
+ ),
4871
+ 'output_type' => array(
4872
+ '11',
4873
+ '1',
4874
+ '1',
4875
+ '1',
4876
+ '1',
4877
+ '1',
4878
+ '1',
4879
+ '1',
4880
+ '1',
4881
+ '1',
4882
+ '1',
4883
+ '1',
4884
+ '1',
4885
+ '1',
4886
+ '1',
4887
+ '1',
4888
+ '1',
4889
+ '1',
4890
+ '1',
4891
+ '1',
4892
+ '1',
4893
+ '1',
4894
+ '1',
4895
+ '1',
4896
+ '1',
4897
+ '1',
4898
+ '1',
4899
+ '1',
4900
+ '1',
4901
+ '1',
4902
+ '1',
4903
+ '1',
4904
+ '1',
4905
+ '1',
4906
+ '1',
4907
+ '1',
4908
+ '1'
4909
+ ),
4910
+ 'limit' => array(
4911
+ '',
4912
+ '',
4913
+ '',
4914
+ '',
4915
+ '',
4916
+ '',
4917
+ '',
4918
+ '',
4919
+ '',
4920
+ '',
4921
+ '',
4922
+ '',
4923
+ '',
4924
+ '',
4925
+ '',
4926
+ '',
4927
+ '',
4928
+ '',
4929
+ '',
4930
+ '',
4931
+ '',
4932
+ '',
4933
+ '',
4934
+ '',
4935
+ '',
4936
+ '',
4937
+ '',
4938
+ '',
4939
+ '',
4940
+ '',
4941
+ '',
4942
+ '',
4943
+ '',
4944
+ '',
4945
+ '',
4946
+ '',
4947
+ ''
4948
+ ),
4949
+ ),
4950
+ 'daisycon_cosmetics' => array(
4951
+ 'mattributes' => array(
4952
+ 'description',
4953
+ 'link',
4954
+ 'price',
4955
+ 'sku',
4956
+ 'title',
4957
+ 'allergic_info',
4958
+ 'amount_content',
4959
+ 'amount_description',
4960
+ 'category',
4961
+ 'category_path',
4962
+ 'delivery_time',
4963
+ 'ean',
4964
+ 'google_category_id',
4965
+ 'in_stock',
4966
+ 'in_stock_amount',
4967
+ 'price_old',
4968
+ 'image_link_1',
4969
+ 'description_ingredients',
4970
+ 'gender_target',
4971
+ 'price_shipping',
4972
+ 'skin_type',
4973
+ 'image_link_2',
4974
+ 'color_primary',
4975
+ 'brand_logo',
4976
+ 'condition',
4977
+ 'delivery_description',
4978
+ 'keywords',
4979
+ 'made_in_country',
4980
+ 'priority',
4981
+ 'size',
4982
+ 'size_description',
4983
+ 'terms_conditions'
4984
+ ),
4985
+ 'prefix' => array(
4986
+ '',
4987
+ '',
4988
+ '',
4989
+ '',
4990
+ '',
4991
+ '',
4992
+ '',
4993
+ '',
4994
+ '',
4995
+ '',
4996
+ '',
4997
+ '',
4998
+ '',
4999
+ '',
5000
+ '',
5001
+ '',
5002
+ '',
5003
+ '',
5004
+ '',
5005
+ '',
5006
+ '',
5007
+ '',
5008
+ '',
5009
+ '',
5010
+ '',
5011
+ '',
5012
+ '',
5013
+ '',
5014
+ '',
5015
+ '',
5016
+ '',
5017
+ ''
5018
+ ),
5019
+ 'type' => array(
5020
+ 'attribute',
5021
+ 'attribute',
5022
+ 'attribute',
5023
+ 'attribute',
5024
+ 'attribute',
5025
+ 'attribute',
5026
+ 'attribute',
5027
+ 'pattern',
5028
+ 'attribute',
5029
+ 'attribute',
5030
+ 'attribute',
5031
+ 'attribute',
5032
+ 'pattern',
5033
+ 'attribute',
5034
+ 'attribute',
5035
+ 'attribute',
5036
+ 'attribute',
5037
+ 'attribute',
5038
+ 'attribute',
5039
+ 'attribute',
5040
+ 'attribute',
5041
+ 'attribute',
5042
+ 'attribute',
5043
+ 'pattern',
5044
+ 'attribute',
5045
+ 'attribute',
5046
+ 'attribute',
5047
+ 'attribute',
5048
+ 'attribute',
5049
+ 'attribute',
5050
+ 'attribute',
5051
+ 'pattern'
5052
+ ),
5053
+ 'attributes' => array(
5054
+ 'description',
5055
+ 'link',
5056
+ 'current_price',
5057
+ 'sku',
5058
+ 'title',
5059
+ '',
5060
+ 'weight',
5061
+ '',
5062
+ 'primary_category',
5063
+ 'product_type',
5064
+ '',
5065
+ '',
5066
+ '',
5067
+ 'availability',
5068
+ 'quantity',
5069
+ 'price',
5070
+ 'image',
5071
+ '',
5072
+ '',
5073
+ '',
5074
+ '',
5075
+ 'image_2',
5076
+ 'wf_attr_pa_color',
5077
+ '',
5078
+ 'condition',
5079
+ '',
5080
+ 'tags',
5081
+ '',
5082
+ '',
5083
+ '',
5084
+ '',
5085
+ ''
5086
+ ),
5087
+ 'default' => array(
5088
+ '',
5089
+ '',
5090
+ '',
5091
+ '',
5092
+ '',
5093
+ '',
5094
+ '',
5095
+ '',
5096
+ '',
5097
+ '',
5098
+ '',
5099
+ '',
5100
+ '',
5101
+ '',
5102
+ '',
5103
+ '',
5104
+ '',
5105
+ '',
5106
+ '',
5107
+ '',
5108
+ '',
5109
+ '',
5110
+ '',
5111
+ '',
5112
+ '',
5113
+ '',
5114
+ '',
5115
+ '',
5116
+ '',
5117
+ '',
5118
+ '',
5119
+ ''
5120
+ ),
5121
+ 'suffix' => array(
5122
+ '',
5123
+ '',
5124
+ '',
5125
+ '',
5126
+ '',
5127
+ '',
5128
+ '',
5129
+ '',
5130
+ '',
5131
+ '',
5132
+ '',
5133
+ '',
5134
+ '',
5135
+ '',
5136
+ '',
5137
+ '',
5138
+ '',
5139
+ '',
5140
+ '',
5141
+ '',
5142
+ '',
5143
+ '',
5144
+ '',
5145
+ '',
5146
+ '',
5147
+ '',
5148
+ '',
5149
+ '',
5150
+ '',
5151
+ '',
5152
+ '',
5153
+ ''
5154
+ ),
5155
+ 'output_type' => array(
5156
+ '11',
5157
+ '1',
5158
+ '1',
5159
+ '1',
5160
+ '1',
5161
+ '1',
5162
+ '1',
5163
+ '1',
5164
+ '1',
5165
+ '1',
5166
+ '1',
5167
+ '1',
5168
+ '1',
5169
+ '1',
5170
+ '1',
5171
+ '1',
5172
+ '1',
5173
+ '1',
5174
+ '1',
5175
+ '1',
5176
+ '1',
5177
+ '1',
5178
+ '1',
5179
+ '1',
5180
+ '1',
5181
+ '1',
5182
+ '1',
5183
+ '1',
5184
+ '1',
5185
+ '1',
5186
+ '1',
5187
+ '1'
5188
+ ),
5189
+ 'limit' => array(
5190
+ '',
5191
+ '',
5192
+ '',
5193
+ '',
5194
+ '',
5195
+ '',
5196
+ '',
5197
+ '',
5198
+ '',
5199
+ '',
5200
+ '',
5201
+ '',
5202
+ '',
5203
+ '',
5204
+ '',
5205
+ '',
5206
+ '',
5207
+ '',
5208
+ '',
5209
+ '',
5210
+ '',
5211
+ '',
5212
+ '',
5213
+ '',
5214
+ '',
5215
+ '',
5216
+ '',
5217
+ '',
5218
+ '',
5219
+ '',
5220
+ '',
5221
+ ''
5222
+ ),
5223
+ ),
5224
+ 'daisycon_daily_offers' => array(
5225
+ 'mattributes' => array(
5226
+ 'description',
5227
+ 'link',
5228
+ 'price',
5229
+ 'sku',
5230
+ 'title',
5231
+ 'brand',
5232
+ 'category',
5233
+ 'category_path',
5234
+ 'delivery_time',
5235
+ 'ean',
5236
+ 'in_stock',
5237
+ 'in_stock_amount',
5238
+ 'price_old',
5239
+ 'image_link_1',
5240
+ 'google_category_id',
5241
+ 'price_shipping',
5242
+ 'image_link_2',
5243
+ 'brand_logo',
5244
+ 'color_primary',
5245
+ 'condition',
5246
+ 'delivery_description',
5247
+ 'discount_amount',
5248
+ 'discount_percentage',
5249
+ 'gender_target',
5250
+ 'keywords',
5251
+ 'model',
5252
+ 'offer_datetime_end',
5253
+ 'offer_datetime_start',
5254
+ 'size',
5255
+ 'size_description',
5256
+ 'terms_conditions'
5257
+ ),
5258
+ 'prefix' => array(
5259
+ '',
5260
+ '',
5261
+ '',
5262
+ '',
5263
+ '',
5264
+ '',
5265
+ '',
5266
+ '',
5267
+ '',
5268
+ '',
5269
+ '',
5270
+ '',
5271
+ '',
5272
+ '',
5273
+ '',
5274
+ '',
5275
+ '',
5276
+ '',
5277
+ '',
5278
+ '',
5279
+ '',
5280
+ '',
5281
+ '',
5282
+ '',
5283
+ '',
5284
+ '',
5285
+ '',
5286
+ '',
5287
+ '',
5288
+ '',
5289
+ ''
5290
+ ),
5291
+ 'type' => array(
5292
+ 'attribute',
5293
+ 'attribute',
5294
+ 'attribute',
5295
+ 'attribute',
5296
+ 'attribute',
5297
+ 'pattern',
5298
+ 'attribute',
5299
+ 'attribute',
5300
+ 'attribute',
5301
+ 'attribute',
5302
+ 'attribute',
5303
+ 'attribute',
5304
+ 'attribute',
5305
+ 'attribute',
5306
+ 'pattern',
5307
+ 'attribute',
5308
+ 'attribute',
5309
+ 'pattern',
5310
+ 'attribute',
5311
+ 'attribute',
5312
+ 'attribute',
5313
+ 'attribute',
5314
+ 'attribute',
5315
+ 'attribute',
5316
+ 'attribute',
5317
+ 'attribute',
5318
+ 'attribute',
5319
+ 'attribute',
5320
+ 'attribute',
5321
+ 'attribute',
5322
+ 'pattern'
5323
+ ),
5324
+ 'attributes' => array(
5325
+ 'description',
5326
+ 'link',
5327
+ 'current_price',
5328
+ 'sku',
5329
+ 'title',
5330
+ '',
5331
+ 'primary_category',
5332
+ 'product_type',
5333
+ '',
5334
+ '',
5335
+ 'availability',
5336
+ 'quantity',
5337
+ 'price',
5338
+ 'image',
5339
+ '',
5340
+ '',
5341
+ 'image_2',
5342
+ '',
5343
+ 'wf_attr_pa_color',
5344
+ 'condition',
5345
+ '',
5346
+ '',
5347
+ '',
5348
+ '',
5349
+ 'tags',
5350
+ '',
5351
+ '',
5352
+ '',
5353
+ '',
5354
+ '',
5355
+ ''
5356
+ ),
5357
+ 'default' => array(
5358
+ '',
5359
+ '',
5360
+ '',
5361
+ '',
5362
+ '',
5363
+ '',
5364
+ '',
5365
+ '',
5366
+ '',
5367
+ '',
5368
+ '',
5369
+ '',
5370
+ '',
5371
+ '',
5372
+ '',
5373
+ '',
5374
+ '',
5375
+ '',
5376
+ '',
5377
+ '',
5378
+ '',
5379
+ '',
5380
+ '',
5381
+ '',
5382
+ '',
5383
+ '',
5384
+ '',
5385
+ '',
5386
+ '',
5387
+ '',
5388
+ ''
5389
+ ),
5390
+ 'suffix' => array(
5391
+ '',
5392
+ '',
5393
+ '',
5394
+ '',
5395
+ '',
5396
+ '',
5397
+ '',
5398
+ '',
5399
+ '',
5400
+ '',
5401
+ '',
5402
+ '',
5403
+ '',
5404
+ '',
5405
+ '',
5406
+ '',
5407
+ '',
5408
+ '',
5409
+ '',
5410
+ '',
5411
+ '',
5412
+ '',
5413
+ '',
5414
+ '',
5415
+ '',
5416
+ '',
5417
+ '',
5418
+ '',
5419
+ '',
5420
+ '',
5421
+ ''
5422
+ ),
5423
+ 'output_type' => array(
5424
+ '11',
5425
+ '1',
5426
+ '1',
5427
+ '1',
5428
+ '1',
5429
+ '1',
5430
+ '1',
5431
+ '1',
5432
+ '1',
5433
+ '1',
5434
+ '1',
5435
+ '1',
5436
+ '1',
5437
+ '1',
5438
+ '1',
5439
+ '1',
5440
+ '1',
5441
+ '1',
5442
+ '1',
5443
+ '1',
5444
+ '1',
5445
+ '1',
5446
+ '1',
5447
+ '1',
5448
+ '1',
5449
+ '1',
5450
+ '1',
5451
+ '1',
5452
+ '1',
5453
+ '1',
5454
+ '1'
5455
+ ),
5456
+ 'limit' => array(
5457
+ '',
5458
+ '',
5459
+ '',
5460
+ '',
5461
+ '',
5462
+ '',
5463
+ '',
5464
+ '',
5465
+ '',
5466
+ '',
5467
+ '',
5468
+ '',
5469
+ '',
5470
+ '',
5471
+ '',
5472
+ '',
5473
+ '',
5474
+ '',
5475
+ '',
5476
+ '',
5477
+ '',
5478
+ '',
5479
+ '',
5480
+ '',
5481
+ '',
5482
+ '',
5483
+ '',
5484
+ '',
5485
+ '',
5486
+ '',
5487
+ ''
5488
+ ),
5489
+ ),
5490
+ 'daisycon_electronics' => array(
5491
+ 'mattributes' => array(
5492
+ 'sku',
5493
+ 'description',
5494
+ 'link',
5495
+ 'price',
5496
+ 'title',
5497
+ 'image_link_1',
5498
+ 'brand',
5499
+ 'category',
5500
+ 'category_path',
5501
+ 'delivery_time',
5502
+ 'ean',
5503
+ 'google_category_id',
5504
+ 'in_stock',
5505
+ 'in_stock_amount',
5506
+ 'price_old',
5507
+ 'color_primary',
5508
+ 'condition',
5509
+ 'gender_target',
5510
+ 'price_shipping',
5511
+ 'brand_logo',
5512
+ 'delivery_description',
5513
+ 'image_link_2',
5514
+ 'keywords',
5515
+ 'size',
5516
+ 'size_description',
5517
+ 'terms_conditions',
5518
+ ),
5519
+ 'prefix' => array(
5520
+ '',
5521
+ '',
5522
+ '',
5523
+ '',
5524
+ '',
5525
+ '',
5526
+ '',
5527
+ '',
5528
+ '',
5529
+ '',
5530
+ '',
5531
+ '',
5532
+ '',
5533
+ '',
5534
+ '',
5535
+ '',
5536
+ '',
5537
+ '',
5538
+ '',
5539
+ '',
5540
+ '',
5541
+ '',
5542
+ '',
5543
+ '',
5544
+ '',
5545
+ '',
5546
+ ),
5547
+ 'type' => array(
5548
+ 'attribute',
5549
+ 'attribute',
5550
+ 'attribute',
5551
+ 'attribute',
5552
+ 'attribute',
5553
+ 'attribute',
5554
+ 'pattern',
5555
+ 'attribute',
5556
+ 'attribute',
5557
+ 'pattern',
5558
+ 'attribute',
5559
+ 'pattern',
5560
+ 'attribute',
5561
+ 'attribute',
5562
+ 'attribute',
5563
+ 'attribute',
5564
+ 'attribute',
5565
+ 'pattern',
5566
+ 'pattern',
5567
+ 'pattern',
5568
+ 'pattern',
5569
+ 'attribute',
5570
+ 'attribute',
5571
+ 'attribute',
5572
+ 'pattern',
5573
+ 'pattern',
5574
+ ),
5575
+ 'attributes' => array(
5576
+ 'sku',
5577
+ 'description',
5578
+ 'link',
5579
+ 'price',
5580
+ 'title',
5581
+ 'image',
5582
+ '',
5583
+ 'primary_category',
5584
+ 'product_type',
5585
+ '',
5586
+ 'sku',
5587
+ '',
5588
+ 'availability',
5589
+ 'wf_cattr__stock',
5590
+ 'price',
5591
+ 'wf_attr_pa_color',
5592
+ 'condition',
5593
+ '',
5594
+ '',
5595
+ '',
5596
+ '',
5597
+ 'image_2',
5598
+ 'tags',
5599
+ 'wf_attr_pa_size',
5600
+ '',
5601
+ '',
5602
+ ),
5603
+ 'default' => array(
5604
+ '',
5605
+ '',
5606
+ '',
5607
+ '',
5608
+ '',
5609
+ '',
5610
+ 'Pxwp',
5611
+ '',
5612
+ '',
5613
+ '',
5614
+ '',
5615
+ '',
5616
+ '',
5617
+ '',
5618
+ '',
5619
+ '',
5620
+ '',
5621
+ '',
5622
+ '',
5623
+ '',
5624
+ '',
5625
+ '',
5626
+ '',
5627
+ '',
5628
+ '',
5629
+ '',
5630
+ ),
5631
+ 'suffix' => array(
5632
+ '',
5633
+ '',
5634
+ '',
5635
+ '',
5636
+ '',
5637
+ '',
5638
+ '',
5639
+ '',
5640
+ '',
5641
+ '',
5642
+ '',
5643
+ '',
5644
+ '',
5645
+ '',
5646
+ '',
5647
+ '',
5648
+ '',
5649
+ '',
5650
+ '',
5651
+ '',
5652
+ '',
5653
+ '',
5654
+ '',
5655
+ '',
5656
+ '',
5657
+ '',
5658
+ ),
5659
+ 'output_type' => array(
5660
+ '1',
5661
+ '11',
5662
+ '1',
5663
+ '1',
5664
+ '1',
5665
+ '1',
5666
+ '1',
5667
+ '1',
5668
+ '1',
5669
+ '1',
5670
+ '1',
5671
+ '1',
5672
+ '1',
5673
+ '1',
5674
+ '1',
5675
+ '1',
5676
+ '1',
5677
+ '1',
5678
+ '1',
5679
+ '1',
5680
+ '1',
5681
+ '1',
5682
+ '1',
5683
+ '1',
5684
+ '1',
5685
+ '1',
5686
+ ),
5687
+ 'limit' => array(
5688
+ '',
5689
+ '',
5690
+ '',
5691
+ '',
5692
+ '',
5693
+ '',
5694
+ '',
5695
+ '',
5696
+ '',
5697
+ '',
5698
+ '',
5699
+ '',
5700
+ '',
5701
+ '',
5702
+ '',
5703
+ '',
5704
+ '',
5705
+ '',
5706
+ '',
5707
+ '',
5708
+ '',
5709
+ '',
5710
+ '',
5711
+ '',
5712
+ '',
5713
+ '',
5714
+ ),
5715
+ ),
5716
+ 'daisycon_fashion' => array(
5717
+ 'mattributes' => array(
5718
+ 'sku',
5719
+ 'description',
5720
+ 'link',
5721
+ 'price',
5722
+ 'title',
5723
+ 'image_link_1',
5724
+ 'brand',
5725
+ 'category',
5726
+ 'category_path',
5727
+ 'delivery_time',
5728
+ 'ean',
5729
+ 'google_category_id',
5730
+ 'in_stock',
5731
+ 'in_stock_amount',
5732
+ 'price_old',
5733
+ 'color_primary',
5734
+ 'condition',
5735
+ 'gender_target',
5736
+ 'price_shipping',
5737
+ 'brand_logo',
5738
+ 'delivery_description',
5739
+ 'image_link_2',
5740
+ 'keywords',
5741
+ 'size',
5742
+ 'size_description',
5743
+ 'terms_conditions',
5744
+ ),
5745
+ 'prefix' => array(
5746
+ '',
5747
+ '',
5748
+ '',
5749
+ '',
5750
+ '',
5751
+ '',
5752
+ '',
5753
+ '',
5754
+ '',
5755
+ '',
5756
+ '',
5757
+ '',
5758
+ '',
5759
+ '',
5760
+ '',
5761
+ '',
5762
+ '',
5763
+ '',
5764
+ '',
5765
+ '',
5766
+ '',
5767
+ '',
5768
+ '',
5769
+ '',
5770
+ '',
5771
+ '',
5772
+ ),
5773
+ 'type' => array(
5774
+ 'attribute',
5775
+ 'attribute',
5776
+ 'attribute',
5777
+ 'attribute',
5778
+ 'attribute',
5779
+ 'attribute',
5780
+ 'pattern',
5781
+ 'attribute',
5782
+ 'attribute',
5783
+ 'pattern',
5784
+ 'attribute',
5785
+ 'pattern',
5786
+ 'attribute',
5787
+ 'attribute',
5788
+ 'attribute',
5789
+ 'attribute',
5790
+ 'attribute',
5791
+ 'pattern',
5792
+ 'pattern',
5793
+ 'pattern',
5794
+ 'pattern',
5795
+ 'attribute',
5796
+ 'attribute',
5797
+ 'attribute',
5798
+ 'pattern',
5799
+ 'pattern',
5800
+ ),
5801
+ 'attributes' => array(
5802
+ 'sku',
5803
+ 'description',
5804
+ 'link',
5805
+ 'price',
5806
+ 'title',
5807
+ 'image',
5808
+ '',
5809
+ 'primary_category',
5810
+ 'product_type',
5811
+ '',
5812
+ 'sku',
5813
+ '',
5814
+ 'availability',
5815
+ 'wf_cattr__stock',
5816
+ 'price',
5817
+ 'wf_attr_pa_color',
5818
+ 'condition',
5819
+ '',
5820
+ '',
5821
+ '',
5822
+ '',
5823
+ 'image_2',
5824
+ 'tags',
5825
+ 'wf_attr_pa_size',
5826
+ '',
5827
+ '',
5828
+ ),
5829
+ 'default' => array(
5830
+ '',
5831
+ '',
5832
+ '',
5833
+ '',
5834
+ '',
5835
+ '',
5836
+ 'Pxwp',
5837
+ '',
5838
+ '',
5839
+ '',
5840
+ '',
5841
+ '',
5842
+ '',
5843
+ '',
5844
+ '',
5845
+ '',
5846
+ '',
5847
+ '',
5848
+ '',
5849
+ '',
5850
+ '',
5851
+ '',
5852
+ '',
5853
+ '',
5854
+ '',
5855
+ '',
5856
+ ),
5857
+ 'suffix' => array(
5858
+ '',
5859
+ '',
5860
+ '',
5861
+ '',
5862
+ '',
5863
+ '',
5864
+ '',
5865
+ '',
5866
+ '',
5867
+ '',
5868
+ '',
5869
+ '',
5870
+ '',
5871
+ '',
5872
+ '',
5873
+ '',
5874
+ '',
5875
+ '',
5876
+ '',
5877
+ '',
5878
+ '',
5879
+ '',
5880
+ '',
5881
+ '',
5882
+ '',
5883
+ '',
5884
+ ),
5885
+ 'output_type' => array(
5886
+ '1',
5887
+ '11',
5888
+ '1',
5889
+ '1',
5890
+ '1',
5891
+ '1',
5892
+ '1',
5893
+ '1',
5894
+ '1',
5895
+ '1',
5896
+ '1',
5897
+ '1',
5898
+ '1',
5899
+ '1',
5900
+ '1',
5901
+ '1',
5902
+ '1',
5903
+ '1',
5904
+ '1',
5905
+ '1',
5906
+ '1',
5907
+ '1',
5908
+ '1',
5909
+ '1',
5910
+ '1',
5911
+ '1',
5912
+ ),
5913
+ 'limit' => array(
5914
+ '',
5915
+ '',
5916
+ '',
5917
+ '',
5918
+ '',
5919
+ '',
5920
+ '',
5921
+ '',
5922
+ '',
5923
+ '',
5924
+ '',
5925
+ '',
5926
+ '',
5927
+ '',
5928
+ '',
5929
+ '',
5930
+ '',
5931
+ '',
5932
+ '',
5933
+ '',
5934
+ '',
5935
+ '',
5936
+ '',
5937
+ '',
5938
+ '',
5939
+ '',
5940
+ ),
5941
+ ),
5942
+ 'daisycon_food_drinks' => array(
5943
+ 'mattributes' => array(
5944
+ 'sku',
5945
+ 'description',
5946
+ 'link',
5947
+ 'price',
5948
+ 'title',
5949
+ 'image_link_1',
5950
+ 'brand',
5951
+ 'category',
5952
+ 'category_path',
5953
+ 'delivery_time',
5954
+ 'ean',
5955
+ 'google_category_id',
5956
+ 'in_stock',
5957
+ 'in_stock_amount',
5958
+ 'price_old',
5959
+ 'color_primary',
5960
+ 'condition',
5961
+ 'gender_target',
5962
+ 'price_shipping',
5963
+ 'brand_logo',
5964
+ 'delivery_description',
5965
+ 'image_link_2',
5966
+ 'keywords',
5967
+ 'size',
5968
+ 'size_description',
5969
+ 'terms_conditions',
5970
+ ),
5971
+ 'prefix' => array(
5972
+ '',
5973
+ '',
5974
+ '',
5975
+ '',
5976
+ '',
5977
+ '',
5978
+ '',
5979
+ '',
5980
+ '',
5981
+ '',
5982
+ '',
5983
+ '',
5984
+ '',
5985
+ '',
5986
+ '',
5987
+ '',
5988
+ '',
5989
+ '',
5990
+ '',
5991
+ '',
5992
+ '',
5993
+ '',
5994
+ '',
5995
+ '',
5996
+ '',
5997
+ '',
5998
+ ),
5999
+ 'type' => array(
6000
+ 'attribute',
6001
+ 'attribute',
6002
+ 'attribute',
6003
+ 'attribute',
6004
+ 'attribute',
6005
+ 'attribute',
6006
+ 'pattern',
6007
+ 'attribute',
6008
+ 'attribute',
6009
+ 'pattern',
6010
+ 'attribute',
6011
+ 'pattern',
6012
+ 'attribute',
6013
+ 'attribute',
6014
+ 'attribute',
6015
+ 'attribute',
6016
+ 'attribute',
6017
+ 'pattern',
6018
+ 'pattern',
6019
+ 'pattern',
6020
+ 'pattern',
6021
+ 'attribute',
6022
+ 'attribute',
6023
+ 'attribute',
6024
+ 'pattern',
6025
+ 'pattern',
6026
+ ),
6027
+ 'attributes' => array(
6028
+ 'sku',
6029
+ 'description',
6030
+ 'link',
6031
+ 'price',
6032
+ 'title',
6033
+ 'image',
6034
+ '',
6035
+ 'primary_category',
6036
+ 'product_type',
6037
+ '',
6038
+ 'sku',
6039
+ '',
6040
+ 'availability',
6041
+ 'wf_cattr__stock',
6042
+ 'price',
6043
+ 'wf_attr_pa_color',
6044
+ 'condition',
6045
+ '',
6046
+ '',
6047
+ '',
6048
+ '',
6049
+ 'image_2',
6050
+ 'tags',
6051
+ 'wf_attr_pa_size',
6052
+ '',
6053
+ '',
6054
+ ),
6055
+ 'default' => array(
6056
+ '',
6057
+ '',
6058
+ '',
6059
+ '',
6060
+ '',
6061
+ '',
6062
+ 'Pxwp',
6063
+ '',
6064
+ '',
6065
+ '',
6066
+ '',
6067
+ '',
6068
+ '',
6069
+ '',
6070
+ '',
6071
+ '',
6072
+ '',
6073
+ '',
6074
+ '',
6075
+ '',
6076
+ '',
6077
+ '',
6078
+ '',
6079
+ '',
6080
+ '',
6081
+ '',
6082
+ ),
6083
+ 'suffix' => array(
6084
+ '',
6085
+ '',
6086
+ '',
6087
+ '',
6088
+ '',
6089
+ '',
6090
+ '',
6091
+ '',
6092
+ '',
6093
+ '',
6094
+ '',
6095
+ '',
6096
+ '',
6097
+ '',
6098
+ '',
6099
+ '',
6100
+ '',
6101
+ '',
6102
+ '',
6103
+ '',
6104
+ '',
6105
+ '',
6106
+ '',
6107
+ '',
6108
+ '',
6109
+ '',
6110
+ ),
6111
+ 'output_type' => array(
6112
+ '1',
6113
+ '11',
6114
+ '1',
6115
+ '1',
6116
+ '1',
6117
+ '1',
6118
+ '1',
6119
+ '1',
6120
+ '1',
6121
+ '1',
6122
+ '1',
6123
+ '1',
6124
+ '1',
6125
+ '1',
6126
+ '1',
6127
+ '1',
6128
+ '1',
6129
+ '1',
6130
+ '1',
6131
+ '1',
6132
+ '1',
6133
+ '1',
6134
+ '1',
6135
+ '1',
6136
+ '1',
6137
+ '1',
6138
+ ),
6139
+ 'limit' => array(
6140
+ '',
6141
+ '',
6142
+ '',
6143
+ '',
6144
+ '',
6145
+ '',
6146
+ '',
6147
+ '',
6148
+ '',
6149
+ '',
6150
+ '',
6151
+ '',
6152
+ '',
6153
+ '',
6154
+ '',
6155
+ '',
6156
+ '',
6157
+ '',
6158
+ '',
6159
+ '',
6160
+ '',
6161
+ '',
6162
+ '',
6163
+ '',
6164
+ '',
6165
+ '',
6166
+ ),
6167
+ ),
6168
+ 'daisycon_holidays'
6169
+ . '_accommodations_and'
6170
+ . '_transport' => array(
6171
+ 'mattributes' => array(
6172
+ 'sku',
6173
+ 'description',
6174
+ 'link',
6175
+ 'price',
6176
+ 'title',
6177
+ 'image_link_1',
6178
+ 'brand',
6179
+ 'category',
6180
+ 'category_path',
6181
+ 'delivery_time',
6182
+ 'ean',
6183
+ 'google_category_id',
6184
+ 'in_stock',
6185
+ 'in_stock_amount',
6186
+ 'price_old',
6187
+ 'color_primary',
6188
+ 'condition',
6189
+ 'gender_target',
6190
+ 'price_shipping',
6191
+ 'brand_logo',
6192
+ 'delivery_description',
6193
+ 'image_link_2',
6194
+ 'keywords',
6195
+ 'size',
6196
+ 'size_description',
6197
+ 'terms_conditions',
6198
+ ),
6199
+ 'prefix' => array(
6200
+ '',
6201
+ '',
6202
+ '',
6203
+ '',
6204
+ '',
6205
+ '',
6206
+ '',
6207
+ '',
6208
+ '',
6209
+ '',
6210
+ '',
6211
+ '',
6212
+ '',
6213
+ '',
6214
+ '',
6215
+ '',
6216
+ '',
6217
+ '',
6218
+ '',
6219
+ '',
6220
+ '',
6221
+ '',
6222
+ '',
6223
+ '',
6224
+ '',
6225
+ '',
6226
+ ),
6227
+ 'type' => array(
6228
+ 'attribute',
6229
+ 'attribute',
6230
+ 'attribute',
6231
+ 'attribute',
6232
+ 'attribute',
6233
+ 'attribute',
6234
+ 'pattern',
6235
+ 'attribute',
6236
+ 'attribute',
6237
+ 'pattern',
6238
+ 'attribute',
6239
+ 'pattern',
6240
+ 'attribute',
6241
+ 'attribute',
6242
+ 'attribute',
6243
+ 'attribute',
6244
+ 'attribute',
6245
+ 'pattern',
6246
+ 'pattern',
6247
+ 'pattern',
6248
+ 'pattern',
6249
+ 'attribute',
6250
+ 'attribute',
6251
+ 'attribute',
6252
+ 'pattern',
6253
+ 'pattern',
6254
+ ),
6255
+ 'attributes' => array(
6256
+ 'sku',
6257
+ 'description',
6258
+ 'link',
6259
+ 'price',
6260
+ 'title',
6261
+ 'image',
6262
+ '',
6263
+ 'primary_category',
6264
+ 'product_type',
6265
+ '',
6266
+ 'sku',
6267
+ '',
6268
+ 'availability',
6269
+ 'wf_cattr__stock',
6270
+ 'price',
6271
+ 'wf_attr_pa_color',
6272
+ 'condition',
6273
+ '',
6274
+ '',
6275
+ '',
6276
+ '',
6277
+ 'image_2',
6278
+ 'tags',
6279
+ 'wf_attr_pa_size',
6280
+ '',
6281
+ '',
6282
+ ),
6283
+ 'default' => array(
6284
+ '',
6285
+ '',
6286
+ '',
6287
+ '',
6288
+ '',
6289
+ '',
6290
+ 'Pxwp',
6291
+ '',
6292
+ '',
6293
+ '',
6294
+ '',
6295
+ '',
6296
+ '',
6297
+ '',
6298
+ '',
6299
+ '',
6300
+ '',
6301
+ '',
6302
+ '',
6303
+ '',
6304
+ '',
6305
+ '',
6306
+ '',
6307
+ '',
6308
+ '',
6309
+ '',
6310
+ ),
6311
+ 'suffix' => array(
6312
+ '',
6313
+ '',
6314
+ '',
6315
+ '',
6316
+ '',
6317
+ '',
6318
+ '',
6319
+ '',
6320
+ '',
6321
+ '',
6322
+ '',
6323
+ '',
6324
+ '',
6325
+ '',
6326
+ '',
6327
+ '',
6328
+ '',
6329
+ '',
6330
+ '',
6331
+ '',
6332
+ '',
6333
+ '',
6334
+ '',
6335
+ '',
6336
+ '',
6337
+ '',
6338
+ ),
6339
+ 'output_type' => array(
6340
+ '1',
6341
+ '11',
6342
+ '1',
6343
+ '1',
6344
+ '1',
6345
+ '1',
6346
+ '1',
6347
+ '1',
6348
+ '1',
6349
+ '1',
6350
+ '1',
6351
+ '1',
6352
+ '1',
6353
+ '1',
6354
+ '1',
6355
+ '1',
6356
+ '1',
6357
+ '1',
6358
+ '1',
6359
+ '1',
6360
+ '1',
6361
+ '1',
6362
+ '1',
6363
+ '1',
6364
+ '1',
6365
+ '1',
6366
+ ),
6367
+ 'limit' => array(
6368
+ '',
6369
+ '',
6370
+ '',
6371
+ '',
6372
+ '',
6373
+ '',
6374
+ '',
6375
+ '',
6376
+ '',
6377
+ '',
6378
+ '',
6379
+ '',
6380
+ '',
6381
+ '',
6382
+ '',
6383
+ '',
6384
+ '',
6385
+ '',
6386
+ '',
6387
+ '',
6388
+ '',
6389
+ '',
6390
+ '',
6391
+ '',
6392
+ '',
6393
+ '',
6394
+ ),
6395
+ ),
6396
+ 'daisycon_holidays'
6397
+ . '_accommodations' => array(
6398
+ 'mattributes' => array(
6399
+ 'sku',
6400
+ 'description',
6401
+ 'link',
6402
+ 'price',
6403
+ 'title',
6404
+ 'image_link_1',
6405
+ 'brand',
6406
+ 'category',
6407
+ 'category_path',
6408
+ 'delivery_time',
6409
+ 'ean',
6410
+ 'google_category_id',
6411
+ 'in_stock',
6412
+ 'in_stock_amount',
6413
+ 'price_old',
6414
+ 'color_primary',
6415
+ 'condition',
6416
+ 'gender_target',
6417
+ 'price_shipping',
6418
+ 'brand_logo',
6419
+ 'delivery_description',
6420
+ 'image_link_2',
6421
+ 'keywords',
6422
+ 'size',
6423
+ 'size_description',
6424
+ 'terms_conditions',
6425
+ ),
6426
+ 'prefix' => array(
6427
+ '',
6428
+ '',
6429
+ '',
6430
+ '',
6431
+ '',
6432
+ '',
6433
+ '',
6434
+ '',
6435
+ '',
6436
+ '',
6437
+ '',
6438
+ '',
6439
+ '',
6440
+ '',
6441
+ '',
6442
+ '',
6443
+ '',
6444
+ '',
6445
+ '',
6446
+ '',
6447
+ '',
6448
+ '',
6449
+ '',
6450
+ '',
6451
+ '',
6452
+ '',
6453
+ ),
6454
+ 'type' => array(
6455
+ 'attribute',
6456
+ 'attribute',
6457
+ 'attribute',
6458
+ 'attribute',
6459
+ 'attribute',
6460
+ 'attribute',
6461
+ 'pattern',
6462
+ 'attribute',
6463
+ 'attribute',
6464
+ 'pattern',
6465
+ 'attribute',
6466
+ 'pattern',
6467
+ 'attribute',
6468
+ 'attribute',
6469
+ 'attribute',
6470
+ 'attribute',
6471
+ 'attribute',
6472
+ 'pattern',
6473
+ 'pattern',
6474
+ 'pattern',
6475
+ 'pattern',
6476
+ 'attribute',
6477
+ 'attribute',
6478
+ 'attribute',
6479
+ 'pattern',
6480
+ 'pattern',
6481
+ ),
6482
+ 'attributes' => array(
6483
+ 'sku',
6484
+ 'description',
6485
+ 'link',
6486
+ 'price',
6487
+ 'title',
6488
+ 'image',
6489
+ '',
6490
+ 'primary_category',
6491
+ 'product_type',
6492
+ '',
6493
+ 'sku',
6494
+ '',
6495
+ 'availability',
6496
+ 'wf_cattr__stock',
6497
+ 'price',
6498
+ 'wf_attr_pa_color',
6499
+ 'condition',
6500
+ '',
6501
+ '',
6502
+ '',
6503
+ '',
6504
+ 'image_2',
6505
+ 'tags',
6506
+ 'wf_attr_pa_size',
6507
+ '',
6508
+ '',
6509
+ ),
6510
+ 'default' => array(
6511
+ '',
6512
+ '',
6513
+ '',
6514
+ '',
6515
+ '',
6516
+ '',
6517
+ 'Pxwp',
6518
+ '',
6519
+ '',
6520
+ '',
6521
+ '',
6522
+ '',
6523
+ '',
6524
+ '',
6525
+ '',
6526
+ '',
6527
+ '',
6528
+ '',
6529
+ '',
6530
+ '',
6531
+ '',
6532
+ '',
6533
+ '',
6534
+ '',
6535
+ '',
6536
+ '',
6537
+ ),
6538
+ 'suffix' => array(
6539
+ '',
6540
+ '',
6541
+ '',
6542
+ '',
6543
+ '',
6544
+ '',
6545
+ '',
6546
+ '',
6547
+ '',
6548
+ '',
6549
+ '',
6550
+ '',
6551
+ '',
6552
+ '',
6553
+ '',
6554
+ '',
6555
+ '',
6556
+ '',
6557
+ '',
6558
+ '',
6559
+ '',
6560
+ '',
6561
+ '',
6562
+ '',
6563
+ '',
6564
+ '',
6565
+ ),
6566
+ 'output_type' => array(
6567
+ '1',
6568
+ '11',
6569
+ '1',
6570
+ '1',
6571
+ '1',
6572
+ '1',
6573
+ '1',
6574
+ '1',
6575
+ '1',
6576
+ '1',
6577
+ '1',
6578
+ '1',
6579
+ '1',
6580
+ '1',
6581
+ '1',
6582
+ '1',
6583
+ '1',
6584
+ '1',
6585
+ '1',
6586
+ '1',
6587
+ '1',
6588
+ '1',
6589
+ '1',
6590
+ '1',
6591
+ '1',
6592
+ '1',
6593
+ ),
6594
+ 'limit' => array(
6595
+ '',
6596
+ '',
6597
+ '',
6598
+ '',
6599
+ '',
6600
+ '',
6601
+ '',
6602
+ '',
6603
+ '',
6604
+ '',
6605
+ '',
6606
+ '',
6607
+ '',
6608
+ '',
6609
+ '',
6610
+ '',
6611
+ '',
6612
+ '',
6613
+ '',
6614
+ '',
6615
+ '',
6616
+ '',
6617
+ '',
6618
+ '',
6619
+ '',
6620
+ '',
6621
+ ),
6622
+ ),
6623
+ 'daisycon_holidays'
6624
+ . '_trips' => array(
6625
+ 'mattributes' => array(
6626
+ 'sku',
6627
+ 'description',
6628
+ 'link',
6629
+ 'price',
6630
+ 'title',
6631
+ 'image_link_1',
6632
+ 'brand',
6633
+ 'category',
6634
+ 'category_path',
6635
+ 'delivery_time',
6636
+ 'ean',
6637
+ 'google_category_id',
6638
+ 'in_stock',
6639
+ 'in_stock_amount',
6640
+ 'price_old',
6641
+ 'color_primary',
6642
+ 'condition',
6643
+ 'gender_target',
6644
+ 'price_shipping',
6645
+ 'brand_logo',
6646
+ 'delivery_description',
6647
+ 'image_link_2',
6648
+ 'keywords',
6649
+ 'size',
6650
+ 'size_description',
6651
+ 'terms_conditions',
6652
+ ),
6653
+ 'prefix' => array(
6654
+ '',
6655
+ '',
6656
+ '',
6657
+ '',
6658
+ '',
6659
+ '',
6660
+ '',
6661
+ '',
6662
+ '',
6663
+ '',
6664
+ '',
6665
+ '',
6666
+ '',
6667
+ '',
6668
+ '',
6669
+ '',
6670
+ '',
6671
+ '',
6672
+ '',
6673
+ '',
6674
+ '',
6675
+ '',
6676
+ '',
6677
+ '',
6678
+ '',
6679
+ '',
6680
+ ),
6681
+ 'type' => array(
6682
+ 'attribute',
6683
+ 'attribute',
6684
+ 'attribute',
6685
+ 'attribute',
6686
+ 'attribute',
6687
+ 'attribute',
6688
+ 'pattern',
6689
+ 'attribute',
6690
+ 'attribute',
6691
+ 'pattern',
6692
+ 'attribute',
6693
+ 'pattern',
6694
+ 'attribute',
6695
+ 'attribute',
6696
+ 'attribute',
6697
+ 'attribute',
6698
+ 'attribute',
6699
+ 'pattern',
6700
+ 'pattern',
6701
+ 'pattern',
6702
+ 'pattern',
6703
+ 'attribute',
6704
+ 'attribute',
6705
+ 'attribute',
6706
+ 'pattern',
6707
+ 'pattern',
6708
+ ),
6709
+ 'attributes' => array(
6710
+ 'sku',
6711
+ 'description',
6712
+ 'link',
6713
+ 'price',
6714
+ 'title',
6715
+ 'image',
6716
+ '',
6717
+ 'primary_category',
6718
+ 'product_type',
6719
+ '',
6720
+ 'sku',
6721
+ '',
6722
+ 'availability',
6723
+ 'wf_cattr__stock',
6724
+ 'price',
6725
+ 'wf_attr_pa_color',
6726
+ 'condition',
6727
+ '',
6728
+ '',
6729
+ '',
6730
+ '',
6731
+ 'image_2',
6732
+ 'tags',
6733
+ 'wf_attr_pa_size',
6734
+ '',
6735
+ '',
6736
+ ),
6737
+ 'default' => array(
6738
+ '',
6739
+ '',
6740
+ '',
6741
+ '',
6742
+ '',
6743
+ '',
6744
+ 'Pxwp',
6745
+ '',
6746
+ '',
6747
+ '',
6748
+ '',
6749
+ '',
6750
+ '',
6751
+ '',
6752
+ '',
6753
+ '',
6754
+ '',
6755
+ '',
6756
+ '',
6757
+ '',
6758
+ '',
6759
+ '',
6760
+ '',
6761
+ '',
6762
+ '',
6763
+ '',
6764
+ ),
6765
+ 'suffix' => array(
6766
+ '',
6767
+ '',
6768
+ '',
6769
+ '',
6770
+ '',
6771
+ '',
6772
+ '',
6773
+ '',
6774
+ '',
6775
+ '',
6776
+ '',
6777
+ '',
6778
+ '',
6779
+ '',
6780
+ '',
6781
+ '',
6782
+ '',
6783
+ '',
6784
+ '',
6785
+ '',
6786
+ '',
6787
+ '',
6788
+ '',
6789
+ '',
6790
+ '',
6791
+ '',
6792
+ ),
6793
+ 'output_type' => array(
6794
+ '1',
6795
+ '11',
6796
+ '1',
6797
+ '1',
6798
+ '1',
6799
+ '1',
6800
+ '1',
6801
+ '1',
6802
+ '1',
6803
+ '1',
6804
+ '1',
6805
+ '1',
6806
+ '1',
6807
+ '1',
6808
+ '1',
6809
+ '1',
6810
+ '1',
6811
+ '1',
6812
+ '1',
6813
+ '1',
6814
+ '1',
6815
+ '1',
6816
+ '1',
6817
+ '1',
6818
+ '1',
6819
+ '1',
6820
+ ),
6821
+ 'limit' => array(
6822
+ '',
6823
+ '',
6824
+ '',
6825
+ '',
6826
+ '',
6827
+ '',
6828
+ '',
6829
+ '',
6830
+ '',
6831
+ '',
6832
+ '',
6833
+ '',
6834
+ '',
6835
+ '',
6836
+ '',
6837
+ '',
6838
+ '',
6839
+ '',
6840
+ '',
6841
+ '',
6842
+ '',
6843
+ '',
6844
+ '',
6845
+ '',
6846
+ '',
6847
+ '',
6848
+ ),
6849
+ ),
6850
+ 'daisycon_home_garden' => array(
6851
+ 'mattributes' => array(
6852
+ 'sku',
6853
+ 'description',
6854
+ 'link',
6855
+ 'price',
6856
+ 'title',
6857
+ 'image_link_1',
6858
+ 'brand',
6859
+ 'category',
6860
+ 'category_path',
6861
+ 'delivery_time',
6862
+ 'ean',
6863
+ 'google_category_id',
6864
+ 'in_stock',
6865
+ 'in_stock_amount',
6866
+ 'price_old',
6867
+ 'color_primary',
6868
+ 'condition',
6869
+ 'gender_target',
6870
+ 'price_shipping',
6871
+ 'brand_logo',
6872
+ 'delivery_description',
6873
+ 'image_link_2',
6874
+ 'keywords',
6875
+ 'size',
6876
+ 'size_description',
6877
+ 'terms_conditions',
6878
+ ),
6879
+ 'prefix' => array(
6880
+ '',
6881
+ '',
6882
+ '',
6883
+ '',
6884
+ '',
6885
+ '',
6886
+ '',
6887
+ '',
6888
+ '',
6889
+ '',
6890
+ '',
6891
+ '',
6892
+ '',
6893
+ '',
6894
+ '',
6895
+ '',
6896
+ '',
6897
+ '',
6898
+ '',
6899
+ '',
6900
+ '',
6901
+ '',
6902
+ '',
6903
+ '',
6904
+ '',
6905
+ '',
6906
+ ),
6907
+ 'type' => array(
6908
+ 'attribute',
6909
+ 'attribute',
6910
+ 'attribute',
6911
+ 'attribute',
6912
+ 'attribute',
6913
+ 'attribute',
6914
+ 'pattern',
6915
+ 'attribute',
6916
+ 'attribute',
6917
+ 'pattern',
6918
+ 'attribute',
6919
+ 'pattern',
6920
+ 'attribute',
6921
+ 'attribute',
6922
+ 'attribute',
6923
+ 'attribute',
6924
+ 'attribute',
6925
+ 'pattern',
6926
+ 'pattern',
6927
+ 'pattern',
6928
+ 'pattern',
6929
+ 'attribute',
6930
+ 'attribute',
6931
+ 'attribute',
6932
+ 'pattern',
6933
+ 'pattern',
6934
+ ),
6935
+ 'attributes' => array(
6936
+ 'sku',
6937
+ 'description',
6938
+ 'link',
6939
+ 'price',
6940
+ 'title',
6941
+ 'image',
6942
+ '',
6943
+ 'primary_category',
6944
+ 'product_type',
6945
+ '',
6946
+ 'sku',
6947
+ '',
6948
+ 'availability',
6949
+ 'wf_cattr__stock',
6950
+ 'price',
6951
+ 'wf_attr_pa_color',
6952
+ 'condition',
6953
+ '',
6954
+ '',
6955
+ '',
6956
+ '',
6957
+ 'image_2',
6958
+ 'tags',
6959
+ 'wf_attr_pa_size',
6960
+ '',
6961
+ '',
6962
+ ),
6963
+ 'default' => array(
6964
+ '',
6965
+ '',
6966
+ '',
6967
+ '',
6968
+ '',
6969
+ '',
6970
+ 'Pxwp',
6971
+ '',
6972
+ '',
6973
+ '',
6974
+ '',
6975
+ '',
6976
+ '',
6977
+ '',
6978
+ '',
6979
+ '',
6980
+ '',
6981
+ '',
6982
+ '',
6983
+ '',
6984
+ '',
6985
+ '',
6986
+ '',
6987
+ '',
6988
+ '',
6989
+ '',
6990
+ ),
6991
+ 'suffix' => array(
6992
+ '',
6993
+ '',
6994
+ '',
6995
+ '',
6996
+ '',
6997
+ '',
6998
+ '',
6999
+ '',
7000
+ '',
7001
+ '',
7002
+ '',
7003
+ '',
7004
+ '',
7005
+ '',
7006
+ '',
7007
+ '',
7008
+ '',
7009
+ '',
7010
+ '',
7011
+ '',
7012
+ '',
7013
+ '',
7014
+ '',
7015
+ '',
7016
+ '',
7017
+ '',
7018
+ ),
7019
+ 'output_type' => array(
7020
+ '1',
7021
+ '11',
7022
+ '1',
7023
+ '1',
7024
+ '1',
7025
+ '1',
7026
+ '1',
7027
+ '1',
7028
+ '1',
7029
+ '1',
7030
+ '1',
7031
+ '1',
7032
+ '1',
7033
+ '1',
7034
+ '1',
7035
+ '1',
7036
+ '1',
7037
+ '1',
7038
+ '1',
7039
+ '1',
7040
+ '1',
7041
+ '1',
7042
+ '1',
7043
+ '1',
7044
+ '1',
7045
+ '1',
7046
+ ),
7047
+ 'limit' => array(
7048
+ '',
7049
+ '',
7050
+ '',
7051
+ '',
7052
+ '',
7053
+ '',
7054
+ '',
7055
+ '',
7056
+ '',
7057
+ '',
7058
+ '',
7059
+ '',
7060
+ '',
7061
+ '',
7062
+ '',
7063
+ '',
7064
+ '',
7065
+ '',
7066
+ '',
7067
+ '',
7068
+ '',
7069
+ '',
7070
+ '',
7071
+ '',
7072
+ '',
7073
+ '',
7074
+ ),
7075
+ ),
7076
+ 'daisycon_housing' => array(
7077
+ 'mattributes' => array(
7078
+ 'sku',
7079
+ 'description',
7080
+ 'link',
7081
+ 'price',
7082
+ 'title',
7083
+ 'image_link_1',
7084
+ 'brand',
7085
+ 'category',
7086
+ 'category_path',
7087
+ 'delivery_time',
7088
+ 'ean',
7089
+ 'google_category_id',
7090
+ 'in_stock',
7091
+ 'in_stock_amount',
7092
+ 'price_old',
7093
+ 'color_primary',
7094
+ 'condition',
7095
+ 'gender_target',
7096
+ 'price_shipping',
7097
+ 'brand_logo',
7098
+ 'delivery_description',
7099
+ 'image_link_2',
7100
+ 'keywords',
7101
+ 'size',
7102
+ 'size_description',
7103
+ 'terms_conditions',
7104
+ ),
7105
+ 'prefix' => array(
7106
+ '',
7107
+ '',
7108
+ '',
7109
+ '',
7110
+ '',
7111
+ '',
7112
+ '',
7113
+ '',
7114
+ '',
7115
+ '',
7116
+ '',
7117
+ '',
7118
+ '',
7119
+ '',
7120
+ '',
7121
+ '',
7122
+ '',
7123
+ '',
7124
+ '',
7125
+ '',
7126
+ '',
7127
+ '',
7128
+ '',
7129
+ '',
7130
+ '',
7131
+ '',
7132
+ ),
7133
+ 'type' => array(
7134
+ 'attribute',
7135
+ 'attribute',
7136
+ 'attribute',
7137
+ 'attribute',
7138
+ 'attribute',
7139
+ 'attribute',
7140
+ 'pattern',
7141
+ 'attribute',
7142
+ 'attribute',
7143
+ 'pattern',
7144
+ 'attribute',
7145
+ 'pattern',
7146
+ 'attribute',
7147
+ 'attribute',
7148
+ 'attribute',
7149
+ 'attribute',
7150
+ 'attribute',
7151
+ 'pattern',
7152
+ 'pattern',
7153
+ 'pattern',
7154
+ 'pattern',
7155
+ 'attribute',
7156
+ 'attribute',
7157
+ 'attribute',
7158
+ 'pattern',
7159
+ 'pattern',
7160
+ ),
7161
+ 'attributes' => array(
7162
+ 'sku',
7163
+ 'description',
7164
+ 'link',
7165
+ 'price',
7166
+ 'title',
7167
+ 'image',
7168
+ '',
7169
+ 'primary_category',
7170
+ 'product_type',
7171
+ '',
7172
+ 'sku',
7173
+ '',
7174
+ 'availability',
7175
+ 'wf_cattr__stock',
7176
+ 'price',
7177
+ 'wf_attr_pa_color',
7178
+ 'condition',
7179
+ '',
7180
+ '',
7181
+ '',
7182
+ '',
7183
+ 'image_2',
7184
+ 'tags',
7185
+ 'wf_attr_pa_size',
7186
+ '',
7187
+ '',
7188
+ ),
7189
+ 'default' => array(
7190
+ '',
7191
+ '',
7192
+ '',
7193
+ '',
7194
+ '',
7195
+ '',
7196
+ 'Pxwp',
7197
+ '',
7198
+ '',
7199
+ '',
7200
+ '',
7201
+ '',
7202
+ '',
7203
+ '',
7204
+ '',
7205
+ '',
7206
+ '',
7207
+ '',
7208
+ '',
7209
+ '',
7210
+ '',
7211
+ '',
7212
+ '',
7213
+ '',
7214
+ '',
7215
+ '',
7216
+ ),
7217
+ 'suffix' => array(
7218
+ '',
7219
+ '',
7220
+ '',
7221
+ '',
7222
+ '',
7223
+ '',
7224
+ '',
7225
+ '',
7226
+ '',
7227
+ '',
7228
+ '',
7229
+ '',
7230
+ '',
7231
+ '',
7232
+ '',
7233
+ '',
7234
+ '',
7235
+ '',
7236
+ '',
7237
+ '',
7238
+ '',
7239
+ '',
7240
+ '',
7241
+ '',
7242
+ '',
7243
+ '',
7244
+ ),
7245
+ 'output_type' => array(
7246
+ '1',
7247
+ '11',
7248
+ '1',
7249
+ '1',
7250
+ '1',
7251
+ '1',
7252
+ '1',
7253
+ '1',
7254
+ '1',
7255
+ '1',
7256
+ '1',
7257
+ '1',
7258
+ '1',
7259
+ '1',
7260
+ '1',
7261
+ '1',
7262
+ '1',
7263
+ '1',
7264
+ '1',
7265
+ '1',
7266
+ '1',
7267
+ '1',
7268
+ '1',
7269
+ '1',
7270
+ '1',
7271
+ '1',
7272
+ ),
7273
+ 'limit' => array(
7274
+ '',
7275
+ '',
7276
+ '',
7277
+ '',
7278
+ '',
7279
+ '',
7280
+ '',
7281
+ '',
7282
+ '',
7283
+ '',
7284
+ '',
7285
+ '',
7286
+ '',
7287
+ '',
7288
+ '',
7289
+ '',
7290
+ '',
7291
+ '',
7292
+ '',
7293
+ '',
7294
+ '',
7295
+ '',
7296
+ '',
7297
+ '',
7298
+ '',
7299
+ '',
7300
+ ),
7301
+ ),
7302
+ 'daisycon_magazines' => array(
7303
+ 'mattributes' => array(
7304
+ 'sku',
7305
+ 'description',
7306
+ 'link',
7307
+ 'price',
7308
+ 'title',
7309
+ 'image_link_1',
7310
+ 'brand',
7311
+ 'category',
7312
+ 'category_path',
7313
+ 'delivery_time',
7314
+ 'ean',
7315
+ 'google_category_id',
7316
+ 'in_stock',
7317
+ 'in_stock_amount',
7318
+ 'price_old',
7319
+ 'color_primary',
7320
+ 'condition',
7321
+ 'gender_target',
7322
+ 'price_shipping',
7323
+ 'brand_logo',
7324
+ 'delivery_description',
7325
+ 'image_link_2',
7326
+ 'keywords',
7327
+ 'size',
7328
+ 'size_description',
7329
+ 'terms_conditions',
7330
+ ),
7331
+ 'prefix' => array(
7332
+ '',
7333
+ '',
7334
+ '',
7335
+ '',
7336
+ '',
7337
+ '',
7338
+ '',
7339
+ '',
7340
+ '',
7341
+ '',
7342
+ '',
7343
+ '',
7344
+ '',
7345
+ '',
7346
+ '',
7347
+ '',
7348
+ '',
7349
+ '',
7350
+ '',
7351
+ '',
7352
+ '',
7353
+ '',
7354
+ '',
7355
+ '',
7356
+ '',
7357
+ '',
7358
+ ),
7359
+ 'type' => array(
7360
+ 'attribute',
7361
+ 'attribute',
7362
+ 'attribute',
7363
+ 'attribute',
7364
+ 'attribute',
7365
+ 'attribute',
7366
+ 'pattern',
7367
+ 'attribute',
7368
+ 'attribute',
7369
+ 'pattern',
7370
+ 'attribute',
7371
+ 'pattern',
7372
+ 'attribute',
7373
+ 'attribute',
7374
+ 'attribute',
7375
+ 'attribute',
7376
+ 'attribute',
7377
+ 'pattern',
7378
+ 'pattern',
7379
+ 'pattern',
7380
+ 'pattern',
7381
+ 'attribute',
7382
+ 'attribute',
7383
+ 'attribute',
7384
+ 'pattern',
7385
+ 'pattern',
7386
+ ),
7387
+ 'attributes' => array(
7388
+ 'sku',
7389
+ 'description',
7390
+ 'link',
7391
+ 'price',
7392
+ 'title',
7393
+ 'image',
7394
+ '',
7395
+ 'primary_category',
7396
+ 'product_type',
7397
+ '',
7398
+ 'sku',
7399
+ '',
7400
+ 'availability',
7401
+ 'wf_cattr__stock',
7402
+ 'price',
7403
+ 'wf_attr_pa_color',
7404
+ 'condition',
7405
+ '',
7406
+ '',
7407
+ '',
7408
+ '',
7409
+ 'image_2',
7410
+ 'tags',
7411
+ 'wf_attr_pa_size',
7412
+ '',
7413
+ '',
7414
+ ),
7415
+ 'default' => array(
7416
+ '',
7417
+ '',
7418
+ '',
7419
+ '',
7420
+ '',
7421
+ '',
7422
+ 'Pxwp',
7423
+ '',
7424
+ '',
7425
+ '',
7426
+ '',
7427
+ '',
7428
+ '',
7429
+ '',
7430
+ '',
7431
+ '',
7432
+ '',
7433
+ '',
7434
+ '',
7435
+ '',
7436
+ '',
7437
+ '',
7438
+ '',
7439
+ '',
7440
+ '',
7441
+ '',
7442
+ ),
7443
+ 'suffix' => array(
7444
+ '',
7445
+ '',
7446
+ '',
7447
+ '',
7448
+ '',
7449
+ '',
7450
+ '',
7451
+ '',
7452
+ '',
7453
+ '',
7454
+ '',
7455
+ '',
7456
+ '',
7457
+ '',
7458
+ '',
7459
+ '',
7460
+ '',
7461
+ '',
7462
+ '',
7463
+ '',
7464
+ '',
7465
+ '',
7466
+ '',
7467
+ '',
7468
+ '',
7469
+ '',
7470
+ ),
7471
+ 'output_type' => array(
7472
+ '1',
7473
+ '11',
7474
+ '1',
7475
+ '1',
7476
+ '1',
7477
+ '1',
7478
+ '1',
7479
+ '1',
7480
+ '1',
7481
+ '1',
7482
+ '1',
7483
+ '1',
7484
+ '1',
7485
+ '1',
7486
+ '1',
7487
+ '1',
7488
+ '1',
7489
+ '1',
7490
+ '1',
7491
+ '1',
7492
+ '1',
7493
+ '1',
7494
+ '1',
7495
+ '1',
7496
+ '1',
7497
+ '1',
7498
+ ),
7499
+ 'limit' => array(
7500
+ '',
7501
+ '',
7502
+ '',
7503
+ '',
7504
+ '',
7505
+ '',
7506
+ '',
7507
+ '',
7508
+ '',
7509
+ '',
7510
+ '',
7511
+ '',
7512
+ '',
7513
+ '',
7514
+ '',
7515
+ '',
7516
+ '',
7517
+ '',
7518
+ '',
7519
+ '',
7520
+ '',
7521
+ '',
7522
+ '',
7523
+ '',
7524
+ '',
7525
+ '',
7526
+ ),
7527
+ ),
7528
+ 'daisycon_studies'
7529
+ . '_trainings' => array(
7530
+ 'mattributes' => array(
7531
+ 'sku',
7532
+ 'description',
7533
+ 'link',
7534
+ 'price',
7535
+ 'title',
7536
+ 'image_link_1',
7537
+ 'brand',
7538
+ 'category',
7539
+ 'category_path',
7540
+ 'delivery_time',
7541
+ 'ean',
7542
+ 'google_category_id',
7543
+ 'in_stock',
7544
+ 'in_stock_amount',
7545
+ 'price_old',
7546
+ 'color_primary',
7547
+ 'condition',
7548
+ 'gender_target',
7549
+ 'price_shipping',
7550
+ 'brand_logo',
7551
+ 'delivery_description',
7552
+ 'image_link_2',
7553
+ 'keywords',
7554
+ 'size',
7555
+ 'size_description',
7556
+ 'terms_conditions',
7557
+ ),
7558
+ 'prefix' => array(
7559
+ '',
7560
+ '',
7561
+ '',
7562
+ '',
7563
+ '',
7564
+ '',
7565
+ '',
7566
+ '',
7567
+ '',
7568
+ '',
7569
+ '',
7570
+ '',
7571
+ '',
7572
+ '',
7573
+ '',
7574
+ '',
7575
+ '',
7576
+ '',
7577
+ '',
7578
+ '',
7579
+ '',
7580
+ '',
7581
+ '',
7582
+ '',
7583
+ '',
7584
+ '',
7585
+ ),
7586
+ 'type' => array(
7587
+ 'attribute',
7588
+ 'attribute',
7589
+ 'attribute',
7590
+ 'attribute',
7591
+ 'attribute',
7592
+ 'attribute',
7593
+ 'pattern',
7594
+ 'attribute',
7595
+ 'attribute',
7596
+ 'pattern',
7597
+ 'attribute',
7598
+ 'pattern',
7599
+ 'attribute',
7600
+ 'attribute',
7601
+ 'attribute',
7602
+ 'attribute',
7603
+ 'attribute',
7604
+ 'pattern',
7605
+ 'pattern',
7606
+ 'pattern',
7607
+ 'pattern',
7608
+ 'attribute',
7609
+ 'attribute',
7610
+ 'attribute',
7611
+ 'pattern',
7612
+ 'pattern',
7613
+ ),
7614
+ 'attributes' => array(
7615
+ 'sku',
7616
+ 'description',
7617
+ 'link',
7618
+ 'price',
7619
+ 'title',
7620
+ 'image',
7621
+ '',
7622
+ 'primary_category',
7623
+ 'product_type',
7624
+ '',
7625
+ 'sku',
7626
+ '',
7627
+ 'availability',
7628
+ 'wf_cattr__stock',
7629
+ 'price',
7630
+ 'wf_attr_pa_color',
7631
+ 'condition',
7632
+ '',
7633
+ '',
7634
+ '',
7635
+ '',
7636
+ 'image_2',
7637
+ 'tags',
7638
+ 'wf_attr_pa_size',
7639
+ '',
7640
+ '',
7641
+ ),
7642
+ 'default' => array(
7643
+ '',
7644
+ '',
7645
+ '',
7646
+ '',
7647
+ '',
7648
+ '',
7649
+ 'Pxwp',
7650
+ '',
7651
+ '',
7652
+ '',
7653
+ '',
7654
+ '',
7655
+ '',
7656
+ '',
7657
+ '',
7658
+ '',
7659
+ '',
7660
+ '',
7661
+ '',
7662
+ '',
7663
+ '',
7664
+ '',
7665
+ '',
7666
+ '',
7667
+ '',
7668
+ '',
7669
+ ),
7670
+ 'suffix' => array(
7671
+ '',
7672
+ '',
7673
+ '',
7674
+ '',
7675
+ '',
7676
+ '',
7677
+ '',
7678
+ '',
7679
+ '',
7680
+ '',
7681
+ '',
7682
+ '',
7683
+ '',
7684
+ '',
7685
+ '',
7686
+ '',
7687
+ '',
7688
+ '',
7689
+ '',
7690
+ '',
7691
+ '',
7692
+ '',
7693
+ '',
7694
+ '',
7695
+ '',
7696
+ '',
7697
+ ),
7698
+ 'output_type' => array(
7699
+ '1',
7700
+ '11',
7701
+ '1',
7702
+ '1',
7703
+ '1',
7704
+ '1',
7705
+ '1',
7706
+ '1',
7707
+ '1',
7708
+ '1',
7709
+ '1',
7710
+ '1',
7711
+ '1',
7712
+ '1',
7713
+ '1',
7714
+ '1',
7715
+ '1',
7716
+ '1',
7717
+ '1',
7718
+ '1',
7719
+ '1',
7720
+ '1',
7721
+ '1',
7722
+ '1',
7723
+ '1',
7724
+ '1',
7725
+ ),
7726
+ 'limit' => array(
7727
+ '',
7728
+ '',
7729
+ '',
7730
+ '',
7731
+ '',
7732
+ '',
7733
+ '',
7734
+ '',
7735
+ '',
7736
+ '',
7737
+ '',
7738
+ '',
7739
+ '',
7740
+ '',
7741
+ '',
7742
+ '',
7743
+ '',
7744
+ '',
7745
+ '',
7746
+ '',
7747
+ '',
7748
+ '',
7749
+ '',
7750
+ '',
7751
+ '',
7752
+ '',
7753
+ ),
7754
+ ),
7755
+ 'daisycon_telecom'
7756
+ . '_accessories' => array(
7757
+ 'mattributes' => array(
7758
+ 'sku',
7759
+ 'description',
7760
+ 'link',
7761
+ 'price',
7762
+ 'title',
7763
+ 'image_link_1',
7764
+ 'brand',
7765
+ 'category',
7766
+ 'category_path',
7767
+ 'delivery_time',
7768
+ 'ean',
7769
+ 'google_category_id',
7770
+ 'in_stock',
7771
+ 'in_stock_amount',
7772
+ 'price_old',
7773
+ 'color_primary',
7774
+ 'condition',
7775
+ 'gender_target',
7776
+ 'price_shipping',
7777
+ 'brand_logo',
7778
+ 'delivery_description',
7779
+ 'image_link_2',
7780
+ 'keywords',
7781
+ 'size',
7782
+ 'size_description',
7783
+ 'terms_conditions',
7784
+ ),
7785
+ 'prefix' => array(
7786
+ '',
7787
+ '',
7788
+ '',
7789
+ '',
7790
+ '',
7791
+ '',
7792
+ '',
7793
+ '',
7794
+ '',
7795
+ '',
7796
+ '',
7797
+ '',
7798
+ '',
7799
+ '',
7800
+ '',
7801
+ '',
7802
+ '',
7803
+ '',
7804
+ '',
7805
+ '',
7806
+ '',
7807
+ '',
7808
+ '',
7809
+ '',
7810
+ '',
7811
+ '',
7812
+ ),
7813
+ 'type' => array(
7814
+ 'attribute',
7815
+ 'attribute',
7816
+ 'attribute',
7817
+ 'attribute',
7818
+ 'attribute',
7819
+ 'attribute',
7820
+ 'pattern',
7821
+ 'attribute',
7822
+ 'attribute',
7823
+ 'pattern',
7824
+ 'attribute',
7825
+ 'pattern',
7826
+ 'attribute',
7827
+ 'attribute',
7828
+ 'attribute',
7829
+ 'attribute',
7830
+ 'attribute',
7831
+ 'pattern',
7832
+ 'pattern',
7833
+ 'pattern',
7834
+ 'pattern',
7835
+ 'attribute',
7836
+ 'attribute',
7837
+ 'attribute',
7838
+ 'pattern',
7839
+ 'pattern',
7840
+ ),
7841
+ 'attributes' => array(
7842
+ 'sku',
7843
+ 'description',
7844
+ 'link',
7845
+ 'price',
7846
+ 'title',
7847
+ 'image',
7848
+ '',
7849
+ 'primary_category',
7850
+ 'product_type',
7851
+ '',
7852
+ 'sku',
7853
+ '',
7854
+ 'availability',
7855
+ 'wf_cattr__stock',
7856
+ 'price',
7857
+ 'wf_attr_pa_color',
7858
+ 'condition',
7859
+ '',
7860
+ '',
7861
+ '',
7862
+ '',
7863
+ 'image_2',
7864
+ 'tags',
7865
+ 'wf_attr_pa_size',
7866
+ '',
7867
+ '',
7868
+ ),
7869
+ 'default' => array(
7870
+ '',
7871
+ '',
7872
+ '',
7873
+ '',
7874
+ '',
7875
+ '',
7876
+ 'Pxwp',
7877
+ '',
7878
+ '',
7879
+ '',
7880
+ '',
7881
+ '',
7882
+ '',
7883
+ '',
7884
+ '',
7885
+ '',
7886
+ '',
7887
+ '',
7888
+ '',
7889
+ '',
7890
+ '',
7891
+ '',
7892
+ '',
7893
+ '',
7894
+ '',
7895
+ '',
7896
+ ),
7897
+ 'suffix' => array(
7898
+ '',
7899
+ '',
7900
+ '',
7901
+ '',
7902
+ '',
7903
+ '',
7904
+ '',
7905
+ '',
7906
+ '',
7907
+ '',
7908
+ '',
7909
+ '',
7910
+ '',
7911
+ '',
7912
+ '',
7913
+ '',
7914
+ '',
7915
+ '',
7916
+ '',
7917
+ '',
7918
+ '',
7919
+ '',
7920
+ '',
7921
+ '',
7922
+ '',
7923
+ '',
7924
+ ),
7925
+ 'output_type' => array(
7926
+ '1',
7927
+ '11',
7928
+ '1',
7929
+ '1',
7930
+ '1',
7931
+ '1',
7932
+ '1',
7933
+ '1',
7934
+ '1',
7935
+ '1',
7936
+ '1',
7937
+ '1',
7938
+ '1',
7939
+ '1',
7940
+ '1',
7941
+ '1',
7942
+ '1',
7943
+ '1',
7944
+ '1',
7945
+ '1',
7946
+ '1',
7947
+ '1',
7948
+ '1',
7949
+ '1',
7950
+ '1',
7951
+ '1',
7952
+ ),
7953
+ 'limit' => array(
7954
+ '',
7955
+ '',
7956
+ '',
7957
+ '',
7958
+ '',
7959
+ '',
7960
+ '',
7961
+ '',
7962
+ '',
7963
+ '',
7964
+ '',
7965
+ '',
7966
+ '',
7967
+ '',
7968
+ '',
7969
+ '',
7970
+ '',
7971
+ '',
7972
+ '',
7973
+ '',
7974
+ '',
7975
+ '',
7976
+ '',
7977
+ '',
7978
+ '',
7979
+ '',
7980
+ ),
7981
+ ),
7982
+ 'daisycon_telecom'
7983
+ . '_all_in_one' => array(
7984
+ 'mattributes' => array(
7985
+ 'sku',
7986
+ 'description',
7987
+ 'link',
7988
+ 'price',
7989
+ 'title',
7990
+ 'image_link_1',
7991
+ 'brand',
7992
+ 'category',
7993
+ 'category_path',
7994
+ 'delivery_time',
7995
+ 'ean',
7996
+ 'google_category_id',
7997
+ 'in_stock',
7998
+ 'in_stock_amount',
7999
+ 'price_old',
8000
+ 'color_primary',
8001
+ 'condition',
8002
+ 'gender_target',
8003
+ 'price_shipping',
8004
+ 'brand_logo',
8005
+ 'delivery_description',
8006
+ 'image_link_2',
8007
+ 'keywords',
8008
+ 'size',
8009
+ 'size_description',
8010
+ 'terms_conditions',
8011
+ ),
8012
+ 'prefix' => array(
8013
+ '',
8014
+ '',
8015
+ '',
8016
+ '',
8017
+ '',
8018
+ '',
8019
+ '',
8020
+ '',
8021
+ '',
8022
+ '',
8023
+ '',
8024
+ '',
8025
+ '',
8026
+ '',
8027
+ '',
8028
+ '',
8029
+ '',
8030
+ '',
8031
+ '',
8032
+ '',
8033
+ '',
8034
+ '',
8035
+ '',
8036
+ '',
8037
+ '',
8038
+ '',
8039
+ ),
8040
+ 'type' => array(
8041
+ 'attribute',
8042
+ 'attribute',
8043
+ 'attribute',
8044
+ 'attribute',
8045
+ 'attribute',
8046
+ 'attribute',
8047
+ 'pattern',
8048
+ 'attribute',
8049
+ 'attribute',
8050
+ 'pattern',
8051
+ 'attribute',
8052
+ 'pattern',
8053
+ 'attribute',
8054
+ 'attribute',
8055
+ 'attribute',
8056
+ 'attribute',
8057
+ 'attribute',
8058
+ 'pattern',
8059
+ 'pattern',
8060
+ 'pattern',
8061
+ 'pattern',
8062
+ 'attribute',
8063
+ 'attribute',
8064
+ 'attribute',
8065
+ 'pattern',
8066
+ 'pattern',
8067
+ ),
8068
+ 'attributes' => array(
8069
+ 'sku',
8070
+ 'description',
8071
+ 'link',
8072
+ 'price',
8073
+ 'title',
8074
+ 'image',
8075
+ '',
8076
+ 'primary_category',
8077
+ 'product_type',
8078
+ '',
8079
+ 'sku',
8080
+ '',
8081
+ 'availability',
8082
+ 'wf_cattr__stock',
8083
+ 'price',
8084
+ 'wf_attr_pa_color',
8085
+ 'condition',
8086
+ '',
8087
+ '',
8088
+ '',
8089
+ '',
8090
+ 'image_2',
8091
+ 'tags',
8092
+ 'wf_attr_pa_size',
8093
+ '',
8094
+ '',
8095
+ ),
8096
+ 'default' => array(
8097
+ '',
8098
+ '',
8099
+ '',
8100
+ '',
8101
+ '',
8102
+ '',
8103
+ 'Pxwp',
8104
+ '',
8105
+ '',
8106
+ '',
8107
+ '',
8108
+ '',
8109
+ '',
8110
+ '',
8111
+ '',
8112
+ '',
8113
+ '',
8114
+ '',
8115
+ '',
8116
+ '',
8117
+ '',
8118
+ '',
8119
+ '',
8120
+ '',
8121
+ '',
8122
+ '',
8123
+ ),
8124
+ 'suffix' => array(
8125
+ '',
8126
+ '',
8127
+ '',
8128
+ '',
8129
+ '',
8130
+ '',
8131
+ '',
8132
+ '',
8133
+ '',
8134
+ '',
8135
+ '',
8136
+ '',
8137
+ '',
8138
+ '',
8139
+ '',
8140
+ '',
8141
+ '',
8142
+ '',
8143
+ '',
8144
+ '',
8145
+ '',
8146
+ '',
8147
+ '',
8148
+ '',
8149
+ '',
8150
+ '',
8151
+ ),
8152
+ 'output_type' => array(
8153
+ '1',
8154
+ '11',
8155
+ '1',
8156
+ '1',
8157
+ '1',
8158
+ '1',
8159
+ '1',
8160
+ '1',
8161
+ '1',
8162
+ '1',
8163
+ '1',
8164
+ '1',
8165
+ '1',
8166
+ '1',
8167
+ '1',
8168
+ '1',
8169
+ '1',
8170
+ '1',
8171
+ '1',
8172
+ '1',
8173
+ '1',
8174
+ '1',
8175
+ '1',
8176
+ '1',
8177
+ '1',
8178
+ '1',
8179
+ ),
8180
+ 'limit' => array(
8181
+ '',
8182
+ '',
8183
+ '',
8184
+ '',
8185
+ '',
8186
+ '',
8187
+ '',
8188
+ '',
8189
+ '',
8190
+ '',
8191
+ '',
8192
+ '',
8193
+ '',
8194
+ '',
8195
+ '',
8196
+ '',
8197
+ '',
8198
+ '',
8199
+ '',
8200
+ '',
8201
+ '',
8202
+ '',
8203
+ '',
8204
+ '',
8205
+ '',
8206
+ '',
8207
+ ),
8208
+ ),
8209
+ 'daisycon_telecom'
8210
+ . '_gsm_subscription' => array(
8211
+ 'mattributes' => array(
8212
+ 'sku',
8213
+ 'description',
8214
+ 'link',
8215
+ 'price',
8216
+ 'title',
8217
+ 'image_link_1',
8218
+ 'brand',
8219
+ 'category',
8220
+ 'category_path',
8221
+ 'delivery_time',
8222
+ 'ean',
8223
+ 'google_category_id',
8224
+ 'in_stock',
8225
+ 'in_stock_amount',
8226
+ 'price_old',
8227
+ 'color_primary',
8228
+ 'condition',
8229
+ 'gender_target',
8230
+ 'price_shipping',
8231
+ 'brand_logo',
8232
+ 'delivery_description',
8233
+ 'image_link_2',
8234
+ 'keywords',
8235
+ 'size',
8236
+ 'size_description',
8237
+ 'terms_conditions',
8238
+ ),
8239
+ 'prefix' => array(
8240
+ '',
8241
+ '',
8242
+ '',
8243
+ '',
8244
+ '',
8245
+ '',
8246
+ '',
8247
+ '',
8248
+ '',
8249
+ '',
8250
+ '',
8251
+ '',
8252
+ '',
8253
+ '',
8254
+ '',
8255
+ '',
8256
+ '',
8257
+ '',
8258
+ '',
8259
+ '',
8260
+ '',
8261
+ '',
8262
+ '',
8263
+ '',
8264
+ '',
8265
+ '',
8266
+ ),
8267
+ 'type' => array(
8268
+ 'attribute',
8269
+ 'attribute',
8270
+ 'attribute',
8271
+ 'attribute',
8272
+ 'attribute',
8273
+ 'attribute',
8274
+ 'pattern',
8275
+ 'attribute',
8276
+ 'attribute',
8277
+ 'pattern',
8278
+ 'attribute',
8279
+ 'pattern',
8280
+ 'attribute',
8281
+ 'attribute',
8282
+ 'attribute',
8283
+ 'attribute',
8284
+ 'attribute',
8285
+ 'pattern',
8286
+ 'pattern',
8287
+ 'pattern',
8288
+ 'pattern',
8289
+ 'attribute',
8290
+ 'attribute',
8291
+ 'attribute',
8292
+ 'pattern',
8293
+ 'pattern',
8294
+ ),
8295
+ 'attributes' => array(
8296
+ 'sku',
8297
+ 'description',
8298
+ 'link',
8299
+ 'price',
8300
+ 'title',
8301
+ 'image',
8302
+ '',
8303
+ 'primary_category',
8304
+ 'product_type',
8305
+ '',
8306
+ 'sku',
8307
+ '',
8308
+ 'availability',
8309
+ 'wf_cattr__stock',
8310
+ 'price',
8311
+ 'wf_attr_pa_color',
8312
+ 'condition',
8313
+ '',
8314
+ '',
8315
+ '',
8316
+ '',
8317
+ 'image_2',
8318
+ 'tags',
8319
+ 'wf_attr_pa_size',
8320
+ '',
8321
+ '',
8322
+ ),
8323
+ 'default' => array(
8324
+ '',
8325
+ '',
8326
+ '',
8327
+ '',
8328
+ '',
8329
+ '',
8330
+ 'Pxwp',
8331
+ '',
8332
+ '',
8333
+ '',
8334
+ '',
8335
+ '',
8336
+ '',
8337
+ '',
8338
+ '',
8339
+ '',
8340
+ '',
8341
+ '',
8342
+ '',
8343
+ '',
8344
+ '',
8345
+ '',
8346
+ '',
8347
+ '',
8348
+ '',
8349
+ '',
8350
+ ),
8351
+ 'suffix' => array(
8352
+ '',
8353
+ '',
8354
+ '',
8355
+ '',
8356
+ '',
8357
+ '',
8358
+ '',
8359
+ '',
8360
+ '',
8361
+ '',
8362
+ '',
8363
+ '',
8364
+ '',
8365
+ '',
8366
+ '',
8367
+ '',
8368
+ '',
8369
+ '',
8370
+ '',
8371
+ '',
8372
+ '',
8373
+ '',
8374
+ '',
8375
+ '',
8376
+ '',
8377
+ '',
8378
+ ),
8379
+ 'output_type' => array(
8380
+ '1',
8381
+ '11',
8382
+ '1',
8383
+ '1',
8384
+ '1',
8385
+ '1',
8386
+ '1',
8387
+ '1',
8388
+ '1',
8389
+ '1',
8390
+ '1',
8391
+ '1',
8392
+ '1',
8393
+ '1',
8394
+ '1',
8395
+ '1',
8396
+ '1',
8397
+ '1',
8398
+ '1',
8399
+ '1',
8400
+ '1',
8401
+ '1',
8402
+ '1',
8403
+ '1',
8404
+ '1',
8405
+ '1',
8406
+ ),
8407
+ 'limit' => array(
8408
+ '',
8409
+ '',
8410
+ '',
8411
+ '',
8412
+ '',
8413
+ '',
8414
+ '',
8415
+ '',
8416
+ '',
8417
+ '',
8418
+ '',
8419
+ '',
8420
+ '',
8421
+ '',
8422
+ '',
8423
+ '',
8424
+ '',
8425
+ '',
8426
+ '',
8427
+ '',
8428
+ '',
8429
+ '',
8430
+ '',
8431
+ '',
8432
+ '',
8433
+ '',
8434
+ ),
8435
+ ),
8436
+ 'daisycon_telecom_gsm' => array(
8437
+ 'mattributes' => array(
8438
+ 'sku',
8439
+ 'description',
8440
+ 'link',
8441
+ 'price',
8442
+ 'title',
8443
+ 'image_link_1',
8444
+ 'brand',
8445
+ 'category',
8446
+ 'category_path',
8447
+ 'delivery_time',
8448
+ 'ean',
8449
+ 'google_category_id',
8450
+ 'in_stock',
8451
+ 'in_stock_amount',
8452
+ 'price_old',
8453
+ 'color_primary',
8454
+ 'condition',
8455
+ 'gender_target',
8456
+ 'price_shipping',
8457
+ 'brand_logo',
8458
+ 'delivery_description',
8459
+ 'image_link_2',
8460
+ 'keywords',
8461
+ 'size',
8462
+ 'size_description',
8463
+ 'terms_conditions',
8464
+ ),
8465
+ 'prefix' => array(
8466
+ '',
8467
+ '',
8468
+ '',
8469
+ '',
8470
+ '',
8471
+ '',
8472
+ '',
8473
+ '',
8474
+ '',
8475
+ '',
8476
+ '',
8477
+ '',
8478
+ '',
8479
+ '',
8480
+ '',
8481
+ '',
8482
+ '',
8483
+ '',
8484
+ '',
8485
+ '',
8486
+ '',
8487
+ '',
8488
+ '',
8489
+ '',
8490
+ '',
8491
+ '',
8492
+ ),
8493
+ 'type' => array(
8494
+ 'attribute',
8495
+ 'attribute',
8496
+ 'attribute',
8497
+ 'attribute',
8498
+ 'attribute',
8499
+ 'attribute',
8500
+ 'pattern',
8501
+ 'attribute',
8502
+ 'attribute',
8503
+ 'pattern',
8504
+ 'attribute',
8505
+ 'pattern',
8506
+ 'attribute',
8507
+ 'attribute',
8508
+ 'attribute',
8509
+ 'attribute',
8510
+ 'attribute',
8511
+ 'pattern',
8512
+ 'pattern',
8513
+ 'pattern',
8514
+ 'pattern',
8515
+ 'attribute',
8516
+ 'attribute',
8517
+ 'attribute',
8518
+ 'pattern',
8519
+ 'pattern',
8520
+ ),
8521
+ 'attributes' => array(
8522
+ 'sku',
8523
+ 'description',
8524
+ 'link',
8525
+ 'price',
8526
+ 'title',
8527
+ 'image',
8528
+ '',
8529
+ 'primary_category',
8530
+ 'product_type',
8531
+ '',
8532
+ 'sku',
8533
+ '',
8534
+ 'availability',
8535
+ 'wf_cattr__stock',
8536
+ 'price',
8537
+ 'wf_attr_pa_color',
8538
+ 'condition',
8539
+ '',
8540
+ '',
8541
+ '',
8542
+ '',
8543
+ 'image_2',
8544
+ 'tags',
8545
+ 'wf_attr_pa_size',
8546
+ '',
8547
+ '',
8548
+ ),
8549
+ 'default' => array(
8550
+ '',
8551
+ '',
8552
+ '',
8553
+ '',
8554
+ '',
8555
+ '',
8556
+ 'Pxwp',
8557
+ '',
8558
+ '',
8559
+ '',
8560
+ '',
8561
+ '',
8562
+ '',
8563
+ '',
8564
+ '',
8565
+ '',
8566
+ '',
8567
+ '',
8568
+ '',
8569
+ '',
8570
+ '',
8571
+ '',
8572
+ '',
8573
+ '',
8574
+ '',
8575
+ '',
8576
+ ),
8577
+ 'suffix' => array(
8578
+ '',
8579
+ '',
8580
+ '',
8581
+ '',
8582
+ '',
8583
+ '',
8584
+ '',
8585
+ '',
8586
+ '',
8587
+ '',
8588
+ '',
8589
+ '',
8590
+ '',
8591
+ '',
8592
+ '',
8593
+ '',
8594
+ '',
8595
+ '',
8596
+ '',
8597
+ '',
8598
+ '',
8599
+ '',
8600
+ '',
8601
+ '',
8602
+ '',
8603
+ '',
8604
+ ),
8605
+ 'output_type' => array(
8606
+ '1',
8607
+ '11',
8608
+ '1',
8609
+ '1',
8610
+ '1',
8611
+ '1',
8612
+ '1',
8613
+ '1',
8614
+ '1',
8615
+ '1',
8616
+ '1',
8617
+ '1',
8618
+ '1',
8619
+ '1',
8620
+ '1',
8621
+ '1',
8622
+ '1',
8623
+ '1',
8624
+ '1',
8625
+ '1',
8626
+ '1',
8627
+ '1',
8628
+ '1',
8629
+ '1',
8630
+ '1',
8631
+ '1',
8632
+ ),
8633
+ 'limit' => array(
8634
+ '',
8635
+ '',
8636
+ '',
8637
+ '',
8638
+ '',
8639
+ '',
8640
+ '',
8641
+ '',
8642
+ '',
8643
+ '',
8644
+ '',
8645
+ '',
8646
+ '',
8647
+ '',
8648
+ '',
8649
+ '',
8650
+ '',
8651
+ '',
8652
+ '',
8653
+ '',
8654
+ '',
8655
+ '',
8656
+ '',
8657
+ '',
8658
+ '',
8659
+ '',
8660
+ ),
8661
+ ),
8662
+ 'daisycon_telecom_sim' => array(
8663
+ 'mattributes' => array(
8664
+ 'sku',
8665
+ 'description',
8666
+ 'link',
8667
+ 'price',
8668
+ 'title',
8669
+ 'image_link_1',
8670
+ 'brand',
8671
+ 'category',
8672
+ 'category_path',
8673
+ 'delivery_time',
8674
+ 'ean',
8675
+ 'google_category_id',
8676
+ 'in_stock',
8677
+ 'in_stock_amount',
8678
+ 'price_old',
8679
+ 'color_primary',
8680
+ 'condition',
8681
+ 'gender_target',
8682
+ 'price_shipping',
8683
+ 'brand_logo',
8684
+ 'delivery_description',
8685
+ 'image_link_2',
8686
+ 'keywords',
8687
+ 'size',
8688
+ 'size_description',
8689
+ 'terms_conditions',
8690
+ ),
8691
+ 'prefix' => array(
8692
+ '',
8693
+ '',
8694
+ '',
8695
+ '',
8696
+ '',
8697
+ '',
8698
+ '',
8699
+ '',
8700
+ '',
8701
+ '',
8702
+ '',
8703
+ '',
8704
+ '',
8705
+ '',
8706
+ '',
8707
+ '',
8708
+ '',
8709
+ '',
8710
+ '',
8711
+ '',
8712
+ '',
8713
+ '',
8714
+ '',
8715
+ '',
8716
+ '',
8717
+ '',
8718
+ ),
8719
+ 'type' => array(
8720
+ 'attribute',
8721
+ 'attribute',
8722
+ 'attribute',
8723
+ 'attribute',
8724
+ 'attribute',
8725
+ 'attribute',
8726
+ 'pattern',
8727
+ 'attribute',
8728
+ 'attribute',
8729
+ 'pattern',
8730
+ 'attribute',
8731
+ 'pattern',
8732
+ 'attribute',
8733
+ 'attribute',
8734
+ 'attribute',
8735
+ 'attribute',
8736
+ 'attribute',
8737
+ 'pattern',
8738
+ 'pattern',
8739
+ 'pattern',
8740
+ 'pattern',
8741
+ 'attribute',
8742
+ 'attribute',
8743
+ 'attribute',
8744
+ 'pattern',
8745
+ 'pattern',
8746
+ ),
8747
+ 'attributes' => array(
8748
+ 'sku',
8749
+ 'description',
8750
+ 'link',
8751
+ 'price',
8752
+ 'title',
8753
+ 'image',
8754
+ '',
8755
+ 'primary_category',
8756
+ 'product_type',
8757
+ '',
8758
+ 'sku',
8759
+ '',
8760
+ 'availability',
8761
+ 'wf_cattr__stock',
8762
+ 'price',
8763
+ 'wf_attr_pa_color',
8764
+ 'condition',
8765
+ '',
8766
+ '',
8767
+ '',
8768
+ '',
8769
+ 'image_2',
8770
+ 'tags',
8771
+ 'wf_attr_pa_size',
8772
+ '',
8773
+ '',
8774
+ ),
8775
+ 'default' => array(
8776
+ '',
8777
+ '',
8778
+ '',
8779
+ '',
8780
+ '',
8781
+ '',
8782
+ 'Pxwp',
8783
+ '',
8784
+ '',
8785
+ '',
8786
+ '',
8787
+ '',
8788
+ '',
8789
+ '',
8790
+ '',
8791
+ '',
8792
+ '',
8793
+ '',
8794
+ '',
8795
+ '',
8796
+ '',
8797
+ '',
8798
+ '',
8799
+ '',
8800
+ '',
8801
+ '',
8802
+ ),
8803
+ 'suffix' => array(
8804
+ '',
8805
+ '',
8806
+ '',
8807
+ '',
8808
+ '',
8809
+ '',
8810
+ '',
8811
+ '',
8812
+ '',
8813
+ '',
8814
+ '',
8815
+ '',
8816
+ '',
8817
+ '',
8818
+ '',
8819
+ '',
8820
+ '',
8821
+ '',
8822
+ '',
8823
+ '',
8824
+ '',
8825
+ '',
8826
+ '',
8827
+ '',
8828
+ '',
8829
+ '',
8830
+ ),
8831
+ 'output_type' => array(
8832
+ '1',
8833
+ '11',
8834
+ '1',
8835
+ '1',
8836
+ '1',
8837
+ '1',
8838
+ '1',
8839
+ '1',
8840
+ '1',
8841
+ '1',
8842
+ '1',
8843
+ '1',
8844
+ '1',
8845
+ '1',
8846
+ '1',
8847
+ '1',
8848
+ '1',
8849
+ '1',
8850
+ '1',
8851
+ '1',
8852
+ '1',
8853
+ '1',
8854
+ '1',
8855
+ '1',
8856
+ '1',
8857
+ '1',
8858
+ ),
8859
+ 'limit' => array(
8860
+ '',
8861
+ '',
8862
+ '',
8863
+ '',
8864
+ '',
8865
+ '',
8866
+ '',
8867
+ '',
8868
+ '',
8869
+ '',
8870
+ '',
8871
+ '',
8872
+ '',
8873
+ '',
8874
+ '',
8875
+ '',
8876
+ '',
8877
+ '',
8878
+ '',
8879
+ '',
8880
+ '',
8881
+ '',
8882
+ '',
8883
+ '',
8884
+ '',
8885
+ '',
8886
+ ),
8887
+ ),
8888
+ 'daisycon_work_jobs' => array(
8889
+ 'mattributes' => array(
8890
+ 'sku',
8891
+ 'description',
8892
+ 'link',
8893
+ 'price',
8894
+ 'title',
8895
+ 'image_link_1',
8896
+ 'brand',
8897
+ 'category',
8898
+ 'category_path',
8899
+ 'delivery_time',
8900
+ 'ean',
8901
+ 'google_category_id',
8902
+ 'in_stock',
8903
+ 'in_stock_amount',
8904
+ 'price_old',
8905
+ 'color_primary',
8906
+ 'condition',
8907
+ 'gender_target',
8908
+ 'price_shipping',
8909
+ 'brand_logo',
8910
+ 'delivery_description',
8911
+ 'image_link_2',
8912
+ 'keywords',
8913
+ 'size',
8914
+ 'size_description',
8915
+ 'terms_conditions',
8916
+ ),
8917
+ 'prefix' => array(
8918
+ '',
8919
+ '',
8920
+ '',
8921
+ '',
8922
+ '',
8923
+ '',
8924
+ '',
8925
+ '',
8926
+ '',
8927
+ '',
8928
+ '',
8929
+ '',
8930
+ '',
8931
+ '',
8932
+ '',
8933
+ '',
8934
+ '',
8935
+ '',
8936
+ '',
8937
+ '',
8938
+ '',
8939
+ '',
8940
+ '',
8941
+ '',
8942
+ '',
8943
+ '',
8944
+ ),
8945
+ 'type' => array(
8946
+ 'attribute',
8947
+ 'attribute',
8948
+ 'attribute',
8949
+ 'attribute',
8950
+ 'attribute',
8951
+ 'attribute',
8952
+ 'pattern',
8953
+ 'attribute',
8954
+ 'attribute',
8955
+ 'pattern',
8956
+ 'attribute',
8957
+ 'pattern',
8958
+ 'attribute',
8959
+ 'attribute',
8960
+ 'attribute',
8961
+ 'attribute',
8962
+ 'attribute',
8963
+ 'pattern',
8964
+ 'pattern',
8965
+ 'pattern',
8966
+ 'pattern',
8967
+ 'attribute',
8968
+ 'attribute',
8969
+ 'attribute',
8970
+ 'pattern',
8971
+ 'pattern',
8972
+ ),
8973
+ 'attributes' => array(
8974
+ 'sku',
8975
+ 'description',
8976
+ 'link',
8977
+ 'price',
8978
+ 'title',
8979
+ 'image',
8980
+ '',
8981
+ 'primary_category',
8982
+ 'product_type',
8983
+ '',
8984
+ 'sku',
8985
+ '',
8986
+ 'availability',
8987
+ 'wf_cattr__stock',
8988
+ 'price',
8989
+ 'wf_attr_pa_color',
8990
+ 'condition',
8991
+ '',
8992
+ '',
8993
+ '',
8994
+ '',
8995
+ 'image_2',
8996
+ 'tags',
8997
+ 'wf_attr_pa_size',
8998
+ '',
8999
+ '',
9000
+ ),
9001
+ 'default' => array(
9002
+ '',
9003
+ '',
9004
+ '',
9005
+ '',
9006
+ '',
9007
+ '',
9008
+ 'Pxwp',
9009
+ '',
9010
+ '',
9011
+ '',
9012
+ '',
9013
+ '',
9014
+ '',
9015
+ '',
9016
+ '',
9017
+ '',
9018
+ '',
9019
+ '',
9020
+ '',
9021
+ '',
9022
+ '',
9023
+ '',
9024
+ '',
9025
+ '',
9026
+ '',
9027
+ '',
9028
+ ),
9029
+ 'suffix' => array(
9030
+ '',
9031
+ '',
9032
+ '',
9033
+ '',
9034
+ '',
9035
+ '',
9036
+ '',
9037
+ '',
9038
+ '',
9039
+ '',
9040
+ '',
9041
+ '',
9042
+ '',
9043
+ '',
9044
+ '',
9045
+ '',
9046
+ '',
9047
+ '',
9048
+ '',
9049
+ '',
9050
+ '',
9051
+ '',
9052
+ '',
9053
+ '',
9054
+ '',
9055
+ '',
9056
+ ),
9057
+ 'output_type' => array(
9058
+ '1',
9059
+ '11',
9060
+ '1',
9061
+ '1',
9062
+ '1',
9063
+ '1',
9064
+ '1',
9065
+ '1',
9066
+ '1',
9067
+ '1',
9068
+ '1',
9069
+ '1',
9070
+ '1',
9071
+ '1',
9072
+ '1',
9073
+ '1',
9074
+ '1',
9075
+ '1',
9076
+ '1',
9077
+ '1',
9078
+ '1',
9079
+ '1',
9080
+ '1',
9081
+ '1',
9082
+ '1',
9083
+ '1',
9084
+ ),
9085
+ 'limit' => array(
9086
+ '',
9087
+ '',
9088
+ '',
9089
+ '',
9090
+ '',
9091
+ '',
9092
+ '',
9093
+ '',
9094
+ '',
9095
+ '',
9096
+ '',
9097
+ '',
9098
+ '',
9099
+ '',
9100
+ '',
9101
+ '',
9102
+ '',
9103
+ '',
9104
+ '',
9105
+ '',
9106
+ '',
9107
+ '',
9108
+ '',
9109
+ '',
9110
+ '',
9111
+ '',
9112
+ ),
9113
+ ),
9114
+ 'shopee' => array(
9115
+ 'mattributes' => array(
9116
+ 'Category',
9117
+ 'Product Name',
9118
+ 'Product Description',
9119
+ 'Price',
9120
+ 'Stock',
9121
+ 'SKU',
9122
+ 'Cover image',
9123
+ 'Weight'
9124
+ ),
9125
+ 'prefix' => array( '', '', '', '', '', '', '', '' ),
9126
+ 'type' => array(
9127
+ 'pattern',
9128
+ 'attribute',
9129
+ 'attribute',
9130
+ 'attribute',
9131
+ 'attribute',
9132
+ 'attribute',
9133
+ 'attribute',
9134
+ 'attribute'
9135
+ ),
9136
+ 'attributes' => array(
9137
+ '',
9138
+ 'title',
9139
+ 'description',
9140
+ 'current_price',
9141
+ 'quantity',
9142
+ 'sku',
9143
+ 'image',
9144
+ 'weight'
9145
+ ),
9146
+ 'default' => array( '', '', '', '', '', '', '', 'Localhost' ),
9147
+ 'suffix' => array( '', '', '', '', '', '', '', '' ),
9148
+ 'output_type' => array( '1', '1', '11', '1', '1', '1', '1', '1' ),
9149
+ 'limit' => array( '', '', '', '', '', '', '', '' ),
9150
+ ),
9151
+ 'zalando' => array(
9152
+ 'mattributes' => array(
9153
+ 'store',
9154
+ 'ean',
9155
+ 'price',
9156
+ 'retail_price',
9157
+ 'quantity',
9158
+ 'article_number',
9159
+ 'product_number',
9160
+ 'product_name',
9161
+ 'store_article_location'
9162
+ ),
9163
+ 'prefix' => array( '', '', '', '', '', '', '', '', '' ),
9164
+ 'type' => array(
9165
+ 'pattern',
9166
+ 'attribute',
9167
+ 'attribute',
9168
+ 'attribute',
9169
+ 'attribute',
9170
+ 'attribute',
9171
+ 'attribute',
9172
+ 'attribute',
9173
+ 'pattern'
9174
+ ),
9175
+ 'attributes' => array( '', '', 'price', 'sale_price', 'quantity', 'sku', 'id', 'title', '' ),
9176
+ 'default' => array( '', '', '', '', '', '', '', 'Localhost', 'type address here' ),
9177
+ 'suffix' => array( '', '', '', '', '', '', '', '', '' ),
9178
+ 'output_type' => array( '1', '1', '6', '6', '1', '1', '1', '1', '1' ),
9179
+ 'limit' => array( '', '', '', '', '', '', '', '', '' ),
9180
+ ),
9181
+ 'etsy' => array(
9182
+ 'mattributes' => array(
9183
+ 'SKU',
9184
+ 'TITLE',
9185
+ 'DESCRIPTION',
9186
+ 'PRICE',
9187
+ 'CURRENCY_CODE',
9188
+ 'QUANTITY',
9189
+ 'TAGS',
9190
+ 'MATERIALS',
9191
+ 'IMAGE1',
9192
+ 'IMAGE2',
9193
+ 'IMAGE3',
9194
+ 'IMAGE4'
9195
+ ),
9196
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
9197
+ 'type' => array(
9198
+ 'attribute',
9199
+ 'attribute',
9200
+ 'attribute',
9201
+ 'attribute',
9202
+ 'pattern',
9203
+ 'attribute',
9204
+ 'attribute',
9205
+ 'attribute',
9206
+ 'attribute',
9207
+ 'attribute',
9208
+ 'attribute',
9209
+ 'attribute'
9210
+ ),
9211
+ 'attributes' => array(
9212
+ 'sku',
9213
+ 'title',
9214
+ 'description',
9215
+ 'price',
9216
+ '',
9217
+ 'quantity',
9218
+ 'tags',
9219
+ '',
9220
+ 'image',
9221
+ 'image_1',
9222
+ 'image_2',
9223
+ 'image_3'
9224
+ ),
9225
+ 'default' => array( '', '', '', '', 'USD', '', '', '', 'Localhost', '', '', '', '' ),
9226
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
9227
+ 'output_type' => array( '1', '1', '11', '1', '1', '1', '1', '1', '1', '1', '1', '1' ),
9228
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
9229
+ ),
9230
+ 'tweaker_csv' => array(
9231
+ 'mattributes' => array(
9232
+ 'EAN code',
9233
+ 'SKU Code',
9234
+ 'Naam',
9235
+ 'Deeplink',
9236
+ 'Prijs',
9237
+ 'Verzendkosten',
9238
+ 'Levertijd',
9239
+ 'Promotiezin'
9240
+ ),
9241
+ 'prefix' => array( '', '', '', '', '', '', '', '' ),
9242
+ 'type' => array(
9243
+ 'attribute',
9244
+ 'attribute',
9245
+ 'attribute',
9246
+ 'attribute',
9247
+ 'attribute',
9248
+ 'pattern',
9249
+ 'pattern',
9250
+ 'pattern'
9251
+ ),
9252
+ 'attributes' => array( '', 'sku', 'title', 'link', 'price', '', '', '' ),
9253
+ 'default' => array( '', '', '', '', '', '', '', '' ),
9254
+ 'suffix' => array( '', '', '', '', '', '', '', '' ),
9255
+ 'output_type' => array( '1', '1', '1', '1', '6', '1', '1', '1' ),
9256
+ 'limit' => array( '', '', '', '', '', '', '', '' ),
9257
+ ),
9258
+ 'tweaker_xml' => array(
9259
+ 'mattributes' => array(
9260
+ 'Product_in_stock',
9261
+ 'Product_Brand',
9262
+ 'SKU_Code',
9263
+ 'Product_Name',
9264
+ 'Product_Price',
9265
+ 'Delivery_Period',
9266
+ 'Product_Ean',
9267
+ 'Deeplink',
9268
+ 'Delivery_Costs',
9269
+ 'Promotiezin'
9270
+ ),
9271
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '' ),
9272
+ 'type' => array(
9273
+ 'attribute',
9274
+ 'pattern',
9275
+ 'attribute',
9276
+ 'attribute',
9277
+ 'attribute',
9278
+ 'pattern',
9279
+ 'attribute',
9280
+ 'attribute',
9281
+ 'pattern',
9282
+ 'pattern'
9283
+ ),
9284
+ 'attributes' => array( 'quantity', '', 'sku', 'title', 'price', '', '', 'link', '', '' ),
9285
+ 'default' => array( '', '', '', '', '', '3 dagen', '', 'Localhost', '', '' ),
9286
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '' ),
9287
+ 'output_type' => array( '1', '1', '1', '1', '6', '1', '1', '1', '1', '1' ),
9288
+ 'limit' => array( '', '', '', '', '', '', '', '', '', 'test' ),
9289
+ ),
9290
+ 'profit_share' => array(
9291
+ 'mattributes' => array(
9292
+ 'Cod categorie',
9293
+ 'Categorie',
9294
+ 'Categorie parinte',
9295
+ 'Producator',
9296
+ 'Cod producator',
9297
+ 'Model',
9298
+ 'Cod produs',
9299
+ 'Nume ',
9300
+ 'Descriere',
9301
+ 'Link produs',
9302
+ 'Imagine produs',
9303
+ 'Pret fara TVA',
9304
+ 'Pret cu TVA',
9305
+ 'Pret cu discount fara TVA',
9306
+ 'Moneda',
9307
+ 'Disponibilitate',
9308
+ 'Livrare gratuita',
9309
+ 'Cadou inclus',
9310
+ 'Status',
9311
+ 'ID categorie parinte'
9312
+ ),
9313
+ 'prefix' => array(
9314
+ '',
9315
+ '',
9316
+ '',
9317
+ '',
9318
+ '',
9319
+ '',
9320
+ '',
9321
+ '',
9322
+ '',
9323
+ '',
9324
+ '',
9325
+ '',
9326
+ '',
9327
+ '',
9328
+ '',
9329
+ '',
9330
+ '',
9331
+ '',
9332
+ '',
9333
+ ''
9334
+ ),
9335
+ 'type' => array(
9336
+ 'attribute',
9337
+ 'attribute',
9338
+ 'attribute',
9339
+ 'attribute',
9340
+ 'pattern',
9341
+ 'attribute',
9342
+ 'attribute',
9343
+ 'attribute',
9344
+ 'attribute',
9345
+ 'attribute',
9346
+ 'attribute',
9347
+ 'attribute',
9348
+ 'attribute',
9349
+ 'attribute',
9350
+ 'attribute',
9351
+ 'attribute',
9352
+ 'pattern',
9353
+ 'pattern',
9354
+ 'pattern',
9355
+ 'attribute'
9356
+ ),
9357
+ 'attributes' => array(
9358
+ 'child_category',
9359
+ 'child_category_id',
9360
+ 'primary_category',
9361
+ '',
9362
+ '',
9363
+ 'sku',
9364
+ 'id',
9365
+ 'title',
9366
+ 'description',
9367
+ 'link',
9368
+ 'image',
9369
+ 'current_price',
9370
+ 'current_price_with_tax',
9371
+ 'sale_price',
9372
+ 'store_currency',
9373
+ 'availability',
9374
+ '',
9375
+ '',
9376
+ '',
9377
+ 'primary_category_id'
9378
+ ),
9379
+ 'default' => array(
9380
+ '',
9381
+ '',
9382
+ '',
9383
+ '',
9384
+ '',
9385
+ '',
9386
+ '',
9387
+ 'Develop-pro',
9388
+ '',
9389
+ '',
9390
+ '',
9391
+ '',
9392
+ '',
9393
+ '',
9394
+ '',
9395
+ '',
9396
+ '1',
9397
+ '0',
9398
+ '1',
9399
+ ''
9400
+ ),
9401
+ 'suffix' => array(
9402
+ '',
9403
+ '',
9404
+ '',
9405
+ '',
9406
+ '',
9407
+ '',
9408
+ '',
9409
+ '',
9410
+ '',
9411
+ '',
9412
+ '',
9413
+ '',
9414
+ '',
9415
+ '',
9416
+ '',
9417
+ '',
9418
+ '',
9419
+ '',
9420
+ '',
9421
+ ''
9422
+ ),
9423
+ 'output_type' => array(
9424
+ '1',
9425
+ '1',
9426
+ '1',
9427
+ '1',
9428
+ '1',
9429
+ '1',
9430
+ '1',
9431
+ '1',
9432
+ '11',
9433
+ '1',
9434
+ '1',
9435
+ '6',
9436
+ '6',
9437
+ '6',
9438
+ '1',
9439
+ '1',
9440
+ '1',
9441
+ '1',
9442
+ '1',
9443
+ '1'
9444
+ ),
9445
+ 'limit' => array(
9446
+ '',
9447
+ '',
9448
+ '',
9449
+ '',
9450
+ '',
9451
+ '',
9452
+ '',
9453
+ '',
9454
+ '',
9455
+ '',
9456
+ '',
9457
+ '',
9458
+ '',
9459
+ '',
9460
+ '',
9461
+ '',
9462
+ '',
9463
+ '',
9464
+ '',
9465
+ ''
9466
+ ),
9467
+ ),
9468
+ 'trendyol' => array(
9469
+ 'mattributes' => array(
9470
+ 'Barkod',
9471
+ 'Model Kodu',
9472
+ 'Marka',
9473
+ 'Kategori',
9474
+ 'Para Birimi',
9475
+ 'Ürün Adı',
9476
+ 'Ürün Açıklaması',
9477
+ 'Piyasa Satış Fiyatı (KDV Dahil)',
9478
+ 'Trendyol\'da Satılacak Fiyat (KDV Dahil)',
9479
+ 'Ürün Stok Adedi',
9480
+ 'Stok Kodu',
9481
+ 'KDV Oranı',
9482
+ 'Desi',
9483
+ 'Görsel Linki',
9484
+ 'Sevkiyat Süresi',
9485
+ 'Beden',
9486
+ 'Kol Tipi',
9487
+ 'Desen',
9488
+ 'Boy / Ölçü',
9489
+ 'Materyal',
9490
+ 'Yaş Grubu',
9491
+ 'Cinsiyet',
9492
+ 'Yaka',
9493
+ 'Renk'
9494
+ ),
9495
+ 'prefix' => array(
9496
+ '',
9497
+ '',
9498
+ '',
9499
+ '',
9500
+ '',
9501
+ '',
9502
+ '',
9503
+ '',
9504
+ '',
9505
+ '',
9506
+ '',
9507
+ '',
9508
+ '',
9509
+ '',
9510
+ '',
9511
+ '',
9512
+ '',
9513
+ '',
9514
+ '',
9515
+ '',
9516
+ '',
9517
+ '',
9518
+ '',
9519
+ ''
9520
+ ),
9521
+ 'type' => array(
9522
+ 'attribute',
9523
+ 'attribute',
9524
+ 'pattern',
9525
+ 'attribute',
9526
+ 'attribute',
9527
+ 'attribute',
9528
+ 'attribute',
9529
+ 'attribute',
9530
+ 'attribute',
9531
+ 'attribute',
9532
+ 'attribute',
9533
+ 'attribute',
9534
+ 'attribute',
9535
+ 'attribute',
9536
+ 'attribute',
9537
+ 'attribute',
9538
+ 'attribute',
9539
+ 'attribute',
9540
+ 'attribute',
9541
+ 'attribute',
9542
+ 'attribute',
9543
+ 'attribute',
9544
+ 'attribute',
9545
+ 'attribute'
9546
+ ),
9547
+ 'attributes' => array(
9548
+ 'id',
9549
+ 'sku',
9550
+ '',
9551
+ 'product_type',
9552
+ 'store_currency',
9553
+ 'title',
9554
+ 'description',
9555
+ 'current_price_with_tax',
9556
+ 'current_price_with_tax',
9557
+ 'quantity',
9558
+ '',
9559
+ '',
9560
+ '',
9561
+ 'link',
9562
+ '',
9563
+ '',
9564
+ '',
9565
+ '',
9566
+ '',
9567
+ '',
9568
+ '',
9569
+ '',
9570
+ '',
9571
+ ''
9572
+ ),
9573
+ 'default' => array(
9574
+ '',
9575
+ '',
9576
+ '',
9577
+ '',
9578
+ '',
9579
+ '',
9580
+ '',
9581
+ 'Localhost',
9582
+ '',
9583
+ '',
9584
+ '',
9585
+ '',
9586
+ '',
9587
+ '',
9588
+ '',
9589
+ '',
9590
+ '',
9591
+ '',
9592
+ '',
9593
+ '',
9594
+ '',
9595
+ '',
9596
+ '',
9597
+ ''
9598
+ ),
9599
+ 'suffix' => array(
9600
+ '',
9601
+ '',
9602
+ '',
9603
+ '',
9604
+ '',
9605
+ '',
9606
+ '',
9607
+ '',
9608
+ '',
9609
+ '',
9610
+ '',
9611
+ '',
9612
+ '',
9613
+ '',
9614
+ '',
9615
+ '',
9616
+ '',
9617
+ '',
9618
+ '',
9619
+ '',
9620
+ '',
9621
+ '',
9622
+ '',
9623
+ ''
9624
+ ),
9625
+ 'output_type' => array(
9626
+ '1',
9627
+ '1',
9628
+ '1',
9629
+ '1',
9630
+ '1',
9631
+ '1',
9632
+ '11',
9633
+ '1',
9634
+ '1',
9635
+ '1',
9636
+ '1',
9637
+ '1',
9638
+ '1',
9639
+ '1',
9640
+ '1',
9641
+ '1',
9642
+ '1',
9643
+ '1',
9644
+ '1',
9645
+ '1',
9646
+ '1',
9647
+ '1',
9648
+ '1',
9649
+ '1'
9650
+ ),
9651
+ 'limit' => array(
9652
+ '',
9653
+ '',
9654
+ '',
9655
+ '',
9656
+ '',
9657
+ '',
9658
+ '',
9659
+ 'test',
9660
+ 'test',
9661
+ 'test',
9662
+ '',
9663
+ '',
9664
+ '',
9665
+ '',
9666
+ '',
9667
+ '',
9668
+ '',
9669
+ '',
9670
+ '',
9671
+ '',
9672
+ '',
9673
+ '',
9674
+ '',
9675
+ ''
9676
+ ),
9677
+ ),
9678
+ 'gittigidiyor' => array(
9679
+ 'mattributes' => array(
9680
+ 'Kategori No',
9681
+ 'Dükkan No',
9682
+ 'Stok No',
9683
+ 'Başlık',
9684
+ 'Alt Başlık',
9685
+ 'Açıklama',
9686
+ '1. Fotoğraf',
9687
+ '2. Fotoğraf',
9688
+ '3. Fotoğraf',
9689
+ '4. Fotoğraf',
9690
+ '5. Fotoğraf',
9691
+ '6. Fotoğraf',
9692
+ '7. Fotoğraf',
9693
+ '8. Fotoğraf',
9694
+ 'Sayfa Düzeni No',
9695
+ 'Katalog No',
9696
+ 'Katalog Detay',
9697
+ 'Ürün Formatı',
9698
+ 'Hemen Al Fiyatı',
9699
+ 'Süre (Gün)',
9700
+ 'Ürün Adeti',
9701
+ 'Şehir No',
9702
+ 'Kargo Ölçüleri',
9703
+ 'Kargo Desi',
9704
+ 'Kargo Şirketleri',
9705
+ 'Kargo Ücreti',
9706
+ 'Gönderi Yapılacak Alanlar',
9707
+ 'Gönderi Yapacağınız Zaman',
9708
+ 'İş Ortaklığı',
9709
+ 'Kalın Yazı',
9710
+ 'Katalog',
9711
+ 'Vitrin',
9712
+ 'Ürün Seçeneği',
9713
+ 'Ürün Özelliği',
9714
+ 'Üretici Parça Numarası (MPN)',
9715
+ 'Global Ticari Öğe Numarası (GTIN)',
9716
+ 'Yeni Katalog No'
9717
+ ),
9718
+ 'prefix' => array(
9719
+ '',
9720
+ '',
9721
+ '',
9722
+ '',
9723
+ '',
9724
+ '',
9725
+ '',
9726
+ '',
9727
+ '',
9728
+ '',
9729
+ '',
9730
+ '',
9731
+ '',
9732
+ '',
9733
+ '',
9734
+ '',
9735
+ '',
9736
+ '',
9737
+ '',
9738
+ '',
9739
+ '',
9740
+ '',
9741
+ '',
9742
+ '',
9743
+ '',
9744
+ '',
9745
+ '',
9746
+ '',
9747
+ '',
9748
+ '',
9749
+ '',
9750
+ '',
9751
+ '',
9752
+ '',
9753
+ '',
9754
+ '',
9755
+ ''
9756
+ ),
9757
+ 'type' => array(
9758
+ 'attribute',
9759
+ 'pattern',
9760
+ 'attribute',
9761
+ 'attribute',
9762
+ 'attribute',
9763
+ 'attribute',
9764
+ 'attribute',
9765
+ 'attribute',
9766
+ 'attribute',
9767
+ 'attribute',
9768
+ 'attribute',
9769
+ 'attribute',
9770
+ 'attribute',
9771
+ 'attribute',
9772
+ 'attribute',
9773
+ 'attribute',
9774
+ 'attribute',
9775
+ 'attribute',
9776
+ 'attribute',
9777
+ 'pattern',
9778
+ 'attribute',
9779
+ 'pattern',
9780
+ 'attribute',
9781
+ 'attribute',
9782
+ 'attribute',
9783
+ 'attribute',
9784
+ 'attribute',
9785
+ 'pattern',
9786
+ 'pattern',
9787
+ 'pattern',
9788
+ 'pattern',
9789
+ 'pattern',
9790
+ 'attribute',
9791
+ 'attribute',
9792
+ 'attribute',
9793
+ 'attribute',
9794
+ 'pattern'
9795
+ ),
9796
+ 'attributes' => array(
9797
+ 'primary_category_id',
9798
+ '',
9799
+ '',
9800
+ 'title',
9801
+ 'short_description',
9802
+ 'description',
9803
+ 'image_1',
9804
+ 'image_2',
9805
+ 'image_3',
9806
+ 'image_4',
9807
+ 'image_5',
9808
+ 'image_6',
9809
+ 'image_7',
9810
+ 'image_8',
9811
+ 'id',
9812
+ 'id',
9813
+ 'id',
9814
+ 'id',
9815
+ 'current_price',
9816
+ '',
9817
+ 'quantity',
9818
+ '',
9819
+ 'id',
9820
+ 'id',
9821
+ 'id',
9822
+ 'id',
9823
+ 'id',
9824
+ '',
9825
+ '',
9826
+ '',
9827
+ '',
9828
+ '',
9829
+ '',
9830
+ '',
9831
+ '',
9832
+ '',
9833
+ ''
9834
+ ),
9835
+ 'default' => array(
9836
+ '',
9837
+ '',
9838
+ '',
9839
+ '',
9840
+ '',
9841
+ '',
9842
+ '',
9843
+ '',
9844
+ '',
9845
+ '',
9846
+ '',
9847
+ '',
9848
+ '',
9849
+ '',
9850
+ '',
9851
+ '',
9852
+ '',
9853
+ '',
9854
+ '',
9855
+ '3',
9856
+ '',
9857
+ '',
9858
+ '',
9859
+ '',
9860
+ '',
9861
+ '',
9862
+ '',
9863
+ '2-3days',
9864
+ 'false',
9865
+ 'false',
9866
+ 'false',
9867
+ 'false',
9868
+ '',
9869
+ '',
9870
+ '',
9871
+ '',
9872
+ ''
9873
+ ),
9874
+ 'suffix' => array(
9875
+ '',
9876
+ '',
9877
+ '',
9878
+ '',
9879
+ '',
9880
+ '',
9881
+ '',
9882
+ '',
9883
+ '',
9884
+ '',
9885
+ '',
9886
+ '',
9887
+ '',
9888
+ '',
9889
+ '',
9890
+ '',
9891
+ '',
9892
+ '',
9893
+ '',
9894
+ '',
9895
+ '',
9896
+ '',
9897
+ '',
9898
+ '',
9899
+ '',
9900
+ '',
9901
+ '',
9902
+ '',
9903
+ '',
9904
+ '',
9905
+ '',
9906
+ '',
9907
+ '',
9908
+ '',
9909
+ '',
9910
+ '',
9911
+ ''
9912
+ ),
9913
+ 'output_type' => array(
9914
+ '1',
9915
+ '1',
9916
+ '1',
9917
+ '1',
9918
+ '1',
9919
+ '11',
9920
+ '1',
9921
+ '1',
9922
+ '1',
9923
+ '1',
9924
+ '1',
9925
+ '1',
9926
+ '1',
9927
+ '1',
9928
+ '1',
9929
+ '1',
9930
+ '1',
9931
+ '1',
9932
+ '1',
9933
+ '1',
9934
+ '1',
9935
+ '1',
9936
+ '1',
9937
+ '1',
9938
+ '1',
9939
+ '1',
9940
+ '1',
9941
+ '1',
9942
+ '1',
9943
+ '1',
9944
+ '1',
9945
+ '1',
9946
+ '1',
9947
+ '1',
9948
+ '1',
9949
+ '1',
9950
+ '1'
9951
+ ),
9952
+ 'limit' => array(
9953
+ '',
9954
+ '',
9955
+ '',
9956
+ '',
9957
+ '',
9958
+ '',
9959
+ '',
9960
+ '',
9961
+ '',
9962
+ '',
9963
+ '',
9964
+ '',
9965
+ '',
9966
+ '',
9967
+ '',
9968
+ '',
9969
+ '',
9970
+ '',
9971
+ '',
9972
+ '',
9973
+ '',
9974
+ '',
9975
+ '',
9976
+ '',
9977
+ '',
9978
+ '',
9979
+ '',
9980
+ '',
9981
+ '',
9982
+ '',
9983
+ '',
9984
+ '',
9985
+ '',
9986
+ '',
9987
+ '',
9988
+ '',
9989
+ ''
9990
+ ),
9991
+ ),
9992
+ 'heureka.sk' => array(
9993
+ 'mattributes' => array(
9994
+ 'ITEM_ID',
9995
+ 'PRODUCTNAME',
9996
+ 'PRODUCT',
9997
+ 'DESCRIPTION',
9998
+ 'URL',
9999
+ 'IMGURL',
10000
+ 'PRICE_VAT',
10001
+ 'CATEGORYTEXT',
10002
+ 'EAN'
10003
+ ),
10004
+ 'prefix' => array( '', '', '', '', '', '', '', '', '' ),
10005
+ 'type' => array(
10006
+ 'attribute',
10007
+ 'attribute',
10008
+ 'attribute',
10009
+ 'attribute',
10010
+ 'attribute',
10011
+ 'attribute',
10012
+ 'attribute',
10013
+ 'attribute',
10014
+ 'attribute'
10015
+ ),
10016
+ 'attributes' => array(
10017
+ 'id',
10018
+ 'title',
10019
+ 'title',
10020
+ 'description',
10021
+ 'link',
10022
+ 'image',
10023
+ 'current_price_with_tax',
10024
+ 'product_type',
10025
+ 'woo_feed_ean'
10026
+ ),
10027
+ 'default' => array( '', '', '', '', '', '', '', '', 'Develop-pro' ),
10028
+ 'suffix' => array( '', '', '', '', '', '', '', '', '' ),
10029
+ 'output_type' => array( '1', '1', '1', '11', '1', '1', '6', '1', '1' ),
10030
+ 'limit' => array( '', '', '', '', '', '', '', '', '' ),
10031
+ ),
10032
+ 'moebel.de' => array(
10033
+ 'mattributes' => array(
10034
+ 'art_nr',
10035
+ 'art_name',
10036
+ 'art_beschreibung',
10037
+ 'art_url',
10038
+ 'art_img_url',
10039
+ 'art_price',
10040
+ 'art_kategorie',
10041
+ 'art_verfuegbarkeit'
10042
+ ),
10043
+ 'prefix' => array( '', '', '', '', '', '', '', '' ),
10044
+ 'type' => array(
10045
+ 'attribute',
10046
+ 'attribute',
10047
+ 'attribute',
10048
+ 'attribute',
10049
+ 'attribute',
10050
+ 'attribute',
10051
+ 'attribute',
10052
+ 'attribute'
10053
+ ),
10054
+ 'attributes' => array(
10055
+ 'id',
10056
+ 'title',
10057
+ 'description',
10058
+ 'link',
10059
+ 'image',
10060
+ 'price',
10061
+ 'product_type',
10062
+ 'availability'
10063
+ ),
10064
+ 'default' => array( '', '', '', '', '', '', '', '' ),
10065
+ 'suffix' => array( '', '', '', '', '', '', '', '' ),
10066
+ 'output_type' => array( '1', '1', '11', '1', '1', '1', '1', '1' ),
10067
+ 'limit' => array( '', '', '', '', '', '', '', '' ),
10068
+ ),
10069
+ 'zbozi.cz' => array(
10070
+ 'mattributes' => array(
10071
+ 'ITEM_ID',
10072
+ 'PRODUCTNAME',
10073
+ 'DESCRIPTION',
10074
+ 'URL',
10075
+ 'IMGURL',
10076
+ 'CATEGORYTEXT',
10077
+ 'VISIBILITY',
10078
+ 'PRICE_VAT',
10079
+ 'DELIVERY_DATE'
10080
+ ),
10081
+ 'prefix' => array( '', '', '', '', '', '', '', '', '' ),
10082
+ 'type' => array(
10083
+ 'attribute',
10084
+ 'attribute',
10085
+ 'attribute',
10086
+ 'attribute',
10087
+ 'attribute',
10088
+ 'attribute',
10089
+ 'attribute',
10090
+ 'attribute',
10091
+ 'pattern'
10092
+ ),
10093
+ 'attributes' => array(
10094
+ 'id',
10095
+ 'title',
10096
+ 'description',
10097
+ 'link',
10098
+ 'image',
10099
+ 'product_type',
10100
+ 'visibility',
10101
+ 'current_price_with_tax',
10102
+ ''
10103
+ ),
10104
+ 'default' => array( '', '', '', '', '', '', 'Develop-free', '', '0' ),
10105
+ 'suffix' => array( '', '', '', '', '', '', '', '', '' ),
10106
+ 'output_type' => array( '1', '1', '11', '1', '1', '1', '1', '6', '1' ),
10107
+ 'limit' => array( '', '', '', '', '', '', '', '', '' ),
10108
+ ),
10109
+ 'catch.com.au' => array(
10110
+ 'mattributes' => array( 'product-id', 'title', 'product-description', 'image-1', 'price', 'state' ),
10111
+ 'prefix' => array( '', '', '', '', '', '' ),
10112
+ 'type' => array( 'attribute', 'attribute', 'attribute', 'attribute', 'attribute', 'pattern' ),
10113
+ 'attributes' => array( 'id', 'title', 'description', 'image', 'price', '' ),
10114
+ 'default' => array( '', '', '', '', '', 'new' ),
10115
+ 'suffix' => array( '', '', '', '', '', '' ),
10116
+ 'output_type' => array( '1', '1', '11', '1', '6', '1' ),
10117
+ 'limit' => array( '', '', '', '', '', '' ),
10118
+ ),
10119
+ 'fashionchick' => array(
10120
+ 'mattributes' => array(
10121
+ 'Product ID',
10122
+ 'Titel',
10123
+ 'Omschrijving',
10124
+ 'Url',
10125
+ 'Image',
10126
+ 'Prijs',
10127
+ 'Category',
10128
+ 'Geslacht',
10129
+ 'Merk'
10130
+ ),
10131
+ 'prefix' => array( '', '', '', '', '', '', '', '', '' ),
10132
+ 'type' => array(
10133
+ 'attribute',
10134
+ 'attribute',
10135
+ 'attribute',
10136
+ 'attribute',
10137
+ 'attribute',
10138
+ 'attribute',
10139
+ 'attribute',
10140
+ 'pattern',
10141
+ 'pattern'
10142
+ ),
10143
+ 'attributes' => array(
10144
+ 'id',
10145
+ 'title',
10146
+ 'description',
10147
+ 'link',
10148
+ 'image',
10149
+ 'price',
10150
+ 'product_type',
10151
+ '',
10152
+ ''
10153
+ ),
10154
+ 'default' => array( '', '', '', '', '', '', '', 'male', '' ),
10155
+ 'suffix' => array( '', '', '', '', '', '', '', '', '' ),
10156
+ 'output_type' => array( '1', '1', '2, 11', '1', '1', '6', '1', '1', '1' ),
10157
+ 'limit' => array( '', '', '', '', '', '', '', '', '' ),
10158
+ ),
10159
+ 'wine_searcher' => array(
10160
+ 'mattributes' => array(
10161
+ 'name',
10162
+ 'description',
10163
+ 'vintage',
10164
+ 'unit-size',
10165
+ 'price',
10166
+ 'url',
10167
+ 'min-order',
10168
+ 'tax',
10169
+ 'offer-type',
10170
+ 'delivery-time',
10171
+ 'stock-level'
10172
+ ),
10173
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '' ),
10174
+ 'type' => array(
10175
+ 'attribute',
10176
+ 'attribute',
10177
+ 'pattern',
10178
+ 'pattern',
10179
+ 'attribute',
10180
+ 'attribute',
10181
+ 'pattern',
10182
+ 'pattern',
10183
+ 'pattern',
10184
+ 'pattern',
10185
+ 'attribute'
10186
+ ),
10187
+ 'attributes' => array( 'title', 'description', '', '', 'price', 'link', '', '', '', '', 'quantity' ),
10188
+ 'default' => array( '', '', '', '', '', 'Develop-free', '', '', '', '', '' ),
10189
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '', '' ),
10190
+ 'output_type' => array( '1', '11', '1', '1', '6', '1', '1', '1', '1', '1', '1' ),
10191
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '' ),
10192
+ ),
10193
+ 'modalova' => array(
10194
+ 'mattributes' => array(
10195
+ 'id',
10196
+ 'title',
10197
+ 'description',
10198
+ 'link',
10199
+ 'sku',
10200
+ 'main_image',
10201
+ 'images',
10202
+ 'price',
10203
+ 'sale_price',
10204
+ 'availability',
10205
+ 'category',
10206
+ 'condition',
10207
+ 'child_category'
10208
+ ),
10209
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '', '', '' ),
10210
+ 'type' => array(
10211
+ 'attribute',
10212
+ 'attribute',
10213
+ 'attribute',
10214
+ 'attribute',
10215
+ 'attribute',
10216
+ 'attribute',
10217
+ 'attribute',
10218
+ 'attribute',
10219
+ 'attribute',
10220
+ 'attribute',
10221
+ 'attribute',
10222
+ 'attribute',
10223
+ 'attribute'
10224
+ ),
10225
+ 'attributes' => array(
10226
+ 'id',
10227
+ 'title',
10228
+ 'description',
10229
+ 'link',
10230
+ 'sku',
10231
+ 'image',
10232
+ 'images',
10233
+ 'price',
10234
+ 'current_price',
10235
+ 'availability',
10236
+ 'primary_category',
10237
+ 'condition',
10238
+ 'child_category'
10239
+ ),
10240
+ 'default' => array( '', '', '', '', '', '', '', '', self::$brand, '', '', '', '' ),
10241
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '', '', '', '' ),
10242
+ 'output_type' => array( '1', '1', '11', '1', '1', '1', '1', '6', '6', '1', '1', '1', '1' ),
10243
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '', '', '' ),
10244
+ ),
10245
+ 'ecommerceit' => array(
10246
+ 'mattributes' => array(
10247
+ 'sku',
10248
+ 'qty',
10249
+ 'name',
10250
+ 'brand',
10251
+ 'category',
10252
+ 'picture_url',
10253
+ 'price',
10254
+ 'product_url',
10255
+ 'mpn',
10256
+ 'shipping_cost',
10257
+ 'max_delivery_days',
10258
+ 'delivery_label'
10259
+ ),
10260
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
10261
+ 'type' => array(
10262
+ 'attribute',
10263
+ 'attribute',
10264
+ 'attribute',
10265
+ 'pattern',
10266
+ 'attribute',
10267
+ 'attribute',
10268
+ 'attribute',
10269
+ 'attribute',
10270
+ 'pattern',
10271
+ 'attribute',
10272
+ 'pattern',
10273
+ 'pattern'
10274
+ ),
10275
+ 'attributes' => array(
10276
+ 'sku',
10277
+ 'quantity',
10278
+ 'title',
10279
+ '',
10280
+ 'primary_category',
10281
+ 'image',
10282
+ 'price',
10283
+ 'link',
10284
+ '',
10285
+ 'shipping_cost',
10286
+ '',
10287
+ ''
10288
+ ),
10289
+ 'default' => array( '', '', '', self::$brand, '', '', '', '', '', '', '3', '1-5 days' ),
10290
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
10291
+ 'output_type' => array( '1', '1', '1', '1', '1', '1', '6', '1', '1', '6', '1', '1' ),
10292
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '', '' ),
10293
+ ),
10294
+ 'tiktok' => array(
10295
+ 'mattributes' => array(
10296
+ 'sku_id',
10297
+ 'title',
10298
+ 'description',
10299
+ 'availability',
10300
+ 'link',
10301
+ 'image_link',
10302
+ 'price',
10303
+ 'brand',
10304
+ 'condition',
10305
+ 'google_product_category',
10306
+ 'item_group_id',
10307
+ 'product_type',
10308
+ ),
10309
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', '', '', ),
10310
+ 'type' => array(
10311
+ 'attribute',
10312
+ 'attribute',
10313
+ 'attribute',
10314
+ 'attribute',
10315
+ 'attribute',
10316
+ 'attribute',
10317
+ 'attribute',
10318
+ 'pattern',
10319
+ 'pattern',
10320
+ 'pattern',
10321
+ 'attribute',
10322
+ 'attribute',
10323
+ ),
10324
+ 'attributes' => array(
10325
+ 'sku_id',
10326
+ 'title',
10327
+ 'description',
10328
+ 'availability',
10329
+ 'link',
10330
+ 'image',
10331
+ 'price',
10332
+ '',
10333
+ '',
10334
+ '',
10335
+ 'item_group_id',
10336
+ 'product_type',
10337
+ ),
10338
+ 'default' => array( '', '', '', '', '', '', '', self::$brand, 'new', '', '', '', ),
10339
+ 'suffix' => array( '', '', '', '', '', '', self::$currency, '', '', '', '', '', ),
10340
+ 'output_type' => array( '1', '1', '1', '1', '1', '1', '6', '1', '1', '1', '1', '1', ),
10341
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', '', '', ),
10342
+ ),
10343
+ 'shopflix' => array(
10344
+ 'mattributes' => array(
10345
+ 'sku',
10346
+ 'name',
10347
+ 'description',
10348
+ 'ean',
10349
+ 'manufacturer',
10350
+ 'weight',
10351
+ 'color',
10352
+ 'price',
10353
+ 'quantity',
10354
+ 'shipping_lead_time',
10355
+ ),
10356
+ 'prefix' => array( '', '', '', '', '', '', '', '', '', '', ),
10357
+ 'type' => array(
10358
+ 'attribute',
10359
+ 'attribute',
10360
+ 'attribute',
10361
+ 'attribute',
10362
+ 'pattern',
10363
+ 'attribute',
10364
+ 'attribute',
10365
+ 'attribute',
10366
+ 'attribute',
10367
+ 'pattern',
10368
+ ),
10369
+ 'attributes' => array( 'sku', 'title', 'description', '', '', '', '', 'price', 'quantity', '', ),
10370
+ 'default' => array( '', '', '', '', self::$brand, '', '', '', '', '1', ),
10371
+ 'suffix' => array( '', '', '', '', '', '', '', '', '', '', ),
10372
+ 'output_type' => array( '1', '1', '1', '1', '1', '1', '1', '6', '1', '1', ),
10373
+ 'limit' => array( '', '', '', '', '', '', '', '', '', '', ),
10374
+ ),
10375
+ );
10376
+
10377
+ return $config[ self::$template ];
10378
+ }
10379
+ }
V5/Merchant/TemplateInfo.php ADDED
@@ -0,0 +1,437 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Merchant;
3
+ class TemplateInfo {
4
+ public static function get( $template = 'custom' ) {
5
+ $info = array(
6
+ 'default' => array(
7
+ 'feed_file_type' => array( 'XML', 'CSV', 'TSV', 'XLS', 'TXT' ),
8
+ ),
9
+ 'custom' => array(
10
+ 'feed_file_type' => array( 'XML', 'CSV', 'TSV', 'XLS', 'TXT', 'JSON' ),
11
+ ),
12
+ 'google' => array(
13
+ 'link' => 'https://support.google.com/merchants/answer/7052112?hl=en',
14
+ 'video' => 'https://youtu.be/PTUYgF7DwEo',
15
+ 'feed_file_type' => array( 'XML', 'CSV','TSV', 'TXT' ),
16
+ 'doc' => array(
17
+ esc_html__( 'How to make google merchant feed?', 'woo-feed' ) => 'https://youtu.be/PTUYgF7DwEo',
18
+ esc_html__( 'How to configure shipping info?', 'woo-feed' ) => 'https://webappick.com/docs/woo-feed/merchants/how-to-configure-google-merchant-shipping-attribute/',
19
+ esc_html__( 'How to set price with tax?', 'woo-feed' ) => 'https://webappick.com/docs/woo-feed/product-attributes/how-to-include-include-value-added-tax-vat-in-my-prices/',
20
+ esc_html__( 'How to configure google product categories?', 'woo-feed' ) => 'https://webappick.com/docs/woo-feed/feed-configuration/how-to-map-store-category-with-merchant-category/',
21
+ ),
22
+ ), // Google.
23
+ 'google_local' => array(
24
+ 'link' => 'https://support.google.com/merchants/answer/3061198?hl=en',
25
+ 'feed_file_type' => array( 'XML', 'CSV', 'TXT' ),
26
+ ),
27
+ 'google_local_inventory' => array(
28
+ 'link' => 'https://support.google.com/merchants/answer/3061342?hl=en',
29
+ 'feed_file_type' => array( 'XML', 'CSV', 'TXT' ),
30
+ ),
31
+ 'googlereview' => array(
32
+ 'link' => 'https://developers.google.com/product-review-feeds/sample',
33
+ 'feed_file_type' => array( 'XML' ),
34
+ ),
35
+ 'google_dynamic_ads' => array(
36
+ 'link' => '',
37
+ 'feed_file_type' => array( 'CSV' ),
38
+ ),
39
+ 'adwords' => array(
40
+ 'link' => 'https://support.google.com/google-ads/answer/6053288?hl=en',
41
+ 'feed_file_type' => array( 'CSV' ),
42
+ ),
43
+ 'adwords_local_product' => array(
44
+ 'link' => 'https://support.google.com/google-ads/answer/9580085?hl=en',
45
+ 'feed_file_type' => array( 'CSV' ),
46
+ ),
47
+ 'facebook' => array(
48
+ 'link' => 'https://www.facebook.com/business/help/120325381656392?id=725943027795860',
49
+ 'video' => 'https://youtu.be/Wo3V_nf_eUU',
50
+ 'feed_file_type' => array( 'XML', 'CSV', 'TXT' ),
51
+ ), // Facebook.
52
+ 'pinterest' => array(
53
+ 'link' => 'https://help.pinterest.com/en/business/article/before-you-get-started-with-catalogs',
54
+ 'feed_file_type' => array( 'XML', 'CSV', 'TSV','TXT' ),
55
+ 'doc' => array(
56
+ esc_html__( 'How to configure google product categories?', 'woo-feed' ) => 'https://webappick.com/docs/woo-feed/feed-configuration/how-to-map-store-category-with-merchant-category/',
57
+ ),
58
+ ), // Pinterest.
59
+ 'pinterest_rss' => array(
60
+ 'link' => 'https://help.pinterest.com/en/business/article/before-you-get-started-with-catalogs',
61
+ 'feed_file_type' => array( 'XML' ),
62
+ ), // Pinterest.
63
+ 'bing' => array(
64
+ 'link' => 'https://help.ads.microsoft.com/apex/index/3/en/51084',
65
+ 'feed_file_type' => array( 'CSV', 'TSV', 'XLS', 'TXT' ),
66
+ ), // Bing.
67
+ 'pricespy' => array(
68
+ 'link' => 'https://pricespy.co.nz/info/register-and-feature-your-shop--i10',
69
+ 'feed_file_type' => array( 'TXT' ),
70
+ ), // PriceSpy.
71
+ 'prisjakt' => array(
72
+ 'link' => 'https://www.prisjakt.nu/info/registrera-och-profilera-din-butik--i10',
73
+ 'feed_file_type' => array( 'TXT' ),
74
+ ), // Prisjakt.
75
+ 'idealo' => array(
76
+ 'link' => 'https://connect.idealo.de/import/en/csv/#_attributes_documentation',
77
+ 'feed_file_type' => array( 'CSV', 'TXT' ),
78
+ ), // Idealo.
79
+ 'yandex_csv' => array(
80
+ 'link' => 'https://yandex.com/support/partnermarket/export/recommendation.html#csv',
81
+ 'feed_file_type' => array( 'CSV', 'TXT' ),
82
+ ), // Yandex (CSV).
83
+ 'adroll' => array(
84
+ 'link' => 'https://help.adroll.com/hc/en-us/articles/216673657-Set-Up-Your-Product-Feed',
85
+ 'feed_file_type' => array( 'XML', 'CSV' ),
86
+ ), // adroll
87
+ 'adform' => array(
88
+ 'link' => 'https://www.adformhelp.com/s/topic/0TO3W0000008PC5WAM/good-to-know',
89
+ 'feed_file_type' => array( 'XML', 'CSV', 'JSON' ),
90
+ ), // adform
91
+ 'kelkoo' => array(
92
+ 'link' => 'https://developers.kelkoogroup.com/app/documentation/navigate/_publisher/feedServicePublic/_/_/MerchantFeeds#data-structure',
93
+ 'feed_file_type' => array( 'XML', 'CSV' ),
94
+ ), // Kelkoo.
95
+ 'shopmania' => array(
96
+ 'link' => 'https://partner.shopmania.com/cp.help/datafeed-specifications',
97
+ 'feed_file_type' => array( 'XML', 'CSV' ),
98
+ ), // Shop Mania.
99
+ 'connexity' => array(
100
+ 'link' => 'https://www.operationroi.com/wp-content/downloads/Connexity-Feed-Specs-09-2015.pdf',
101
+ 'feed_file_type' => array( 'TXT' ),
102
+ ), // Connexity.
103
+ 'twenga' => array(
104
+ 'link' => 'https://support.twenga-solutions.com/hc/en-gb/articles/115014901088-Create-a-feed-to-import-your-catalog',
105
+ 'feed_file_type' => array( 'XML', 'TXT' ),
106
+ ), // Twenga.
107
+ 'fruugo' => array(
108
+ 'link' => 'https://fruugo.atlassian.net/wiki/spaces/RR/pages/67608211/Field+Specification',
109
+ 'feed_file_type' => array( 'XML', 'CSV' ),
110
+ ), // Fruugo.
111
+ 'fruugo.au' => array(
112
+ 'link' => 'https://fruugo.atlassian.net/wiki/spaces/RR/pages/67608211/Field+Specification',
113
+ 'feed_file_type' => array( 'XML', 'CSV' ),
114
+ ), // Fruugo Australia.
115
+ 'goedgeplaatst' => array(
116
+ 'feed_file_type' => array( 'CSV' ),
117
+ ), // GoedGeplaatst.nl.
118
+ 'pricerunner' => array(
119
+ 'link' => 'https://www.pricerunner.com/info/getting-started',
120
+ 'feed_file_type' => array( 'XML', 'CSV', 'TXT' ),
121
+ ), // Price Runner.
122
+ 'bonanza' => array(
123
+ 'link' => 'https://support.bonanza.com/hc/en-us/articles/360000656491',
124
+ 'feed_file_type' => array( 'CSV' ),
125
+ ), // Bonanza
126
+ 'bol' => array(
127
+ 'link' => 'https://partnerblog.bol.com/app/files/2018/02/Kolomnamen_productfeeds-2.2.pdf',
128
+ 'feed_file_type' => array( 'XML', 'CSV' ),
129
+ ), // Bol.
130
+ 'wish' => array(
131
+ 'link' => 'https://merchantfaq.wish.com/hc/en-us/articles/204530468',
132
+ 'feed_file_type' => array( 'CSV' ),
133
+ ), // Wish.com.
134
+ 'myshopping.com.au' => array(
135
+ 'link' => 'https://merchant.myshopping.com.au/doc/Product_Feed_Specification.pdf',
136
+ 'feed_file_type' => array( 'XML', 'CSV', 'TXT' ),
137
+ ), // Myshopping.com.au.
138
+ 'skinflint.co.uk' => array(
139
+ 'feed_file_type' => array( 'CSV' ),
140
+ ), // SkinFlint.co.uk.
141
+ 'yahoo_nfa' => array(
142
+ 'feed_file_type' => array( 'XML', 'CSV', 'TXT' ),
143
+ ), // Yahoo NFA.
144
+ 'comparer.be' => array(
145
+ 'link' => 'https://sc.vergelijk.nl/data/fr_FR/ignore/folders/annexe_3-directives_fichier.pdf',
146
+ 'feed_file_type' => array( 'XML', 'CSV' ),
147
+ ), // Comparer.be.
148
+ 'rakuten.de' => array(
149
+ 'link' => 'https://rakutenadvertising.com/product-feed-specification/',
150
+ 'feed_file_type' => array( 'CSV', 'TXT' ),
151
+ ), // rakuten.
152
+ 'avantlink' => array(
153
+ 'link' => 'https://support.avantlink.com/hc/en-us/articles/203883345-All-About-Datafeeds',
154
+ 'feed_file_type' => array( 'XML', 'CSV', 'TXT' ),
155
+ ), // Avantlink
156
+ 'shareasale' => array(
157
+ 'link' => 'https://blog.shareasale.com/2013/07/18/how-to-create-a-product-datafeed/',
158
+ 'feed_file_type' => array( 'XML', 'CSV', 'TXT' ),
159
+ ), // ShareASale.
160
+ 'trovaprezzi' => array(
161
+ 'feed_file_type' => array( 'XML', 'CSV', 'TXT' ),
162
+ ), // trovaprezzi.it.
163
+ 'skroutz' => array(
164
+ 'link' => 'https://developer.skroutz.gr/feedspec/',
165
+ 'video' => '',
166
+ 'doc' => array(
167
+ esc_html__( 'Validator', 'woo-feed' ) => 'https://validator.skroutz.gr/',
168
+ ),
169
+ 'feed_file_type' => array( 'XML' ),
170
+ ),
171
+ 'bestprice' => array(
172
+ 'link' => 'https://merchants.bestprice.gr/assets/bestprice-xml-specification.pdf',
173
+ 'feed_file_type' => array( 'XML' ),
174
+ ),
175
+ 'google_shopping_action' => array(
176
+ 'link' => 'https://support.google.com/merchants/answer/9111285',
177
+ 'video' => '',
178
+ 'doc' => array(
179
+ esc_html__( 'Set up return policies for Shopping Actions', 'woo-feed' ) => 'https://support.google.com/merchants/answer/7660817',
180
+ esc_html__( 'Set up a return address for Shopping Actions', 'woo-feed' ) => 'https://support.google.com/merchants/answer/9035057',
181
+ ),
182
+ 'feed_file_type' => array( 'XML', 'CSV' ),
183
+ ), // Google Shopping Action
184
+ 'daisycon' => array(
185
+ 'link' => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000721785--As-an-advertiser-how-do-I-submit-a-product-feed-',
186
+ 'video' => '',
187
+ 'doc' => array(
188
+ esc_html__( 'Feed Field Data Types', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000727049-Legend-productfeed-field-types',
189
+ esc_html__( 'Product Feed Standard', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115001431109-Productfeed-standard-General',
190
+ ),
191
+ 'feed_file_type' => array( 'XML', 'CSV' ),
192
+ ), // Daisycon Advertiser: General
193
+ 'daisycon_automotive' => array(
194
+ 'link' => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000721785--As-an-advertiser-how-do-I-submit-a-product-feed-',
195
+ 'video' => '',
196
+ 'doc' => array(
197
+ esc_html__( 'Feed Field Data Types', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000727049-Legend-productfeed-field-types',
198
+ esc_html__( 'Product Feed Standard', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115001440805-Productfeed-standard-Automotive',
199
+ ),
200
+ 'feed_file_type' => array( 'XML', 'CSV' ),
201
+ ), // Daisycon Advertiser: Automotive
202
+ 'daisycon_books' => array(
203
+ 'link' => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000721785--As-an-advertiser-how-do-I-submit-a-product-feed-',
204
+ 'video' => '',
205
+ 'doc' => array(
206
+ esc_html__( 'Feed Field Data Types', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000727049-Legend-productfeed-field-types',
207
+ esc_html__( 'Product Feed Standard', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115001436885-Productfeed-standard-Books',
208
+ ),
209
+ 'feed_file_type' => array( 'XML', 'CSV' ),
210
+ ), // Daisycon Advertiser: Books
211
+ 'daisycon_cosmetics' => array(
212
+ 'link' => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000721785--As-an-advertiser-how-do-I-submit-a-product-feed-',
213
+ 'video' => '',
214
+ 'doc' => array(
215
+ esc_html__( 'Feed Field Data Types', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000727049-Legend-productfeed-field-types',
216
+ esc_html__( 'Product Feed Standard', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115001435825-Productfeed-standard-Cosmetics',
217
+ ),
218
+ 'feed_file_type' => array( 'XML', 'CSV' ),
219
+ ), // Daisycon Advertiser: Cosmetics
220
+ 'daisycon_daily_offers' => array(
221
+ 'link' => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000721785--As-an-advertiser-how-do-I-submit-a-product-feed-',
222
+ 'video' => '',
223
+ 'doc' => array(
224
+ esc_html__( 'Feed Field Data Types', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000727049-Legend-productfeed-field-types',
225
+ esc_html__( 'Product Feed Standard', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115001422549-Productfeed-standard-Daily-offers',
226
+ ),
227
+ 'feed_file_type' => array( 'XML', 'CSV' ),
228
+ ), // Daisycon Advertiser: Daily Offers
229
+ 'daisycon_electronics' => array(
230
+ 'link' => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000721785--As-an-advertiser-how-do-I-submit-a-product-feed-',
231
+ 'video' => '',
232
+ 'doc' => array(
233
+ esc_html__( 'Feed Field Data Types', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000727049-Legend-productfeed-field-types',
234
+ esc_html__( 'Product Feed Standard', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115001401605-Productfeed-standard-Electronics',
235
+ ),
236
+ 'feed_file_type' => array( 'XML', 'CSV' ),
237
+ ), // Daisycon Advertiser: Electronics
238
+ 'daisycon_food_drinks' => array(
239
+ 'link' => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000721785--As-an-advertiser-how-do-I-submit-a-product-feed-',
240
+ 'video' => '',
241
+ 'doc' => array(
242
+ esc_html__( 'Feed Field Data Types', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000727049-Legend-productfeed-field-types',
243
+ esc_html__( 'Product Feed Standard', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115001392409-Productfeed-standard-Food-Drinks',
244
+ ),
245
+ 'feed_file_type' => array( 'XML', 'CSV' ),
246
+ ), // Daisycon Advertiser: Food & Drinks
247
+ 'daisycon_home_garden' => array(
248
+ 'link' => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000721785--As-an-advertiser-how-do-I-submit-a-product-feed-',
249
+ 'video' => '',
250
+ 'doc' => array(
251
+ esc_html__( 'Feed Field Data Types', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000727049-Legend-productfeed-field-types',
252
+ esc_html__( 'Product Feed Standard', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115001406165-Productfeed-standard-House-and-Garden',
253
+ ),
254
+ 'feed_file_type' => array( 'XML' ),
255
+ ), // Daisycon Advertiser: Home & Garden
256
+ 'daisycon_housing' => array(
257
+ 'link' => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000721785--As-an-advertiser-how-do-I-submit-a-product-feed-',
258
+ 'video' => '',
259
+ 'doc' => array(
260
+ esc_html__( 'Feed Field Data Types', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000727049-Legend-productfeed-field-types',
261
+ esc_html__( 'Product Feed Standard', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115001397509-Productfeed-standard-Housing',
262
+ ),
263
+ 'feed_file_type' => array( 'XML', 'CSV' ),
264
+ ), // Daisycon Advertiser: Housing
265
+ 'daisycon_fashion' => array(
266
+ 'link' => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000721785--As-an-advertiser-how-do-I-submit-a-product-feed-',
267
+ 'video' => '',
268
+ 'doc' => array(
269
+ esc_html__( 'Feed Field Data Types', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000727049-Legend-productfeed-field-types',
270
+ esc_html__( 'Product Feed Standard', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115001410905-Productfeed-standard-Fashion',
271
+ ),
272
+ 'feed_file_type' => array( 'XML', 'CSV' ),
273
+ ), // Daisycon Advertiser: Fashion
274
+ 'daisycon_studies_trainings' => array(
275
+ 'link' => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000721785--As-an-advertiser-how-do-I-submit-a-product-feed-',
276
+ 'video' => '',
277
+ 'doc' => array(
278
+ esc_html__( 'Feed Field Data Types', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000727049-Legend-productfeed-field-types',
279
+ esc_html__( 'Product Feed Standard', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115001376185-Productfeed-standard-Studies-Courses',
280
+ ),
281
+ 'feed_file_type' => array( 'XML', 'CSV' ),
282
+ ), // Daisycon Advertiser: Studies & Trainings
283
+ 'daisycon_telecom_accessories' => array(
284
+ 'link' => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000721785--As-an-advertiser-how-do-I-submit-a-product-feed-',
285
+ 'video' => '',
286
+ 'doc' => array(
287
+ esc_html__( 'Feed Field Data Types', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000727049-Legend-productfeed-field-types',
288
+ esc_html__( 'Product Feed Standard', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115001359405-Productfeed-standard-Telecom-Accessoires',
289
+ ),
290
+ 'feed_file_type' => array( 'XML', 'CSV' ),
291
+ ), // Daisycon Advertiser: Telecom: Accessories
292
+ 'daisycon_telecom_all_in_one' => array(
293
+ 'link' => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000721785--As-an-advertiser-how-do-I-submit-a-product-feed-',
294
+ 'video' => '',
295
+ 'doc' => array(
296
+ esc_html__( 'Feed Field Data Types', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000727049-Legend-productfeed-field-types',
297
+ esc_html__( 'Product Feed Standard', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000740505-Productfeed-standard-Telecom-All-in-one',
298
+ ),
299
+ 'feed_file_type' => array( 'XML', 'CSV' ),
300
+ ), // Daisycon Advertiser: Telecom: All-in-one
301
+ 'daisycon_telecom_gsm_subscription' => array(
302
+ 'link' => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000721785--As-an-advertiser-how-do-I-submit-a-product-feed-',
303
+ 'video' => '',
304
+ 'doc' => array(
305
+ esc_html__( 'Feed Field Data Types', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000727049-Legend-productfeed-field-types',
306
+ esc_html__( 'Product Feed Standard', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000711709-Productfeed-standard-Telecom-GSM-Subscription',
307
+ ),
308
+ 'feed_file_type' => array( 'XML', 'CSV' ),
309
+ ), // Daisycon Advertiser: Telecom: GSM + Subscription
310
+ 'daisycon_telecom_gsm' => array(
311
+ 'link' => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000721785--As-an-advertiser-how-do-I-submit-a-product-feed-',
312
+ 'video' => '',
313
+ 'doc' => array(
314
+ esc_html__( 'Feed Field Data Types', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000727049-Legend-productfeed-field-types',
315
+ esc_html__( 'Product Feed Standard', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115001359365-Productfeed-standard-GSM-devices',
316
+ ),
317
+ 'feed_file_type' => array( 'XML', 'CSV' ),
318
+ ), // Daisycon Advertiser: Telecom: GSM only
319
+ 'daisycon_telecom_sim' => array(
320
+ 'link' => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000721785--As-an-advertiser-how-do-I-submit-a-product-feed-',
321
+ 'video' => '',
322
+ 'doc' => array(
323
+ esc_html__( 'Feed Field Data Types', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000727049-Legend-productfeed-field-types',
324
+ esc_html__( 'Product Feed Standard', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115001359545-Productfeed-standard-Telecom-Simonly',
325
+ ),
326
+ 'feed_file_type' => array( 'XML', 'CSV' ),
327
+ ), // Daisycon Advertiser: Telecom: Sim only
328
+ 'daisycon_magazines' => array(
329
+ 'link' => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000721785--As-an-advertiser-how-do-I-submit-a-product-feed-',
330
+ 'video' => '',
331
+ 'doc' => array(
332
+ esc_html__( 'Feed Field Data Types', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000727049-Legend-productfeed-field-types',
333
+ esc_html__( 'Product Feed Standard', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115001357309-Productfeed-standard-Magazines',
334
+ ),
335
+ 'feed_file_type' => array( 'XML', 'CSV' ),
336
+ ), // Daisycon Advertiser: Magazines
337
+ 'daisycon_holidays_accommodations' => array(
338
+ 'link' => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000721785--As-an-advertiser-how-do-I-submit-a-product-feed-',
339
+ 'video' => '',
340
+ 'doc' => array(
341
+ esc_html__( 'Feed Field Data Types', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000727049-Legend-productfeed-field-types',
342
+ esc_html__( 'Product Feed Standard', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115001346949-Productfeed-standard-Vacation-Accommodations',
343
+ ),
344
+ 'feed_file_type' => array( 'XML', 'CSV' ),
345
+ ), // Daisycon Advertiser: Holidays: Accommodations
346
+ 'daisycon_holidays_accommodations_and_transport' => array(
347
+ 'link' => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000721785--As-an-advertiser-how-do-I-submit-a-product-feed-',
348
+ 'video' => '',
349
+ 'doc' => array(
350
+ esc_html__( 'Feed Field Data Types', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000727049-Legend-productfeed-field-types',
351
+ esc_html__( 'Product Feed Standard', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115001347069-Productfeed-standard-Vacation-Accommodations-Transport',
352
+ ),
353
+ 'feed_file_type' => array( 'XML', 'CSV' ),
354
+ ), // Daisycon Advertiser: Holidays: Accommodations and transport
355
+ 'daisycon_holidays_trips' => array(
356
+ 'link' => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000721785--As-an-advertiser-how-do-I-submit-a-product-feed-',
357
+ 'video' => '',
358
+ 'doc' => array(
359
+ esc_html__( 'Feed Field Data Types', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000727049-Legend-productfeed-field-types',
360
+ esc_html__( 'Product Feed Standard', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115001360205-Productfeed-standard-Vacation-Trips',
361
+ ),
362
+ 'feed_file_type' => array( 'XML', 'CSV' ),
363
+ ), // Daisycon Advertiser: Holidays: Trips
364
+ 'daisycon_work_jobs' => array(
365
+ 'link' => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000721785--As-an-advertiser-how-do-I-submit-a-product-feed-',
366
+ 'video' => '',
367
+ 'doc' => array(
368
+ esc_html__( 'Feed Field Data Types', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115000727049-Legend-productfeed-field-types',
369
+ esc_html__( 'Product Feed Standard', 'woo-feed' ) => 'https://faq-advertiser.daisycon.com/hc/en-us/articles/115001360329-Productfeed-standard-Work-Jobs',
370
+ ),
371
+ 'feed_file_type' => array( 'XML', 'CSV' ),
372
+ ), // Daisycon Advertiser: Work & Jobs
373
+ 'spartoo.fi' => array(
374
+ 'feed_file_type' => array( 'CSV' ),
375
+ ),
376
+ 'shopee' => array(
377
+ 'feed_file_type' => array( 'CSV' ),
378
+ ),
379
+ 'zalando' => array(
380
+ 'link' => 'https://docs.partner-solutions.zalan.do/de/fci/getting-started.html#format',
381
+ 'feed_file_type' => array( 'CSV' ),
382
+ ),
383
+ 'etsy' => array(
384
+ 'feed_file_type' => array( 'CSV' ),
385
+ ),
386
+ 'tweaker_xml' => array(
387
+ 'link' => 'https://webappick.com/wp-content/uploads/2020/08/Specificaties-productfeed-Tweakers-Pricewatch.pdf',
388
+ 'feed_file_type' => array( 'XML' ),
389
+ ),
390
+ 'tweaker_csv' => array(
391
+ 'link' => 'https://webappick.com/wp-content/uploads/2020/08/Specificaties-productfeed-Tweakers-Pricewatch.pdf',
392
+ 'feed_file_type' => array( 'CSV' ),
393
+ ),
394
+ 'profit_share' => array(
395
+ 'link' => 'https://support.profitshare.ro/hc/ro/articles/211436229-Importul-produselor-prin-CSV',
396
+ 'feed_file_type' => array( 'CSV' ),
397
+ ),
398
+ 'heureka.sk' => array(
399
+ 'link' => 'https://sluzby.heureka.sk/napoveda/xml-feed/',
400
+ 'feed_file_type' => array( 'XML' ),
401
+ ),
402
+ 'moebel.de' => array(
403
+ 'link' => 'https://feedonomics.com/supported-channels/moebel-de-feed-specifications/',
404
+ 'feed_file_type' => array( 'XML', 'CSV', 'TXT' ),
405
+ ),
406
+ 'zbozi.cz' => array(
407
+ 'link' => 'https://napoveda.sklik.cz/wp-content/uploads/offer_feed_en.pdf',
408
+ 'feed_file_type' => array( 'XML' ),
409
+ ),
410
+ 'catchdotcom' => array(
411
+ 'feed_file_type' => array( 'XML' ),
412
+ ),
413
+ 'fashionchick' => array(
414
+ 'feed_file_type' => array( 'CSV', 'TXT' ),
415
+ ),
416
+ 'wine_searcher' => array(
417
+ 'feed_file_type' => array( 'XML', 'TXT' ),
418
+ ),
419
+ 'modalova' => array(
420
+ 'feed_file_type' => array( 'XML' ),
421
+ ),
422
+ 'ecommerceit' => array(
423
+ 'link' => 'https://media.ecommerce.eu/merchant/templates/catalog.csv',
424
+ 'feed_file_type' => array( 'CSV' ),
425
+ ),
426
+ 'tiktok' => array(
427
+ 'link' => 'https://ads.tiktok.com/help/article?aid=10001006',
428
+ 'feed_file_type' => array( 'CSV' ),
429
+ ),
430
+ 'shopflix' => array(
431
+ 'feed_file_type' => array( 'XML' ),
432
+ ),
433
+ );
434
+
435
+ return $info[ $template ];
436
+ }
437
+ }
V5/Merchant/Templates.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Merchant;
3
+ class Templates {
4
+
5
+ }
V5/Notice/Dismiss.php ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php /** @noinspection ALL */ // phpcs:ignore WordPress.Files.FileName
2
+ /**
3
+ * Handles dismissing admin notices.
4
+ *
5
+ * @package pressmodo/wp-admin-notices
6
+ * @author WPTRT <themes@wordpress.org>
7
+ * @author Pressmodo <hello@pressmodo.com>
8
+ * @copyright 2019 WPTRT
9
+ * @copyright 2020 Sematico LTD
10
+ * @license https://www.gnu.org/licenses/gpl-3.0.html GPL-3.0-or-later
11
+ * @link https://github.com/pressmodo/wp-admin-notices
12
+ */
13
+
14
+ namespace CTXFeed\V5\Notice;
15
+
16
+ /**
17
+ * The Dismiss class, responsible for dismissing and checking the status of admin notices.
18
+ *
19
+ * @since 1.0.0
20
+ */
21
+ class Dismiss {
22
+
23
+ /**
24
+ * The notice-ID.
25
+ *
26
+ * @access private
27
+ * @since 1.0
28
+ * @var string
29
+ */
30
+ private $id;
31
+
32
+ /**
33
+ * The prefix we'll be using for the option/user-meta.
34
+ *
35
+ * @access private
36
+ * @since 1.0
37
+ * @var string
38
+ */
39
+ private $prefix;
40
+
41
+ /**
42
+ * The notice's scope. Can be "user" or "global".
43
+ *
44
+ * @access private
45
+ * @since 1.0
46
+ * @var string
47
+ */
48
+ private $scope;
49
+
50
+ /**
51
+ * Constructor.
52
+ *
53
+ * @access public
54
+ * @param string $id A unique ID for this notice. Can contain lowercase characters and underscores.
55
+ * @param string $prefix The prefix that will be used for the option/user-meta.
56
+ * @param string $scope Whether the notification is a global or user type.
57
+ * @since 1.0
58
+ */
59
+ public function __construct( $id, $prefix, $scope = 'global' ) {
60
+
61
+ // Set the object properties.
62
+ $this->id = sanitize_key( $id );
63
+ $this->prefix = sanitize_key( $prefix );
64
+ $this->scope = ( in_array( $scope, array( 'global', 'user' ), true ) ) ? $scope : 'global';
65
+
66
+ // Handle AJAX requests to dismiss the notice.
67
+ add_action( 'wp_ajax_pressmodo_dismiss_notice', array( $this, 'ajax_maybe_dismiss_notice' ) );
68
+ }
69
+
70
+ /**
71
+ * Print the script for dismissing the notice.
72
+ *
73
+ * @access private
74
+ * @since 1.0
75
+ * @return void
76
+ */
77
+ public function print_script() {
78
+
79
+ // Create a nonce.
80
+ $nonce = wp_create_nonce( 'pressmodo_dismiss_notice_' . $this->id );
81
+ ?>
82
+ <script>
83
+ window.addEventListener( 'load', function() {
84
+ var dismissBtn = document.querySelector( '#pressmodo-notice-<?php echo esc_attr( $this->id ); ?> .notice-dismiss' );
85
+
86
+ if ( dismissBtn === null ) {
87
+ return
88
+ }
89
+
90
+ // Add an event listener to the dismiss button.
91
+ dismissBtn.addEventListener( 'click', function( event ) {
92
+ var httpRequest = new XMLHttpRequest(),
93
+ postData = '';
94
+
95
+ // Build the data to send in our request.
96
+ // Data has to be formatted as a string here.
97
+ postData += 'id=<?php echo esc_attr( rawurlencode( $this->id ) ); ?>';
98
+ postData += '&action=pressmodo_dismiss_notice';
99
+ postData += '&nonce=<?php echo esc_html( $nonce ); ?>';
100
+
101
+ httpRequest.open( 'POST', '<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>' );
102
+ httpRequest.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
103
+ httpRequest.send( postData );
104
+ });
105
+ });
106
+ </script>
107
+ <?php
108
+ }
109
+
110
+ /**
111
+ * Check if the notice has been dismissed or not.
112
+ *
113
+ * @access public
114
+ * @since 1.0
115
+ * @return bool
116
+ */
117
+ public function is_dismissed() {
118
+
119
+ // Check if the notice has been dismissed when using user-meta.
120
+ if ( 'user' === $this->scope ) {
121
+ return ( get_user_meta( get_current_user_id(), "{$this->prefix}_{$this->id}", true ) );
122
+ }
123
+
124
+ return ( get_option( "{$this->prefix}_{$this->id}" ) );
125
+ }
126
+
127
+ /**
128
+ * Run check to see if we need to dismiss the notice.
129
+ * If all tests are successful then call the dismiss_notice() method.
130
+ *
131
+ * @access public
132
+ * @since 1.0
133
+ * @return void
134
+ */
135
+ public function ajax_maybe_dismiss_notice() {
136
+
137
+ // Sanity check: Early exit if we're not on a pressmodo_dismiss_notice action.
138
+ if ( ! isset( $_POST['action'] ) || 'pressmodo_dismiss_notice' !== $_POST['action'] ) {
139
+ return;
140
+ }
141
+
142
+ // Sanity check: Early exit if the ID of the notice is not the one from this object.
143
+ if ( ! isset( $_POST['id'] ) || $this->id !== $_POST['id'] ) {
144
+ return;
145
+ }
146
+
147
+ // Security check: Make sure nonce is OK.
148
+ check_ajax_referer( 'pressmodo_dismiss_notice_' . $this->id, 'nonce', true );
149
+
150
+ // If we got this far, we need to dismiss the notice.
151
+ $this->dismiss_notice();
152
+ }
153
+
154
+ /**
155
+ * Actually dismisses the notice.
156
+ *
157
+ * @access private
158
+ * @since 1.0
159
+ * @return void
160
+ */
161
+ private function dismiss_notice() {
162
+ if ( 'user' === $this->scope ) {
163
+ update_user_meta( get_current_user_id(), "{$this->prefix}_{$this->id}", true );
164
+ return;
165
+ }
166
+ update_option( "{$this->prefix}_{$this->id}", true, false );
167
+ }
168
+ }
V5/Notice/Notice.php ADDED
@@ -0,0 +1,276 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php // phpcs:ignore WordPress.Files.FileName
2
+ /**
3
+ * Admin-Notices class.
4
+ *
5
+ * Creates an admin notice with consistent styling.
6
+ *
7
+ * @package pressmodo/wp-admin-notices
8
+ * @author WPTRT <themes@wordpress.org>
9
+ * @author Pressmodo <hello@pressmodo.com>
10
+ * @copyright 2019 WPTRT
11
+ * @copyright 2020 Sematico LTD
12
+ * @license https://www.gnu.org/licenses/gpl-3.0.html GPL-3.0-or-later
13
+ * @link https://github.com/pressmodo/wp-admin-notices
14
+ */
15
+
16
+ namespace CTXFeed\V5\Notice;
17
+
18
+ /**
19
+ * The Admin_Notice class, responsible for creating admin notices.
20
+ *
21
+ * Each notice is a new instance of the object.
22
+ *
23
+ * @since 1.0.0
24
+ */
25
+ class Notice {
26
+
27
+ /**
28
+ * The notice-ID.
29
+ *
30
+ * @access private
31
+ * @since 1.0
32
+ * @var string
33
+ */
34
+ private $id;
35
+
36
+ /**
37
+ * The notice message.
38
+ *
39
+ * @access private
40
+ * @since 1.0
41
+ * @var string
42
+ */
43
+ private $message;
44
+
45
+ /**
46
+ * An instance of the \Pressmodo\AdminNotices\Dismiss object.
47
+ *
48
+ * @access public
49
+ * @since 1.0
50
+ * @var Dismiss
51
+ */
52
+ public $dismiss;
53
+
54
+ /**
55
+ * The notice arguments.
56
+ *
57
+ * @access private
58
+ * @since 1.0
59
+ * @var array
60
+ */
61
+ private $options = array(
62
+ 'scope' => 'global',
63
+ 'type' => 'info',
64
+ 'alt_style' => false,
65
+ 'capability' => 'edit_theme_options',
66
+ 'option_prefix' => 'pressmodo_notice_dismissed',
67
+ 'screens' => array(),
68
+ 'dismissible' => true,
69
+ );
70
+
71
+ /**
72
+ * An array of allowed types.
73
+ *
74
+ * @access private
75
+ * @since 1.0
76
+ * @var array
77
+ */
78
+ private $allowed_types = array(
79
+ 'info',
80
+ 'success',
81
+ 'error',
82
+ 'warning',
83
+ );
84
+
85
+ /**
86
+ * The title for our notice.
87
+ *
88
+ * @var string
89
+ */
90
+ private $title;
91
+
92
+ /**
93
+ * Constructor.
94
+ *
95
+ * @access public
96
+ * @since 1.0
97
+ * @param string $id A unique ID for this notice. Can contain lowercase characters and underscores.
98
+ * @param string $title The title for our notice.
99
+ * @param string $message The message for our notice.
100
+ * @param array $options An array of additional options to change the defaults for this notice.
101
+ * [
102
+ * 'screens' => (array) An array of screens where the notice will be displayed.
103
+ * Leave empty to always show.
104
+ * Defaults to an empty array.
105
+ * 'scope' => (string) Can be "global" or "user".
106
+ * Determines if the dismissed status will be saved as an option or user-meta.
107
+ * Defaults to "global".
108
+ * 'type' => (string) Can be one of "info", "success", "warning", "error".
109
+ * Defaults to "info".
110
+ * 'alt_style' => (bool) Whether we want to use alt styles or not.
111
+ * Defaults to false.
112
+ * 'capability' => (string) The user capability required to see the notice.
113
+ * Defaults to "edit_theme_options".
114
+ * 'option_prefix' => (string) The prefix that will be used to build the option (or post-meta) name.
115
+ * Can contain lowercase latin letters and underscores.
116
+ * 'dismissible' => (bool) Whether or not the notice can be dismissed. Defaults to true.
117
+ * ].
118
+ */
119
+ public function __construct( $id, $title, $message, $options = array() ) {
120
+
121
+ // Set the object properties.
122
+ $this->id = $id;
123
+ $this->title = $title;
124
+ $this->message = $message;
125
+ $this->options = wp_parse_args( $options, $this->options );
126
+
127
+ // Sanity check: Early exit if ID or message are empty.
128
+ if ( ! $this->id || ! $this->message ) {
129
+ return;
130
+ }
131
+
132
+ // Instantiate the Dismiss object.
133
+ $this->dismiss = new Dismiss( $this->id, $this->options['option_prefix'], $this->options['scope'] );
134
+ }
135
+
136
+ /**
137
+ * Prints the notice.
138
+ *
139
+ * @access public
140
+ * @since 1.0
141
+ * @return void
142
+ */
143
+ public function the_notice() {
144
+
145
+ // Early exit if we don't want to show this notice.
146
+ if ( ! $this->show() ) {
147
+ return;
148
+ }
149
+
150
+ $html = $this->get_title();
151
+ $html .= $this->get_message();
152
+
153
+ // Print the notice.
154
+ printf(
155
+ '<div id="%1$s" class="%2$s">%3$s</div>',
156
+ 'pressmodo-notice-' . esc_attr( $this->id ), // The ID.
157
+ esc_attr( $this->get_classes() ), // The classes.
158
+ $html // The HTML.
159
+ );
160
+ }
161
+
162
+ /**
163
+ * Determine if the notice should be shown or not.
164
+ *
165
+ * @access public
166
+ * @since 1.0
167
+ * @return bool
168
+ */
169
+ public function show() {
170
+
171
+ // Don't show if the user doesn't have the required capability.
172
+ if ( ! current_user_can( $this->options['capability'] ) ) {
173
+ return false;
174
+ }
175
+
176
+ // Don't show if we're not on the right screen.
177
+ if ( ! $this->is_screen() ) {
178
+ return false;
179
+ }
180
+
181
+ // Don't show if notice has been dismissed.
182
+ if ( $this->dismiss->is_dismissed() ) {
183
+ return false;
184
+ }
185
+
186
+ return true;
187
+ }
188
+
189
+ /**
190
+ * Get the notice classes.
191
+ *
192
+ * @access public
193
+ * @since 1.0
194
+ * @return string
195
+ */
196
+ public function get_classes() {
197
+ $classes = array(
198
+ 'notice',
199
+ 'is-dismissible',
200
+ );
201
+
202
+ // Make sure the defined type is allowed.
203
+ $this->options['type'] = in_array( $this->options['type'], $this->allowed_types, true ) ? $this->options['type'] : 'info';
204
+
205
+ // Add the class for notice-type.
206
+ $classes[] = 'notice-' . $this->options['type'];
207
+
208
+ // Do we want alt styles?
209
+ if ( $this->options['alt_style'] ) {
210
+ $classes[] = 'notice-alt';
211
+ }
212
+
213
+ if ( ! $this->options['dismissible'] ) {
214
+ if ( ( $key = array_search( 'is-dismissible', $classes, true ) ) !== false ) {
215
+ unset( $classes[ $key ] );
216
+ }
217
+ }
218
+
219
+ // Combine classes to a string.
220
+ return implode( ' ', $classes );
221
+ }
222
+
223
+ /**
224
+ * Returns the title.
225
+ *
226
+ * @access public
227
+ * @since 1.0
228
+ * @return string
229
+ */
230
+ public function get_title() {
231
+
232
+ // Sanity check: Early exit if no title is defined.
233
+ if ( ! $this->title ) {
234
+ return '';
235
+ }
236
+
237
+ return sprintf(
238
+ '<h2 class="notice-title">%s</h2>',
239
+ wp_strip_all_tags( $this->title )
240
+ );
241
+ }
242
+
243
+ /**
244
+ * Returns the message.
245
+ *
246
+ * @access public
247
+ * @since 1.0
248
+ * @return string
249
+ */
250
+ public function get_message() {
251
+ return wpautop( wp_kses_post( $this->message ) );
252
+ }
253
+
254
+ /**
255
+ * Evaluate if we're on the right place depending on the "screens" argument.
256
+ *
257
+ * @access private
258
+ * @since 1.0
259
+ * @return bool
260
+ */
261
+ private function is_screen() {
262
+
263
+ // If screen is empty we want this shown on all screens.
264
+ if ( ! $this->options['screens'] || empty( $this->options['screens'] ) ) {
265
+ return true;
266
+ }
267
+
268
+ // Make sure the get_current_screen function exists.
269
+ if ( ! function_exists( 'get_current_screen' ) ) {
270
+ require_once ABSPATH . 'wp-admin/includes/screen.php';
271
+ }
272
+
273
+ // Check if we're on one of the defined screens.
274
+ return ( in_array( get_current_screen()->id, $this->options['screens'], true ) );
275
+ }
276
+ }
V5/Notice/Notices.php ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php // phpcs:ignore WordPress.Files.FileName
2
+ /**
3
+ * Admin-Notices class.
4
+ *
5
+ * Handles creating Notices and printing them.
6
+ *
7
+ * @package pressmodo/wp-admin-notices
8
+ * @author WPTRT <themes@wordpress.org>
9
+ * @author Pressmodo <hello@pressmodo.com>
10
+ * @copyright 2019 WPTRT
11
+ * @copyright 2020 Sematico LTD
12
+ * @license https://www.gnu.org/licenses/gpl-3.0.html GPL-3.0-or-later
13
+ * @link https://github.com/pressmodo/wp-admin-notices
14
+ */
15
+
16
+ namespace CTXFeed\V5\Notice;
17
+
18
+ /**
19
+ * The Admin_Notice class, responsible for creating admin notices.
20
+ *
21
+ * Each notice is a new instance of the object.
22
+ *
23
+ * @since 1.0.0
24
+ */
25
+ class Notices {
26
+
27
+ /**
28
+ * An array of notices.
29
+ *
30
+ * @access private
31
+ * @since 1.0
32
+ * @var array
33
+ */
34
+ private $notices = array();
35
+
36
+ /**
37
+ * Adds actions for the notices.
38
+ *
39
+ * @access public
40
+ * @since 1.0
41
+ * @return void
42
+ */
43
+ public function boot() {
44
+
45
+ // Add the notice.
46
+ add_action( 'admin_notices', array( $this, 'the_notices' ) );
47
+
48
+ // Print the script to the footer.
49
+ add_action( 'admin_footer', array( $this, 'print_scripts' ) );
50
+ }
51
+
52
+ /**
53
+ * Add a notice.
54
+ *
55
+ * @access public
56
+ * @since 1.0
57
+ * @param string $id A unique ID for this notice. Can contain lowercase characters and underscores.
58
+ * @param string $title The title for our notice.
59
+ * @param string $message The message for our notice.
60
+ * @param array $options An array of additional options to change the defaults for this notice.
61
+ * See Notice::__constructor() for details.
62
+ * @return void
63
+ */
64
+ public function add( $id, $title, $message, $options = array() ) {
65
+ $this->notices[ $id ] = new Notice( $id, $title, $message, $options );
66
+ }
67
+
68
+ /**
69
+ * Remove a notice.
70
+ *
71
+ * @access public
72
+ * @since 1.0
73
+ * @param string $id The unique ID of the notice we want to remove.
74
+ * @return void
75
+ */
76
+ public function remove( $id ) {
77
+ unset( $this->notices[ $id ] );
78
+ }
79
+
80
+ /**
81
+ * Get a single notice.
82
+ *
83
+ * @access public
84
+ * @since 1.0
85
+ * @param string $id The unique ID of the notice we want to retrieve.
86
+ * @return Notice|null
87
+ */
88
+ public function get( $id ) {
89
+ if ( isset( $this->notices[ $id ] ) ) {
90
+ return $this->notices[ $id ];
91
+ }
92
+
93
+ return null;
94
+ }
95
+
96
+ /**
97
+ * Get all notices.
98
+ *
99
+ * @access public
100
+ * @since 1.0
101
+ * @return array
102
+ */
103
+ public function get_all() {
104
+ return $this->notices;
105
+ }
106
+
107
+ /**
108
+ * Prints the notice.
109
+ *
110
+ * @access public
111
+ * @since 1.0
112
+ * @return void
113
+ */
114
+ public function the_notices() {
115
+ $notices = $this->get_all();
116
+
117
+ foreach ( $notices as $notice ) {
118
+ $notice->the_notice();
119
+ }
120
+ }
121
+
122
+ /**
123
+ * Prints scripts for the notices.
124
+ *
125
+ * @access public
126
+ * @since 1.0
127
+ * @return void
128
+ */
129
+ public function print_scripts() {
130
+ $notices = $this->get_all();
131
+
132
+ foreach ( $notices as $notice ) {
133
+ if ( $notice->show() ) {
134
+ $notice->dismiss->print_script();
135
+ }
136
+ }
137
+ }
138
+ }
V5/Output/FormatOutput.php ADDED
@@ -0,0 +1,413 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Output;
3
+ use CTXFeed\V5\Utility\Config;
4
+ use CTXFeed\V5\Helper\CommonHelper;
5
+ use CTXFeed\V5\Helper\ProductHelper;
6
+
7
+ class FormatOutput {
8
+ private $product;
9
+ /**
10
+ * @var Config $config
11
+ */
12
+ private $config;
13
+ private $attribute;
14
+
15
+ public function __construct( $product, $config, $attribute ) {
16
+ $this->product = $product;
17
+ $this->config = $config;
18
+ $this->attribute = $attribute;
19
+ }
20
+
21
+ public function get_output( $output, $outputTypes ) {
22
+ if ( ! empty( $outputTypes ) && is_array( $outputTypes ) ) {
23
+
24
+ // Format Output According to output type
25
+ if ( in_array( 2, $outputTypes, true ) ) { // Strip Tags
26
+ $output = woo_feed_strip_all_tags( html_entity_decode( $output ) );
27
+ }
28
+
29
+ if ( in_array( 4, $outputTypes, true ) ) { // htmlentities
30
+ $output = htmlentities( $output, ENT_QUOTES, 'UTF-8' );
31
+ }
32
+
33
+ if ( in_array( 5, $outputTypes, true ) ) { // Integer
34
+ $output = (int) $output;
35
+ }
36
+
37
+ if ( in_array( 6, $outputTypes, true ) ) { // Format Price
38
+ if ( ! empty( $output ) && $output > 0 ) {
39
+ $decimals = $this->config->get_price_format()['decimals'];
40
+ $decimal_separator = $this->config->get_price_format()['decimal_separator'];
41
+ $thousand_separator = $this->config->get_price_format()['thousand_separator'];
42
+ $output = (float) $output;
43
+
44
+ // TODO: Remove this and make a hook.
45
+ if ( "idealo" === $this->config->get_feed_template() ) {
46
+ $output = number_format( $output, 2, '.', '' );
47
+ } else {
48
+ $output = number_format( $output, $decimals, wp_specialchars_decode( wp_unslash( $decimal_separator ) ), wp_specialchars_decode( wp_unslash( $thousand_separator ) ) );
49
+ }
50
+ }
51
+ }
52
+
53
+ if ( ! empty( $output ) && $output > 0 && in_array( 7, $outputTypes, true ) ) { // Rounded Price
54
+ $output = round( $output );
55
+ $output = number_format( $output, 2, '.', '' );
56
+ }
57
+
58
+ if ( in_array( 8, $outputTypes, true ) ) { // Delete Space
59
+ $output = htmlentities( $output, null, 'utf-8' );
60
+ $output = str_replace( "&nbsp;", " ", $output );
61
+ $output = html_entity_decode( $output );
62
+ $output = preg_replace( "/\\s+/", ' ', $output );
63
+ }
64
+
65
+ if ( in_array( 10, $outputTypes, true ) ) { // Remove Invalid Character
66
+ $output = woo_feed_stripInvalidXml( $output );
67
+ }
68
+
69
+ if ( in_array( 11, $outputTypes, true ) ) { // Remove ShortCodes
70
+ $output = CommonHelper::remove_shortcodes( $output );
71
+ }
72
+
73
+ if ( in_array( 12, $outputTypes, true ) ) {
74
+ $output = ucwords( mb_strtolower( $output ) );
75
+ }
76
+
77
+ if ( in_array( 13, $outputTypes, true ) ) {
78
+ $output = ucfirst( mb_strtolower( $output ) );
79
+ }
80
+
81
+ if ( in_array( 14, $outputTypes, true ) ) {
82
+ $output = mb_strtoupper( strtolower( $output ) );
83
+ }
84
+
85
+ if ( in_array( 15, $outputTypes, true ) ) {
86
+ $output = mb_strtolower( $output );
87
+ }
88
+
89
+ if ( in_array( 16, $outputTypes, true ) && strpos( $output, 'http' ) === 0 ) {
90
+ $output = str_replace( 'http://', 'https://', $output );
91
+ }
92
+
93
+ if ( in_array( 17, $outputTypes, true ) && strpos( $output, 'http' ) === 0 ) {
94
+ $output = str_replace( 'https://', 'http://', $output );
95
+ }
96
+
97
+ if ( in_array( 18, $outputTypes, true ) ) { // only parent
98
+ $output = $this->get_only_parent( $output );
99
+ }
100
+
101
+ if ( in_array( 19, $outputTypes, true ) ) { // child if parent empty
102
+ $output = $this->get_parent( $output );
103
+ }
104
+
105
+ if ( in_array( 20, $outputTypes, true ) ) { // parent if child empty
106
+ $output = $this->get_parent_if_empty( $output );
107
+ }
108
+
109
+ if ( 'xml' === $this->config->get_feed_file_type() && in_array( 9, $outputTypes, true ) ) { // Add CDATA
110
+ $output = '<![CDATA[' . $output . ']]>';
111
+ }
112
+
113
+ if ( in_array( 23, $outputTypes, true ) || in_array( 24, $outputTypes, true ) ) { // parent lang if child empty
114
+ $id = $this->product->get_id();
115
+
116
+
117
+ //check if the format type is `parent` or `parent_lang_if_empty`
118
+ if ( in_array( 23, $outputTypes, true ) ) {
119
+ $force_parent = true;
120
+ } elseif ( in_array( 24, $outputTypes, true ) ) {
121
+ $force_parent = empty( $output );
122
+ }
123
+
124
+ /**
125
+ * when format type is `parent` then force getting parent value
126
+ * when format type is `parent_lang_if_empty` then get the parent value on current empty value
127
+ */
128
+ if ( $force_parent ) {
129
+ //when wpml plugin is activated, get parent language post id
130
+ if ( class_exists( 'SitePress', false ) ) {
131
+ $parent_id = woo_feed_wpml_get_original_post_id( $id );
132
+
133
+ //remove wpml term filter
134
+ global $sitepress;
135
+ remove_filter( 'get_term', array( $sitepress, 'get_term_adjust_id' ), 1 );
136
+ remove_filter( 'get_terms_args', array( $sitepress, 'get_terms_args_filter' ), 1 );
137
+ }
138
+
139
+ // when polylang plugin is activated, get parent language post id
140
+ if ( defined( 'POLYLANG_BASENAME' ) || function_exists( 'PLL' ) ) {
141
+ $parent_id = woo_feed_pll_get_original_post_id( $id );
142
+ }
143
+
144
+ //get attribute value of parent language post id
145
+ if ( ! empty( $parent_id ) ) {
146
+ $parentProduct = wc_get_product( $parent_id );
147
+ $output = ProductHelper::getAttributeValueByType( $this->attribute, $parentProduct, $this->config );
148
+ }
149
+
150
+ }
151
+ }
152
+
153
+ }
154
+
155
+ return $output;
156
+ }
157
+
158
+ /**
159
+ * Process commands.
160
+ *
161
+ * @param $output
162
+ * @param $commands
163
+ *
164
+ * @return array|false|mixed|string|string[]|null
165
+ */
166
+ public function process_command( $output, $commands ) {
167
+ // Custom Template 2 return commands as array
168
+ if ( ! is_array( $commands ) ) {
169
+ $commands = $this->get_functions( $commands );
170
+ }
171
+
172
+ foreach ( $commands as $command ) {
173
+ if ( ! empty( $command ) ) {
174
+ $function = $this->get_function( $command );
175
+ switch ( $function ) {
176
+ case 'substr':
177
+ $args = preg_split( '/\s+/', $command );
178
+ $output = woo_feed_strip_all_tags( $output );
179
+ $output = substr( $output, $args[1], $args[2] );
180
+ break;
181
+ case 'strip_tags':
182
+ $output = woo_feed_strip_all_tags( $output );
183
+ break;
184
+ case 'htmlentities':
185
+ $output = htmlentities( $output );
186
+ break;
187
+ case 'clear':
188
+ $output = woo_feed_stripInvalidXml( $output );
189
+ break;
190
+ case 'ucwords':
191
+ $output = ucwords( mb_strtolower( $output ) );
192
+ break;
193
+ case 'ucfirst':
194
+ $output = ucfirst( mb_strtolower( $output ) );
195
+ break;
196
+ case 'strtoupper':
197
+ $output = mb_strtoupper( $output );
198
+ break;
199
+ case 'strtolower':
200
+ $output = mb_strtolower( $output );
201
+ break;
202
+ case 'strip_shortcodes':
203
+ $output = CommonHelper::remove_shortcodes( $output );
204
+ break;
205
+ case 'number_format':
206
+ $output = $this->format_number( $output, $command );
207
+ break;
208
+ case 'urltounsecure':
209
+ if ( strpos( $output, 'http' ) === 0 ) {
210
+ $output = str_replace( 'https://', 'http://', $output );
211
+ }
212
+ break;
213
+ case 'urltosecure':
214
+ if ( strpos( $output, 'http' ) === 0 ) {
215
+ $output = str_replace( 'http://', 'https://', $output );
216
+ }
217
+ break;
218
+ case 'str_replace':
219
+ $output = $this->replace_string( $output, $command );
220
+ break;
221
+ case 'preg_replace':
222
+ $output = $this->replace_string( $output, $command, 'preg_replace' );
223
+ break;
224
+ case 'only_parent';
225
+ $output = $this->get_only_parent( $output );
226
+ break;
227
+ case 'parent_if_empty';
228
+ $output = $this->get_parent_if_empty( $output );
229
+ break;
230
+ case 'parent';
231
+ $output = $this->get_parent( $output );
232
+ break;
233
+ default:
234
+ break;
235
+ }
236
+ }
237
+ }
238
+
239
+ return $output;
240
+ }
241
+
242
+ /**
243
+ * Remove shortcodes from string.
244
+ *
245
+ * @param string $string String to remove shortcodes from.
246
+ *
247
+ * @return array
248
+ */
249
+
250
+ private function get_functions( $string ) {
251
+ $functions = explode( ',', $string );
252
+ $funArray = array();
253
+ if ( $functions ) {
254
+ foreach ( $functions as $value ) {
255
+ if ( ! empty( $value ) ) {
256
+ $funArray['formatter'][] = woo_feed_get_string_between( $value, '[', ']' );
257
+ }
258
+ }
259
+ }
260
+
261
+ return $funArray;
262
+ }
263
+
264
+ /**
265
+ * php function from string.
266
+ *
267
+ * @param string $string String to remove shortcodes from.
268
+ *
269
+ * @return string
270
+ */
271
+ private function get_function( $string ) {
272
+ $function = explode( ' ', $string );
273
+
274
+ return $function[0];
275
+ }
276
+
277
+ /**
278
+ * Number Format Output.
279
+ *
280
+ * @param string $output
281
+ * @param string $command
282
+ *
283
+ * @return string
284
+ */
285
+ public function format_number( $output, $command ) {
286
+ if ( ! empty( $output ) ) {
287
+ $args = explode( ' ', $command, 3 );
288
+ $arguments = array( 0 => '' );
289
+
290
+ if ( isset( $args[1] ) ) {
291
+ $arguments[1] = $args[1];
292
+ }
293
+
294
+ if ( isset( $args[2] ) && 'point' === $args[2] ) {
295
+ $arguments[2] = '.';
296
+ } elseif ( isset( $args[2] ) && 'comma' === $args[2] ) {
297
+ $arguments[2] = ',';
298
+ } elseif ( isset( $args[2] ) && 'space' === $args[2] ) {
299
+ $arguments[2] = ' ';
300
+ }
301
+
302
+ if ( isset( $args[3] ) && 'point' === $args[3] ) {
303
+ $arguments[3] = '.';
304
+ } elseif ( isset( $args[3] ) && 'comma' === $args[3] ) {
305
+ $arguments[3] = ',';
306
+ } elseif ( isset( $args[3] ) && 'space' === $args[3] ) {
307
+ $arguments[3] = ' ';
308
+ } else {
309
+ $arguments[3] = '';
310
+ }
311
+
312
+ if ( isset( $arguments[1], $arguments[2], $arguments[3] ) ) {
313
+ $output = number_format( $output, $arguments[1], $arguments[2], $arguments[3] );
314
+ } elseif ( isset( $arguments[1], $arguments[2] ) ) {
315
+ $output = number_format( $output, $arguments[1], $arguments[2], $arguments[3] );
316
+ } elseif ( isset( $arguments[1] ) ) {
317
+ $output = number_format( $output, $arguments[1] );
318
+ } else {
319
+ $output = number_format( $output );
320
+ }
321
+ }
322
+
323
+ return $output;
324
+ }
325
+
326
+ /**
327
+ * Remove shortcodes from string.
328
+ *
329
+ * @param string $output
330
+ * @param string $command
331
+ *
332
+ * @return string
333
+ */
334
+ private function replace_string( $output, $command, $type = 'str_replace' ) {
335
+ $args = explode( '=>', $command, 3 );
336
+ if ( array_key_exists( 1, $args ) && array_key_exists( 2, $args ) ) {
337
+
338
+ list( $argument1, $argument2 ) = array_map( 'trim', array( $args[1], $args[2] ) );
339
+
340
+ if ( false !== strpos( $args[1], 'comma' ) ) {
341
+ $argument1 = str_replace( 'comma', ',', $args[1] );
342
+ }
343
+
344
+ if ( false !== strpos( $args[2], 'comma' ) ) {
345
+ $argument2 = str_replace( 'comma', ',', $args[2] );
346
+ }
347
+ if ( 'str_replace' === $type ) {
348
+ $output = str_replace( (string) $argument1, (string) $argument2, $output );
349
+ } else {
350
+ $output = preg_replace( wp_unslash( $argument1 ), wp_unslash( $argument2 ), $output );
351
+ }
352
+ }
353
+
354
+ return $output;
355
+ }
356
+
357
+ /**
358
+ * Get Variable Product Value.
359
+ *
360
+ * @param string $output
361
+ *
362
+ * @return string
363
+ */
364
+ private function get_only_parent( $output ) {
365
+ if ( $this->product->is_type( 'variation' ) ) {
366
+ $id = $this->product->get_parent_id();
367
+ $parent = wc_get_product( $id );
368
+ $output = ProductHelper::getAttributeValueByType( $this->attribute, $parent, $this->config );
369
+ }
370
+
371
+ return $output;
372
+ }
373
+
374
+ /**
375
+ * Get variation value if Variable Product Value empty.
376
+ *
377
+ * @param string $output
378
+ *
379
+ * @return string
380
+ */
381
+ private function get_parent( $output ) {
382
+ if ( $this->product->is_type( 'variation' ) ) {
383
+ $id = $this->product->get_parent_id();
384
+ $parentProduct = wc_get_product( $id );
385
+ $output = ProductHelper::getAttributeValueByType( $this->attribute, $parentProduct, $this->config );
386
+ if ( empty( $output ) ) {
387
+ $output = ProductHelper::getAttributeValueByType( $this->attribute, $this->product, $this->config );
388
+ }
389
+ }
390
+
391
+ return $output;
392
+ }
393
+
394
+ /**
395
+ * Get Variable Product Value if variation value empty.
396
+ *
397
+ * @param string $output
398
+ *
399
+ * @return string
400
+ */
401
+ private function get_parent_if_empty( $output ) {
402
+ if ( $this->product->is_type( 'variation' ) ) {
403
+ $output = ProductHelper::getAttributeValueByType( $this->attribute, $this->product, $this->config );
404
+ if ( empty( $output ) ) {
405
+ $id = $this->product->get_parent_id();
406
+ $parent = wc_get_product( $id );
407
+ $output = ProductHelper::getAttributeValueByType( $this->attribute, $parent, $this->config );
408
+ }
409
+ }
410
+
411
+ return $output;
412
+ }
413
+ }
V5/Override/Advance.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Override;
4
+
5
+ use CTXFeed\V5\Utility\Config;
6
+
7
+ /**
8
+ * Class Advance
9
+ *
10
+ * @package CTXFeed\V5\Override
11
+ * @subpackage CTXFeed\V5\Override
12
+ */
13
+ class Advance {
14
+ public function __construct() {
15
+ add_filter( 'woo_feed_filter_product_attribute', [ $this, 'get_product_variation_attribute' ], 10, 4 );
16
+ }
17
+
18
+ /**
19
+ * Get Variation attribute values for only in stock variations.
20
+ *
21
+ * @param $value
22
+ * @param $attr
23
+ * @param \WC_Product $product
24
+ * @param \CTXFeed\V5\Utility\Config $config
25
+ *
26
+ * @return mixed|string
27
+ */
28
+ public function get_product_variation_attribute( $value, $attr, $product, $config ) {
29
+ //TODO: Make an Option on Filter tab and apply the logic here.
30
+ // Also add the option to settings class
31
+
32
+ if ( $config instanceof Config ) {
33
+ $outOfStockEnabled = $config->remove_outofstock_product();
34
+ } else {
35
+ $outOfStockEnabled = $config['is_outOfStock'];
36
+ }
37
+
38
+ if ( $outOfStockEnabled && $product->is_type( 'variable' ) && $product->has_child() ) {
39
+ $attr = "pa_" . $attr;
40
+ $child_ids = $product->get_children();
41
+ $variationAttributes = array_keys( $product->get_variation_attributes() );
42
+
43
+ if ( ! in_array( $attr, $variationAttributes, true ) ) {
44
+ return $value;
45
+ }
46
+
47
+ $newValue = []; //reset the value to concat by child values
48
+ foreach ( $child_ids as $id ) {
49
+ $child_product = wc_get_product( $id );
50
+ $attr_value = $child_product->get_attribute( $attr );
51
+
52
+ if ( ! empty( $attr_value ) && ( $child_product->is_in_stock() || ( $child_product->managing_stock() && 0 < $child_product->get_stock_quantity() ) ) ) {
53
+ $newValue [] = $attr_value;
54
+ }
55
+ }
56
+ $value = ! empty( $newValue ) ? implode( ', ', $newValue ) : $value;
57
+ }
58
+
59
+ return $value;
60
+ }
61
+ }
V5/Override/BestpriceTemplate.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Override;
4
+
5
+
6
+ /**
7
+ * Class BestpriceTemplate
8
+ *
9
+ * @package CTXFeed
10
+ * @subpackage CTXFeed\V5\Override
11
+ */
12
+ class BestpriceTemplate {
13
+
14
+ }
V5/Override/Common.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Override;
4
+
5
+
6
+ /**
7
+ * Class Common
8
+ *
9
+ * @package CTXFeed\V5\Override
10
+ * @subpackage CTXFeed\V5\Override
11
+ */
12
+ class Common {
13
+ public function __construct( ) {
14
+
15
+ }
16
+ }
V5/Override/DaisyconTemplate.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Override;
4
+
5
+
6
+ /**
7
+ * Class DaisyconTemplate
8
+ *
9
+ * @package CTXFeed\V5\Override
10
+ * @subpackage CTXFeed\V5\Override
11
+ */
12
+ class DaisyconTemplate {
13
+
14
+ }
V5/Override/FacebookTemplate.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Override;
4
+
5
+
6
+ /**
7
+ * Class FacebookTemplate
8
+ *
9
+ * @package CTXFeed\V5\Override
10
+ * @subpackage CTXFeed\V5\Override
11
+ */
12
+ class FacebookTemplate {
13
+
14
+ }
V5/Override/GoogleTemplate.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Override;
4
+ class GoogleTemplate {
5
+ public function __construct() {
6
+ add_filter( 'woo_feed_get_google_color_attribute', [
7
+ $this,
8
+ 'woo_feed_get_google_color_size_attribute_callback'
9
+ ], 10, 5 );
10
+
11
+ add_filter( 'woo_feed_get_google_size_attribute', [
12
+ $this,
13
+ 'woo_feed_get_google_color_size_attribute_callback'
14
+ ], 10, 5 );
15
+
16
+ add_filter( 'woo_feed_get_google_attribute', [
17
+ $this,
18
+ 'woo_feed_get_google_attribute_callback'
19
+ ], 10, 5 );
20
+ }
21
+
22
+ public function woo_feed_get_google_color_size_attribute_callback( $output ) {
23
+ return str_replace( [ ' ', ',' ], [ '', '/' ], $output );
24
+ }
25
+
26
+ public function woo_feed_get_google_attribute_callback( $output, $product, $config, $product_attribute, $merchant_attribute ) {
27
+ $weightAttributes = [ 'product_weight', 'shipping_weight' ];
28
+ $dimensionAttributes = [
29
+ 'product_length',
30
+ 'product_width',
31
+ 'product_height',
32
+ 'shipping_length',
33
+ 'shipping_width',
34
+ 'shipping_height'
35
+ ];
36
+
37
+ $wc_unit = '';
38
+ $override = false;
39
+ if ( in_array( $product_attribute, $weightAttributes, true ) ) {
40
+ $override = true;
41
+ $wc_unit = ' ' . get_option( 'woocommerce_weight_unit' );
42
+ }
43
+
44
+ if ( in_array( $product_attribute, $dimensionAttributes, true ) ) {
45
+ $override = true;
46
+ $wc_unit = ' ' . get_option( 'woocommerce_dimension_unit' );
47
+ }
48
+
49
+ if ( ! $override ) {
50
+ return $output;
51
+ }
52
+
53
+ $attributes = ( $config->attributes ) ?: false;
54
+
55
+ if ( ! $attributes ) {
56
+ return $output;
57
+ }
58
+
59
+ $key = array_search( $product_attribute, $attributes, true );
60
+ if ( isset( $config->suffix ) && ! empty( $key ) && array_key_exists( $key, $config->suffix ) ) {
61
+ $unit = $config->suffix[ $key ];
62
+
63
+ if ( empty( $unit ) && ! empty( $output ) ) {
64
+ $output .= $wc_unit;
65
+ }
66
+ }
67
+
68
+
69
+ return $output;
70
+ }
71
+ }
72
+
V5/Override/OverrideFactory.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Override;
4
+
5
+
6
+ use CTXFeed\V5\Compatibility\ExcludeCaching;
7
+
8
+ /**
9
+ * Class OverrideFactory
10
+ *
11
+ * @package CTXFeed
12
+ * @subpackage CTXFeed\V5\Override
13
+ */
14
+ class OverrideFactory {
15
+
16
+ public static function TemplateOverride( $config ) {
17
+ $class = "\CTXFeed\V5\Override\\" . ucfirst( $config->provider ) . 'Template';
18
+ if ( class_exists( $class ) ) {
19
+ return new $class();
20
+ }
21
+
22
+ return false;
23
+ }
24
+
25
+ public static function excludeCache() {
26
+ return new ExcludeCaching();
27
+ }
28
+
29
+ public static function Common() {
30
+ return new Common();
31
+ }
32
+
33
+ public static function Advance() {
34
+ return new Advance();
35
+ }
36
+
37
+ }
V5/Override/PinterestTemplate.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Override;
4
+
5
+
6
+ /**
7
+ * Class PinterestTemplate
8
+ *
9
+ * @package CTXFeed
10
+ * @subpackage CTXFeed\V5\Override
11
+ */
12
+ class PinterestTemplate {
13
+ public function __construct() {
14
+ add_filter( 'woo_feed_get_pinterest_color_attribute', [
15
+ $this,
16
+ 'woo_feed_get_pinterest_color_size_attribute_callback'
17
+ ] );
18
+ add_filter( 'woo_feed_get_pinterest_size_attribute', [
19
+ $this,
20
+ 'woo_feed_get_pinterest_color_size_attribute_callback'
21
+ ] );
22
+ }
23
+
24
+ public function woo_feed_get_pinterest_color_size_attribute_callback( $output ) {
25
+ return str_replace( [ ' ' ], [ '' ], $output );
26
+ }
27
+ }
28
+
V5/Override/Pinterest_rssTemplate.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Override;
4
+
5
+
6
+ /**
7
+ * Class Pinterest_rssTemplate
8
+ *
9
+ * @package CTXFeed\V5\Override
10
+ * @subpackage CTXFeed\V5\Override
11
+ */
12
+ class Pinterest_rssTemplate {
13
+ public function __construct() {
14
+ add_filter( 'ctx_xml_header_template_variables', [
15
+ $this,
16
+ 'ctx_pinterest_rss_xml_header_template_variables_callback'
17
+ ] );
18
+
19
+ add_filter( 'woo_feed_get_pinterest_rss_pubDate_attribute', [
20
+ $this,
21
+ 'woo_feed_get_pinterest_rss_pubDate_attribute_callback'
22
+ ], 9, 3 );
23
+ }
24
+
25
+ public function ctx_pinterest_rss_xml_header_template_variables_callback( $variables ) {
26
+
27
+ $variables["{DateTimeNow}"] = date( 'r', strtotime( current_time( 'mysql' ) ) );
28
+
29
+ return $variables;
30
+ }
31
+
32
+ public function woo_feed_get_pinterest_rss_pubDate_attribute_callback( $output ) {
33
+ if ( ! empty( $output ) ) {
34
+ return date( 'r', strtotime( $output ) );
35
+ }
36
+
37
+ return $output;
38
+ }
39
+ }
V5/Override/PricerunnerTemplate.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Override;
4
+
5
+
6
+ /**
7
+ * Class PricerunnerTemplate
8
+ *
9
+ * @package CTXFeed\V5\Override
10
+ * @subpackage CTXFeed\V5\Override
11
+ */
12
+ class PricerunnerTemplate {
13
+
14
+ }
V5/Override/SpartooTemplate.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Override;
4
+
5
+
6
+ /**
7
+ * Class SpartooTemplate
8
+ *
9
+ * @package CTXFeed\V5\Override
10
+ * @subpackage CTXFeed\V5\Override
11
+ */
12
+ class SpartooTemplate {
13
+
14
+ }
V5/Override/TiktokTemplate.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Override;
4
+
5
+
6
+ /**
7
+ * Class Tiktok
8
+ *
9
+ * @package CTXFeed\V5\Override
10
+ * @subpackage CTXFeed\V5\Override
11
+ */
12
+ class TiktokTemplate {
13
+ public function __construct() {
14
+ add_filter( 'woo_feed_get_tiktok_color_attribute', [
15
+ $this,
16
+ 'woo_feed_get_tiktok_color_size_attribute_callback'
17
+ ] );
18
+ add_filter( 'woo_feed_get_tiktok_size_attribute', [
19
+ $this,
20
+ 'woo_feed_get_tiktok_color_size_attribute_callback'
21
+ ] );
22
+ add_filter( 'woo_feed_get_tiktok_shipping_weight_attribute', [
23
+ $this,
24
+ 'woo_feed_get_tiktok_shipping_weight_attribute_callback'
25
+ ] );
26
+ }
27
+
28
+ public function woo_feed_get_tiktok_color_size_attribute_callback( $output ) {
29
+ return str_replace( [ ' ' ], [ '' ], $output );
30
+ }
31
+
32
+ public function woo_feed_get_tiktok_shipping_weight_attribute_callback( $output, $product, $config, $product_attribute ) {
33
+
34
+ $wc_unit = ' ' . get_option( 'woocommerce_weight_unit' );
35
+ $attributes = ( $config->attributes ) ?: false;
36
+
37
+ if ( ! $attributes ) {
38
+ return $output;
39
+ }
40
+
41
+ $key = array_search( $product_attribute, $attributes, true );
42
+ if ( isset( $config->suffix ) && ! empty( $key ) && array_key_exists( $key, $config->suffix ) ) {
43
+ $unit = $config->suffix[ $key ];
44
+
45
+ if ( empty( $unit ) && ! empty( $output ) ) {
46
+ $output .= $wc_unit;
47
+ }
48
+ }
49
+
50
+ return $output;
51
+ }
52
+ }
V5/Override/TrovaprezziTemplate.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Override;
4
+
5
+
6
+ /**
7
+ * Class TrovaprezziTemplate
8
+ *
9
+ * @package CTXFeed\V5\Override
10
+ * @subpackage CTXFeed\V5\Override
11
+ */
12
+ class TrovaprezziTemplate {
13
+
14
+ }
V5/Price/GroupProductPrice.php ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Price;
3
+ use CTXFeed\V5\Common\Config;
4
+ use WC_Product;
5
+
6
+ class GroupProductPrice implements PriceInterface {
7
+
8
+ private $product;
9
+ private $config;
10
+
11
+ /**
12
+ * @param WC_Product $product
13
+ * @param Config $config
14
+ */
15
+ public function __construct( $product, $config ) {
16
+
17
+ $this->product = $product;
18
+ $this->config = $config;
19
+ }
20
+
21
+ /**
22
+ * Get Grouped Product Price.
23
+ *
24
+ * @param $price_type
25
+ * @param $tax
26
+ *
27
+ * @return int|string
28
+ */
29
+ protected function getGroupProductPrice( $price_type, $tax = false ) {
30
+ $groupProductIds = $this->product->get_children();
31
+ $price = 0;
32
+ if ( ! empty( $groupProductIds ) ) {
33
+ foreach ( $groupProductIds as $id ) {
34
+ $product = wc_get_product( $id );
35
+ if ( ! is_object( $product ) ) {
36
+ continue; // make sure that the product exists.
37
+ }
38
+ switch ( $price_type ) {
39
+ case 'regular_price':
40
+ $get_price = $this->product->get_regular_price();
41
+ break;
42
+ case 'sale_price':
43
+ $get_price = $this->product->get_sale_price();
44
+ break;
45
+ default:
46
+ $get_price = $this->product->get_price();
47
+ break;
48
+ }
49
+ $get_price = $this->convert_currency( $get_price, $price_type );
50
+ $get_price = $this->add_tax( $get_price, $tax );
51
+ if ( ! empty( $get_price ) ) {
52
+ $price += $get_price;
53
+ }
54
+ }
55
+ }
56
+
57
+ return $price > 0 ? $price : '';
58
+ }
59
+
60
+ /**
61
+ * Get Regular Price.
62
+ *
63
+ * @param bool $tax
64
+ *
65
+ * @return int|string
66
+ */
67
+ public function regular_price( $tax = false ) {
68
+ return $this->getGroupProductPrice( 'regular_price', $tax );
69
+ }
70
+
71
+ /**
72
+ * Get Price.
73
+ *
74
+ * @param bool $tax
75
+ *
76
+ * @return int|string
77
+ */
78
+ public function price( $tax = false ) {
79
+ return $this->getGroupProductPrice( 'price', $tax );
80
+ }
81
+
82
+ /**
83
+ * Get Sale Price.
84
+ *
85
+ * @param bool $tax
86
+ *
87
+ * @return int|string
88
+ */
89
+ public function sale_price( $tax = false ) {
90
+ return $this->getGroupProductPrice( 'sale_price', $tax );
91
+ }
92
+
93
+ /**
94
+ * Convert Currency.
95
+ *
96
+ * @param $price
97
+ * @param string $price_type price type (regular_price|price|sale_price)
98
+ *
99
+ * @return mixed|void
100
+ */
101
+ public function convert_currency( $price, $price_type ) {
102
+
103
+ return apply_filters( 'woo_feed_wcml_price',
104
+ $price, $this->product->get_id(), $this->config->get_feed_currency(), '_' . $price_type
105
+ );
106
+ }
107
+
108
+ /**
109
+ * Get Price with Tax.
110
+ *
111
+ * @return int
112
+ */
113
+ public function add_tax( $price, $tax = false ) {
114
+ if ( true === $tax ) {
115
+ return woo_feed_get_price_with_tax( $price, $this->product );
116
+ }
117
+
118
+ return $price;
119
+ }
120
+ }
V5/Price/IconicBundleProductPrice.php ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Price;
3
+ use CTXFeed\V5\Common\Config;
4
+ use WC_Product;
5
+
6
+ class IconicBundleProductPrice implements PriceInterface {
7
+
8
+ private $product;
9
+ private $config;
10
+ private $bundle;
11
+
12
+ /**
13
+ * @param WC_Product $product
14
+ * @param Config $config
15
+ */
16
+ public function __construct( $product, $config ) {
17
+
18
+ $this->product = $product;
19
+ $this->config = $config;
20
+
21
+ if ( class_exists( 'WC_Product_Bundled' ) ) {
22
+ $this->bundle = new WC_Product_Bundled( $this->product->get_id() );
23
+ }
24
+ }
25
+
26
+ /**
27
+ * Get Bundle Product Price.
28
+ *
29
+ * @param bool $tax
30
+ *
31
+ * @return int|string
32
+ */
33
+ public function bundle_price( $price_type = 'price', $tax = false ) {
34
+
35
+ if ( ! class_exists( 'WC_Product_Bundled' ) ) {
36
+ return $this->product->get_price();
37
+ }
38
+
39
+ $price = $this->product->get_price();
40
+
41
+ $price_display = ( ! is_null( $this->bundle->options['price_display'] ) ) ? $this->bundle->options['price_display'] : '';
42
+ $product_ids = $this->bundle->options['product_ids'];
43
+
44
+ //Set discount
45
+ $discount = 0;
46
+ if ( ! empty( $this->bundle->options['fixed_discount'] ) ) {
47
+ $discount = $this->bundle->options['fixed_discount'];
48
+ }
49
+
50
+ // Get price
51
+ if ( is_array( $product_ids ) ) {
52
+ $prices = [];
53
+ foreach ( $product_ids as $pid ) {
54
+ $product = wc_get_product( $pid );
55
+ switch ( $price_type ) {
56
+ case 'regular_price':
57
+ $prices[] = $product->get_regular_price();
58
+ break;
59
+ case 'sale_price':
60
+ $prices[] = $product->get_sale_price();
61
+ break;
62
+ default:
63
+ $prices[] = $product->get_price();
64
+ break;
65
+ }
66
+ }
67
+
68
+ if ( 'range' === $price_display ) {
69
+ $price = min( $prices );
70
+ } else {
71
+ $price = array_sum( $prices );
72
+ }
73
+ }
74
+
75
+ // Get sale price if discount enabled
76
+ if ( $discount && 'regular_price' !== $price_type ) {
77
+ $price -= $discount;
78
+ }
79
+
80
+ $price = $this->convert_currency( $price, $price_type );
81
+ $price = $this->add_tax( $price, false );
82
+
83
+ return $price > 0 ? $price : '';
84
+ }
85
+
86
+ /**
87
+ * Get Regular Price.
88
+ *
89
+ * @param bool $tax
90
+ *
91
+ * @return int|string
92
+ */
93
+ public function regular_price( $tax = false ) {
94
+ return $this->bundle_price( 'regular_price', $tax );
95
+ }
96
+
97
+ /**
98
+ * Get Price.
99
+ *
100
+ * @param bool $tax
101
+ *
102
+ * @return int|string
103
+ */
104
+ public function price( $tax = false ) {
105
+ return $this->bundle_price( 'price', $tax );
106
+ }
107
+
108
+ /**
109
+ * Get Sale Price.
110
+ *
111
+ * @param bool $tax
112
+ *
113
+ * @return int|string
114
+ */
115
+ public function sale_price( $tax = false ) {
116
+ return $this->bundle_price( 'sale_price', $tax );
117
+ }
118
+
119
+ /**
120
+ * Convert Currency.
121
+ *
122
+ * @param $price
123
+ * @param string $price_type price type (regular_price|price|sale_price)
124
+ *
125
+ * @return mixed|void
126
+ */
127
+ public function convert_currency( $price, $price_type ) {
128
+
129
+ return apply_filters( 'woo_feed_wcml_price',
130
+ $price, $this->product->get_id(), $this->config->get_feed_currency(), '_' . $price_type
131
+ );
132
+ }
133
+
134
+ /**
135
+ * Get Price with Tax.
136
+ *
137
+ * @return int
138
+ */
139
+ public function add_tax( $price, $tax = false ) {
140
+ if ( true === $tax ) {
141
+ return woo_feed_get_price_with_tax( $price, $this->product );
142
+ }
143
+
144
+ return $price;
145
+ }
146
+ }
V5/Price/PriceFactory.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Price;
3
+ use CTXFeed\V5\Utility\Config;
4
+ use WC_Product;
5
+
6
+ class PriceFactory {
7
+ /**
8
+ * @param WC_Product $product
9
+ * @param Config $config
10
+ * @return ProductPrice
11
+ */
12
+ public static function get( $product, $config ) {
13
+ if ( $product->is_type( 'variable' ) ) {
14
+ /**
15
+ * Variable Product does not have its price. So its depends on variations.
16
+ */
17
+ $class = new ProductPrice( new VariableProductPrice( $product, $config ) );
18
+ } elseif ( $product->is_type( 'grouped' ) ) {
19
+ /**
20
+ * Grouped Product does not have its price. So its depends on a group of simple Products.
21
+ */
22
+ $class = new ProductPrice( new GroupProductPrice( $product, $config ) );
23
+ } /**
24
+ * Plugin Name: WooCommerce Product Bundles.
25
+ * @link https://woocommerce.com/products/product-bundles
26
+ */
27
+ elseif ( class_exists( 'WC_Product_Bundle' ) && $product->is_type( 'bundle' ) ) {
28
+ $class = new ProductPrice( new WCBundleProductPrice( $product, $config ) );
29
+ } /**
30
+ * Plugin Name: WooCommerce Product Bundles.
31
+ * @link https://iconicwp.com/products/woocommerce-bundled-products/
32
+ */
33
+ elseif ( class_exists( 'WC_Product_Bundled' ) && $product->is_type( 'bundled' ) ) {
34
+ $class = new ProductPrice( new IconicBundleProductPrice( $product, $config ) );
35
+ } /**
36
+ * Plugin Name:
37
+ * @link
38
+ */
39
+ elseif ( class_exists( 'WC_Product_Composite' ) && $product->is_type( 'composite' ) ) {
40
+ $class = new ProductPrice( new WCCompositeProductPrice( $product, $config ) );
41
+ } /**
42
+ * Plugin Name: WooCommerce Composite Products.
43
+ * @link https://wordpress.org/plugins/wpc-composite-products/
44
+ */
45
+ elseif ( class_exists( 'WPCleverWooco' ) && $product->is_type( 'composite' ) ) {
46
+ $class = new ProductPrice( new WPCCompositeProductPrice( $product, $config ) );
47
+ } /**
48
+ * Plugin Name: WooCommerce Composite Products.
49
+ * @link https://woocommerce.com/products/composite-products/
50
+ */
51
+ elseif ( class_exists( 'WC_Composite_Products' ) && $product->is_type( 'composite' ) ) {
52
+ $class = new ProductPrice( new WCCompositeProductPrice( $product, $config ) );
53
+ } else {
54
+ /**
55
+ * Simple Product, External Product, Product Variation, YITH Composite etc.
56
+ * Note*: YITH does not auto select components. So no need to calculate component price.
57
+ */
58
+ $class = new ProductPrice( new SimpleProductPrice( $product, $config ) );
59
+ }
60
+
61
+ return $class;
62
+ }
63
+ }
V5/Price/PriceInterface.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Price;
3
+ interface PriceInterface {
4
+ public function __construct( $product, $config );
5
+
6
+ public function regular_price( $tax = false );
7
+
8
+ public function price( $tax = false );
9
+
10
+ public function sale_price( $tax = false );
11
+
12
+ public function convert_currency( $price, $price_type );
13
+
14
+ public function add_tax( $price );
15
+
16
+ }
17
+
18
+
19
+
V5/Price/ProductPrice.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Price;
4
+ class ProductPrice {
5
+ private $price;
6
+
7
+ public function __construct( PriceInterface $price ) {
8
+ $this->price = $price;
9
+ }
10
+
11
+ /**
12
+ * @param $tax
13
+ *
14
+ * @return string
15
+ */
16
+ public function regular_price( $tax = false ) {
17
+ $regular_price = $this->price->regular_price( $tax );
18
+ if ( $regular_price <= 0 ) {
19
+ return '';
20
+ }
21
+
22
+ return $regular_price;
23
+ }
24
+ /**
25
+ * @param $tax
26
+ *
27
+ * @return string
28
+ */
29
+ public function price( $tax = false ) {
30
+ $price = $this->price->price( $tax );
31
+ if ( $price <= 0 ) {
32
+ return '';
33
+ }
34
+
35
+ return $price;
36
+ }
37
+
38
+ /**
39
+ * @param $tax
40
+ *
41
+ * @return string
42
+ */
43
+ public function sale_price( $tax = false ) {
44
+ $sale_price = $this->price->sale_price( $tax );
45
+ if ( $sale_price <= 0 ) {
46
+ return '';
47
+ }
48
+
49
+ return $sale_price;
50
+ }
51
+ }
V5/Price/SimpleProductPrice.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Price;
3
+ use CTXFeed\V5\Utility\Config;
4
+ use WC_Product;
5
+
6
+ class SimpleProductPrice implements PriceInterface {
7
+
8
+ private $product;
9
+ private $config;
10
+
11
+ /**
12
+ * @param WC_Product $product
13
+ * @param Config $config
14
+ */
15
+ public function __construct( $product, $config ) {
16
+
17
+ $this->product = $product;
18
+ $this->config = $config;
19
+ }
20
+
21
+ /**
22
+ * Get Regular Price.
23
+ *
24
+ * @param bool $tax
25
+ *
26
+ * @return float|int
27
+ */
28
+ public function regular_price( $tax = false ) {
29
+ $regular_price = $this->product->get_regular_price();
30
+ $regular_price = $this->convert_currency( $regular_price, 'regular_price' );
31
+ return $this->add_tax( $regular_price, $tax );
32
+ }
33
+
34
+ /**
35
+ * Get Price.
36
+ *
37
+ * @param bool $tax
38
+ *
39
+ * @return int|float
40
+ */
41
+ public function price( $tax = false ) {
42
+ $price = $this->product->get_price();
43
+ $price = $this->convert_currency( $price, 'price' );
44
+ return $this->add_tax( $price, $tax );
45
+ }
46
+
47
+ /**
48
+ * Get Sale Price.
49
+ *
50
+ * @param bool $tax
51
+ *
52
+ * @return int|float
53
+ */
54
+ public function sale_price( $tax = false ) {
55
+ $sale_price = $this->product->get_sale_price();
56
+ $sale_price = $this->convert_currency( $sale_price, 'sale_price' );
57
+ return $this->add_tax( $sale_price, $tax );
58
+ }
59
+
60
+ /**
61
+ * Convert Currency.
62
+ *
63
+ * @param $price
64
+ * @param string $price_type price type (regular_price|price|sale_price)
65
+ *
66
+ * @return mixed|void
67
+ */
68
+ public function convert_currency( $price, $price_type ) {
69
+
70
+ return apply_filters( 'woo_feed_wcml_price',
71
+ $price, $this->product->get_id(), $this->config->get_feed_currency(), '_' . $price_type
72
+ );
73
+ }
74
+
75
+ /**
76
+ * Get Price with Tax.
77
+ *
78
+ * @return int|float
79
+ */
80
+ public function add_tax( $price, $tax = false ) {
81
+ if ( true === $tax ) {
82
+ return woo_feed_get_price_with_tax( $price, $this->product );
83
+ }
84
+
85
+ return $price;
86
+ }
87
+ }
V5/Price/SubscriptionProductPrice.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Price;
3
+ class Subscription {
4
+
5
+ }
V5/Price/VariableProductPrice.php ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Price;
3
+ use CTXFeed\V5\Common\Config;
4
+ use WC_Product;
5
+ use WC_Product_Variable;
6
+ use WC_Product_Variation;
7
+
8
+ class VariableProductPrice implements PriceInterface {
9
+ private $product;
10
+ private $config;
11
+ private $min_max_first;
12
+
13
+ /**
14
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation $product
15
+ * @param Config $config
16
+ */
17
+ public function __construct( $product, $config ) {
18
+
19
+ $this->product = $product;
20
+ $this->config = $config;
21
+ $this->min_max_first = $this->config->get_variable_config();
22
+
23
+ }
24
+
25
+ /**
26
+ * Get First Variation Price.
27
+ *
28
+ * @param bool $tax
29
+ *
30
+ * @return int
31
+ */
32
+ private function first_variation( $price_type = 'price', $tax = false ) {
33
+ $children = $this->product->get_visible_children();
34
+ $price = $this->product->get_variation_price();
35
+ if ( isset( $children[0] ) && ! empty( $children[0] ) ) {
36
+ $variation = wc_get_product( $children[0] );
37
+
38
+ switch ( $price_type ) {
39
+ case 'regular_price':
40
+ $price = $variation->get_regular_price();
41
+ break;
42
+ case 'sale_price':
43
+ $price = $variation->get_sale_price();
44
+ break;
45
+ default:
46
+ $price = $variation->get_price();
47
+ break;
48
+ }
49
+ }
50
+
51
+ $price = $this->convert_currency( $price, $price_type );
52
+
53
+ return $this->add_tax( $price, $tax );
54
+ }
55
+
56
+ /**
57
+ * Get Regular Price.
58
+ *
59
+ * @param bool $tax
60
+ *
61
+ * @return float|int
62
+ */
63
+ public function regular_price( $tax = false ) {
64
+ $min_max_first = ( $this->min_max_first['variable_price'] ) ?: "min";
65
+ if ( 'first' === $min_max_first ) {
66
+ $regular_price = $this->first_variation( 'regular_price', $tax );
67
+ } else {
68
+ $regular_price = $this->product->get_variation_regular_price( $min_max_first );
69
+ $regular_price = $this->convert_currency( $regular_price, 'regular_price' );
70
+ $regular_price = $this->add_tax( $regular_price, $tax );
71
+ }
72
+
73
+ return $regular_price;
74
+ }
75
+
76
+ /**
77
+ * Get Price.
78
+ *
79
+ * @param bool $tax
80
+ *
81
+ * @return float|int
82
+ */
83
+ public function price( $tax = false ) {
84
+ $min_max_first = ( $this->min_max_first['variable_price'] ) ?: "min";
85
+ if ( 'first' === $min_max_first ) {
86
+ $price = $this->first_variation( 'price', $tax );
87
+ } else {
88
+ $price = $this->product->get_variation_price( $min_max_first );
89
+ $price = $this->convert_currency( $price, 'price' );
90
+ $price = $this->add_tax( $price, $tax );
91
+ }
92
+
93
+ return $price;
94
+ }
95
+
96
+ /**
97
+ * Get Sale Price.
98
+ *
99
+ * @param bool $tax
100
+ *
101
+ * @return float|int
102
+ */
103
+ public function sale_price( $tax = false ) {
104
+ $min_max_first = ( $this->min_max_first['variable_price'] ) ?: "min";
105
+ if ( 'first' === $min_max_first ) {
106
+ $sale_price = $this->first_variation( 'sale_price', $tax );
107
+ } else {
108
+ $sale_price = $this->product->get_variation_sale_price( $min_max_first );
109
+ $sale_price = $this->convert_currency( $sale_price, 'sale_price' );
110
+ $sale_price = $this->add_tax( $sale_price, $tax );
111
+ }
112
+
113
+ return $sale_price;
114
+ }
115
+
116
+ /**
117
+ * Convert Currency.
118
+ *
119
+ * @param $price
120
+ * @param string $price_type price type (regular_price|price|sale_price)
121
+ *
122
+ * @return mixed|void
123
+ */
124
+ public function convert_currency( $price, $price_type ) {
125
+
126
+ return apply_filters( 'woo_feed_wcml_price',
127
+ $price, $this->product->get_id(), $this->config->get_feed_currency(), '_' . $price_type
128
+ );
129
+ }
130
+
131
+ /**
132
+ * Get Price with Tax.
133
+ *
134
+ * @return int|float
135
+ */
136
+ public function add_tax( $price, $tax = false ) {
137
+ if ( true === $tax ) {
138
+ return woo_feed_get_price_with_tax( $price, $this->product );
139
+ }
140
+
141
+ return $price;
142
+ }
143
+ }
V5/Price/WCBundleProductPrice.php ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Price;
3
+ use CTXFeed\V5\Common\Config;
4
+ use WC_Product;
5
+ use WC_Product_Variable;
6
+ use WC_Product_Variation;
7
+ class WCBundleProductPrice implements PriceInterface {
8
+
9
+ private $product;
10
+ private $config;
11
+
12
+ /**
13
+ * @param WC_Product $product
14
+ * @param Config $config
15
+ */
16
+ public function __construct( $product, $config ) {
17
+
18
+ $this->product = $product;
19
+ $this->config = $config;
20
+ }
21
+
22
+ /**
23
+ * Get Bundle Price.
24
+ * @param $price_type
25
+ * @param $tax
26
+ *
27
+ * @return int|string
28
+ */
29
+ public function bundle_price( $price_type = 'price', $tax = false ) {
30
+ if ( ! class_exists( 'WC_Product_Bundle' ) ) {
31
+ return $this->product->get_price();
32
+ }
33
+
34
+ $bundle = new WC_Product_Bundle( $this->product );
35
+
36
+ if ( $price_type === 'regular_price' ) {
37
+ $price = $bundle->get_bundle_regular_price();
38
+ } else {
39
+ $price = $bundle->get_bundle_price();
40
+ }
41
+
42
+ // Get WooCommerce Multi language Price by Currency.
43
+ $price = $this->convert_currency( $price, $price_type );
44
+
45
+ // Get Price with tax
46
+ $price = $this->add_tax( $price, $tax );
47
+
48
+ return $price > 0 ? $price : '';
49
+ }
50
+
51
+ /**
52
+ * Get Regular Price.
53
+ *
54
+ * @param bool $tax
55
+ *
56
+ * @return int|string
57
+ */
58
+ public function regular_price( $tax = false ) {
59
+ return $this->bundle_price( 'regular_price', $tax );
60
+ }
61
+
62
+ /**
63
+ * Get Price.
64
+ *
65
+ * @param bool $tax
66
+ *
67
+ * @return int|string
68
+ */
69
+ public
70
+ function price(
71
+ $tax = false
72
+ ) {
73
+ return $this->bundle_price( 'price', $tax );
74
+ }
75
+
76
+ /**
77
+ * Get Sale Price.
78
+ *
79
+ * @param bool $tax
80
+ *
81
+ * @return int|string
82
+ */
83
+ public
84
+ function sale_price(
85
+ $tax = false
86
+ ) {
87
+ return $this->bundle_price( 'sale_price', $tax );
88
+ }
89
+
90
+ /**
91
+ * Convert Currency.
92
+ *
93
+ * @param $price
94
+ * @param string $price_type price type (regular_price|price|sale_price)
95
+ *
96
+ * @return mixed|void
97
+ */
98
+ public
99
+ function convert_currency(
100
+ $price, $price_type
101
+ ) {
102
+
103
+ return apply_filters( 'woo_feed_wcml_price',
104
+ $price, $this->product->get_id(), $this->config->get_feed_currency(), '_' . $price_type
105
+ );
106
+ }
107
+
108
+ /**
109
+ * Get Price with Tax.
110
+ *
111
+ * @return int
112
+ */
113
+ public
114
+ function add_tax(
115
+ $price, $tax = false
116
+ ) {
117
+ if ( true === $tax ) {
118
+ return woo_feed_get_price_with_tax( $price, $this->product );
119
+ }
120
+
121
+ return $price;
122
+ }
123
+ }
V5/Price/WCCompositeProductPrice.php ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Price;
3
+ use CTXFeed\V5\Common\Config;
4
+ use WC_Product;
5
+ use WC_Product_Variable;
6
+ use WC_Product_Variation;
7
+ class WCCompositeProductPrice implements PriceInterface {
8
+
9
+ private $product;
10
+ private $config;
11
+
12
+ /**
13
+ * @param WC_Product $product
14
+ * @param Config $config
15
+ */
16
+ public function __construct( $product, $config ) {
17
+
18
+ $this->product = $product;
19
+ $this->config = $config;
20
+ }
21
+
22
+ /**
23
+ * Get Composite Price.
24
+ *
25
+ * @param bool $tax
26
+ *
27
+ * @return float|int
28
+ */
29
+ public function composite_price( $price_type = 'price', $tax = false ) {
30
+
31
+ // Parent Component Price
32
+ $price = $this->product->$price_type();
33
+
34
+ if ( ! class_exists( 'WC_Product_Composite' ) ) {
35
+ return $price;
36
+ }
37
+
38
+ if ( isset( $this->config['composite_price'] ) && 'all_product_price' === $this->config['composite_price'] ) {
39
+
40
+ $composite = new WC_Product_Composite( $this->product );
41
+
42
+ if ( 'regular_price' === $price_type ) {
43
+ $price = $composite->get_composite_regular_price();
44
+ } else {
45
+ $price = $composite->get_composite_price();
46
+ }
47
+
48
+ // Get WooCommerce Multi language Price by Currency.
49
+ $price = $this->convert_currency( $price, $price_type );
50
+
51
+ // Get Price with tax
52
+ $price = $this->add_tax( $price, $tax );
53
+ }
54
+
55
+ return $price > 0 ? $price : '';
56
+ }
57
+
58
+ /**
59
+ * Get Regular Price.
60
+ *
61
+ * @param bool $tax
62
+ *
63
+ * @return float|int|string
64
+ */
65
+ public function regular_price( $tax = false ) {
66
+ return $this->composite_price( 'regular_price', $tax );
67
+ }
68
+
69
+ /**
70
+ * Get Price.
71
+ *
72
+ * @param bool $tax
73
+ *
74
+ * @return float|int|string
75
+ */
76
+ public function price( $tax = false ) {
77
+ return $this->composite_price( 'price', $tax );
78
+ }
79
+
80
+ /**
81
+ * Get Sale Price.
82
+ *
83
+ * @param bool $tax
84
+ *
85
+ * @return float|int|string
86
+ */
87
+ public function sale_price( $tax = false ) {
88
+ return $this->composite_price( 'sale_price', $tax );
89
+ }
90
+
91
+ /**
92
+ * Convert Currency.
93
+ *
94
+ * @param $price
95
+ * @param string $price_type price type (regular_price|price|sale_price)
96
+ *
97
+ * @return mixed|void
98
+ */
99
+ public function convert_currency( $price, $price_type ) {
100
+
101
+ return apply_filters( 'woo_feed_wcml_price',
102
+ $price, $this->product->get_id(), $this->config->get_feed_currency(), '_' . $price_type
103
+ );
104
+ }
105
+
106
+ /**
107
+ * Get Price with Tax.
108
+ *
109
+ * @return float|int
110
+ */
111
+ public function add_tax( $price, $tax = false ) {
112
+ if ( true === $tax ) {
113
+ return woo_feed_get_price_with_tax( $price, $this->product );
114
+ }
115
+
116
+ return $price;
117
+ }
118
+ }
V5/Price/WPCCompositeProductPrice.php ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Price;
3
+ use CTXFeed\V5\Common\Config;
4
+ use WC_Product;
5
+ use WC_Product_Variable;
6
+ use WC_Product_Variation;
7
+ class WPCCompositeProductPrice implements PriceInterface {
8
+
9
+ private $product;
10
+ private $config;
11
+
12
+ /**
13
+ * @param WC_Product|WC_Product_Composite $product
14
+ * @param Config $config
15
+ */
16
+ public function __construct( $product, $config ) {
17
+
18
+ $this->product = $product;
19
+ $this->config = $config;
20
+ }
21
+
22
+ public function composite_price( $price_type='price', $tax = false ) {
23
+
24
+ $price = 0;
25
+ // Parent Component Price
26
+ $base_price = $this->product->$price_type();
27
+
28
+ if (isset($this->config['composite_price']) && 'all_product_price' === $this->config['composite_price']) {
29
+ $components_price = 0;
30
+ $components = $this->product->get_components();
31
+ if (!empty($components) && is_array($components)) {
32
+ foreach ($components as $component) {
33
+ $products = explode(',', $component['products']);
34
+ foreach ($products as $product_id) {
35
+ $default_product = wc_get_product($product_id);
36
+ if (is_object($default_product) && $default_product->is_in_stock()) {
37
+ $quantity = (isset($component['qty']) && $component['qty'] > 0) ? $component['qty'] : 1;
38
+ if ( 'products' === $component['type'] && empty($component['price'])) {
39
+ $components_price += $this->get_price_by_price_type($default_product, 'price');
40
+ $components_price *= $quantity;
41
+ } elseif ( 'products' === $component['type'] && !empty($component['price'])) {
42
+ $clever = new WPCleverWooco();
43
+ $old_price = $this->get_price_by_price_type($default_product, 'price');
44
+ $new_price = $component['price'];
45
+ $components_price += $clever::wooco_new_price($old_price, $new_price);
46
+ $components_price *= $quantity;
47
+ }
48
+ break; // Get first in stock product from component options.
49
+ }
50
+ }
51
+ }
52
+
53
+ // Apply discount to components price.
54
+ $discount = $this->product->get_discount();
55
+ if ($discount > 0) {
56
+ $components_price -= (($discount / 100) * $components_price);
57
+ }
58
+ }
59
+
60
+ if ('exclude' === $this->product->get_pricing()) {
61
+ $price = $components_price;
62
+ } elseif ('include' === $this->product->get_pricing()) {
63
+ $price = $components_price + $base_price;
64
+ } elseif ('only' === $this->product->get_pricing()) {
65
+ $price = $base_price;
66
+ }
67
+ } else {
68
+ $price = $base_price;
69
+ }
70
+
71
+ return $price > 0 ? $price : '';
72
+
73
+ }
74
+
75
+ public function get_price_by_price_type( $product, $price_type='price') {
76
+ switch ( $price_type ) {
77
+ case 'regular_price':
78
+ $price = $product->get_regular_price();
79
+ break;
80
+ case 'sale_price':
81
+ $price = $product->get_sale_price();
82
+ break;
83
+ default:
84
+ $price = $product->get_price();
85
+ break;
86
+ }
87
+
88
+ return $price;
89
+ }
90
+
91
+ /**
92
+ * Get Regular Price.
93
+ *
94
+ * @param bool $tax
95
+ *
96
+ * @return mixed|void
97
+ */
98
+ public function regular_price( $tax = false ) {
99
+ $regular_price = $this->product->get_regular_price();
100
+ $regular_price = $this->convert_currency( $regular_price, 'regular_price' );
101
+ $regular_price = $this->add_tax( $regular_price, $tax );
102
+
103
+ return apply_filters( 'woo_feed_filter_product_regular_price', $regular_price, $this->product, $this->config );
104
+ }
105
+
106
+ /**
107
+ * Get Price.
108
+ *
109
+ * @param bool $tax
110
+ *
111
+ * @return mixed|void
112
+ */
113
+ public function price( $tax = false ) {
114
+ $price = $this->product->get_price();
115
+ $price = $this->convert_currency( $price, 'price' );
116
+ $price = $this->add_tax( $price, $tax );
117
+
118
+ return apply_filters( 'woo_feed_filter_product_price', $price, $this->product, $this->config );
119
+ }
120
+
121
+ /**
122
+ * Get Sale Price.
123
+ *
124
+ * @param bool $tax
125
+ *
126
+ * @return mixed|void
127
+ */
128
+ public function sale_price( $tax = false ) {
129
+ $sale_price = $this->product->get_sale_price();
130
+ $sale_price = $this->convert_currency( $sale_price, 'sale_price' );
131
+ $sale_price = $this->add_tax( $sale_price, $tax );
132
+
133
+ return apply_filters( 'woo_feed_filter_product_sale_price', $sale_price, $this->product, $this->config );
134
+ }
135
+
136
+ /**
137
+ * Convert Currency.
138
+ *
139
+ * @param $price
140
+ * @param string $price_type price type (regular_price|price|sale_price)
141
+ *
142
+ * @return mixed|void
143
+ */
144
+ public function convert_currency( $price, $price_type ) {
145
+
146
+ return apply_filters( 'woo_feed_wcml_price',
147
+ $price, $this->product->get_id(), $this->config->get_feed_currency(), '_' . $price_type
148
+ );
149
+ }
150
+
151
+ /**
152
+ * Get Price with Tax.
153
+ *
154
+ * @return int
155
+ */
156
+ public function add_tax( $price, $tax = false ) {
157
+ if ( true === $tax ) {
158
+ return woo_feed_get_price_with_tax( $price, $this->product );
159
+ }
160
+
161
+ return $price;
162
+ }
163
+ }
V5/Product/AttributeValueByType.php ADDED
@@ -0,0 +1,252 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Product;
4
+
5
+ use CTXFeed\V5\Helper\ProductHelper;
6
+ use CTXFeed\V5\Override\OverrideFactory;
7
+ use WC_Abstract_Legacy_Product;
8
+ use WC_Product;
9
+ use WC_Product_External;
10
+ use WC_Product_Grouped;
11
+ use WC_Product_Variable;
12
+ use WC_Product_Variation;
13
+
14
+ class AttributeValueByType {
15
+
16
+ /**
17
+ * Advance Custom Field (ACF) Prefix
18
+ *
19
+ * @since 3.1.18
20
+ * @var string
21
+ */
22
+ const PRODUCT_ACF_FIELDS = 'acf_fields_';
23
+ /**
24
+ * Post meta prefix for dropdown item
25
+ *
26
+ * @since 3.1.18
27
+ * @var string
28
+ */
29
+ const POST_META_PREFIX = 'wf_cattr_';
30
+ /**
31
+ * Product Attribute (taxonomy & local) Prefix
32
+ *
33
+ * @since 3.1.18
34
+ * @var string
35
+ */
36
+ const PRODUCT_ATTRIBUTE_PREFIX = 'wf_attr_';
37
+ /**
38
+ * Product Taxonomy Prefix
39
+ *
40
+ * @since 3.1.18
41
+ * @var string
42
+ */
43
+ const PRODUCT_TAXONOMY_PREFIX = 'wf_taxo_';
44
+ /**
45
+ * Product Category Mapping Prefix
46
+ *
47
+ * @since 3.1.18
48
+ * @var string
49
+ */
50
+ const PRODUCT_CATEGORY_MAPPING_PREFIX = 'wf_cmapping_';
51
+ /**
52
+ * Product Dynamic Attribute Prefix
53
+ *
54
+ * @since 3.1.18
55
+ * @var string
56
+ */
57
+ const PRODUCT_DYNAMIC_ATTRIBUTE_PREFIX = 'wf_dattribute_';
58
+ /**
59
+ * WordPress Option Prefix
60
+ *
61
+ * @since 3.1.18
62
+ * @var string
63
+ */
64
+ const WP_OPTION_PREFIX = 'wf_option_';
65
+ /**
66
+ * Extra Attribute Prefix
67
+ *
68
+ * @since 3.2.20
69
+ */
70
+ const PRODUCT_EXTRA_ATTRIBUTE_PREFIX = 'wf_extra_';
71
+ /**
72
+ * Product Attribute Mappings Prefix
73
+ *
74
+ * @since 3.3.2*
75
+ */
76
+ const PRODUCT_ATTRIBUTE_MAPPING_PREFIX = 'wp_attr_mapping_';
77
+ /**
78
+ * Product Custom Field Prefix
79
+ *
80
+ * @since 3.1.18
81
+ * @var string
82
+ */
83
+ const PRODUCT_CUSTOM_IDENTIFIER = 'woo_feed_';
84
+
85
+ private $attribute;
86
+ private $merchant_attribute;
87
+ private $product;
88
+ private $productInfo;
89
+ private $config;
90
+
91
+ /**
92
+ * @param $attribute
93
+ * @param $merchant_attribute
94
+ * @param $product
95
+ * @param $config
96
+ */
97
+ public function __construct( $attribute, $product, $config, $merchant_attribute = null ) {
98
+ $this->attribute = $attribute;
99
+ $this->merchant_attribute = $merchant_attribute;
100
+ $this->product = $product;
101
+ $this->config = $config;
102
+ $this->productInfo = new ProductInfo( $this->product, $this->config );
103
+
104
+ // Load Merchant Template Override File.
105
+ OverrideFactory::init( $config );
106
+ }
107
+
108
+ /**
109
+ * Get product attribute value by attribute type.
110
+ *
111
+ * @return mixed|void
112
+ */
113
+ public function get_value( $attr = '' ) {
114
+ if ( ! empty( $attr ) ) {
115
+ $this->attribute = $attr;
116
+ }
117
+
118
+ if ( method_exists( $this->productInfo, $this->attribute ) ) {
119
+ $attribute = $this->attribute;
120
+ $output = $this->productInfo->$attribute();
121
+ } elseif ( false !== strpos( $this->attribute, self::PRODUCT_EXTRA_ATTRIBUTE_PREFIX ) ) {
122
+ $attribute = str_replace( self::PRODUCT_EXTRA_ATTRIBUTE_PREFIX, '', $this->attribute );
123
+
124
+ /**
125
+ * Filter output for extra attribute, which can be added via 3rd party plugins.
126
+ *
127
+ * @param string $output the output
128
+ * @param WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External|WC_Product_Composite $product Product Object.
129
+ *
130
+ *
131
+ * @since 3.3.5
132
+ */
133
+ return apply_filters( "woo_feed_get_extra_{$attribute}_attribute", '', $this->product, $this->config );
134
+ } elseif ( false !== strpos( $this->attribute, 'csv_tax_' ) ) {
135
+ $key = str_replace( 'csv_tax_', '', $this->attribute );
136
+ $output = $this->productInfo->tax( (string) $key );
137
+ } elseif ( false !== strpos( $this->attribute, 'csv_shipping_' ) ) {
138
+ $key = str_replace( 'csv_shipping_', '', $this->attribute );
139
+ $output = $this->productInfo->shipping( (string) $key );
140
+ } elseif ( false !== strpos( $this->attribute, self::PRODUCT_ACF_FIELDS ) ) {
141
+ $output = ProductHelper::get_acf_field( $this->product, $this->attribute );
142
+ } elseif ( false !== strpos( $this->attribute, self::PRODUCT_ATTRIBUTE_MAPPING_PREFIX ) ) {
143
+ $output = ProductHelper::get_attribute_mapping( $this->product, $this->attribute, $this->merchant_attribute, $this->config );
144
+ } elseif ( false !== strpos( $this->attribute, self::PRODUCT_DYNAMIC_ATTRIBUTE_PREFIX ) ) {
145
+ $output = ProductHelper::get_dynamic_attribute( $this->product, $this->attribute, $this->merchant_attribute, $this->config );
146
+ } elseif ( false !== strpos( $this->attribute, self::PRODUCT_CUSTOM_IDENTIFIER ) || woo_feed_strpos_array( array(
147
+ '_identifier_gtin',
148
+ '_identifier_ean',
149
+ '_identifier_mpn'
150
+ ), $this->attribute ) ) {
151
+ $output = ProductHelper::get_custom_filed( $this->attribute, $this->product, $this->config );
152
+ } elseif ( false !== strpos( $this->attribute, self::PRODUCT_ATTRIBUTE_PREFIX ) ) {
153
+ $this->attribute = str_replace( self::PRODUCT_ATTRIBUTE_PREFIX, '', $this->attribute );
154
+ $output = ProductHelper::get_product_attribute( $this->attribute, $this->product, $this->config );
155
+ } elseif ( false !== strpos( $this->attribute, self::POST_META_PREFIX ) ) {
156
+ $this->attribute = str_replace( self::POST_META_PREFIX, '', $this->attribute );
157
+ $output = ProductHelper::get_product_meta( $this->attribute, $this->product, $this->config );
158
+ } elseif ( false !== strpos( $this->attribute, self::PRODUCT_TAXONOMY_PREFIX ) ) {
159
+ $this->attribute = str_replace( self::PRODUCT_TAXONOMY_PREFIX, '', $this->attribute );
160
+ $output = ProductHelper::get_product_taxonomy( $this->attribute, $this->product, $this->config );
161
+ } elseif ( false !== strpos( $this->attribute, self::PRODUCT_CATEGORY_MAPPING_PREFIX ) ) {
162
+ $id = $this->product->is_type( 'variation' ) ? $this->product->get_parent_id() : $this->product->get_id();
163
+ $output = ProductHelper::get_category_mapping( $this->attribute, $id );
164
+ } elseif ( false !== strpos( $this->attribute, self::WP_OPTION_PREFIX ) ) {
165
+ $optionName = str_replace( self::WP_OPTION_PREFIX, '', $this->attribute );
166
+ $output = get_option( $optionName );
167
+ } elseif ( strpos( $this->attribute, 'image_' ) === 0 ) {
168
+ // For additional image method images() will be used with extra parameter - image number
169
+ $imageKey = explode( '_', $this->attribute );
170
+ if ( empty( $imageKey[1] ) || ! is_numeric( $imageKey[1] ) ) {
171
+ $imageKey[1] = '';
172
+ }
173
+ $output = $this->productInfo->images( $imageKey[1] );
174
+ } else {
175
+ // return the attribute so multiple attribute can be used with separator to make custom attribute.
176
+ $output = $this->attribute;
177
+ }
178
+
179
+ // Json encode if value is an array
180
+ if ( is_array( $output ) ) {
181
+ $output = wp_json_encode( $output );
182
+ }
183
+
184
+ return $this->apply_filters_to_attribute_value( $output, $this->merchant_attribute );
185
+ }
186
+
187
+ /**
188
+ * Apply Filter to Attribute value
189
+ *
190
+ * @param $output
191
+ * @param $merchant_attribute
192
+ *
193
+ * @return mixed|void
194
+ */
195
+ protected function apply_filters_to_attribute_value( $output, $merchant_attribute ) {
196
+ $product_attribute = $this->attribute;
197
+ /**
198
+ * Filter attribute value
199
+ *
200
+ * @param string $output the output
201
+ * @param WC_Abstract_Legacy_Product $product Product Object.
202
+ * @param array feed config/rule
203
+ *
204
+ * @since 3.4.3
205
+ *
206
+ */
207
+ $output = apply_filters( 'woo_feed_get_attribute', $output, $this->product, $this->config, $product_attribute, $merchant_attribute );
208
+
209
+ /**
210
+ * Filter attribute value before return based on product attribute name
211
+ *
212
+ * @param string $output the output
213
+ * @param WC_Abstract_Legacy_Product $product Product Object.
214
+ * @param array feed config/rule
215
+ *
216
+ * @since 3.3.5
217
+ *
218
+ */
219
+
220
+ $output = apply_filters( "woo_feed_get_{$product_attribute}_attribute", $output, $this->product, $this->config, $product_attribute, $merchant_attribute );
221
+
222
+ /**
223
+ * Filter attribute value before return based on merchant name
224
+ *
225
+ * @param string $output the output
226
+ * @param WC_Abstract_Legacy_Product $product Product Object.
227
+ * @param array feed config/rule
228
+ *
229
+ * @since 3.3.5
230
+ *
231
+ */
232
+
233
+ $output = apply_filters( "woo_feed_get_{$this->config->provider}_attribute", $output, $this->product, $this->config, $product_attribute, $merchant_attribute );
234
+
235
+ /**
236
+ * Filter attribute value before return based on merchant and merchant attribute name
237
+ *
238
+ * @param string $output the output
239
+ * @param WC_Abstract_Legacy_Product $product Product Object.
240
+ * @param array feed config/rule
241
+ *
242
+ * @since 3.3.7
243
+ *
244
+ */
245
+ $merchant_attribute = str_replace( [ ' ', 'g:' ], '', $merchant_attribute );
246
+
247
+ //$output = "woo_feed_get_{$this->config->provider}_{$merchant_attribute}_attribute";
248
+ return apply_filters( "woo_feed_get_{$this->config->provider}_{$merchant_attribute}_attribute", $output, $this->product, $this->config, $product_attribute, $merchant_attribute );
249
+ }
250
+
251
+
252
+ }
V5/Product/ProductAttributeFactory.php ADDED
@@ -0,0 +1,771 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Product;
4
+
5
+ use CTXFeed\V5\Utility\Cache;
6
+ use Woo_Feed_Custom_Identifier_Filter;
7
+ use Woo_Feed_Products_v3;
8
+
9
+ /**
10
+ * The file that defines the merchants attributes
11
+ *
12
+ * A class definition that includes attributes and functions used across the
13
+ * admin area.
14
+ *
15
+ * @link https://webappick.com/
16
+ * @since 1.0.0
17
+ *
18
+ * @package Woo_Feed
19
+ * @subpackage Woo_Feed/includes
20
+ * @author Ohidul Islam <wahid@webappick.com>
21
+ */
22
+ class ProductAttributeFactory {
23
+ /**
24
+ * Hold Product Attributes.
25
+ *
26
+ * @var $attributes
27
+ */
28
+ public $attributes;
29
+
30
+ /**
31
+ * Get Product Attributes
32
+ *
33
+ * @return string
34
+ */
35
+ public static function getAttributes() {
36
+ return self::setAttributes();
37
+ }
38
+
39
+ private static function setAttributes() {
40
+ $attributes = [];
41
+ $primaryAttributes = [
42
+ 'optionGroup' => esc_html__( 'Primary Attributes', 'woo-feed' ),
43
+ 'options' => [
44
+ 'id' => esc_html__( 'Product Id', 'woo-feed' ),
45
+ 'title' => esc_html__( 'Product Title', 'woo-feed' ),
46
+ 'parent_title' => esc_html__( 'Parent Title', 'woo-feed' ),
47
+ 'description' => esc_html__( 'Product Description', 'woo-feed' ),
48
+ 'description_with_html' => esc_html__( 'Product Description (with HTML)', 'woo-feed' ),
49
+ 'short_description' => esc_html__( 'Product Short Description', 'woo-feed' ),
50
+ 'primary_category' => esc_html__( 'Parent Category', 'woo-feed' ),
51
+ 'primary_category_id' => esc_html__( 'Parent Category ID', 'woo-feed' ),
52
+ 'child_category' => esc_html__( 'Child Category', 'woo-feed' ),
53
+ 'child_category_id' => esc_html__( 'Child Category ID', 'woo-feed' ),
54
+ 'product_type' => esc_html__( 'Product Category [Category Path]', 'woo-feed' ),
55
+ 'product_full_cat' => esc_html__( 'Product Full Category [Category Full Path]', 'woo-feed' ),
56
+ 'link' => esc_html__( 'Product URL', 'woo-feed' ),
57
+ 'parent_link' => esc_html__( 'Parent URL', 'woo-feed' ),
58
+ 'canonical_link' => esc_html__( 'Canonical URL', 'woo-feed' ),
59
+ 'ex_link' => esc_html__( 'External Product URL', 'woo-feed' ),
60
+ 'add_to_cart_link' => esc_html__( 'Add to Cart URL', 'woo-feed' ),
61
+ 'item_group_id' => esc_html__( 'Parent Id [Group Id]', 'woo-feed' ),
62
+ 'sku' => esc_html__( 'SKU', 'woo-feed' ),
63
+ 'sku_id' => esc_html__( 'SKU_ID', 'woo-feed' ),
64
+ 'parent_sku' => esc_html__( 'Parent SKU', 'woo-feed' ),
65
+ 'availability' => esc_html__( 'Availability', 'woo-feed' ),
66
+ 'availability_date' => esc_html__( 'Availability Date', 'woo-feed' ),
67
+ 'quantity' => esc_html__( 'Quantity', 'woo-feed' ),
68
+ 'reviewer_name' => esc_html__( 'Reviewer Name', 'woo-feed' ),
69
+ 'weight' => esc_html__( 'Weight', 'woo-feed' ),
70
+ 'weight_unit' => esc_html__( 'Weight Unit', 'woo-feed' ),
71
+ 'width' => esc_html__( 'Width', 'woo-feed' ),
72
+ 'height' => esc_html__( 'Height', 'woo-feed' ),
73
+ 'length' => esc_html__( 'Length', 'woo-feed' ),
74
+ 'type' => esc_html__( 'Product Type', 'woo-feed' ),
75
+ 'visibility' => esc_html__( 'Visibility', 'woo-feed' ),
76
+ 'rating_total' => esc_html__( 'Total Rating', 'woo-feed' ),
77
+ 'rating_average' => esc_html__( 'Average Rating', 'woo-feed' ),
78
+ 'tags' => esc_html__( 'Tags', 'woo-feed' ),
79
+ 'is_bundle' => esc_html__( 'Is Bundle', 'woo-feed' ),
80
+ 'author_name' => esc_html__( 'Author Name', 'woo-feed' ),
81
+ 'author_email' => esc_html__( 'Author Email', 'woo-feed' ),
82
+ 'date_created' => esc_html__( 'Date Created', 'woo-feed' ),
83
+ 'date_updated' => esc_html__( 'Date Updated', 'woo-feed' ),
84
+ ]
85
+ ];
86
+
87
+ $attributes [] = $primaryAttributes;
88
+
89
+
90
+ $imageAttributes = [
91
+ 'optionGroup' => esc_html__( 'Images', 'woo-feed' ),
92
+ 'options' => [
93
+ 'image' => esc_html__( 'Main Image', 'woo-feed' ),
94
+ 'feature_image' => esc_html__( 'Featured Image', 'woo-feed' ),
95
+ 'images' => esc_html__( 'Images [Comma Separated]', 'woo-feed' ),
96
+ 'image_1' => esc_html__( 'Additional Image 1', 'woo-feed' ),
97
+ 'image_2' => esc_html__( 'Additional Image 2', 'woo-feed' ),
98
+ 'image_3' => esc_html__( 'Additional Image 3', 'woo-feed' ),
99
+ 'image_4' => esc_html__( 'Additional Image 4', 'woo-feed' ),
100
+ 'image_5' => esc_html__( 'Additional Image 5', 'woo-feed' ),
101
+ 'image_6' => esc_html__( 'Additional Image 6', 'woo-feed' ),
102
+ 'image_7' => esc_html__( 'Additional Image 7', 'woo-feed' ),
103
+ 'image_8' => esc_html__( 'Additional Image 8', 'woo-feed' ),
104
+ 'image_9' => esc_html__( 'Additional Image 9', 'woo-feed' ),
105
+ 'image_10' => esc_html__( 'Additional Image 10', 'woo-feed' ),
106
+ ],
107
+ ];
108
+
109
+ $attributes [] = $imageAttributes;
110
+
111
+ $priceAttributes = [
112
+ 'optionGroup' => esc_html__( 'Price', 'woo-feed' ),
113
+ 'options' => [
114
+ 'currency' => esc_html__( 'Currency', 'woo-feed' ),
115
+ 'price' => esc_html__( 'Regular Price', 'woo-feed' ),
116
+ 'current_price' => esc_html__( 'Price', 'woo-feed' ),
117
+ 'sale_price' => esc_html__( 'Sale Price', 'woo-feed' ),
118
+ 'price_with_tax' => esc_html__( 'Regular Price With Tax', 'woo-feed' ),
119
+ 'current_price_with_tax' => esc_html__( 'Price With Tax', 'woo-feed' ),
120
+ 'sale_price_with_tax' => esc_html__( 'Sale Price With Tax', 'woo-feed' ),
121
+ 'sale_price_sdate' => esc_html__( 'Sale Start Date', 'woo-feed' ),
122
+ 'sale_price_edate' => esc_html__( 'Sale End Date', 'woo-feed' ),
123
+ 'sale_price_effective_date' => esc_html__( 'Sale Price Effective Date', 'woo-feed' ),
124
+ ],
125
+ ];
126
+
127
+ $attributes [] = $priceAttributes;
128
+
129
+ $shippingAttributes = [
130
+ 'optionGroup' => esc_html__( 'Shipping', 'woo-feed' ),
131
+ 'options' => [
132
+ 'shipping' => esc_html__( 'Shipping (Google Format)', 'woo-feed' ),
133
+ 'shipping_class' => esc_html__( 'Shipping Class', 'woo-feed' ),
134
+ // 'shipping_zone_name' => esc_html__( 'Shipping Zone Name', 'woo-feed' ),
135
+ // 'shipping_country' => esc_html__( 'Shipping Country', 'woo-feed' ),
136
+ // 'shipping_region' => esc_html__( 'Shipping Regions', 'woo-feed' ),
137
+ // 'shipping_postcode' => esc_html__( 'Shipping Postcodes', 'woo-feed' ),
138
+ // 'shipping_service' => esc_html__( 'Shipping Method Name', 'woo-feed' ),
139
+ // 'shipping_price' => esc_html__( 'Shipping Cost', 'woo-feed' ),
140
+ ],
141
+ ];
142
+
143
+ $attributes [] = $shippingAttributes;
144
+
145
+ $taxAttributes = [
146
+ 'optionGroup' => esc_html__( 'Tax', 'woo-feed' ),
147
+ 'options' => [
148
+ 'tax' => esc_html__( 'Tax (Google Format)', 'woo-feed' ),
149
+ 'tax_class' => esc_html__( 'Tax Class', 'woo-feed' ),
150
+ // 'tax_status' => esc_html__( 'Tax Status', 'woo-feed' ),
151
+ // 'tax_country' => esc_html__( 'Tax Country', 'woo-feed' ),
152
+ // 'tax_state' => esc_html__( 'Tax State', 'woo-feed' ),
153
+ // 'tax_postcode' => esc_html__( 'Tax Postcodes', 'woo-feed' ),
154
+ // 'tax_city' => esc_html__( 'Tax City', 'woo-feed' ),
155
+ // 'tax_rate' => esc_html__( 'Tax Rate', 'woo-feed' ),
156
+ // 'tax_label' => esc_html__( 'Tax Name', 'woo-feed' ),
157
+ ],
158
+ ];
159
+
160
+ $attributes [] = $taxAttributes;
161
+
162
+ $subscriptionAttributes = [
163
+ 'optionGroup' => esc_html__( 'Subscription & Installment', 'woo-feed' ),
164
+ 'options' => [
165
+ 'subscription_period' => esc_html__( 'Subscription Period', 'woo-feed' ),
166
+ 'subscription_period_interval' => esc_html__( 'Subscription Period Length', 'woo-feed' ),
167
+ 'subscription_amount' => esc_html__( 'Subscription Amount', 'woo-feed' ),
168
+ 'installment_months' => esc_html__( 'Installment Months', 'woo-feed' ),
169
+ 'installment_amount' => esc_html__( 'Installment Amount', 'woo-feed' ),
170
+ ],
171
+ ];
172
+
173
+ $customXMLAttributes = [
174
+ 'optionGroup' => esc_html__( 'Custom Template 2 (XML)', 'woo-feed' ),
175
+ 'options' => [
176
+ 'custom_xml_variations' => esc_html__( 'Product Variations', 'woo-feed' ),
177
+ 'custom_xml_images' => esc_html__( 'Product Gallery Images', 'woo-feed' ),
178
+ 'custom_xml_categories' => esc_html__( 'Product Categories', 'woo-feed' ),
179
+ ]
180
+ ];
181
+
182
+ /**
183
+ * Add subscription attributes if WooCommerce Subscription plugin installed.
184
+ *
185
+ * @link https://woocommerce.com/products/woocommerce-subscriptions/
186
+ */
187
+ if ( class_exists( 'WC_Subscriptions' ) ) {
188
+ $attributes[] = $subscriptionAttributes;
189
+ }
190
+
191
+ $attributes[] = self::getPluginsCustomFields();
192
+ $attributes[] = self::getUnitPriceAttributes();
193
+ $attributes[] = self::getSeoPluginAttributes();
194
+ $attributes[] = self::getGlobalAttributes();
195
+ $attributes[] = self::getCustomAttributes();
196
+ $attributes[] = self::getAllTaxonomy();
197
+ $attributes[] = self::getAllOptions();
198
+ // Category Mapping
199
+ $attributes[] = self::getCategoryMappedAttributes();
200
+ // ACF Plugin custom fields getACFAttributes
201
+ $attributes[] = self::getACFAttributes();
202
+ // Custom Fields & Post Metas
203
+ $attributes[] = self::getProductMetaKeyAttributes();
204
+
205
+ if ( defined( 'WOO_FEED_PRO_VERSION' ) ) { // class_exists( 'Woo_Feed_Products_v3_Pro' )
206
+ $attributes [] = self::getMultiLanguageAttributes();
207
+ $attributes [] = self::getMultiVendorAttributes();
208
+ // Dynamic Attributes
209
+ $attributes[] = self::getDynamicAttributes();
210
+ // Attribute Mappings
211
+ $attributes[] = self::getCustomMappedAttributes();
212
+ // Custom Template 2 Attributes
213
+ $attributes [] = $customXMLAttributes;
214
+ }
215
+
216
+ return apply_filters( 'woo_feed_product_attribute_dropdown', $attributes );
217
+ }
218
+
219
+ /**
220
+ * Get CTX Feed plugins Custom Fields.
221
+ *
222
+ * @return array
223
+ */
224
+ private static function getPluginsCustomFields() {
225
+
226
+ $custom_fields = woo_feed_product_custom_fields();
227
+ $custom_identifier_filter = new Woo_Feed_Custom_Identifier_Filter( $custom_fields );
228
+ $custom_identifier = iterator_to_array( $custom_identifier_filter );
229
+ $activeAttributes = [ 'optionGroup' => esc_html__( 'Custom Fields by CTX Feed', 'woo-feed' ), ];
230
+ if ( ! empty( $custom_identifier ) ) {
231
+ foreach ( $custom_identifier as $key => $value ) {
232
+ $activeAttributes['options'][ 'woo_feed_identifier_' . sanitize_text_field( wp_unslash( $key ) ) ] = sanitize_text_field( $value[0] );
233
+ }
234
+ }
235
+
236
+ return ! empty( $activeAttributes['options'] ) ? $activeAttributes : [];
237
+ }
238
+
239
+ /**
240
+ * Get Unit Price Attributes.
241
+ *
242
+ * @return array
243
+ */
244
+ private static function getUnitPriceAttributes() {
245
+
246
+ $unitPriceAttributes = [
247
+ 'optionGroup' => esc_html__( 'Unit Price (CTX Feed)', 'woo-feed' ),
248
+ 'options' => [
249
+ 'unit_price_unit' => esc_html__( 'Unit', 'woo-feed' ),
250
+ 'unit_price_measure' => esc_html__( 'Unit Price Measure', 'woo-feed' ),
251
+ 'unit_price_base_measure' => esc_html__( 'Unit Price Base Measure', 'woo-feed' ),
252
+ ],
253
+ ];
254
+
255
+ /**
256
+ * Get Germanized for WooCommerce plugins unit attributes.
257
+ *
258
+ * @link https://wordpress.org/plugins/woocommerce-germanized/
259
+ */
260
+ if ( class_exists( 'WooCommerce_Germanized' ) ) {
261
+ $wcUnitPriceAttributes = [
262
+ 'optionGroup' => esc_html__( 'Unit Price (WooCommerce Germanized)', 'woo-feed' ),
263
+ 'options' => [
264
+ 'wc_germanized_unit_price_measure' => esc_html__( 'Unit Price Measure', 'woo-feed' ),
265
+ 'wc_germanized_unit_price_base_measure' => esc_html__( 'Unit Price Base Measure', 'woo-feed' ),
266
+ 'wc_germanized_gtin' => esc_html__( 'GTIN', 'woo-feed' ),
267
+ 'wc_germanized_mpn' => esc_html__( 'MPN', 'woo-feed' ),
268
+ ],
269
+ ];
270
+ $unitPriceAttributes += $wcUnitPriceAttributes;
271
+ }
272
+
273
+ return $unitPriceAttributes;
274
+ }
275
+
276
+ /**
277
+ * Get installed SEO plugin attributes.
278
+ *
279
+ * @return array
280
+ */
281
+ private static function getSeoPluginAttributes() {
282
+
283
+ $seoAttributes = [];
284
+ /**
285
+ * Get Yoast SEO Plugin Attributes.
286
+ *
287
+ * @link https://wordpress.org/plugins/wordpress-seo/
288
+ */
289
+ if ( class_exists( 'WPSEO_Frontend' ) || class_exists( 'WPSEO_Premium' ) ) {
290
+
291
+ $seoAttributes = [
292
+ 'optionGroup' => esc_html__( 'Yoast SEO', 'woo-feed' ),
293
+ 'options' => [
294
+ 'yoast_wpseo_title' => esc_html__( 'Title [Yoast SEO]', 'woo-feed' ),
295
+ 'yoast_wpseo_metadesc' => esc_html__( 'Description [Yoast SEO]', 'woo-feed' ),
296
+ 'yoast_canonical_url' => esc_html__( 'Canonical URL [Yoast SEO]', 'woo-feed' ),
297
+ ],
298
+ ];
299
+
300
+ /**
301
+ * Get Yoast WooCommerce SEO plugins Identifier Attributes.
302
+ *
303
+ * @link https://yoast.com/wordpress/plugins/yoast-woocommerce-seo/
304
+ */
305
+ if ( class_exists( 'Yoast_WooCommerce_SEO' ) ) {
306
+ $seoAttributes['options'] += [
307
+ 'yoast_gtin8' => esc_html__( 'GTIN8 [Yoast SEO]', 'woo-feed' ),
308
+ 'yoast_gtin12' => esc_html__( 'GTIN12 / UPC [Yoast SEO]', 'woo-feed' ),
309
+ 'yoast_gtin13' => esc_html__( 'GTIN13 / EAN [Yoast SEO]', 'woo-feed' ),
310
+ 'yoast_gtin14' => esc_html__( 'GTIN14 / ITF-14 [Yoast SEO]', 'woo-feed' ),
311
+ 'yoast_isbn' => esc_html__( 'ISBN [Yoast SEO]', 'woo-feed' ),
312
+ 'yoast_mpn' => esc_html__( 'MPN [Yoast SEO]', 'woo-feed' ),
313
+ ];
314
+ }
315
+ }
316
+
317
+ if ( class_exists( 'RankMath' ) || class_exists( 'RankMathPro' ) ) {
318
+ $seoAttributes = [
319
+ 'optionGroup' => esc_html__( 'RANK MATH SEO', 'woo-feed' ),
320
+ 'options' => [
321
+ 'rank_math_title' => esc_html__( 'Title [RankMath SEO]', 'woo-feed' ),
322
+ 'rank_math_description' => esc_html__( 'Description [RankMath SEO]', 'woo-feed' ),
323
+ 'rank_math_canonical_url' => esc_html__( 'Canonical URL [RankMath SEO]', 'woo-feed' )
324
+ ],
325
+ ];
326
+
327
+ if ( class_exists( 'RankMathPro' ) ) {
328
+ $seoAttributes['options'] += [ 'rank_math_gtin' => esc_html__( 'GTIN [RankMath Pro SEO]', 'woo-feed' ) ];
329
+ }
330
+ }
331
+
332
+ if ( class_exists( 'AIOSEO\Plugin\AIOSEO' ) ) {
333
+ $seoAttributes = [
334
+ 'optionGroup' => esc_html__( 'ALL IN ONE SEO', 'woo-feed' ),
335
+ 'options' => [
336
+ '_aioseop_title' => esc_html__( 'Title [All in One SEO]', 'woo-feed' ),
337
+ '_aioseop_description' => esc_html__( 'Description [All in One SEO]', 'woo-feed' ),
338
+ '_aioseop_canonical_url' => esc_html__( 'Canonical URL [All in One SEO]', 'woo-feed' ),
339
+ ],
340
+ ];
341
+ }
342
+
343
+ return $seoAttributes;
344
+ }
345
+
346
+ /**
347
+ * Get Product Global Attributes.
348
+ *
349
+ * @retun array
350
+ */
351
+ private static function getGlobalAttributes() {
352
+ $taxonomies = Cache::get( 'getAttributeTaxonomies' );
353
+ if ( false === $taxonomies ) {
354
+ // Load the main attributes
355
+ $globalAttributes = wc_get_attribute_taxonomy_labels();
356
+ if ( count( $globalAttributes ) ) {
357
+ foreach ( $globalAttributes as $key => $value ) {
358
+ $taxonomies[ Woo_Feed_Products_v3::PRODUCT_ATTRIBUTE_PREFIX . 'pa_' . $key ] = $value;
359
+ }
360
+ }
361
+ Cache::set( 'getAttributeTaxonomies', $taxonomies );
362
+ }
363
+
364
+ return [
365
+ 'optionGroup' => esc_html__( 'Product Attributes', 'woo-feed' ),
366
+ 'options' => $taxonomies,
367
+ ];
368
+ }
369
+
370
+ /**
371
+ * Get Product Custom Attributes.
372
+ *
373
+ * @retun array
374
+ */
375
+ private static function getCustomAttributes() {
376
+ $attributes = Cache::get( 'woo_feed_dropdown_product_custom_attributes' );
377
+ if ( false === $attributes ) {
378
+ // Get Variation Attributes
379
+ $attributes = self::queryVariationsAttributes();
380
+ // Get Product Custom Attributes
381
+ $attributes += self::queryCustomAttributes();
382
+
383
+ Cache::set( 'woo_feed_dropdown_product_custom_attributes', $attributes );
384
+ }
385
+
386
+ return [
387
+ 'optionGroup' => esc_html__( 'Product Custom Attributes', 'woo-feed' ),
388
+ 'options' => $attributes,
389
+ ];
390
+ }
391
+
392
+ /**
393
+ * Get Variation Attributes
394
+ * Local attributes will be found on variation product meta only with attribute_ suffix
395
+ */
396
+ private static function queryVariationsAttributes() {
397
+ // Get Variation Attributes
398
+ global $wpdb;
399
+ $attributes = array();
400
+ $sql = "SELECT DISTINCT( meta_key ) FROM $wpdb->postmeta
401
+ WHERE post_id IN (
402
+ SELECT ID FROM $wpdb->posts WHERE post_type = 'product_variation' -- local attributes will be found on variation product meta only with attribute_ suffix
403
+ ) AND (
404
+ meta_key LIKE 'attribute_%' -- include only product attributes from meta list
405
+ AND meta_key NOT LIKE 'attribute_pa_%'
406
+ )";
407
+ // sanitization ok
408
+ $localAttributes = $wpdb->get_col( $sql ); // phpcs:ignore
409
+
410
+ foreach ( $localAttributes as $localAttribute ) {
411
+ $localAttribute = str_replace( 'attribute_', '', $localAttribute );
412
+ $attributes[ AttributeValueByType::PRODUCT_ATTRIBUTE_PREFIX . $localAttribute ] = ucwords( str_replace( '-', ' ', $localAttribute ) );
413
+ }
414
+
415
+ return $attributes;
416
+ }
417
+
418
+ /**
419
+ * Get Product Custom Attributes
420
+ */
421
+ private static function queryCustomAttributes() {
422
+ global $wpdb;
423
+ $attributes = array();
424
+ $sql = 'SELECT meta.meta_id, meta.meta_key as name, meta.meta_value as type FROM ' . $wpdb->postmeta . ' AS meta, ' . $wpdb->posts . " AS posts WHERE meta.post_id = posts.id AND posts.post_type LIKE '%product%' AND meta.meta_key='_product_attributes';";
425
+ $customAttributes = $wpdb->get_results( $sql ); // phpcs:ignore
426
+ if ( ! empty( $customAttributes ) ) {
427
+ foreach ( $customAttributes as $value ) {
428
+ $product_attr = maybe_unserialize( $value->type );
429
+ if ( is_array( $product_attr ) ) {
430
+ foreach ( $product_attr as $key => $arr_value ) {
431
+ if ( strpos( $key, 'pa_' ) === false ) {
432
+ $attributes[ AttributeValueByType::PRODUCT_ATTRIBUTE_PREFIX . $key ] = ucwords( str_replace( '-', ' ', $arr_value['name'] ) );
433
+ }
434
+ }
435
+ }
436
+ }
437
+ }
438
+
439
+ return $attributes;
440
+ }
441
+
442
+ /**
443
+ * Get All Taxonomy
444
+ *
445
+ * @return array
446
+ */
447
+ private static function getAllTaxonomy() {
448
+ $info = Cache::get( 'woo_feed_dropdown_product_taxonomy' );
449
+ if ( false === $info ) {
450
+ $info = array();
451
+ global $wp_taxonomies;
452
+ $default_excludes = array(
453
+ 'product_type',
454
+ 'product_visibility',
455
+ 'product_cat',
456
+ 'product_tag',
457
+ 'product_shipping_class',
458
+ 'translation_priority',
459
+ );
460
+
461
+ /**
462
+ * Exclude Taxonomy from dropdown
463
+ *
464
+ * @param array $user_excludes
465
+ * @param array $default_excludes
466
+ */
467
+
468
+ $user_excludes = apply_filters( 'woo_feed_dropdown_exclude_taxonomy', null, $default_excludes );
469
+ $default_excludes = ! empty( $user_excludes ) ? array_merge( $default_excludes, $user_excludes ) : $default_excludes;
470
+
471
+ foreach ( get_object_taxonomies( 'product' ) as $value ) {
472
+ $value = ! empty( $value ) ? trim( $value ) : $value;
473
+ if ( in_array( $value, $default_excludes, true ) || strpos( $value, 'pa_' ) !== false ) {
474
+ continue;
475
+ }
476
+ $label = isset( $wp_taxonomies[ $value ] ) ? $wp_taxonomies[ $value ]->label . " [$value]" : $value;
477
+ $info[ Woo_Feed_Products_v3::PRODUCT_TAXONOMY_PREFIX . $value ] = $label;
478
+ }
479
+
480
+ Cache::set( 'woo_feed_dropdown_product_taxonomy', $info );
481
+ }
482
+
483
+ return [
484
+ 'optionGroup' => esc_html__( 'Product Taxonomies', 'woo-feed' ),
485
+ 'options' => $info,
486
+ ];
487
+ }
488
+
489
+ /**
490
+ * Get All Options
491
+ *
492
+ * @return array
493
+ */
494
+ private static function getAllOptions() {
495
+ $_wp_options = wp_list_pluck( get_option( 'wpfp_option', array() ), 'option_name' );
496
+ $_wp_options_val = str_replace( 'wf_option_', '', $_wp_options );
497
+ $_wp_options = array_combine( $_wp_options, $_wp_options_val );
498
+
499
+ return [
500
+ 'optionGroup' => esc_html__( 'Options', 'woo-feed' ),
501
+ 'options' => $_wp_options,
502
+ ];
503
+ }
504
+
505
+ /**
506
+ * Get Category Mappings
507
+ *
508
+ * @return array
509
+ */
510
+ private static function getCategoryMappedAttributes() {
511
+ global $wpdb;
512
+ // Load Custom Category Mapped Attributes
513
+ $info = array();
514
+ // query cached and escaped
515
+ $data = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->options WHERE option_name LIKE %s;", Woo_Feed_Products_v3::PRODUCT_CATEGORY_MAPPING_PREFIX . '%' ) ); // phpcs:ignore
516
+ if ( count( $data ) ) {
517
+ foreach ( $data as $value ) {
518
+ $opts = maybe_unserialize( $value->option_value );
519
+ $opts = maybe_unserialize( $opts );
520
+ $info[ $value->option_name ] = is_array( $opts ) && isset( $opts['mappingname'] ) ? $opts['mappingname'] : str_replace(
521
+ 'wf_cmapping_',
522
+ '',
523
+ $value->option_name
524
+ );
525
+ }
526
+ }
527
+
528
+ return [
529
+ 'optionGroup' => esc_html__( 'Category Mapping', 'woo-feed' ),
530
+ 'options' => $info,
531
+ ];
532
+ }
533
+
534
+ /**
535
+ * Get Advance Custom Field (ACF) field list
536
+ *
537
+ * @return array
538
+ */
539
+ private static function getACFAttributes() {
540
+ $options = [];
541
+ if ( class_exists( 'ACF' ) ) {
542
+ $acf_fields = Cache::get( 'acf_field_list' );
543
+ if ( false === $acf_fields && function_exists( 'acf_get_field_groups' ) ) {
544
+ $field_groups = acf_get_field_groups();
545
+ foreach ( $field_groups as $group ) {
546
+ // DO NOT USE here: $fields = acf_get_fields($group['key']);
547
+ // because it causes repeater field bugs and returns "trashed" fields
548
+ $fields = get_posts(
549
+ array(
550
+ 'posts_per_page' => - 1,
551
+ 'post_type' => 'acf-field',
552
+ 'orderby' => 'menu_order',
553
+ 'order' => 'ASC',
554
+ 'suppress_filters' => true, // DO NOT allow WPML to modify the query
555
+ 'post_parent' => $group['ID'],
556
+ 'post_status' => 'any',
557
+ 'update_post_meta_cache' => false,
558
+ )
559
+ );
560
+ foreach ( $fields as $field ) {
561
+ $options[ 'acf_fields_' . $field->post_name ] = $field->post_title;
562
+ }
563
+ }
564
+
565
+ Cache::set( 'acf_field_list', $options );
566
+ }
567
+ }
568
+
569
+ return [
570
+ 'optionGroup' => esc_html__( 'Advance Custom Fields (ACF)', 'woo-feed' ),
571
+ 'options' => $options,
572
+ ];
573
+ }
574
+
575
+ /**
576
+ * Get All Custom Attributes
577
+ *
578
+ * @return array
579
+ */
580
+ private static function getProductMetaKeyAttributes() {
581
+ $info = Cache::get( 'woo_feed_dropdown_meta_keys' );
582
+ if ( false === $info ) {
583
+ global $wpdb;
584
+ $info = [];
585
+ // Load the main attributes.
586
+
587
+ $default_exclude_keys = [
588
+ // WP internals.
589
+ '_edit_lock',
590
+ '_wp_old_slug',
591
+ '_edit_last',
592
+ '_wp_old_date',
593
+ // WC internals.
594
+ '_downloadable_files',
595
+ '_sku',
596
+ '_weight',
597
+ '_width',
598
+ '_height',
599
+ '_length',
600
+ '_file_path',
601
+ '_file_paths',
602
+ '_default_attributes',
603
+ '_product_attributes',
604
+ '_children',
605
+ '_variation_description',
606
+ // ignore variation description, engine will get child product description from WC CRUD WC_Product::get_description().
607
+ // Plugin Data.
608
+ '_wpcom_is_markdown',
609
+ // JetPack Meta.
610
+ '_yith_wcpb_bundle_data',
611
+ // Yith product bundle data.
612
+ '_et_builder_version',
613
+ // Divi builder data.
614
+ '_vc_post_settings',
615
+ // Visual Composer (WP Bakery) data.
616
+ '_enable_sidebar',
617
+ 'frs_woo_product_tabs',
618
+ // WooCommerce Custom Product Tabs http://www.skyverge.com/.
619
+ ];
620
+
621
+ /**
622
+ * Exclude meta keys from dropdown
623
+ *
624
+ * @param array $exclude meta keys to exclude.
625
+ * @param array $default_exclude_keys Exclude keys by default.
626
+ */
627
+ $user_exclude = apply_filters( 'woo_feed_dropdown_exclude_meta_keys', null, $default_exclude_keys );
628
+
629
+ if ( is_array( $user_exclude ) && ! empty( $user_exclude ) ) {
630
+ $user_exclude = esc_sql( $user_exclude );
631
+ $default_exclude_keys = array_merge( $default_exclude_keys, $user_exclude );
632
+ }
633
+
634
+ $default_exclude_keys = array_map( 'esc_sql', $default_exclude_keys );
635
+ $exclude_keys = '\'' . implode( '\', \'', $default_exclude_keys ) . '\'';
636
+
637
+ $default_exclude_key_patterns = [
638
+ '%_et_pb_%', // Divi builder data
639
+ 'attribute_%', // Exclude product attributes from meta list
640
+ '_yoast_wpseo_%', // Yoast SEO Data
641
+ '_acf-%', // ACF duplicate fields
642
+ '_aioseop_%', // All In One SEO Pack Data
643
+ '_oembed%', // exclude oEmbed cache meta
644
+ '_wpml_%', // wpml metas
645
+ '_oh_add_script_%', // SOGO Add Script to Individual Pages Header Footer.
646
+ ];
647
+
648
+ /**
649
+ * Exclude meta key patterns from dropdown
650
+ *
651
+ * @param array $exclude meta keys to exclude.
652
+ * @param array $default_exclude_key_patterns Exclude keys by default.
653
+ */
654
+ $user_exclude_patterns = apply_filters( 'woo_feed_dropdown_exclude_meta_keys_pattern', null, $default_exclude_key_patterns );
655
+ if ( is_array( $user_exclude_patterns ) && ! empty( $user_exclude_patterns ) ) {
656
+ $default_exclude_key_patterns = array_merge( $default_exclude_key_patterns, $user_exclude_patterns );
657
+ }
658
+ $exclude_key_patterns = '';
659
+ foreach ( $default_exclude_key_patterns as $pattern ) {
660
+ $exclude_key_patterns .= $wpdb->prepare( ' AND meta_key NOT LIKE %s', $pattern );
661
+ }
662
+
663
+ $sql = sprintf( /** @lang text */ "SELECT DISTINCT( meta_key ) FROM %s WHERE 1=1 AND post_id IN ( SELECT ID FROM %s WHERE post_type = 'product' OR post_type = 'product_variation' ) AND ( meta_key NOT IN ( %s ) %s )", $wpdb->postmeta, $wpdb->posts, $exclude_keys, $exclude_key_patterns );
664
+
665
+ // sql escaped, cached
666
+ $data = $wpdb->get_results( $sql ); // phpcs:ignore
667
+
668
+ if ( count( $data ) ) {
669
+ foreach ( $data as $value ) {
670
+ //TODO Remove ACF Fields
671
+ $info[ AttributeValueByType::POST_META_PREFIX . $value->meta_key ] = $value->meta_key;
672
+ }
673
+ }
674
+ Cache::set( 'woo_feed_dropdown_meta_keys', $info );
675
+ }
676
+
677
+ return [
678
+ 'optionGroup' => esc_html__( 'Custom Fields & Post Metas', 'woo-feed' ),
679
+ 'options' => $info,
680
+ ];
681
+ }
682
+
683
+ /**
684
+ * Get Dynamic Attribute List
685
+ *
686
+ * @return array
687
+ */
688
+ private static function getDynamicAttributes() {
689
+ global $wpdb;
690
+
691
+ // Load Custom Category Mapped Attributes
692
+ $info = array();
693
+ // query escaped and cached
694
+ $data = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->options WHERE option_name LIKE %s;", AttributeValueByType::PRODUCT_DYNAMIC_ATTRIBUTE_PREFIX . '%' ) ); // phpcs:ignore
695
+ if ( count( $data ) ) {
696
+ foreach ( $data as $value ) {
697
+ $opts = maybe_unserialize( $value->option_value );
698
+ $opts = maybe_unserialize( $opts );
699
+ $info[ $value->option_name ] = is_array( $opts ) && isset( $opts['wfDAttributeName'] ) ? $opts['wfDAttributeName'] : str_replace(
700
+ 'wf_dattribute_',
701
+ '',
702
+ $value->option_name
703
+ );
704
+ }
705
+ }
706
+
707
+ return [
708
+ 'optionGroup' => esc_html__( 'Dynamic Attributes', 'woo-feed' ),
709
+ 'options' => $info,
710
+ ];
711
+ }
712
+
713
+ /**
714
+ * Get Attribute Mappings
715
+ *
716
+ * @return array
717
+ */
718
+ private static function getCustomMappedAttributes() {
719
+ global $wpdb;
720
+ // Load Custom Category Mapped Attributes
721
+ $info = [];
722
+ // query cached and escaped
723
+ $data = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->options WHERE option_name LIKE %s;", AttributeValueByType::PRODUCT_ATTRIBUTE_MAPPING_PREFIX . '%' ) ); // phpcs:ignore
724
+ if ( count( $data ) ) {
725
+ foreach ( $data as $value ) {
726
+ $opts = maybe_unserialize( $value->option_value );
727
+ $info[ $value->option_name ] = is_array( $opts ) && isset( $opts['name'] ) ? $opts['name'] : str_replace( AttributeValueByType::PRODUCT_ATTRIBUTE_MAPPING_PREFIX, '', $value->option_name );
728
+ }
729
+ }
730
+
731
+ return [
732
+ 'optionGroup' => esc_html__( 'Attribute Mappings', 'woo-feed' ),
733
+ 'options' => $info,
734
+ ];
735
+ }
736
+
737
+ /**
738
+ * @return array
739
+ */
740
+ private static function getMultiLanguageAttributes() {
741
+ $attributes = [];
742
+ if ( class_exists( 'SitePress' ) ) {
743
+ $attributes = [
744
+ 'optionGroup' => esc_html__( 'WPML Attributes', 'woo-feed' ),
745
+ 'options' => [
746
+ 'parent_id' => esc_html__( 'Parent Product ID', 'woo-feed' )
747
+ ]
748
+ ];
749
+ }
750
+
751
+ return $attributes;
752
+ }
753
+
754
+ /**
755
+ * @return array
756
+ */
757
+ private static function getMultiVendorAttributes() {
758
+ $attributes = [];
759
+ if ( function_exists( 'woo_feed_is_multi_vendor' ) && woo_feed_is_multi_vendor() ) {
760
+ $attributes = [
761
+ 'optionGroup' => esc_html__( 'Multi Vendor Attributes', 'woo-feed' ),
762
+ 'options' => [
763
+ 'vendor_store_name' => esc_html__( 'Vendor Store Name', 'woo-feed' )
764
+ ]
765
+ ];
766
+ }
767
+
768
+ return $attributes;
769
+ }
770
+ }
771
+
V5/Product/ProductFactory.php ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Product;
4
+
5
+ use CTXFeed\V5\File\FileFactory;
6
+ use CTXFeed\V5\Filter\ValidateProduct;
7
+ use CTXFeed\V5\Helper\ProductHelper;
8
+ use CTXFeed\V5\Utility\Logs;
9
+
10
+ /**
11
+ *
12
+ */
13
+ class ProductFactory {
14
+
15
+ /**
16
+ * @param $ids
17
+ * @param $config
18
+ * @param $structure
19
+ *
20
+ * @return \CTXFeed\V5\File\FileInfo
21
+ */
22
+ public static function get_content( $ids, $config, $structure ) {
23
+ $info = [];
24
+ Logs::log_feed_process( $config->filename, 'Getting Products Information.' );
25
+ Logs::log_feed_process( $config->filename, 'Validating Product' );
26
+
27
+ foreach ( $ids as $id ) {
28
+ $product = wc_get_product( $id );
29
+
30
+ // Validate Product and add for feed.
31
+ if ( ValidateProduct::is_valid( $product, $config, $id ) ) {
32
+ $info1 = [];
33
+ $info [] = self::get_product_info( $product, $structure, $config, $info1 );
34
+ }
35
+ }
36
+
37
+ return FileFactory::GetData( $info, $config );
38
+ }
39
+
40
+ /**
41
+ * @param $product
42
+ * @param $structure
43
+ * @param $config
44
+ * @param $info
45
+ *
46
+ * @return array|mixed
47
+ */
48
+ public static function get_product_info( $product, $structure, $config, $info ) {
49
+ if ( is_array( $structure ) ) {
50
+ foreach ( $structure as $key => $attribute ) {
51
+ if ( is_array( $attribute ) ) {
52
+ $value[ $key ] = self::get_product_info( $product, $attribute, $config, $info );
53
+ } else if ( $config->feedType === 'xml' ) {
54
+ $value[ $key ] = ProductHelper::getAttributeValueByType( $attribute, $product, $config, $key );
55
+ } else {
56
+ $value[ $key ] = self::get_csv_attribute_value( $attribute, $product, $config, $key );
57
+ }
58
+ }
59
+ } else {
60
+ return $info;
61
+ }
62
+
63
+ return $value;
64
+ }
65
+
66
+ /**
67
+ * @param $attribute
68
+ * @param $product
69
+ * @param \CTXFeed\V5\Utility\Config $config
70
+ * @param $merchant_attribute
71
+ *
72
+ * @return mixed|void
73
+ */
74
+ public static function get_csv_attribute_value( $attribute, $product, $config, $merchant_attribute ) {
75
+
76
+ $value = [];
77
+ if ( strpos( $attribute, ',' ) ) {
78
+ $separator = ',';
79
+ $data3 = explode( ',', $attribute );
80
+ foreach ( $data3 as $data2 ) {
81
+ if ( strpos( $attribute, ':' ) ) {
82
+ $value[] = self::get_csv_attribute_value( $data2, $product, $config, $merchant_attribute );
83
+ } else {
84
+ $value[] = ProductHelper::getAttributeValueByType( $data2, $product, $config, $merchant_attribute );
85
+ }
86
+ }
87
+
88
+ return implode( $separator, array_filter( $value ) );
89
+ }
90
+
91
+ if ( strpos( $attribute, ':' ) ) {
92
+ $separator = ':';
93
+ $attribute = explode( ':', $attribute );
94
+ foreach ( $attribute as $data ) {
95
+ $value [] = ProductHelper::getAttributeValueByType( $data, $product, $config );
96
+ }
97
+
98
+ return implode( $separator, array_filter( $value ) );
99
+ }
100
+
101
+ return ProductHelper::getAttributeValueByType( $attribute, $product, $config );
102
+ }
103
+
104
+ }
V5/Product/ProductInfo.php ADDED
@@ -0,0 +1,1340 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Product;
4
+
5
+ use CTXFeed\V5\Helper\CommonHelper;
6
+ use CTXFeed\V5\Helper\ProductHelper;
7
+ use CTXFeed\V5\Price\PriceFactory;
8
+ use CTXFeed\V5\Shipping\ShippingFactory;
9
+ use CTXFeed\V5\Tax\TaxFactory;
10
+ use CTXFeed\V5\Utility\Config;
11
+ use Exception;
12
+ use WC_Product;
13
+ use WC_Product_External;
14
+ use WC_Product_Grouped;
15
+ use WC_Product_Variable;
16
+ use WC_Product_Variation;
17
+
18
+ class ProductInfo {
19
+ /**
20
+ * @var WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External
21
+ */
22
+ private $product;
23
+ /**
24
+ * @var WC_Product|WC_Product_Variable|WC_Product_Variation|WC_Product_Grouped|WC_Product_External
25
+ */
26
+ private $parent_product;
27
+ /**
28
+ * @var Config
29
+ */
30
+ private $config;
31
+
32
+ /**
33
+ *
34
+ * @param WC_Product $product
35
+ * @param Config $config
36
+ */
37
+ public function __construct( $product, $config ) {
38
+ $this->product = $product;
39
+ $this->parent_product = $product;//->is_type('variable') ? wc_get_product( $product->get_parent_id() ) : wc_get_product( $product->get_id() );
40
+ $this->config = $config;
41
+ }
42
+
43
+ /**
44
+ * Get product id.
45
+ *
46
+ * @return mixed|void
47
+ */
48
+ public function id() {
49
+ return apply_filters( 'woo_feed_filter_product_id', $this->product->get_id(), $this->product, $this->config );
50
+ }
51
+
52
+ /**
53
+ * Get product name.
54
+ *
55
+ * @return mixed|void
56
+ */
57
+ public function title() {
58
+
59
+ $title = woo_feed_strip_all_tags( CommonHelper::remove_shortcodes( $this->product->get_name() ) );
60
+
61
+ // Add all available variation attributes to variation title.
62
+ if ( $this->product->is_type( 'variation' ) && ! empty( $this->product->get_attributes() ) ) {
63
+ $title = $this->parent_product->get_name();
64
+ $attributes = [];
65
+ foreach ( $this->product->get_attributes() as $slug => $value ) {
66
+ $attribute = $this->product->get_attribute( $slug );
67
+ if ( ! empty( $attribute ) ) {
68
+ $attributes[ $slug ] = $attribute;
69
+ }
70
+ }
71
+
72
+ // set variation attributes with separator
73
+ $separator = ',';
74
+ if ( 'google' === $this->config->get_feed_template() ) {
75
+ $separator = '-';
76
+ }
77
+ $variation_attributes = implode( $separator, $attributes );
78
+
79
+ //get product title with variation attribute
80
+ $get_with_var_attributes = apply_filters( "woo_feed_get_product_title_with_variation_attribute", true, $this->product, $this->config );
81
+
82
+ if ( $get_with_var_attributes ) {
83
+ $title .= " - " . $variation_attributes;
84
+ }
85
+ }
86
+
87
+ return apply_filters( 'woo_feed_filter_product_title', $title, $this->product, $this->config );
88
+ }
89
+
90
+ /**
91
+ * Get parent product title for variation.
92
+ *
93
+ * @return mixed|void
94
+ */
95
+ public function parent_title() {
96
+ if ( $this->product->is_type( 'variation' ) ) {
97
+ $title = woo_feed_strip_all_tags( CommonHelper::remove_shortcodes( $this->parent_product->get_name() ) );
98
+ } else {
99
+ $title = $this->title();
100
+ }
101
+
102
+ return apply_filters( 'woo_feed_filter_product_parent_title', $title, $this->product, $this->config );
103
+ }
104
+
105
+ /**
106
+ * Get product description.
107
+ *
108
+ * @return mixed|void
109
+ */
110
+ public function description() {
111
+ $description = $this->product->get_description();
112
+
113
+ // Get Variation Description
114
+ if ( empty( $description ) && $this->product->is_type( 'variation' ) ) {
115
+ $description = '';
116
+ if ( ! is_null( $this->parent_product ) ) {
117
+ $description = $this->parent_product->get_description();
118
+ }
119
+ }
120
+
121
+ if ( empty( $description ) ) {
122
+ $description = $this->product->get_short_description();
123
+ }
124
+
125
+ $description = CommonHelper::remove_shortcodes( $description );
126
+
127
+ // Add variations attributes after description to prevent Facebook error
128
+ if ( 'facebook' === $this->config->get_feed_template() && $this->product->is_type( 'variation' ) ) {
129
+ $variationInfo = explode( '-', $this->product->get_name() );
130
+ if ( isset( $variationInfo[1] ) ) {
131
+ $extension = $variationInfo[1];
132
+ } else {
133
+ $extension = $this->product->get_id();
134
+ }
135
+ $description .= ' ' . $extension;
136
+ }
137
+
138
+ //strip tags and spacial characters
139
+ $strip_description = woo_feed_strip_all_tags( wp_specialchars_decode( $description ) );
140
+
141
+ $description = ! empty( strlen( $strip_description ) ) && 0 < strlen( $strip_description ) ? $strip_description : $description;
142
+
143
+ return apply_filters( 'woo_feed_filter_product_description', $description, $this->product, $this->config );
144
+ }
145
+
146
+ /**
147
+ * Get product description with HTML tags.
148
+ *
149
+ * @return mixed|void
150
+ */
151
+ public function description_with_html() {
152
+ $description = $this->product->get_description();
153
+
154
+ // Get Variation Description
155
+ if ( empty( $description ) && $this->product->is_type( 'variation' ) ) {
156
+ $description = '';
157
+ if ( ! is_null( $this->parent_product ) ) {
158
+ $description = $this->parent_product->get_description();
159
+ }
160
+ }
161
+
162
+ if ( empty( $description ) ) {
163
+ $description = $this->product->get_short_description();
164
+ }
165
+
166
+ $description = CommonHelper::remove_shortcodes( $description );
167
+
168
+ // Add variations attributes after description to prevent Facebook error
169
+ if ( 'facebook' === $this->config->get_feed_template() && $this->product->is_type( 'variation' ) ) {
170
+ $variationInfo = explode( '-', $this->product->get_name() );
171
+ if ( isset( $variationInfo[1] ) ) {
172
+ $extension = $variationInfo[1];
173
+ } else {
174
+ $extension = $this->product->get_id();
175
+ }
176
+ $description .= ' ' . $extension;
177
+ }
178
+
179
+ //remove spacial characters
180
+ $description = wp_check_invalid_utf8( wp_specialchars_decode( $description ), true );
181
+
182
+ return apply_filters( 'woo_feed_filter_product_description_with_html', $description, $this->product, $this->config );
183
+ }
184
+
185
+ /**
186
+ * Get product short description.
187
+ *
188
+ * @return mixed|void
189
+ */
190
+ public function short_description() {
191
+ $short_description = $this->product->get_short_description();
192
+
193
+ // Get Variation Short Description
194
+ if ( empty( $short_description ) && $this->product->is_type( 'variation' ) ) {
195
+ $short_description = $this->parent_product->get_short_description();
196
+ }
197
+
198
+ $short_description = CommonHelper::remove_shortcodes( $short_description );
199
+
200
+ // Strip tags and spacial characters
201
+ $short_description = woo_feed_strip_all_tags( wp_specialchars_decode( $short_description ) );
202
+
203
+ return apply_filters( 'woo_feed_filter_product_short_description', $short_description, $this->product, $this->config );
204
+ }
205
+
206
+ /**
207
+ * Get product primary category.
208
+ *
209
+ * @return mixed|void
210
+ */
211
+ public function primary_category() {
212
+ $parent_category = "";
213
+ $separator = apply_filters( 'woo_feed_product_type_separator', ' > ', $this->config );
214
+
215
+ $full_category = $this->product_type();
216
+ if ( ! empty( $full_category ) ) {
217
+ $full_category_array = explode( $separator, $full_category );
218
+ $parent_category = $full_category_array[0];
219
+ }
220
+
221
+ return apply_filters( 'woo_feed_filter_product_primary_category', $parent_category, $this->product, $this->config );
222
+ }
223
+
224
+ /**
225
+ * Get product primary category id.
226
+ *
227
+ * @return mixed|void
228
+ */
229
+ public function primary_category_id() {
230
+ $parent_category_id = "";
231
+ $separator = apply_filters( 'woo_feed_product_type_separator', ' > ', $this->config );
232
+ $full_category = $this->product_type();
233
+ if ( ! empty( $full_category ) ) {
234
+ $full_category_array = explode( $separator, $full_category );
235
+ $parent_category_obj = get_term_by( 'name', $full_category_array[0], 'product_cat' );
236
+ $parent_category_id = isset( $parent_category_obj->term_id ) ? $parent_category_obj->term_id : "";
237
+ }
238
+
239
+ return apply_filters( 'woo_feed_filter_product_primary_category_id', $parent_category_id, $this->product, $this->config );
240
+ }
241
+
242
+ /**
243
+ * Get product child category.
244
+ *
245
+ * @return mixed|void
246
+ */
247
+ public function child_category() {
248
+ $child_category = "";
249
+ $separator = apply_filters( 'woo_feed_product_type_separator', ' > ', $this->config );
250
+ $full_category = $this->product_type();
251
+ if ( ! empty( $full_category ) ) {
252
+ $full_category_array = explode( $separator, $full_category );
253
+ $child_category = end( $full_category_array );
254
+ }
255
+
256
+ return apply_filters( 'woo_feed_filter_product_child_category', $child_category, $this->product, $this->config );
257
+ }
258
+
259
+ /**
260
+ * Get product child category id.
261
+ *
262
+ * @return mixed|void
263
+ */
264
+ public function child_category_id() {
265
+ $child_category_id = "";
266
+ $separator = apply_filters( 'woo_feed_product_type_separator', ' > ', $this->config );
267
+ $full_category = $this->product_type();
268
+ if ( ! empty( $full_category ) ) {
269
+ $full_category_array = explode( $separator, $full_category );
270
+ $child_category_obj = get_term_by( 'name', end( $full_category_array ), 'product_cat' );
271
+ $child_category_id = isset( $child_category_obj->term_id ) ? $child_category_obj->term_id : "";
272
+ }
273
+
274
+ return apply_filters( 'woo_feed_filter_product_child_category_id', $child_category_id, $this->product, $this->config );
275
+ }
276
+
277
+ /**
278
+ * Get product type.
279
+ *
280
+ * @return mixed|void
281
+ */
282
+ public function product_type() {
283
+ $id = $this->product->get_id();
284
+ if ( $this->product->is_type( 'variation' ) ) {
285
+ $id = $this->product->get_parent_id();
286
+ }
287
+
288
+ $separator = apply_filters( 'woo_feed_product_type_separator', ' > ', $this->config );
289
+ $product_categories = '';
290
+ $term_list = get_the_terms( $id, 'product_cat' );
291
+
292
+ if ( is_array( $term_list ) ) {
293
+ $col = array_column( $term_list, "term_id" );
294
+ array_multisort( $col, SORT_ASC, $term_list );
295
+ $term_list = array_column( $term_list, "name" );
296
+ //TODO: Remove Manual Separator and add Dynamically with hook. Hook function also need to modified from array to object.
297
+ $product_categories = implode( ' > ', $term_list );
298
+ }
299
+
300
+
301
+ return apply_filters( 'woo_feed_filter_product_local_category', $product_categories, $this->product, $this->config );
302
+ }
303
+
304
+ /**
305
+ * Get product full category.
306
+ *
307
+ * @return mixed|void
308
+ */
309
+ public function product_full_cat() {
310
+
311
+ $id = $this->product->get_id();
312
+ if ( $this->product->is_type( 'variation' ) ) {
313
+ $id = $this->product->get_parent_id();
314
+ }
315
+
316
+ $separator = apply_filters( 'woo_feed_product_type_separator', ' > ', $this->config, $this->product );
317
+
318
+ $product_type = wp_strip_all_tags( wc_get_product_category_list( $id, $separator ) );
319
+
320
+
321
+ return apply_filters( 'woo_feed_filter_product_local_category', $product_type, $this->product, $this->config );
322
+ }
323
+
324
+ /**
325
+ * Get product URL.
326
+ *
327
+ * @return mixed|void
328
+ */
329
+ public function link() {
330
+ $link = $this->product->get_permalink();
331
+
332
+ if ( $this->config->get_campaign_parameters() ) {
333
+ $link = CommonHelper::add_utm_parameter( $this->config->get_campaign_parameters(), $link );
334
+ }
335
+
336
+ return apply_filters( 'woo_feed_filter_product_link', $link, $this->product, $this->config );
337
+ }
338
+
339
+ /**
340
+ * Get product parent URL.
341
+ *
342
+ * @return mixed|void
343
+ */
344
+ public function parent_link() {
345
+ $link = $this->product->get_permalink();
346
+ if ( $this->product->is_type( 'variation' ) ) {
347
+ $link = $this->parent_product->get_permalink();
348
+ }
349
+
350
+ if ( $this->config->get_campaign_parameters() ) {
351
+ $link = CommonHelper::add_utm_parameter( $this->config->get_campaign_parameters(), $link );
352
+ }
353
+
354
+ return apply_filters( 'woo_feed_filter_product_parent_link', $link, $this->product, $this->config );
355
+ }
356
+
357
+ /**
358
+ * Get product Canonical URL.
359
+ *
360
+ * @return mixed|void
361
+ */
362
+ public function canonical_link() {
363
+ //TODO: check if SEO plugin installed then return SEO canonical URL
364
+ $canonical_link = $this->parent_link();
365
+
366
+ return apply_filters( 'woo_feed_filter_product_canonical_link', $canonical_link, $this->product, $this->config );
367
+ }
368
+
369
+ /**
370
+ * Get external product URL.
371
+ *
372
+ * @return mixed|void
373
+ */
374
+ public function ex_link() {
375
+ $ex_link = '';
376
+ if ( $this->product->is_type( 'external' ) ) {
377
+ $ex_link = $this->product->get_product_url();
378
+ if ( $this->config->get_campaign_parameters() ) {
379
+ $ex_link = CommonHelper::add_utm_parameter( $this->config->get_campaign_parameters(), $ex_link );
380
+ }
381
+ }
382
+
383
+ return apply_filters( 'woo_feed_filter_product_ex_link', $ex_link, $this->product, $this->config );
384
+ }
385
+
386
+ /**
387
+ * Get product image URL.
388
+ *
389
+ * @return mixed|void
390
+ */
391
+ public function image() {
392
+ $image = '';
393
+ if ( $this->product->is_type( 'variation' ) ) {
394
+ // Variation product type
395
+ if ( has_post_thumbnail( $this->product->get_id() ) ) {
396
+ $getImage = wp_get_attachment_image_src( get_post_thumbnail_id( $this->product->get_id() ), 'single-post-thumbnail' );
397
+ $image = woo_feed_get_formatted_url( $getImage[0] );
398
+ } elseif ( has_post_thumbnail( $this->product->get_parent_id() ) ) {
399
+ $getImage = wp_get_attachment_image_src( get_post_thumbnail_id( $this->product->get_parent_id() ), 'single-post-thumbnail' );
400
+ $image = woo_feed_get_formatted_url( $getImage[0] );
401
+ }
402
+ } elseif ( has_post_thumbnail( $this->product->get_id() ) ) { // All product type except variation
403
+ $getImage = wp_get_attachment_image_src( get_post_thumbnail_id( $this->product->get_id() ), 'single-post-thumbnail' );
404
+ $image = isset( $getImage[0] ) ? woo_feed_get_formatted_url( $getImage[0] ) : '';
405
+ }
406
+
407
+ return apply_filters( 'woo_feed_filter_product_image', $image, $this->product, $this->config );
408
+ }
409
+
410
+ /**
411
+ * Get product featured image URL.
412
+ *
413
+ * @return mixed|void
414
+ */
415
+ public function feature_image() {
416
+ $id = $this->product->get_id();
417
+ if ( $this->product->is_type( 'variation' ) ) {
418
+ $id = $this->product->get_parent_id();
419
+ }
420
+
421
+ $getImage = wp_get_attachment_image_src( get_post_thumbnail_id( $id ), 'single-post-thumbnail' );
422
+ $image = isset( $getImage[0] ) ? woo_feed_get_formatted_url( $getImage[0] ) : '';
423
+
424
+ return apply_filters( 'woo_feed_filter_product_feature_image', $image, $this->product, $this->config );
425
+ }
426
+
427
+ /**
428
+ * Get product images (comma separated URLs).
429
+ *
430
+ * @return mixed|void
431
+ */
432
+ public function images( $additionalImg = '' ) {
433
+ $imgUrls = ProductHelper::get_product_gallery( $this->product );
434
+ $separator = apply_filters( 'woo_feed_filter_category_separator', ' > ', $this->product, $this->config );
435
+
436
+ // Return Specific Additional Image URL
437
+ if ( '' !== $additionalImg ) {
438
+ if ( array_key_exists( $additionalImg, $imgUrls ) ) {
439
+ $images = $imgUrls[ $additionalImg ];
440
+ } else {
441
+ $images = '';
442
+ }
443
+ } else {
444
+ if ( "idealo" === $this->config->get_feed_template() ) {
445
+ $separator = ';';
446
+ }
447
+
448
+ $images = implode( $separator, array_filter( $imgUrls ) );
449
+ }
450
+
451
+ return apply_filters( 'woo_feed_filter_product_images', $images, $this->product, $this->config );
452
+ }
453
+
454
+ public function condition() {
455
+ return apply_filters( 'woo_feed_product_condition', 'new', $this->product, $this->config );
456
+ }
457
+
458
+ public function type() {
459
+ return apply_filters( 'woo_feed_filter_product_type', $this->product->get_type(), $this->product, $this->config );
460
+ }
461
+
462
+ public function is_bundle() {
463
+ $is_bundle = 'no';
464
+ if ( $this->product->is_type( 'bundle' ) || $this->product->is_type( 'yith_bundle' ) ) {
465
+ $is_bundle = 'yes';
466
+ }
467
+
468
+ return apply_filters( 'woo_feed_filter_product_is_bundle', $is_bundle, $this->product, $this->config );
469
+ }
470
+
471
+ public function multipack() {
472
+ $multi_pack = '';
473
+ if ( $this->product->is_type( 'grouped' ) ) {
474
+ $multi_pack = ( ! empty( $this->product->get_children() ) ) ? count( $this->product->get_children() ) : '';
475
+ }
476
+
477
+ return apply_filters( 'woo_feed_filter_product_is_multipack', $multi_pack, $this->product, $this->config );
478
+ }
479
+
480
+ public function visibility() {
481
+ return apply_filters( 'woo_feed_filter_product_visibility', $this->product->get_catalog_visibility(), $this->product, $this->config );
482
+ }
483
+
484
+ public function rating_total() {
485
+ return apply_filters( 'woo_feed_filter_product_rating_total', $this->product->get_rating_count(), $this->product, $this->config );
486
+ }
487
+
488
+ public function rating_average() {
489
+ return apply_filters( 'woo_feed_filter_product_rating_average', $this->product->get_average_rating(), $this->product, $this->config );
490
+ }
491
+
492
+ public function total_sold() {
493
+ } //TODO: Implement this
494
+
495
+ public function tags() {
496
+ $id = $this->product->get_id();
497
+ if ( $this->product->is_type( 'variation' ) ) {
498
+ $id = $this->product->get_parent_id();
499
+ }
500
+
501
+ /**
502
+ * Separator for multiple tags
503
+ *
504
+ * @param string $separator
505
+ * @param array $config
506
+ * @param WC_Abstract_Legacy_Product $product
507
+ *
508
+ * @since 3.4.3
509
+ */
510
+ $separator = apply_filters( 'woo_feed_tags_separator', ',', $this->product, $this->config );
511
+
512
+ $tags = woo_feed_strip_all_tags( get_the_term_list( $id, 'product_tag', '', $separator, '' ) );
513
+
514
+ return apply_filters( 'woo_feed_filter_product_tags', $tags, $this->product, $this->config );
515
+ }
516
+
517
+ public function item_group_id() {
518
+ $id = $this->product->get_id();
519
+ if ( $this->product->is_type( 'variation' ) ) {
520
+ $id = $this->product->get_parent_id();
521
+ }
522
+
523
+ return apply_filters( 'woo_feed_filter_product_item_group_id', $id, $this->product, $this->config );
524
+ }
525
+
526
+ public function sku() {
527
+ return apply_filters( 'woo_feed_filter_product_sku', $this->product->get_sku(), $this->product, $this->config );
528
+ }
529
+
530
+ public function sku_id() {
531
+ $sku = ! empty( $this->product->get_sku() ) ? $this->product->get_sku() . '_' : '';
532
+ $sku_id = $sku . $this->product->get_id();
533
+
534
+ return apply_filters( 'woo_feed_filter_product_sku_id', $sku_id, $this->product, $this->config );
535
+ }
536
+
537
+ public function parent_sku() {
538
+ $parent_sku = $this->product->get_sku();
539
+ if ( $this->product->is_type( 'variation' ) ) {
540
+ $parent_sku = $this->parent_product->get_sku();
541
+ }
542
+
543
+ return apply_filters( 'woo_feed_filter_product_parent_sku', $parent_sku, $this->product, $this->config );
544
+ }
545
+
546
+ public function availability() {
547
+ $status = $this->product->get_stock_status();
548
+ if ( 'instock' === $status ) {
549
+ $status = 'in stock';
550
+ } elseif ( 'outofstock' === $status ) {
551
+ $status = 'out of stock';
552
+ } elseif ( 'onbackorder' === $status ) {
553
+ $status = 'on backorder';
554
+ }
555
+
556
+ // set (_) as separator for google merchant
557
+ if ( 'google' === $this->config->get_feed_template() ) {
558
+ $status = explode( ' ', $status );
559
+ $status = implode( '_', $status );
560
+ }
561
+
562
+ return apply_filters( 'woo_feed_filter_product_availability', $status, $this->product, $this->config );
563
+ }
564
+
565
+ public function availability_date() {
566
+
567
+ $feed_settings = get_option( 'woo_feed_settings' );
568
+
569
+ $availability_date_settings = isset( $feed_settings['woo_feed_identifier']['availability_date'] )
570
+ ? $feed_settings['woo_feed_identifier']['availability_date']
571
+ : 'enable';
572
+
573
+ if ( $this->product->get_stock_status() !== 'onbackorder' || $availability_date_settings === 'disable' ) {
574
+ return '';
575
+ }
576
+
577
+ $meta_field_name = 'woo_feed_availability_date';
578
+
579
+ if ( $this->product->is_type( 'variation' ) ) {
580
+ $meta_field_name .= '_var';
581
+ }
582
+
583
+ $availability_date = get_post_meta( $this->product->get_id(), $meta_field_name, true );
584
+
585
+ if ( '' !== $availability_date && in_array( $this->config->get_feed_template(), [
586
+ 'google',
587
+ 'facebook',
588
+ 'pinterest',
589
+ 'bing',
590
+ 'snapchat',
591
+ ], true ) ) {
592
+ $availability_date = gmdate( 'c', strtotime( $availability_date ) );
593
+ }
594
+
595
+ return apply_filters( 'woo_feed_filter_product_availability_date', $availability_date, $this->product, $this->config );
596
+ }
597
+
598
+ public function add_to_cart_link() {
599
+ $url = $this->link();
600
+ $suffix = 'add-to-cart=' . $this->product->get_id();
601
+
602
+ $add_to_cart_link = woo_feed_make_url_with_parameter( $url, $suffix );
603
+
604
+ return apply_filters( 'woo_feed_filter_product_add_to_cart_link', $add_to_cart_link, $this->product, $this->config );
605
+ }
606
+
607
+ public function quantity() {
608
+ $quantity = $this->product->get_stock_quantity();
609
+ $status = $this->product->get_stock_status();
610
+
611
+ //when product is outofstock , and it's quantity is empty, set quantity to 0
612
+ if ( 'outofstock' === $status && $quantity === null ) {
613
+ $quantity = 0;
614
+ }
615
+
616
+ if ( $this->product->is_type( 'variable' ) && $this->product->has_child() ) {
617
+ $visible_children = $this->product->get_visible_children();
618
+ $qty = array();
619
+ foreach ( $visible_children as $child ) {
620
+ $childQty = get_post_meta( $child, '_stock', true );
621
+ $qty[] = (int) $childQty + 0;
622
+ }
623
+
624
+ if ( isset( $this->config['variable_quantity'] ) ) {
625
+ $vaQty = $this->config['variable_quantity'];
626
+ if ( 'max' === $vaQty ) {
627
+ $quantity = max( $qty );
628
+ } elseif ( 'min' === $vaQty ) {
629
+ $quantity = min( $qty );
630
+ } elseif ( 'sum' === $vaQty ) {
631
+ $quantity = array_sum( $qty );
632
+ } elseif ( 'first' === $vaQty ) {
633
+ $quantity = ( (int) $qty[0] );
634
+ } else {
635
+ $quantity = array_sum( $qty );
636
+ }
637
+ }
638
+ }
639
+
640
+ return apply_filters( 'woo_feed_filter_product_quantity', $quantity, $this->product, $this->config );
641
+ }
642
+
643
+ /**
644
+ * Get Store Currency.
645
+ *
646
+ * @return mixed|void
647
+ */
648
+ public function currency() {
649
+ $quantity = get_option( 'woocommerce_currency' );
650
+
651
+ return apply_filters( 'woo_feed_filter_product_currency', $quantity, $this->product, $this->config );
652
+ }
653
+
654
+ /**
655
+ * Get Product Sale Price start date.
656
+ *
657
+ * @return mixed|void
658
+ */
659
+ public function sale_price_sdate() {
660
+ $startDate = $this->product->get_date_on_sale_from();
661
+ if ( is_object( $startDate ) ) {
662
+ $sale_price_sdate = $startDate->date_i18n();
663
+ } else {
664
+ $sale_price_sdate = '';
665
+ }
666
+
667
+ return apply_filters( 'woo_feed_filter_product_sale_price_sdate', $sale_price_sdate, $this->product, $this->config );
668
+ }
669
+
670
+ /**
671
+ * Get Product Sale Price End Date.
672
+ *
673
+ * @return mixed|void
674
+ */
675
+ public function sale_price_edate() {
676
+ $endDate = $this->product->get_date_on_sale_to();
677
+ if ( is_object( $endDate ) ) {
678
+ $sale_price_edate = $endDate->date_i18n();
679
+ } else {
680
+ $sale_price_edate = "";
681
+ }
682
+
683
+ return apply_filters( 'woo_feed_filter_product_sale_price_edate', $sale_price_edate, $this->product, $this->config );
684
+ }
685
+
686
+ public function price() {
687
+ return PriceFactory::get( $this->product, $this->config )->regular_price();
688
+ }
689
+
690
+ public function current_price() {
691
+ return PriceFactory::get( $this->product, $this->config )->price();
692
+ }
693
+
694
+ public function sale_price() {
695
+ return PriceFactory::get( $this->product, $this->config )->sale_price();
696
+ }
697
+
698
+ public function price_with_tax() {
699
+ return PriceFactory::get( $this->product, $this->config )->regular_price( true );
700
+ }
701
+
702
+ public function current_price_with_tax() {
703
+ return PriceFactory::get( $this->product, $this->config )->price( true );
704
+ }
705
+
706
+ public function sale_price_with_tax() {
707
+ return PriceFactory::get( $this->product, $this->config )->sale_price( true );
708
+ }
709
+
710
+ /**
711
+ * Get Product Weight.
712
+ *
713
+ * @return mixed|void
714
+ */
715
+ public function weight() {
716
+ return apply_filters( 'woo_feed_filter_product_weight', $this->product->get_weight(), $this->product, $this->config );
717
+ }
718
+
719
+ /**
720
+ * Get Weight Unit.
721
+ *
722
+ * @return mixed|void
723
+ */
724
+ public function weight_unit() {
725
+ return apply_filters( 'woo_feed_filter_product_weight_unit', get_option( 'woocommerce_weight_unit' ), $this->product, $this->config );
726
+ }
727
+
728
+ /**
729
+ * Get Product Width.
730
+ *
731
+ * @return mixed|void
732
+ */
733
+ public function width() {
734
+ return apply_filters( 'woo_feed_filter_product_width', $this->product->get_width(), $this->product, $this->config );
735
+ }
736
+
737
+ /**
738
+ * Get Product Height.
739
+ *
740
+ * @return mixed|void
741
+ */
742
+ public function height() {
743
+ return apply_filters( 'woo_feed_filter_product_height', $this->product->get_height(), $this->product, $this->config );
744
+ }
745
+
746
+ /**
747
+ * Get Product Length.
748
+ *
749
+ * @return mixed|void
750
+ */
751
+ public function length() {
752
+ return apply_filters( 'woo_feed_filter_product_length', $this->product->get_length(), $this->product, $this->config );
753
+ }
754
+
755
+ /** Google Formatted Shipping info
756
+ *
757
+ * @return string
758
+ * @throws \Exception
759
+ */
760
+ public function shipping( $key = '' ) {
761
+ try {
762
+ return ( ShippingFactory::get( $this->product, $this->config ) )->get_shipping($key);
763
+ // return apply_filters( 'woo_feed_filter_product_shipping', $shipping, $this->product, $this->config );
764
+ } catch ( Exception $e ) {
765
+
766
+ }
767
+ }
768
+
769
+
770
+ /**
771
+ * Get Shipping Cost.
772
+ *
773
+ * @throws \Exception
774
+ */
775
+ public function shipping_cost() {
776
+ // Get config to which shipping price to return (first, highest or lowest)
777
+ $shipping = ( ShippingFactory::get( $this->product, $this->config ) )->get_shipping_info();
778
+
779
+ $price = "0";
780
+ if ( ! empty( $shipping ) ) {
781
+ if ( isset( $this->config->shipping_price ) ) {
782
+ if ( 'highest' === $this->config->shipping_price ) {
783
+ $price = max( wp_list_pluck( $shipping, 'price' ) );
784
+ } elseif ( 'lowest' === $this->config->shipping_price ) {
785
+ $price = min( wp_list_pluck( $shipping, 'price' ) );
786
+ } else {
787
+ $shipping_prices = wp_list_pluck( $shipping, 'price' );
788
+ $price = reset( $shipping_prices );
789
+ }
790
+ } else {
791
+ $shipping_prices = wp_list_pluck( $shipping, 'price' );
792
+ $price = reset( $shipping_prices );
793
+ }
794
+ }
795
+
796
+ return apply_filters( 'woo_feed_filter_product_shipping_cost', $price, $this->product, $this->config );
797
+ }
798
+
799
+
800
+ /**
801
+ * Get Product Shipping Class
802
+ *
803
+ * @return mixed
804
+ * @since 3.2.0
805
+ *
806
+ */
807
+ public function shipping_class() {
808
+ return apply_filters( 'woo_feed_filter_product_shipping_class', $this->product->get_shipping_class(), $this->product, $this->config );
809
+ }
810
+
811
+ /**
812
+ * Get author name.
813
+ *
814
+ * @return string
815
+ */
816
+ public function author_name() {
817
+ $post = get_post( $this->product->get_id() );
818
+
819
+ return get_the_author_meta( 'user_login', $post->post_author );
820
+ }
821
+
822
+ /**
823
+ * Get Author Email.
824
+ *
825
+ * @return string
826
+ */
827
+ public function author_email() {
828
+ $post = get_post( $this->product->get_id() );
829
+
830
+ return get_the_author_meta( 'user_email', $post->post_author );
831
+ }
832
+
833
+ /**
834
+ * Get Date Created.
835
+ *
836
+ * @return mixed|void
837
+ */
838
+ public function date_created() {
839
+ $date_created = gmdate( 'Y-m-d', strtotime( $this->product->get_date_created() ) );
840
+
841
+ return apply_filters( 'woo_feed_filter_product_date_created', $date_created, $this->product, $this->config );
842
+ }
843
+
844
+ /**
845
+ * Get Date updated.
846
+ *
847
+ * @return mixed|void
848
+ */
849
+ public function date_updated() {
850
+ $date_updated = gmdate( 'Y-m-d', strtotime( $this->product->get_date_modified() ) );
851
+
852
+ return apply_filters( 'woo_feed_filter_product_date_updated', $date_updated, $this->product, $this->config );
853
+ }
854
+
855
+ /** Get Google Sale Price effective date.
856
+ *
857
+ * @return string
858
+ */
859
+ public function sale_price_effective_date() {
860
+ $effective_date = '';
861
+ $from = $this->sale_price_sdate();
862
+ $to = $this->sale_price_edate();
863
+ if ( ! empty( $from ) && ! empty( $to ) ) {
864
+ $from = gmdate( 'c', strtotime( $from ) );
865
+ $to = gmdate( 'c', strtotime( $to ) );
866
+
867
+ $effective_date = $from . '/' . $to;
868
+ }
869
+
870
+ return $effective_date;
871
+ }
872
+
873
+ public function subscription_period() {
874
+ if ( class_exists( 'WC_Subscriptions' ) ) {
875
+ return ProductHelper::get_product_meta( '_subscription_period', $this->product, $this->config );
876
+ }
877
+
878
+ return '';
879
+ }
880
+
881
+ public function subscription_period_interval() {
882
+ if ( class_exists( 'WC_Subscriptions' ) ) {
883
+ return ProductHelper::get_product_meta( '_subscription_period_interval', $this->product, $this->config );
884
+ }
885
+
886
+ return '';
887
+ }
888
+
889
+ public function subscription_amount() {
890
+ // return $this->price($product);
891
+ }
892
+
893
+ public function installment_amount() {
894
+ // return $this->price($product);
895
+ }
896
+
897
+ public function installment_months() {
898
+ if ( class_exists( 'WC_Subscriptions' ) ) {
899
+ return ProductHelper::get_product_meta( '_subscription_length', $this->product, $this->config );
900
+ }
901
+
902
+ return '';
903
+ }
904
+
905
+ public function unit_price_measure() {
906
+ $unit_price_measure = '';
907
+ $identifiers = woo_feed_get_options( 'woo_feed_identifier' );
908
+ if ( 'enable' === $identifiers['unit_pricing_base_measure']
909
+ && 'enable' === $identifiers['unit_pricing_measure']
910
+ && 'enable' === $identifiers['unit']
911
+ ) {
912
+ $unit = ProductHelper::get_custom_filed( 'woo_feed_unit', $this->product, $this->config );
913
+ $unit_price_measure = ProductHelper::get_custom_filed( 'woo_feed_unit_pricing_measure', $this->product, $this->config );
914
+
915
+ $unit_price_measure .= " " . $unit;
916
+ }
917
+
918
+ if ( empty( $unit_price_measure ) && class_exists( 'WooCommerce_Germanized' ) ) { // For WooCommerce Germanized Plugin
919
+ $unit = ProductHelper::get_product_meta( '_unit', $this->product, $this->config );
920
+ $unit_price_measure = ProductHelper::get_product_meta( '_unit_product', $this->product, $this->config );
921
+
922
+ $unit_price_measure .= " " . $unit;
923
+ }
924
+
925
+ return apply_filters( 'woo_feed_filter_unit_price_measure', $unit_price_measure, $this->product, $this->config );
926
+ }
927
+
928
+ public function unit_price_base_measure() {
929
+ $unit_price_base_measure = '';
930
+ $identifiers = woo_feed_get_options( 'woo_feed_identifier' );
931
+ if ( 'enable' === $identifiers['unit_pricing_base_measure']
932
+ && 'enable' === $identifiers['unit_pricing_measure']
933
+ && 'enable' === $identifiers['unit']
934
+ ) {
935
+ $unit = ProductHelper::get_custom_filed( 'woo_feed_unit', $this->product, $this->config );
936
+ $unit_price_base_measure = ProductHelper::get_custom_filed( 'woo_feed_unit_pricing_base_measure', $this->product, $this->config );
937
+ $unit_price_base_measure .= " " . $unit;
938
+ }
939
+
940
+ if ( empty( $unit_price_base_measure ) && class_exists( 'WooCommerce_Germanized' ) ) { // For WooCommerce Germanized Plugin
941
+ $unit = ProductHelper::get_product_meta( '_unit', $this->product, $this->config );
942
+ $unit_price_base_measure = ProductHelper::get_product_meta( '_unit_base', $this->product, $this->config );
943
+ $unit_price_base_measure .= " " . $unit;
944
+ }
945
+
946
+ return apply_filters( 'woo_feed_filter_unit_price_base_measure', $unit_price_base_measure, $this->product, $this->config );
947
+ }
948
+
949
+ public function wc_germanized_gtin() {
950
+ $wc_germanized_gtin = '';
951
+ if ( class_exists( 'WooCommerce_Germanized' ) ) { // For WooCommerce Germanized Plugin
952
+ $wc_germanized_gtin = ProductHelper::get_product_meta( '_ts_gtin', $this->product, $this->config );
953
+ }
954
+
955
+ return apply_filters( 'woo_feed_filter_wc_germanized_gtin', $wc_germanized_gtin, $this->product, $this->config );
956
+ }
957
+
958
+ public function wc_germanized_mpn() {
959
+ $wc_germanized_mpn = '';
960
+ if ( class_exists( 'WooCommerce_Germanized' ) ) { // For WooCommerce Germanized Plugin
961
+ $wc_germanized_mpn = ProductHelper::get_product_meta( '_ts_mpn', $this->product, $this->config );
962
+ }
963
+
964
+ return apply_filters( 'woo_feed_filter_wc_germanized_mpn', $wc_germanized_mpn, $this->product, $this->config );
965
+ }
966
+
967
+ # SEO Plugins
968
+
969
+ public function yoast_wpseo_title() {
970
+ $product_id = woo_feed_parent_product_id( $this->product );
971
+ $yoast_title = get_post_meta( $product_id, '_yoast_wpseo_title', true );
972
+ if ( strpos( $yoast_title, '%%' ) !== false ) {
973
+ $title = strstr( $yoast_title, '%%', true );
974
+ if ( empty( $title ) ) {
975
+ $title = get_the_title( $product_id );
976
+ }
977
+ $wpseo_titles = get_option( 'wpseo_titles' );
978
+
979
+ $sep_options = WPSEO_Option_Titles::get_instance()->get_separator_options();
980
+ if ( isset( $wpseo_titles['separator'], $sep_options[ $wpseo_titles['separator'] ] ) ) {
981
+ $sep = $sep_options[ $wpseo_titles['separator'] ];
982
+ } else {
983
+ $sep = '-'; //setting default separator if Admin didn't set it from backed
984
+ }
985
+
986
+ $site_title = get_bloginfo( 'name' );
987
+
988
+ $meta_title = $title . ' ' . $sep . ' ' . $site_title;
989
+
990
+ if ( ! empty( $meta_title ) ) {
991
+ $title = $meta_title;
992
+ }
993
+ } elseif ( ! empty( $yoast_title ) ) {
994
+ $title = $yoast_title;
995
+ } else {
996
+ $title = $this->title();
997
+ }
998
+
999
+ return apply_filters( 'woo_feed_filter_product_yoast_wpseo_title', $title, $this->product, $this->config );
1000
+ }
1001
+
1002
+ public function yoast_wpseo_metadesc() {
1003
+ $product_id = woo_feed_parent_product_id( $this->product );
1004
+ $description = '';
1005
+ if ( class_exists( 'WPSEO_Frontend' ) ) {
1006
+ $description = wpseo_replace_vars( WPSEO_Meta::get_value( 'metadesc', $product_id ),
1007
+ get_post( $this->product->get_id() ) );
1008
+ } else {
1009
+ $description = YoastSEO()->meta->for_post( $product_id )->description;
1010
+ }
1011
+
1012
+ if ( empty( $description ) ) {
1013
+ $description = $this->description();
1014
+ }
1015
+
1016
+ return apply_filters( 'woo_feed_filter_product_yoast_wpseo_metadesc', $description, $this->product, $this->config );
1017
+ }
1018
+
1019
+ public function yoast_canonical_url() {
1020
+ $product_id = woo_feed_parent_product_id( $this->product );
1021
+ $yoast_canonical_url = get_post_meta( $product_id, '_yoast_wpseo_canonical', true );
1022
+
1023
+ return apply_filters( 'woo_feed_filter_product_yoast_canonical_url', $yoast_canonical_url, $this->product, $this->config );
1024
+ }
1025
+
1026
+ public function yoast_gtin8() {
1027
+ $yoast_gtin8_value = woo_feed_get_yoast_identifiers_value( 'gtin8', $this->product );
1028
+
1029
+ return apply_filters( 'yoast_gtin8_attribute_value', $yoast_gtin8_value, $this->product );
1030
+ }
1031
+
1032
+ public function yoast_gtin12() {
1033
+ $yoast_gtin8_value = woo_feed_get_yoast_identifiers_value( 'gtin12', $this->product );
1034
+
1035
+ return apply_filters( 'yoast_gtin12_attribute_value', $yoast_gtin8_value, $this->product );
1036
+ }
1037
+
1038
+ public function yoast_gtin13() {
1039
+ $yoast_gtin8_value = woo_feed_get_yoast_identifiers_value( 'gtin13', $this->product );
1040
+
1041
+ return apply_filters( 'yoast_gtin13_attribute_value', $yoast_gtin8_value, $this->product );
1042
+ }
1043
+
1044
+ public function yoast_gtin14() {
1045
+ $yoast_gtin8_value = woo_feed_get_yoast_identifiers_value( 'gtin14', $this->product );
1046
+
1047
+ return apply_filters( 'yoast_gtin14_attribute_value', $yoast_gtin8_value, $this->product );
1048
+ }
1049
+
1050
+ public function yoast_isbn() {
1051
+ $yoast_gtin8_value = woo_feed_get_yoast_identifiers_value( 'isbn', $this->product );
1052
+
1053
+ return apply_filters( 'yoast_isbn_attribute_value', $yoast_gtin8_value, $this->product );
1054
+ }
1055
+
1056
+ public function yoast_mpn() {
1057
+ $yoast_gtin8_value = woo_feed_get_yoast_identifiers_value( 'mpn', $this->product );
1058
+
1059
+ return apply_filters( 'yoast_mpn_attribute_value', $yoast_gtin8_value, $this->product );
1060
+ }
1061
+
1062
+ public function rank_math_title() {
1063
+ $rank_title = '';
1064
+ if ( class_exists( 'RankMath' ) ) {
1065
+ $title = get_post_meta( $this->product->get_id(), 'rank_math_title', true );
1066
+ if ( empty( $title ) ) {
1067
+ $title_format = Helper::get_settings( "titles.pt_product_title" );
1068
+ $title_format = $title_format ? $title_format : '%title%';
1069
+ $sep = Helper::get_settings( 'titles.title_separator' );
1070
+
1071
+ $rank_title = str_replace( '%title%', $this->product->get_title(), $title_format );
1072
+ $rank_title = str_replace( '%sep%', $sep, $rank_title );
1073
+ $rank_title = str_replace( '%page%', '', $rank_title );
1074
+ $rank_title = str_replace( '%sitename%', get_bloginfo( 'name' ), $rank_title );
1075
+ } else {
1076
+ $rank_title = $title;
1077
+ }
1078
+ }
1079
+
1080
+ return apply_filters( 'woo_feed_filter_product_rank_math_title', $rank_title, $this->product, $this->config );
1081
+ }
1082
+
1083
+ public function rank_math_description() {
1084
+ $description = '';
1085
+ if ( class_exists( 'RankMath' ) ) {
1086
+ $description = get_post_meta( $this->product->get_id(), 'rank_math_description' );
1087
+ $desc_format = \RankMath\Helper::get_settings( "titles.pt_post_description" );
1088
+
1089
+ if ( empty( $description ) ) {
1090
+ if ( ! empty( $desc_format ) && strpos( (string) $desc_format, 'excerpt' ) !== false ) {
1091
+ $description = str_replace( '%excerpt%', get_the_excerpt( $this->product->get_id() ), $desc_format );
1092
+ }
1093
+
1094
+ // Get Variation Description
1095
+ if ( empty( $description ) && $this->product->is_type( 'variation' ) ) {
1096
+ $description = $this->parent_product->get_description();
1097
+ }
1098
+ }
1099
+
1100
+ if ( is_array( $description ) ) {
1101
+ $description = reset( $description );
1102
+ }
1103
+
1104
+ $description = CommonHelper::remove_shortcodes( $description );
1105
+
1106
+ //strip tags and spacial characters
1107
+ $strip_description = woo_feed_strip_all_tags( wp_specialchars_decode( $description ) );
1108
+
1109
+ $description = ! empty( strlen( $strip_description ) ) && 0 < strlen( $strip_description ) ? $strip_description : $description;
1110
+ }
1111
+
1112
+ return apply_filters( 'woo_feed_filter_product_rank_math_description', $description, $this->product, $this->config );
1113
+ }
1114
+
1115
+ public function rank_math_canonical_url() {
1116
+ $canonical_url = '';
1117
+
1118
+ if ( class_exists( 'RankMath' ) ) {
1119
+ $post_canonical_url = get_post_meta( $this->product->get_id(), 'rank_math_canonical_url' );
1120
+
1121
+ if ( empty( $post_canonical_url ) ) {
1122
+ $canonical_url = get_the_permalink( $this->product->get_id() );
1123
+ } else {
1124
+ $canonical_url = $post_canonical_url;
1125
+ }
1126
+
1127
+ if ( is_array( $canonical_url ) ) {
1128
+ $canonical_url = reset( $canonical_url );
1129
+ }
1130
+ }
1131
+
1132
+ return apply_filters( 'woo_feed_filter_product_rank_math_canonical_url', $canonical_url, $this->product, $this->config );
1133
+ }
1134
+
1135
+ public function rank_math_gtin() {
1136
+ $product_id = woo_feed_parent_product_id( $this->product );
1137
+ $rankmath_gtin_value = get_post_meta( $product_id, '_rank_math_gtin_code' );
1138
+ $rankmath_gtin_value = ! empty( $rankmath_gtin_value ) && is_array( $rankmath_gtin_value ) ? $rankmath_gtin_value[0] : '';
1139
+
1140
+ return apply_filters( 'rankmath_gtin_attribute_value', $rankmath_gtin_value, $this->product, $this->config );
1141
+ }
1142
+
1143
+ public function _aioseop_title() {
1144
+ $title = '';
1145
+ if ( is_plugin_active( 'all-in-one-seo-pack/all_in_one_seo_pack.php' ) && class_exists( 'AIOSEO\Plugin\Common\Models\Post' ) ) {
1146
+
1147
+ $post = AIOSEO\Plugin\Common\Models\Post::getPost( $this->product->get_id() );
1148
+ $title = ! empty( $post->title ) ? $post->title : aioseo()->meta->title->getPostTypeTitle( 'product' );
1149
+ }
1150
+
1151
+ $title = ! empty( $title ) ? $title : $this->title();
1152
+
1153
+ return apply_filters( 'woo_feed_filter_product_aioseop_title', $title, $this->product, $this->config );
1154
+ }
1155
+
1156
+ public function _aioseop_description() {
1157
+ $description = '';
1158
+
1159
+ if ( is_plugin_active( 'all-in-one-seo-pack/all_in_one_seo_pack.php' ) && class_exists( 'AIOSEO\Plugin\Common\Models\Post' ) ) {
1160
+
1161
+ $post = AIOSEO\Plugin\Common\Models\Post::getPost( $this->product->get_id() );
1162
+ $description = ! empty( $post->description ) ? $post->description : aioseo()->meta->description->getPostTypeDescription( 'product' );
1163
+ }
1164
+
1165
+ if ( empty( $description ) ) {
1166
+ $description = $this->description();
1167
+ }
1168
+
1169
+ return apply_filters( 'woo_feed_filter_product_aioseop_description', $description, $this->product, $this->config );
1170
+ }
1171
+
1172
+ public function _aioseop_canonical_url() {
1173
+ $aioseop_canonical_url = '';
1174
+ if ( is_plugin_active( 'all-in-one-seo-pack/all_in_one_seo_pack.php' ) && class_exists( 'AIOSEO\Plugin\Common\Models\Post' ) ) {
1175
+ $post = AIOSEO\Plugin\Common\Models\Post::getPost( $this->product->get_id() );
1176
+ $aioseop_canonical_url = $post->canonical_url;
1177
+ }
1178
+
1179
+ return apply_filters( 'woo_feed_filter_product_aioseop_canonical_url', $aioseop_canonical_url, $this->product, $this->config );
1180
+ }
1181
+
1182
+ ############# TAX #############
1183
+
1184
+ public function tax( $key = '' ) {
1185
+ $tax = TaxFactory::get( $this->product, $this->config )->merchant_formatted_tax( $key );
1186
+ $taxes = TaxFactory::get( $this->product, $this->config )->get_taxes();
1187
+
1188
+ // GoogleTax and CustomTax class is available.
1189
+ // For others merchant use filter hook to modify value.
1190
+ return apply_filters( 'woo_feed_filter_product_tax', $tax, $this->product, $this->config, $taxes );
1191
+ }
1192
+
1193
+ public function tax_class() {
1194
+ return apply_filters( 'woo_feed_filter_product_tax_class', $this->product->get_tax_class(), $this->product, $this->config );
1195
+ }
1196
+
1197
+ public function tax_status() {
1198
+ return apply_filters( 'woo_feed_filter_product_tax_status', $this->product->get_tax_status(), $this->product, $this->config );
1199
+ }
1200
+
1201
+ public function tax_country() {
1202
+ $taxes = TaxFactory::get( $this->product, $this->config )->get_taxes();
1203
+ $taxClass = empty( $this->product->get_tax_class() ) ? 'standard-rate' : $this->product->get_tax_class();
1204
+ $country = "";
1205
+ if ( isset( $taxes[ $taxClass ] ) && ! empty( $taxes[ $taxClass ] ) ) {
1206
+ $rates = array_values( $taxes[ $taxClass ] );
1207
+ $country = $rates[0]['country'];
1208
+ }
1209
+
1210
+ return apply_filters( 'woo_feed_filter_product_tax_country', $country, $this->product, $this->config, $taxes );
1211
+ }
1212
+
1213
+ public function tax_state() {
1214
+ $taxes = TaxFactory::get( $this->product, $this->config )->get_taxes();
1215
+ $taxClass = empty( $this->product->get_tax_class() ) ? 'standard-rate' : $this->product->get_tax_class();
1216
+ $state = "";
1217
+ if ( isset( $taxes[ $taxClass ] ) && ! empty( $taxes[ $taxClass ] ) ) {
1218
+ $rates = array_values( $taxes[ $taxClass ] );
1219
+ $state = $rates[0]['state'];
1220
+ }
1221
+
1222
+ return apply_filters( 'woo_feed_filter_product_tax_state', $state, $this->product, $this->config, $taxes );
1223
+ }
1224
+
1225
+ public function tax_postcode() {
1226
+ $taxes = TaxFactory::get( $this->product, $this->config )->get_taxes();
1227
+ $taxClass = empty( $this->product->get_tax_class() ) ? 'standard-rate' : $this->product->get_tax_class();
1228
+ $postcode = "";
1229
+ if ( isset( $taxes[ $taxClass ] ) && ! empty( $taxes[ $taxClass ] ) ) {
1230
+ $rates = array_values( $taxes[ $taxClass ] );
1231
+ $postcode = $rates[0]['postcode'];
1232
+ }
1233
+
1234
+ return apply_filters( 'woo_feed_filter_product_tax_postcode', $postcode, $this->product, $this->config, $taxes );
1235
+ }
1236
+
1237
+ public function tax_city() {
1238
+ $taxes = TaxFactory::get( $this->product, $this->config )->get_taxes();
1239
+ $taxClass = empty( $this->product->get_tax_class() ) ? 'standard-rate' : $this->product->get_tax_class();
1240
+ $city = "";
1241
+ if ( isset( $taxes[ $taxClass ] ) && ! empty( $taxes[ $taxClass ] ) ) {
1242
+ $rates = array_values( $taxes[ $taxClass ] );
1243
+ $city = $rates[0]['city'];
1244
+ }
1245
+
1246
+ return apply_filters( 'woo_feed_filter_product_tax_city', $city, $this->product, $this->config, $taxes );
1247
+ }
1248
+
1249
+ public function tax_rate() {
1250
+ $taxes = TaxFactory::get( $this->product, $this->config )->get_taxes();
1251
+ $taxClass = empty( $this->product->get_tax_class() ) ? 'standard-rate' : $this->product->get_tax_class();
1252
+ $rate = "";
1253
+ if ( isset( $taxes[ $taxClass ] ) && ! empty( $taxes[ $taxClass ] ) ) {
1254
+ $rates = array_values( $taxes[ $taxClass ] );
1255
+ $rate = $rates[0]['rate'];
1256
+ }
1257
+
1258
+ return apply_filters( 'woo_feed_filter_product_tax_rate', $rate, $this->product, $this->config, $taxes );
1259
+ }
1260
+
1261
+ public function tax_label() {
1262
+ $taxes = TaxFactory::get( $this->product, $this->config )->get_taxes();
1263
+ $taxClass = empty( $this->product->get_tax_class() ) ? 'standard-rate' : $this->product->get_tax_class();
1264
+ $label = "";
1265
+ if ( isset( $taxes[ $taxClass ] ) && ! empty( $taxes[ $taxClass ] ) ) {
1266
+ $rates = array_values( $taxes[ $taxClass ] );
1267
+ $label = $rates[0]['label'];
1268
+ }
1269
+
1270
+ return apply_filters( 'woo_feed_filter_product_tax_label', $label, $this->product, $this->config, $taxes );
1271
+ }
1272
+
1273
+ # Custom XML Template
1274
+
1275
+ /**
1276
+ * Custom Template 2 images loop
1277
+ *
1278
+ * @return array
1279
+ */
1280
+ public function custom_xml_images() {
1281
+ $images = $this->images();
1282
+ $separator = apply_filters( 'woo_feed_filter_category_separator', ' > ', $this->product, $this->config );
1283
+
1284
+ return explode( $separator, $images );
1285
+ }
1286
+
1287
+ /**
1288
+ * Custom Template 2 attributes loop
1289
+ *
1290
+ * @return array
1291
+ */
1292
+ public function custom_xml_attributes() {
1293
+ $getAttributes = $this->product->get_attributes();
1294
+ $attributes = [];
1295
+ if ( ! empty( $getAttributes ) ) {
1296
+ foreach ( $getAttributes as $key => $attribute ) {
1297
+ $attributes[ $key ]['name'] = wc_attribute_label( $key );
1298
+ $attributes[ $key ]['value'] = $this->product->get_attribute( wc_attribute_label( $key ) );
1299
+ }
1300
+ }
1301
+
1302
+ return $attributes;
1303
+ }
1304
+
1305
+ public function custom_xml_shipping() {
1306
+ }
1307
+
1308
+ public function custom_xml_tax() {
1309
+ }
1310
+
1311
+ public function custom_xml_categories() {
1312
+ $output = []; // Initialising
1313
+ $taxonomy = 'product_cat'; // Taxonomy for product category
1314
+
1315
+ // Get the product categories terms ids in the product:
1316
+ $terms_ids = wp_get_post_terms( $this->product->get_id(), $taxonomy, array( 'fields' => 'ids' ) );
1317
+
1318
+ // Loop though terms ids (product categories)
1319
+ foreach ( $terms_ids as $term_id ) {
1320
+ $term_names = []; // Initialising category array
1321
+
1322
+ // Loop through product category ancestors
1323
+ foreach ( get_ancestors( $term_id, $taxonomy ) as $ancestor_id ) {
1324
+ // Add the ancestor's term names to the category array
1325
+ $term_names[] = get_term( $ancestor_id, $taxonomy )->name;
1326
+ }
1327
+ // Add the product category term name to the category array
1328
+ $term_names[] = get_term( $term_id, $taxonomy )->name;
1329
+
1330
+ // Get category separator
1331
+ $separator = apply_filters( 'woo_feed_filter_category_separator', ' > ', $this->product, $this->config );
1332
+
1333
+ // Add the formatted ancestors with the product category to main array
1334
+ $output[] = implode( $separator, $term_names );
1335
+ }
1336
+
1337
+ return $output;
1338
+ }
1339
+
1340
+ }
V5/Query/BothQuery.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Query;
3
+
4
+ class BothQuery implements QueryInterface {
5
+ private $config;
6
+
7
+ public function __construct( $config ) {
8
+ $this->config = $config;
9
+ }
10
+
11
+ public function get_product_types() {
12
+ return false;
13
+ }
14
+
15
+ public function get_query_arguments() {
16
+ return false;
17
+ }
18
+
19
+ public function get_product_status() {
20
+ return false;
21
+ }
22
+
23
+ public function product_ids() {
24
+ $wp = (new WPQuery($this->config))->product_ids();
25
+ $wc = (new WCQuery($this->config))->product_ids();
26
+
27
+ return array_unique( array_merge( $wc, $wp ) );
28
+ }
29
+ }
V5/Query/Query.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Query;
3
+
4
+ class Query {
5
+ /**
6
+ * @var QueryInterface
7
+ */
8
+ private $query;
9
+
10
+ public function __construct( QueryInterface $query) {
11
+
12
+ $this->query = $query;
13
+ }
14
+
15
+ public function get_ids( ) {
16
+ return $this->query->product_ids();
17
+ }
18
+ }
V5/Query/QueryFactory.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Query;
4
+
5
+ use CTXFeed\V5\Utility\Config;
6
+ use CTXFeed\V5\Utility\Settings;
7
+ use CTXFeed\V5\Query\WCReviewQuery;
8
+
9
+ class QueryFactory {
10
+ /**
11
+ * @param Config $config
12
+ *
13
+ * @return array
14
+ */
15
+ public static function get_ids( $config ) {
16
+ $template = $config->get_feed_template();
17
+ $queryType = Settings::get( 'product_query_type' );
18
+
19
+ $class = "\CTXFeed\V5\Query\\" . strtoupper( $queryType ) . "Query";
20
+ if ( strpos( $template, 'review' ) ) {
21
+ $class = WCReviewQuery::class;
22
+ }
23
+ /**
24
+ * @var WPQuery|WCQuery|WCReviewQuery $class Query Class
25
+ */
26
+ return ( new Query( new $class( $config ) ) )->get_ids();
27
+ }
28
+ }
V5/Query/QueryInterface.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Query;
3
+ interface QueryInterface {
4
+ public function get_query_arguments();
5
+
6
+ public function get_product_types();
7
+
8
+ public function get_product_status();
9
+
10
+ public function product_ids();
11
+ }
12
+
13
+
14
+
V5/Query/WCQuery.php ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Query;
3
+ use CTXFeed\V5\Utility\Settings;
4
+ use WC_Product_Query;
5
+
6
+ class WCQuery implements QueryInterface {
7
+ private $config;
8
+ private $arguments;
9
+
10
+ public function __construct( $config ) {
11
+ $this->config = $config;
12
+ $this->arguments = $this->get_query_arguments();
13
+ }
14
+
15
+ public function get_product_types() {
16
+ $productTypes = [
17
+ 'simple',
18
+ 'variable',
19
+ 'grouped',
20
+ 'external',
21
+ 'composite',
22
+ 'bundle',
23
+ 'bundled',
24
+ 'yith_bundle',
25
+ 'yith-composite',
26
+ 'subscription',
27
+ 'variable-subscription',
28
+ 'woosb',
29
+ ];
30
+
31
+ // Include Product Variations with db query if configured.
32
+ if ( 'variable' !== Settings::get( 'variation_query_type' ) ) {
33
+ $productTypes[100] = 'variation';
34
+ }
35
+
36
+ // Exclude Product Variations with db query if configured
37
+ if ( in_array( 'variation', $productTypes ) && ! $this->config->get_variations_to_include() ) {
38
+ $key = array_search( 'variation', $productTypes );
39
+ unset( $productTypes[ $key ] );
40
+ }
41
+
42
+ return apply_filters( 'ctx_filter_product_types_for_product_query', $productTypes );
43
+ }
44
+
45
+ public function get_query_arguments() {
46
+ $arguments = [
47
+ 'limit' => - 1, // phpcs:ignore
48
+ 'status' => $this->get_product_status(),
49
+ 'type' => $this->get_product_types(),
50
+ 'orderby' => 'date',
51
+ 'order' => 'DESC',
52
+ 'return' => 'ids',
53
+ 'suppress_filters' => false,
54
+ ];
55
+
56
+ // Include Author
57
+ $author = $this->config->get_vendors_to_include();
58
+ if ( $author ) {
59
+ $arguments['author'] = $author;
60
+ }
61
+
62
+ // Include Product Ids.
63
+ $include = $this->config->get_products_to_include();
64
+ if ( $include ) {
65
+ $arguments['include'] = $include;
66
+ }
67
+
68
+ // Exclude Product Ids
69
+ $exclude = $this->config->get_products_to_exclude();
70
+ if ( $exclude ) {
71
+ $arguments['exclude'] = $exclude;
72
+ }
73
+
74
+ // Stock Status
75
+ $stockStatus = [ 'instock', 'onbackorder', 'outofstock' ];
76
+ // Remove Out of Stock Products.
77
+ if ( $this->config->remove_outofstock_product() ) {
78
+ $key = array_search( 'outofstock', $stockStatus );
79
+ unset( $stockStatus[ $key ] );
80
+ }
81
+ // Remove On Backorder Products.
82
+ if ( $this->config->remove_backorder_product() ) {
83
+ $key = array_search( 'onbackorder', $stockStatus );
84
+ unset( $stockStatus[ $key ] );
85
+ }
86
+ $arguments['stock_status'] = $stockStatus;
87
+
88
+
89
+ // Include Categories
90
+ $categoriesToInclude = $this->config->get_categories_to_include();
91
+ if ( $categoriesToInclude ) {
92
+ $arguments['category'] = $categoriesToInclude;
93
+ }
94
+
95
+ // Exclude Categories
96
+ $categoriesToExclude = $this->config->get_categories_to_exclude();
97
+ if ( $categoriesToExclude ) {
98
+ $arguments['tax_query'][] = array(
99
+ 'taxonomy' => 'product_cat',
100
+ 'field' => 'slug',
101
+ 'terms' => $categoriesToExclude,
102
+ 'operator' => 'NOT IN',
103
+ );
104
+ }
105
+
106
+ return apply_filters( 'ctx_filter_arguments_for_product_query', $arguments, 'wc' );
107
+ }
108
+
109
+ public function get_product_status() {
110
+ $status = $this->config->get_post_status_to_include();
111
+
112
+ return ( $status ) ?: "publish";
113
+ }
114
+
115
+ public function product_ids() {
116
+ return ( new WC_Product_Query( $this->arguments ) )->get_products();
117
+ }
118
+ }
V5/Query/WCReviewQuery.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Query;
3
+ class WCReviewQuery implements QueryInterface {
4
+ private $config;
5
+ private $arguments;
6
+
7
+ public function __construct( $config ) {
8
+ $this->config = $config;
9
+ $this->arguments = $this->get_query_arguments();
10
+ }
11
+
12
+ /**
13
+ * @return string
14
+ */
15
+ public function get_product_types(){
16
+ return 'product';
17
+ }
18
+
19
+ public function get_query_arguments() {
20
+ $args = array(
21
+ 'post_type' => $this->get_product_types(),
22
+ 'status' => $this->get_product_status(),
23
+ 'fields' => 'ids',
24
+ 'comment_count' => array(
25
+ 'value' => 0,
26
+ 'compare' => '>',
27
+ ),
28
+ );
29
+
30
+
31
+ return apply_filters( 'ctx_filter_arguments_for_product_with_review_query', $args, 'review' );
32
+ }
33
+
34
+ public function get_product_status() {
35
+ $status = $this->config->get_post_status_to_include();
36
+
37
+ return ( $status ) ?: "publish";
38
+ }
39
+
40
+ public function product_ids() {
41
+ return get_posts( $this->arguments );
42
+ }
43
+ }
V5/Query/WPQuery.php ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Query;
3
+ use WP_Query;
4
+
5
+ class WPQuery implements QueryInterface {
6
+ private $config;
7
+ private $arguments;
8
+
9
+ public function __construct( $config ) {
10
+ $this->config = $config;
11
+ $this->arguments = $this->get_query_arguments();
12
+ }
13
+
14
+ public function get_product_types() {
15
+
16
+ $post_type = [ 'product' ];
17
+ // Include Product Variations with db query if configured
18
+ if ( 'variable' !== woo_feed_get_options( 'variation_query_type' ) ) {
19
+ $post_type = [ 'product', 'product_variation' ];
20
+ }
21
+
22
+ // Exclude Product Variations with db query if configured
23
+ if ( in_array( 'product_variation', $post_type ) && ! $this->config->get_variations_to_include() ) {
24
+ $key = array_search( 'product_variation', $post_type );
25
+ unset( $post_type[ $key ] );
26
+ }
27
+
28
+ return apply_filters( 'ctx_filter_product_types_for_product_query', $post_type );
29
+ }
30
+
31
+ public function get_query_arguments() {
32
+ $arguments = [
33
+ 'posts_per_page' => - 1,
34
+ 'post_type' => $this->get_product_types(),
35
+ 'post_status' => $this->get_product_status(),
36
+ 'order' => 'DESC',
37
+ 'fields' => 'ids',
38
+ 'cache_results' => false,
39
+ 'update_post_meta_cache' => false,
40
+ 'update_post_term_cache' => false,
41
+ 'suppress_filters' => false,
42
+ ];
43
+
44
+ // Include Author
45
+ $author = $this->config->get_vendors_to_include();
46
+ if ( $author ) {
47
+ $arguments['author__in'] = $author;
48
+ }
49
+
50
+ // Include Product Ids.
51
+ $include = $this->config->get_products_to_include();
52
+ if ( $include ) {
53
+ $arguments['post__in'] = $include;
54
+ }
55
+
56
+ // Exclude Product Ids
57
+ $exclude = $this->config->get_products_to_exclude();
58
+ if ( $exclude ) {
59
+ $arguments['post__not_in'] = $exclude;
60
+ }
61
+
62
+ // Remove Out of Stock Products.
63
+ if ( $this->config->remove_outofstock_product() ) {
64
+ $arguments['meta_query'] = array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
65
+ array(
66
+ 'key' => '_stock_status',
67
+ 'value' => 'outofstock',
68
+ 'compare' => '!=',
69
+ ),
70
+ );
71
+ }
72
+ // Remove On Backorder Products.
73
+ if ( $this->config->remove_backorder_product() ) {
74
+ $arguments['meta_query'] = array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
75
+ array(
76
+ 'key' => '_stock_status',
77
+ 'value' => 'onbackorder',
78
+ 'compare' => '!=',
79
+ ),
80
+ );
81
+ }
82
+
83
+ // Remove both outofstock and onbackorder products.
84
+ if ( $this->config->remove_outofstock_product() && $this->config->remove_backorder_product() ) {
85
+ $arguments['meta_query'] = array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
86
+ 'relation' => 'AND',
87
+ array(
88
+ 'key' => '_stock_status',
89
+ 'value' => 'onbackorder',
90
+ 'compare' => '!=',
91
+ ),
92
+ array(
93
+ 'key' => '_stock_status',
94
+ 'value' => 'outofstock',
95
+ 'compare' => '!=',
96
+ )
97
+ );
98
+ }
99
+
100
+ // Include Categories
101
+ $categoriesToInclude = $this->config->get_categories_to_include();
102
+ if ( $categoriesToInclude ) {
103
+ $arguments['tax_query'] = array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
104
+ array(
105
+ 'taxonomy' => 'product_cat',
106
+ 'field' => 'slug',
107
+ // This is optional, as it defaults to 'term_id'
108
+ 'terms' => $categoriesToInclude,
109
+ 'operator' => 'IN', // Possible values are 'IN', 'NOT IN', 'AND'.
110
+ ),
111
+ );
112
+ }
113
+
114
+ // Exclude Categories
115
+ $categoriesToExclude = $this->config->get_categories_to_exclude();
116
+ if ( $categoriesToExclude ) {
117
+ $arguments['tax_query'] = array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
118
+ array(
119
+ 'taxonomy' => 'product_cat',
120
+ 'field' => 'slug',
121
+ // This is optional, as it defaults to 'term_id'
122
+ 'terms' => $categoriesToExclude,
123
+ 'operator' => 'NOT IN', // Possible values are 'IN', 'NOT IN', 'AND'.
124
+ ),
125
+ );
126
+ }
127
+
128
+ return apply_filters( 'ctx_filter_arguments_for_product_query', $arguments, 'wc' );
129
+ }
130
+
131
+ public function get_product_status() {
132
+ $status = $this->config->get_post_status_to_include();
133
+
134
+ return ( $status ) ?: "publish";
135
+ }
136
+
137
+ public function product_ids() {
138
+ return ( new WP_Query( $this->arguments ) )->get_posts();
139
+ }
140
+ }
V5/Shipping/CustomShipping.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Shipping;
4
+
5
+ use CTXFeed\V5\Utility\Settings;
6
+
7
+ class CustomShipping extends Shipping {
8
+
9
+ /**
10
+ * @var \CTXFeed\V5\Utility\Config $config
11
+ */
12
+ private $config;
13
+
14
+ public function __construct( $product, $config ) {
15
+ parent::__construct( $product, $config );
16
+ $this->config = $config;
17
+ }
18
+
19
+ /**
20
+ * @throws \Exception
21
+ */
22
+ public function get_shipping_info() {
23
+ $this->get_shipping_zones();
24
+
25
+ return $this->shipping;
26
+ }
27
+
28
+ /**
29
+ *
30
+ * @return string
31
+ * @throws \Exception
32
+ */
33
+ public function get_shipping( $key = '' ) {
34
+ $this->get_shipping_zones();
35
+ $str = "";
36
+ foreach ( $this->shipping as $shipping ) {
37
+
38
+ $allow_all_shipping = Settings::get( 'allow_all_shipping' );
39
+ if ( 'no' === $allow_all_shipping ) {
40
+ $country = $this->config->get_shipping_country();
41
+
42
+ if ( $shipping['country'] !== $country ) {
43
+ continue;
44
+ }
45
+ }
46
+
47
+ $currency = $this->config->get_feed_currency();
48
+ $str .= "<shipping>" . PHP_EOL;
49
+ $str .= "<country>" . $shipping['country'] . "</country>" . PHP_EOL;
50
+ $str .= ( empty( $shipping['state'] ) ) ? "" : "<region>" . $shipping['state'] . "</region>" . PHP_EOL;
51
+ $str .= ( empty( $shipping['postcode'] ) ) ? "" : "<postal_code>" . $shipping['postcode'] . "</postal_code>" . PHP_EOL;
52
+ $str .= ( empty( $shipping['service'] ) ) ? "" : "<service>" . $shipping['service'] . "</service>" . PHP_EOL;
53
+ $str .= "<price>" . $shipping['price'] . " " . $currency . "</price>" . PHP_EOL;
54
+ $str .= "</shipping>" . PHP_EOL;
55
+ }
56
+
57
+ return $str;
58
+ }
59
+ }
V5/Shipping/GoogleShipping.php ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Shipping;
4
+
5
+
6
+ use CTXFeed\V5\Helper\ProductHelper;
7
+ use CTXFeed\V5\Utility\Settings;
8
+
9
+ class GoogleShipping extends Shipping {
10
+
11
+ /**
12
+ * @var \CTXFeed\V5\Utility\Config $config
13
+ */
14
+ private $config;
15
+
16
+ public function __construct( $product, $config ) {
17
+ parent::__construct( $product, $config );
18
+ $this->config = $config;
19
+ }
20
+
21
+ /**
22
+ * @throws \Exception
23
+ */
24
+ public function get_shipping_info() {
25
+ $this->get_shipping_zones();
26
+
27
+ return $this->shipping;
28
+ }
29
+
30
+ /**
31
+ *
32
+ * @return string
33
+ * @throws \Exception
34
+ */
35
+ public function get_shipping( $key = '' ) {
36
+
37
+ $this->get_shipping_zones();
38
+ if ( 'xml' === $this->config->get_feed_file_type() ) {
39
+ return $this->get_xml();
40
+ }
41
+
42
+ return $this->get_csv( $key );
43
+ }
44
+
45
+ private function get_xml() {
46
+ $str = "";
47
+
48
+ $shippingAttrs = [
49
+ 'location_id',
50
+ 'location_group_name',
51
+ 'min_handling_time',
52
+ 'max_handling_time',
53
+ 'min_transit_time',
54
+ 'max_transit_time'
55
+ ];
56
+
57
+ $allow_all_shipping = Settings::get( 'allow_all_shipping' );
58
+ $country = $this->config->get_shipping_country();
59
+ $currency = $this->config->get_feed_currency();
60
+
61
+ $methods = $this->shipping;
62
+ if ( 'no' === $allow_all_shipping ) {
63
+ $methods = array_filter( $this->shipping, static function ( $var ) use ( $country ) {
64
+ return ( $var['country'] === $country );
65
+ } );
66
+ }
67
+ $i = 1;
68
+ foreach ( $methods as $shipping ) {
69
+ $str .= ( $i > 1 ) ? "<g:shipping>" . PHP_EOL : PHP_EOL;
70
+ $str .= "<g:country>" . $shipping['country'] . "</g:country>" . PHP_EOL;
71
+ $str .= ( empty( $shipping['state'] ) ) ? "" : "<g:region>" . $shipping['state'] . "</g:region>" . PHP_EOL;
72
+ $str .= ( empty( $shipping['postcode'] ) ) ? "" : "<g:postal_code>" . $shipping['postcode'] . "</g:postal_code>" . PHP_EOL;
73
+ $str .= ( empty( $shipping['service'] ) ) ? "" : "<g:service>" . $shipping['service'] . "</g:service>" . PHP_EOL;
74
+ $str .= "<g:price>" . $shipping['price'] . " " . $currency . "</g:price>" . PHP_EOL;
75
+
76
+ foreach ( $shippingAttrs as $shipping_attr ) {
77
+ $key = array_search( $shipping_attr, $this->config->mattributes, true );
78
+ if ( $key ) {
79
+ $attributeValue = ( $this->config->type[ $key ] === 'pattern' ) ? $this->config->default[ $key ] : $this->config->attributes[ $key ];
80
+ $value = ProductHelper::getAttributeValueByType( $attributeValue, $this->product, $this->config, $shipping_attr );
81
+ $str .= "<g:$shipping_attr>$value</g:$shipping_attr>" . PHP_EOL;
82
+ }
83
+ }
84
+
85
+ $str .= ( $i !== count( $methods ) ) ? "</g:shipping>" . PHP_EOL : PHP_EOL;
86
+ $i ++;
87
+ }
88
+
89
+ return $str;
90
+ }
91
+
92
+ private function get_csv( $key ) {
93
+ // return "";
94
+ $allow_all_shipping = Settings::get( 'allow_all_shipping' );
95
+ $country = $this->config->get_shipping_country();
96
+ $currency = $this->config->get_feed_currency();
97
+
98
+ $shippingAttrs = [
99
+ 'location_id',
100
+ 'location_group_name',
101
+ 'min_handling_time',
102
+ 'max_handling_time',
103
+ 'min_transit_time',
104
+ 'max_transit_time'
105
+ ];
106
+
107
+ $methods = $this->shipping;
108
+ if ( 'no' === $allow_all_shipping ) {
109
+ $methods = array_filter( $this->shipping, static function ( $var ) use ( $country ) {
110
+ return ( $var['country'] === $country );
111
+ } );
112
+ }
113
+
114
+ $shipping = [
115
+ isset( $methods[ $key ]['country'] ) ? $methods[ $key ]['country'] : "",
116
+ isset( $methods[ $key ]['state'] ) ? $methods[ $key ]['state'] : "",
117
+ isset( $methods[ $key ]['service'] ) ? $methods[ $key ]['service'] : "",
118
+ isset( $methods[ $key ]['price'] ) ? $methods[ $key ]['price'] . " " . $currency : "",
119
+ $this->get_value( 'location_id' ),
120
+ $this->get_value( 'location_group_name' ),
121
+ $this->get_value( 'min_handling_time' ),
122
+ $this->get_value( 'max_handling_time' ),
123
+ $this->get_value( 'min_transit_time' ),
124
+ $this->get_value( 'max_transit_time' ),
125
+ ];
126
+
127
+ return implode( ":", $shipping );
128
+ }
129
+
130
+ public function get_value( $shipping_attr ) {
131
+ $mKey = array_search( $shipping_attr, $this->config->mattributes, true );
132
+ if ( $mKey ) {
133
+ $attributeValue = ( $this->config->type[ $mKey ] === 'pattern' ) ? $this->config->default[ $mKey ] : $this->config->attributes[ $mKey ];
134
+
135
+ return ProductHelper::getAttributeValueByType( $attributeValue, $this->product, $this->config, $shipping_attr );
136
+ }
137
+
138
+ return "";
139
+ }
140
+ }
V5/Shipping/Shipping.php ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Shipping;
4
+
5
+ use CTXFeed\V5\Utility\Cache;
6
+ use WC_Shipping_Flat_Rate;
7
+ use WC_Shipping_Zones;
8
+
9
+ /**
10
+ * Class ShippingInterface
11
+ *
12
+ * @package CTXFeed\V5\Shipping
13
+ * @subpackage CTXFeed\V5\Shipping
14
+ */
15
+ class Shipping {
16
+
17
+ protected $shipping;
18
+ private $zoneId;
19
+ private $zoneName;
20
+ /**
21
+ * @var WC_Shipping_Flat_Rate $methods
22
+ */
23
+ private $methods;
24
+ private $country;
25
+ private $state;
26
+ private $postcode;
27
+ protected $l = 0;
28
+ /**
29
+ * @var \WC_Product $product
30
+ */
31
+ protected $product;
32
+ /**
33
+ * @var \CTXFeed\V5\Utility\Config $config
34
+ */
35
+ private $config;
36
+
37
+
38
+ public function __construct( $product, $config ) {
39
+ $this->product = $product;
40
+ $this->config = $config;
41
+ }
42
+
43
+ /**
44
+ * Set Shipping Zones.
45
+ *
46
+ * @throws \Exception
47
+ */
48
+ protected function get_shipping_zones() {
49
+ $shippingInfo = Cache::get( 'ctx_feed_shipping_info' );
50
+ if ( ! $shippingInfo ) {
51
+ $zones = WC_Shipping_Zones::get_zones();
52
+ if ( ! empty( $zones ) ) {
53
+ foreach ( $zones as $zone ) {
54
+ $this->zoneId = $zone['zone_id'];
55
+ $this->zoneName = $zone['zone_name'];
56
+ $this->methods = $zone['shipping_methods'];
57
+ $this->get_locations( $zone['zone_locations'] );
58
+ }
59
+ }
60
+ Cache::set( 'ctx_feed_shipping_info', $this->shipping );
61
+ }
62
+ $this->shipping = $shippingInfo;
63
+
64
+ return $shippingInfo;
65
+ }
66
+
67
+ /**
68
+ * Set shipping locations.
69
+ *
70
+ * @param $locations
71
+ *
72
+ * @return void
73
+ */
74
+ private function get_locations( $locations ) {
75
+ if ( ! empty( $locations ) ) {
76
+ foreach ( $locations as $location ) {
77
+
78
+ if ( 'country' === $location->type ) {
79
+ $this->country = $location->code;
80
+ $this->get_methods();
81
+ } elseif ( 'state' === $location->type ) {
82
+
83
+ $countryState = explode( ':', $location->code );
84
+ $this->country = $countryState[0];
85
+ $this->state = $countryState[1];
86
+
87
+ $this->get_methods();
88
+
89
+ } elseif ( 'postcode' === $location->type ) {
90
+ $this->postcode = str_replace( "...", "-", $location->code );
91
+ }
92
+ }
93
+ $this->country = "";
94
+ $this->state = "";
95
+ $this->postcode = "";
96
+ $this->zoneId = "";
97
+ $this->zoneName = "";
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Set Shipping Methods.
103
+ *
104
+ * @return void
105
+ */
106
+ private function get_methods() {
107
+ if ( ! empty( $this->methods ) ) {
108
+ foreach ( $this->methods as $method ) {
109
+ if ( 'yes' === $method->enabled && 'local_pickup' !== $method->id ) {
110
+
111
+ if ( empty( $this->country ) ) {
112
+ $service = $this->zoneName . " " . $method->title;
113
+ } else {
114
+ $service = $this->zoneName . " " . $method->title . " " . $this->country;
115
+ }
116
+
117
+ $this->shipping[ $this->l ]['zone_id'] = $this->zoneId;
118
+ $this->shipping[ $this->l ]['zone_name'] = $this->zoneName;
119
+ $this->shipping[ $this->l ]['country'] = $this->country;
120
+ $this->shipping[ $this->l ]['state'] = $this->state;
121
+ $this->shipping[ $this->l ]['service'] = $service;
122
+ $this->shipping[ $this->l ]['postcode'] = $this->postcode;
123
+ $this->shipping[ $this->l ]['method_id'] = $method->id;
124
+ $this->shipping[ $this->l ]['method_instance_id'] = $method->instance_id;
125
+
126
+ if ( 'table_rate' === $method->id ) {
127
+ $this->shipping[ $this->l ]['table_rate_id'] = $method->table_rate_id;
128
+ }
129
+
130
+ $this->shipping[ $this->l ]['method_title'] = $method->get_method_title();
131
+ $this->shipping[ $this->l ]['method_min_amount'] = isset( $method->min_amount ) ? $method->min_amount : "";
132
+ $this->shipping[ $this->l ]['price'] = $this->get_shipping_price( $this->shipping[ $this->l ] );
133
+ $this->l ++;
134
+ }
135
+ }
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Get shipping cost.
141
+ *
142
+ * @param $shipping array shipping information
143
+ *
144
+ * @return mixed $shipping_cost shipping cost
145
+ * @since 5.2.0
146
+ */
147
+ private function get_shipping_price( $shipping ) {
148
+
149
+ if ( ! is_object( $this->product ) ) {
150
+ return "";
151
+ }
152
+
153
+ if ( ( "free_shipping" === $shipping['method_id'] ) && $this->product->get_price() >= $shipping['method_min_amount'] ) {
154
+ return apply_filters( 'woo_feed_filter_shipping_attribute_price', 0, $shipping, $this->config );
155
+ }
156
+
157
+ // Set shipping cost
158
+ $shipping_cost = 0;
159
+ $tax = 0;
160
+ defined( 'WC_ABSPATH' ) || exit;
161
+
162
+ // Load cart functions which are loaded only on the front-end.
163
+ include_once WC_ABSPATH . 'includes/wc-cart-functions.php';
164
+ include_once WC_ABSPATH . 'includes/class-wc-cart.php';
165
+
166
+ wc_load_cart();
167
+ global $woocommerce;
168
+
169
+ // Make sure to empty the cart again
170
+ $woocommerce->cart->empty_cart();
171
+
172
+ // Set Shipping Country.
173
+ if ( isset( $shipping['country'] ) && ! empty( $shipping['country'] ) ) {
174
+ $woocommerce->customer->set_shipping_country( $shipping['country'] );
175
+ }
176
+ // Set Shipping Region.
177
+ if ( isset( $shipping['state'] ) && ! empty( $shipping['state'] ) ) {
178
+ $woocommerce->customer->set_shipping_state( $shipping['state'] );
179
+ } else {
180
+ $woocommerce->customer->set_shipping_state( "" );
181
+ }
182
+
183
+ // set shipping method in the cart
184
+ $chosen_ship_method_id = $shipping['method_id'] . ':' . $shipping['method_instance_id'];
185
+ // If table rate plugin installed
186
+ if ( isset( $shipping['table_rate_id'] ) && 'table_rate' === $shipping['method_id'] && is_plugin_active( 'woocommerce-table-rate-shipping/woocommerce-table-rate-shipping.php' ) ) {
187
+ $chosen_ship_method_id = $shipping['method_id'] . ':' . $shipping['method_instance_id'] . ':' . $shipping['table_rate_id'];
188
+ }
189
+ WC()->session->set( 'chosen_shipping_methods', array( $chosen_ship_method_id ) );
190
+
191
+ // get product id
192
+ if ( "variation" === $this->product->get_type() ) {
193
+ $id = $this->product->get_parent_id();
194
+ } elseif ( "grouped" === $this->product->get_type() ) {
195
+ $id = $this->product->get_children();
196
+ $id = reset( $id );
197
+ } else {
198
+ $id = $this->product->get_id();
199
+ }
200
+
201
+ // add product to cart
202
+ $woocommerce->cart->add_to_cart( $id, 1 );
203
+
204
+ // Read cart and get shipping costs
205
+ $shipping_cost = $woocommerce->cart->get_shipping_total();
206
+ $tax = $woocommerce->cart->get_shipping_tax();
207
+
208
+ // reset chosen shipping methods in the cart
209
+ if ( isset( $method['id'] ) && $method['instance_id'] ) {
210
+ WC()->session->set( 'chosen_shipping_methods', array( '' ) );
211
+ }
212
+
213
+ $shipping_cost += $tax;
214
+
215
+ // Make sure to empty the cart again
216
+ $woocommerce->cart->empty_cart();
217
+
218
+ return $shipping_cost;
219
+ }
220
+ }
V5/Shipping/ShippingFactory.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Shipping;
4
+
5
+
6
+ /**
7
+ * Class ShippingFactory
8
+ *
9
+ * @package CTXFeed\V5\Shipping
10
+ * @subpackage CTXFeed\V5\Shipping
11
+ */
12
+ class ShippingFactory {
13
+ /**
14
+ * @param \WC_Product $product
15
+ * @param \CTXFeed\V5\Utility\Config $config
16
+ *
17
+ * @return \CTXFeed\V5\Shipping\Shipping|void
18
+ */
19
+ public static function get( $product, $config ) {
20
+ $template = $config->get_feed_template();
21
+ $class = "\CTXFeed\V5\Shipping\\" . ucfirst( $template ) . "Shipping";
22
+ if ( class_exists( $class ) ) {
23
+ return new $class( $product, $config );
24
+ }
25
+
26
+ return new CustomShipping( $product, $config );
27
+ }
28
+ }
V5/Structure/Custom2Structure.php ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Structure;
4
+
5
+ use CTXFeed\V5\Utility\Config;
6
+
7
+ class Custom2Structure implements StructureInterface {
8
+
9
+ /**
10
+ * @var Config $config
11
+ */
12
+ private $config;
13
+ /**
14
+ * @var false|int|string
15
+ */
16
+ private $forSubLoop;
17
+ /**
18
+ * @var int
19
+ */
20
+ private $variationElementsStart;
21
+
22
+ public function __construct( $config ) {
23
+ $this->config = $config;
24
+ }
25
+
26
+ public function getXMLStructure() {
27
+ $xml = trim( preg_replace( '/\+/', '', $this->config->feed_config_custom2 ) );
28
+
29
+ // Get XML nodes for each product
30
+ $getFeedBody = woo_feed_get_string_between( $xml, '{{each product start}}', '{{each product end}}' );
31
+ // Explode each element by new line
32
+ $getElements = explode( "\n", $getFeedBody );
33
+
34
+ $Elements = array();
35
+ $i = 1;
36
+
37
+ $subLoopsStart = [
38
+ 'ifVariationAvailable' => '{{if variation available}}',
39
+ 'variation' => '{{each variation start}}',
40
+ 'images' => '{{each image start}}',
41
+ 'shipping' => '{{each shipping start}}',
42
+ 'tax' => '{{each tax start}}',
43
+ 'categories' => '{{each category start}}',
44
+ 'crossSale' => '{{each crossSale start}}',
45
+ 'upSale' => '{{each upSale start}}',
46
+ 'relatedProducts' => '{{each relatedProducts start}}',
47
+ 'associatedProduct' => '{{each associatedProduct start}}'
48
+ ];
49
+
50
+ $subLoopsEnd = [
51
+ 'ifVariationAvailableEnd' => '{{endif variation}}',
52
+ 'variationEnd' => '{{each variation end}}',
53
+ 'imagesEnd' => '{{each image end}}',
54
+ 'shippingEnd' => '{{each shipping end}}',
55
+ 'taxEnd' => '{{each tax end}}',
56
+ 'categoryEnd' => '{{each category end}}',
57
+ 'crossSaleEnd' => '{{each crossSale end}}',
58
+ 'upSaleEnd' => '{{each upSale end}}',
59
+ 'relatedProductsEnd' => '{{each relatedProducts end}}',
60
+ 'associatedProductEnd' => '{{each associatedProduct end}}'
61
+ ];
62
+
63
+ if ( ! empty( $getElements ) ) {
64
+ foreach ( $getElements as $value ) {
65
+ if ( ! empty( $value ) ) {
66
+
67
+ if ( in_array( trim( $value ), $subLoopsStart ) ) {
68
+ $this->forSubLoop = array_search( trim( $value ), $subLoopsStart, false );
69
+ if ( $this->forSubLoop === 'variation' ) {
70
+ $this->variationElementsStart = $i;
71
+ }
72
+ continue;
73
+ }
74
+
75
+ if ( in_array( trim( $value ), $subLoopsEnd ) ) {
76
+ $loopKey = array_search( trim( $value ), $subLoopsEnd, false );
77
+ if ( $loopKey === 'ifVariationAvailableEnd' ) {
78
+ $Elements[ $i - 1 ]['for'] = 'ifVariationAvailable';
79
+ }
80
+ $this->forSubLoop = "";
81
+ continue;
82
+ }
83
+
84
+ // Get Element info
85
+ $element = woo_feed_get_string_between( $value, '<', '>' );
86
+
87
+ if ( empty( $element ) ) {
88
+ continue;
89
+ }
90
+
91
+ // Set Element for
92
+ $Elements[ $i ]['for'] = $this->forSubLoop;
93
+
94
+ // Get starting element
95
+ $Elements[ $i ]['start'] = $this->removeQuotation( $element );
96
+ // Get ending element
97
+ $Elements[ $i ]['end'] = woo_feed_get_string_between( $value, '</', '>' );
98
+
99
+ // Set CDATA status and remove CDATA
100
+ $elementTextInfo = woo_feed_get_string_between( $value, '>', '</' );
101
+ $Elements[ $i ]['include_cdata'] = 'no';
102
+ if ( stripos( $elementTextInfo, 'CDATA' ) !== false ) {
103
+ $Elements[ $i ]['include_cdata'] = 'yes';
104
+ $elementTextInfo = $this->removeCDATA( $elementTextInfo );
105
+ }
106
+ // Get Pattern of the xml node
107
+ $Elements[ $i ]['elementTextInfo'] = $elementTextInfo;
108
+
109
+ if ( ! empty( $Elements[ $i ]['elementTextInfo'] ) ) {
110
+ // Get type of the attribute pattern
111
+ if ( strpos( $elementTextInfo, '{' ) === false && strpos( $elementTextInfo, '}' ) === false ) {
112
+ $Elements[ $i ]['attr_type'] = 'text';
113
+ $Elements[ $i ]['attr_value'] = $elementTextInfo;
114
+ } elseif ( strpos( $elementTextInfo, 'return' ) !== false ) {
115
+ $Elements[ $i ]['attr_type'] = 'return';
116
+ $return = woo_feed_get_string_between( $elementTextInfo, '{(', ')}' );
117
+ $Elements[ $i ]['to_return'] = $return;
118
+ } elseif ( strpos( $elementTextInfo, 'php ' ) !== false ) {
119
+ $Elements[ $i ]['attr_type'] = 'php';
120
+ $php = woo_feed_get_string_between( $elementTextInfo, '{(', ')}' );
121
+ $Elements[ $i ]['to_return'] = str_replace( 'php', '', $php );
122
+ } else {
123
+ $Elements[ $i ]['attr_type'] = 'attribute';
124
+ $attribute = woo_feed_get_string_between( $elementTextInfo, '{', '}' );
125
+ $getAttrBaseFormat = explode( ',', $attribute );
126
+
127
+ $attrInfo = $getAttrBaseFormat[0];
128
+ if ( count( $getAttrBaseFormat ) > 1 ) {
129
+ $j = 0;
130
+ foreach ( $getAttrBaseFormat as $_value ) {
131
+ if ( $value !== "" ) {
132
+ $formatters = woo_feed_get_string_between( $_value, '[', ']' );
133
+ if ( ! empty( $formatters ) ) {
134
+ $Elements[ $i ]['formatter'][ $j ] = $formatters;
135
+ $j ++;
136
+ }
137
+ }
138
+ }
139
+ }
140
+
141
+ $getAttrCodes = explode( '|', $attrInfo );
142
+ $Elements[ $i ]['attr_code'] = $getAttrCodes[0];
143
+ $Elements[ $i ]['id_type'] = isset( $getAttrCodes[1] ) ? $getAttrCodes[1] : '';
144
+ }
145
+
146
+ // Get prefix of the attribute node value
147
+ $Elements[ $i ]['prefix'] = '';
148
+ if ( 'text' !== $Elements[ $i ]['attr_type'] && strpos( trim( $elementTextInfo ), '{' ) !== 0 ) {
149
+ $getPrefix = explode( '{', $elementTextInfo );
150
+ $Elements[ $i ]['prefix'] = ( count( $getPrefix ) > 1 ) ? $getPrefix[0] : '';
151
+ }
152
+ // Get suffix of the attribute node value
153
+ $Elements[ $i ]['suffix'] = '';
154
+ if ( 'text' != $Elements[ $i ]['attr_type'] && strpos( trim( $elementTextInfo ), '}' ) !== 0 ) {
155
+ $getSuffix = explode( '}', $elementTextInfo );
156
+ $Elements[ $i ]['suffix'] = ( count( $getSuffix ) > 1 ) ? $getSuffix[1] : '';
157
+ }
158
+ }
159
+
160
+ preg_match_all( '/{(.*?)}/', $element, $matches );
161
+ $startCodes = ( isset( $matches[0] ) ? $matches[0] : '' );
162
+ $Elements[ $i ]['start_code'] = array_filter( $startCodes );
163
+ $i ++;
164
+ }
165
+ }
166
+ }
167
+
168
+ return [
169
+ 'variationElementsStart' => $this->variationElementsStart,
170
+ 'structure' => $Elements
171
+ ];
172
+ }
173
+
174
+ /** Remove CDATA from String
175
+ *
176
+ * @param string $output
177
+ *
178
+ * @return string
179
+ */
180
+ private function removeCDATA( $output ) {
181
+ return str_replace( [ "<![CDATA[", "]]>" ], "", $output );
182
+ }
183
+
184
+ /**
185
+ * Remove Quotation mark from xml element.
186
+ *
187
+ * @return string
188
+ */
189
+ private function removeQuotation( $string ) {
190
+ return wp_unslash( str_replace( array( "'", "\"", "&quot;" ), "", $string ) );
191
+ }
192
+
193
+ public function getCSVStructure() {
194
+ // TODO: Implement getCSVStructure() method.
195
+ }
196
+
197
+ public function getTSVStructure() {
198
+ // TODO: Implement getTSVStructure() method.
199
+ }
200
+
201
+ public function getTXTStructure() {
202
+ // TODO: Implement getTXTStructure() method.
203
+ }
204
+
205
+ public function getXLSStructure() {
206
+ // TODO: Implement getXLSStructure() method.
207
+ }
208
+
209
+ public function getJSONStructure() {
210
+ // TODO: Implement getJSONStructure() method.
211
+ }
212
+ }
V5/Structure/CustomStructure.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Structure;
4
+
5
+ use CTXFeed\V5\Merchant\MerchantAttributeReplaceFactory;
6
+
7
+ class CustomStructure implements StructureInterface {
8
+ private $config;
9
+
10
+ public function __construct( $config ) {
11
+ $this->config = $config;
12
+ }
13
+
14
+ public function getXMLStructure() {
15
+ $attributes = $this->config->attributes;
16
+ $mattributes = $this->config->mattributes;
17
+ $static = $this->config->default;
18
+ $type = $this->config->type;
19
+ $wrapper = str_replace( " ", "_", $this->config->itemWrapper );;
20
+ $data = [];
21
+ foreach ( $mattributes as $key => $attribute ) {
22
+
23
+ $attributeValue = ( $type[ $key ] === 'pattern' ) ? $static[ $key ] : $attributes[ $key ];
24
+ $replacedAttribute = MerchantAttributeReplaceFactory::replace_attribute( $attribute, $this->config );
25
+ $replacedAttribute = str_replace( " ", "_", $replacedAttribute );
26
+ $data[ $wrapper ][][ $replacedAttribute ] = $attributeValue;
27
+ }
28
+
29
+ return $data;
30
+ }
31
+
32
+ public function getCSVStructure() {
33
+ $attributes = $this->config->attributes;
34
+ $mattributes = $this->config->mattributes;
35
+ $static = $this->config->default;
36
+ $type = $this->config->type;
37
+ $data = [];
38
+ foreach ( $mattributes as $key => $attribute ) {
39
+ $attributeValue = ( $type[ $key ] === 'pattern' ) ? $static[ $key ] : $attributes[ $key ];
40
+ $replacedAttribute = MerchantAttributeReplaceFactory::replace_attribute( $attribute, $this->config );
41
+ $data[][ $replacedAttribute ] = $attributeValue;
42
+ }
43
+
44
+ return $data;
45
+ }
46
+
47
+
48
+ public
49
+ function getTSVStructure() {
50
+ return $this->getCSVStructure();
51
+ }
52
+
53
+ public
54
+ function getTXTStructure() {
55
+ return $this->getCSVStructure();
56
+ }
57
+
58
+ public
59
+ function getXLSStructure() {
60
+ return $this->getCSVStructure();
61
+ }
62
+
63
+ public
64
+ function getJSONStructure() {
65
+ $attributes = $this->config->attributes;
66
+ $mattributes = $this->config->mattributes;
67
+ $static = $this->config->default;
68
+ $type = $this->config->type;
69
+ $data = [];
70
+ foreach ( $mattributes as $key => $attribute ) {
71
+ $attributeValue = ( $type[ $key ] === 'pattern' ) ? $static[ $key ] : $attributes[ $key ];
72
+ $replacedAttribute = MerchantAttributeReplaceFactory::replace_attribute( $attribute, $this->config );
73
+ $data[ $replacedAttribute ] = $attributeValue;
74
+ }
75
+
76
+ return $data;
77
+ }
78
+ }
V5/Structure/FacebookStructure.php ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Structure;
3
+ use CTXFeed\V5\Merchant\MerchantAttributeReplaceFactory;
4
+
5
+ class FacebookStructure implements StructureInterface {
6
+ private $config;
7
+
8
+ public function __construct( $config ) {
9
+ $this->config = $config;
10
+ }
11
+
12
+
13
+ public function get_grouped_attributes() {
14
+ $group['additional_variant'] = [
15
+ 'additional_variant_label',
16
+ 'additional_variant_value'
17
+ ];
18
+
19
+ $group['tax'] = [
20
+ 'tax_country',
21
+ 'tax_region',
22
+ 'tax_rate',
23
+ 'tax_ship'
24
+ ];
25
+ $group['shipping'] = [
26
+ // 'country','region','service','price','postal_code',
27
+ 'location_id',
28
+ 'location_group_name',
29
+ 'min_handling_time',
30
+ 'max_handling_time',
31
+ 'min_transit_time',
32
+ 'max_transit_time'
33
+ ];
34
+
35
+ return $group;
36
+ }
37
+
38
+ public function getXMLStructure() {
39
+ $additional_variant = [];
40
+ $group = $this->get_grouped_attributes();
41
+ $attributes = $this->config->attributes;
42
+ $mattributes = $this->config->mattributes;
43
+ $static = $this->config->default;
44
+ $type = $this->config->type;
45
+ $wrapper = $this->config->itemWrapper;
46
+ $data = [];
47
+ foreach ( $mattributes as $key => $attribute ) {
48
+ $attributeValue = ( $type[ $key ] === 'pattern' ) ? $static[ $key ] : $attributes[ $key ];
49
+ $additional_variant_sub = str_replace( "additional_variant_", "", $attribute );
50
+ $replacedAttribute = MerchantAttributeReplaceFactory::replace_attribute( $attribute, $this->config );
51
+ // Installment Attribute
52
+ if ( in_array( $attribute, $group['additional_variant'], true ) && count( $additional_variant ) < 1 ) {
53
+ $additional_variant[ $additional_variant_sub ] = $attributeValue;
54
+ }elseif ( in_array( $attribute, $group['additional_variant'], true ) ) {
55
+ $additional_variant[ $additional_variant_sub ] = $attributeValue;
56
+ $data[ $wrapper ][]['additional_variant_attribute'] = $additional_variant;
57
+ $additional_variant = [];
58
+ }elseif ( strpos( $attribute, 'images_' ) !== false ) {
59
+ $data[ $wrapper ][][ $replacedAttribute ] = $attributeValue;
60
+ }else {
61
+ $data[ $wrapper ][ $replacedAttribute ] = $attributeValue;
62
+ }
63
+ }
64
+
65
+ return $data;
66
+ }
67
+
68
+ public function getCSVStructure() {
69
+ $group = $this->get_grouped_attributes();
70
+ $attributes = $this->config->attributes;
71
+ $mattributes = $this->config->mattributes;
72
+ $static = $this->config->default;
73
+ $type = $this->config->type;
74
+ $data = [];
75
+
76
+ foreach ( $mattributes as $key => $attribute ) {
77
+ $additional_variant_sub = str_replace( "additional_variant_", "", $attribute );
78
+ $attributeValue = ( $type[ $key ] === 'pattern' ) ? $static[ $key ] : $attributes[ $key ];
79
+
80
+ if ( in_array( $attribute, $group['additional_variant'], true ) && count( $additional_variant ) < 1 ) {
81
+ $additional_variant[ $additional_variant_sub ] = $attributeValue;
82
+ }elseif ( in_array( $attribute, $group['additional_variant'], true ) ) {
83
+ $additional_variant[ $additional_variant_sub ] = $attributeValue;
84
+ $data[ 'additional_variant_attribute' ][] = $additional_variant;
85
+ $additional_variant = [];
86
+ } elseif ( strpos( $attribute, 'images_' ) !== false ) {
87
+ $replacedAttribute = MerchantAttributeReplaceFactory::replace_attribute( 'additional_image_link', $this->config );
88
+ $data[][$replacedAttribute] = $attributeValue;
89
+ } else {
90
+ $replacedAttribute = MerchantAttributeReplaceFactory::replace_attribute( $attribute, $this->config );
91
+ $data[][ $replacedAttribute ] = $attributeValue;
92
+ }
93
+ }
94
+
95
+ if ( array_key_exists( 'shipping', $data ) && ! empty( $data['shipping'] ) ) {
96
+ $attr = 'shipping(' . implode( ':', array_keys( $data['shipping'] ) ) . ')';
97
+ $data[][ $attr ] = implode( ':', array_values( $data['shipping'] ) );
98
+ unset( $data['shipping'] );
99
+ }
100
+
101
+ if ( array_key_exists( 'additional_variant_attribute', $data ) && ! empty( $data['additional_variant_attribute'] ) ) {
102
+ foreach ( $data['additional_variant_attribute'] as $detail ) {
103
+ $additional_variant[] = implode( ':', array_values( $detail ) );
104
+ }
105
+ $data[]['additional_variant_attribute'] = implode( ',', array_values( $additional_variant ) );
106
+ unset( $data['additional_variant_attribute'] );
107
+ }
108
+
109
+
110
+ return $data;
111
+ }
112
+
113
+ public function getTSVStructure() {
114
+ return $this->getCSVStructure();
115
+ }
116
+
117
+ public function getTXTStructure() {
118
+ return $this->getCSVStructure();
119
+ }
120
+
121
+ public function getXLSStructure() {
122
+ return $this->getCSVStructure();
123
+ }
124
+
125
+ public function getJSONStructure() {
126
+ return $this->getCSVStructure();
127
+ }
128
+ }
129
+
V5/Structure/GoogleStructure.php ADDED
@@ -0,0 +1,301 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Structure;
4
+
5
+ use CTXFeed\V5\Merchant\MerchantAttributeReplaceFactory;
6
+ use CTXFeed\V5\Shipping\ShippingFactory;
7
+ use CTXFeed\V5\Utility\Settings;
8
+ use WC_Tax;
9
+
10
+ class GoogleStructure implements StructureInterface {
11
+ private $config;
12
+
13
+ public function __construct( $config ) {
14
+ $this->config = $config;
15
+ $this->config->itemWrapper = 'item';
16
+ $this->config->itemsWrapper = 'items';
17
+ }
18
+
19
+
20
+ public function get_grouped_attributes() {
21
+ $group['installment'] = [
22
+ 'installment_months',
23
+ 'installment_amount'
24
+ ];
25
+ $group['subscription_cost'] = [
26
+ 'subscription_period',
27
+ 'subscription_period_length',
28
+ 'subscription_amount'
29
+ ];
30
+ $group['product_detail'] = [
31
+ 'section_name',
32
+ 'attribute_name',
33
+ 'attribute_value'
34
+ ];
35
+ $group[] = [
36
+ 'product_highlight_1',
37
+ 'product_highlight_2',
38
+ 'product_highlight_3',
39
+ 'product_highlight_4',
40
+ 'product_highlight_5',
41
+ 'product_highlight_6',
42
+ 'product_highlight_7',
43
+ 'product_highlight_8',
44
+ 'product_highlight_9',
45
+ 'product_highlight_10'
46
+ ];
47
+ $group['tax'] = [
48
+ 'tax_country',
49
+ 'tax_region',
50
+ 'tax_rate',
51
+ 'tax_ship'
52
+ ];
53
+ $group['shipping'] = [
54
+ 'country',
55
+ 'region',
56
+ 'service',
57
+ 'price',
58
+ 'location_id',
59
+ 'location_group_name',
60
+ 'min_handling_time',
61
+ 'max_handling_time',
62
+ 'min_transit_time',
63
+ 'max_transit_time'
64
+ ];
65
+
66
+ return $group;
67
+ }
68
+
69
+ public function getXMLStructure() {
70
+ $product_detail = [];
71
+ $subscription = [];
72
+ $installment = [];
73
+ $tax = [];
74
+ $group = $this->get_grouped_attributes();
75
+ $attributes = $this->config->attributes;
76
+ $mattributes = $this->config->mattributes;
77
+ $static = $this->config->default;
78
+ $type = $this->config->type;
79
+ $wrapper = $this->config->itemWrapper;
80
+ $data = [];
81
+ foreach ( $mattributes as $key => $attribute ) {
82
+ $installment_sub = str_replace( "installment_", "", $attribute );
83
+ $installment_sub = MerchantAttributeReplaceFactory::replace_attribute( $installment_sub, $this->config );
84
+
85
+ $subscription_sub = str_replace( "subscription_", "", $attribute );
86
+ $subscription_sub = MerchantAttributeReplaceFactory::replace_attribute( $subscription_sub, $this->config );
87
+
88
+ $tax_attrs = substr_count( implode( '|', $mattributes ), 'tax_' );
89
+ $attributeValue = ( $type[ $key ] === 'pattern' ) ? $static[ $key ] : $attributes[ $key ];
90
+ $replacedAttribute = MerchantAttributeReplaceFactory::replace_attribute( $attribute, $this->config );
91
+ $product_detail_label = MerchantAttributeReplaceFactory::replace_attribute( 'product_detail', $this->config );
92
+ $shipping_label = MerchantAttributeReplaceFactory::replace_attribute( 'shipping', $this->config );
93
+ $tax_label = MerchantAttributeReplaceFactory::replace_attribute( 'tax', $this->config );
94
+ $installment_label = MerchantAttributeReplaceFactory::replace_attribute( 'installment', $this->config );
95
+ // Installment Attribute
96
+ if ( in_array( $attribute, $group['installment'], true ) && count( $installment ) < 1 ) {
97
+ $installment[ $installment_sub ] = $attributeValue;
98
+ } elseif ( in_array( $attribute, $group['installment'], true ) ) {
99
+ $installment[ $installment_sub ] = $attributeValue;
100
+ $data[ $wrapper ][ $installment_label ] = $installment;
101
+ $installment = [];
102
+ } // Subscription Attributes
103
+ elseif ( in_array( $attribute, $group['subscription_cost'], true ) && count( $subscription ) < 2 ) {
104
+ $subscription[ $subscription_sub ] = $attributeValue;
105
+ } elseif ( in_array( $attribute, $group['subscription_cost'], true ) ) {
106
+ $subscription_cost = MerchantAttributeReplaceFactory::replace_attribute( 'subscription_cost', $this->config );
107
+ $subscription[ $subscription_sub ] = $attributeValue;
108
+ $data[ $wrapper ][ $subscription_cost ] = $subscription;
109
+ $subscription = [];
110
+ } elseif ( strpos( $attribute, 'product_highlight' ) !== false ) {
111
+ $product_highlight = MerchantAttributeReplaceFactory::replace_attribute( 'product_highlight', $this->config );
112
+ $data[ $wrapper ][][ $product_highlight ] = $attributeValue;
113
+ } elseif ( strpos( $attribute, 'images_' ) !== false ) {
114
+ $attribute = MerchantAttributeReplaceFactory::replace_attribute( $attribute, $this->config );
115
+ $data[ $wrapper ][][ $attribute ] = $attributeValue;
116
+ } elseif ( in_array( $attribute, $group['tax'], true ) ) {
117
+ $sub = str_replace( [ 'tax_', 'ship' ], [ '', 'tax_ship' ], $attribute );
118
+ $sub = MerchantAttributeReplaceFactory::replace_attribute( $sub, $this->config );
119
+ if ( count( $tax ) < $tax_attrs - 1 ) {
120
+ $tax[ $sub ] = $attributeValue;
121
+
122
+ } else {
123
+ $tax[ $sub ] = $attributeValue;
124
+ $data[ $wrapper ][][ $tax_label ] = $tax;
125
+ $tax = [];
126
+ }
127
+ } elseif ( in_array( $attribute, $group['product_detail'], true ) ) {
128
+ if ( $attribute === 'section_name' || $attribute === 'attribute_name' ) {
129
+ $product_detail[ $replacedAttribute ] = $attributeValue;
130
+ } elseif ( $attribute === 'attribute_value' ) {
131
+ $product_detail[ $replacedAttribute ] = $attributeValue;
132
+ $data[ $wrapper ][][ $product_detail_label ] = $product_detail;
133
+ $product_detail = [];
134
+ }
135
+ } elseif ( in_array( $attribute, $group['shipping'], true ) ) {
136
+ // $shipping[ $replacedAttribute ] = $attributeValue;
137
+ // $data[ $wrapper ][ 'shipping_structure' ] = $shipping;
138
+ $data[ $wrapper ][ $shipping_label ] = 'shipping';
139
+ } else {
140
+ $data[ $wrapper ][ $replacedAttribute ] = $attributeValue;
141
+ }
142
+ }
143
+
144
+ return $data;
145
+ }
146
+
147
+ /**
148
+ * @throws \Exception
149
+ */
150
+ public function getCSVStructure() {
151
+ $product_detail = [];
152
+ $tax = [];
153
+ $group = $this->get_grouped_attributes();
154
+ $attributes = $this->config->attributes;
155
+ $mattributes = $this->config->mattributes;
156
+ $static = $this->config->default;
157
+ $type = $this->config->type;
158
+ $data = [];
159
+ $shipping = false;
160
+
161
+ foreach ( $mattributes as $key => $attribute ) {
162
+ if ( empty( $attribute ) ) {
163
+ continue;
164
+ }
165
+
166
+ $installment_sub = str_replace( "installment_", "", $attribute );
167
+ $subscription_sub = str_replace( "subscription_", "", $attribute );
168
+ $tax_attrs = substr_count( implode( '|', $mattributes ), 'tax_' );
169
+ $attributeValue = ( $type[ $key ] === 'pattern' ) ? $static[ $key ] : $attributes[ $key ];
170
+
171
+
172
+ $product_detail_label = MerchantAttributeReplaceFactory::replace_attribute( 'product_detail', $this->config );
173
+ $shipping_label = MerchantAttributeReplaceFactory::replace_attribute( 'shipping', $this->config );
174
+ $product_highlight_label = MerchantAttributeReplaceFactory::replace_attribute( 'product_highlight', $this->config );
175
+
176
+
177
+ if ( strpos( $attribute, 'images_' ) !== false ) {
178
+ $data['additional_image_link'][] = $attributeValue;
179
+ } elseif ( strpos( $attribute, 'installment_' ) !== false ) {
180
+ $data['installment'][ $installment_sub ] = $attributeValue;
181
+ } elseif ( strpos( $attribute, 'subscription_' ) !== false ) {
182
+ $data['subscription_cost'][ $subscription_sub ] = $attributeValue;
183
+ } elseif ( strpos( $attribute, 'product_highlight_' ) !== false ) {
184
+ $data[][ $product_highlight_label ] = $attributeValue;
185
+ } elseif ( in_array( $attribute, $group['product_detail'], true ) ) {
186
+ if ( $attribute === 'section_name' || $attribute === 'attribute_name' ) {
187
+ $product_detail[ $attribute ] = $attributeValue;
188
+ } elseif ( $attribute === 'attribute_value' ) {
189
+ $product_detail[ $attribute ] = $attributeValue;
190
+ $data[ $product_detail_label ][] = $product_detail;
191
+ $product_detail = [];
192
+ }
193
+ } elseif ( in_array( $attribute, $group['shipping'], true ) ) {
194
+ $shipping = true;
195
+ } elseif ( $attribute === 'shipping' ) {
196
+ continue;
197
+ }elseif ( $attribute === 'tax' ) {
198
+ $replacedAttribute = MerchantAttributeReplaceFactory::replace_attribute( $attribute, $this->config );
199
+ $taxes = $this->get_taxes();
200
+ if ( ! empty( $taxes ) ) {
201
+ foreach ( $taxes as $rates ) {
202
+ if ( $rates > 0 ) {
203
+ for ( $i = 0; $i < $rates; $i ++ ) {
204
+ $data[][ $replacedAttribute ] = "csv_tax_" . $i;
205
+ }
206
+ }
207
+ }
208
+ }
209
+ } else {
210
+ $replacedAttribute = MerchantAttributeReplaceFactory::replace_attribute( $attribute, $this->config );
211
+ $data[][ $replacedAttribute ] = $attributeValue;
212
+ }
213
+ }
214
+
215
+ if ( array_key_exists( 'subscription_cost', $data ) && ! empty( $data['subscription_cost'] ) ) {
216
+ $data[]['subscription_cost'] = implode( ':', array_values( $data['subscription_cost'] ) );
217
+ unset( $data['subscription_cost'] );
218
+ }
219
+
220
+ if ( array_key_exists( 'installment', $data ) && ! empty( $data['installment'] ) ) {
221
+ $data[]['installment'] = implode( ':', array_values( $data['installment'] ) );
222
+ unset( $data['installment'] );
223
+ }
224
+
225
+ if ( array_key_exists( 'additional_image_link', $data ) && ! empty( $data['additional_image_link'] ) ) {
226
+ $imageLinks = $data['additional_image_link'];
227
+ unset( $data['additional_image_link'] );
228
+ $data[]['additional_image_link'] = implode( ',', array_values( $imageLinks ) );
229
+ }
230
+
231
+ if ( array_key_exists( 'product_detail', $data ) && ! empty( $data['product_detail'] ) ) {
232
+ foreach ( $data['product_detail'] as $detail ) {
233
+ $product_detail[] = implode( ':', array_values( $detail ) );
234
+ }
235
+ $data[]['product_detail'] = implode( ',', array_values( $product_detail ) );
236
+ unset( $data['product_detail'] );
237
+ }
238
+
239
+ if ( $shipping ) {
240
+ $allow_all_shipping = Settings::get( 'allow_all_shipping' );
241
+ $country = $this->config->get_shipping_country();
242
+
243
+ $methods = ( ShippingFactory::get( [], $this->config ) )->get_shipping_info();
244
+ if ( 'no' === $allow_all_shipping ) {
245
+ $methods = array_filter( $methods, static function ( $var ) use ( $country ) {
246
+ return ( $var['country'] === $country );
247
+ } );
248
+ }
249
+
250
+ if ( ! empty( $methods ) ) {
251
+ $iMax = count( $methods );
252
+ for ( $i = 0; $i < $iMax; $i ++ ) {
253
+ $data[][ 'shipping(' . implode( ':', $group['shipping'] ) . ')' ] = "csv_shipping_" . $i;
254
+ }
255
+ }
256
+ }
257
+
258
+ unset( $data['shipping'] );
259
+
260
+ return $data;
261
+ }
262
+
263
+ public function get_taxes() {
264
+
265
+ $all_tax_rates = [];
266
+ // Retrieve all tax classes.
267
+ $tax_classes = WC_Tax::get_tax_classes();
268
+
269
+ // Make sure "Standard rate" (empty class name) is present.
270
+ if ( ! in_array( '', $tax_classes, true ) ) {
271
+ array_unshift( $tax_classes, '' );
272
+ }
273
+
274
+ // For each tax class, get all rates.
275
+ if ( ! empty( $tax_classes ) ) {
276
+ foreach ( $tax_classes as $tax_class ) {
277
+ $tax_class_name = ( '' === $tax_class ) ? 'standard-rate' : $tax_class;
278
+ $all_tax_rates [ $tax_class_name ] = count( WC_Tax::get_rates_for_tax_class( $tax_class ) );
279
+ }
280
+ }
281
+
282
+ return ! empty( $all_tax_rates ) ? $all_tax_rates : false;
283
+ }
284
+
285
+ public function getTSVStructure() {
286
+ return $this->getCSVStructure();
287
+ }
288
+
289
+ public function getTXTStructure() {
290
+ return $this->getCSVStructure();
291
+ }
292
+
293
+ public function getXLSStructure() {
294
+ return $this->getCSVStructure();
295
+ }
296
+
297
+ public function getJSONStructure() {
298
+ return $this->getCSVStructure();
299
+ }
300
+ }
301
+
V5/Structure/PinterestStructure.php ADDED
@@ -0,0 +1,233 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Structure;
3
+ use CTXFeed\V5\Merchant\MerchantAttributeReplaceFactory;
4
+
5
+ class PinterestStructure implements StructureInterface {
6
+ private $config;
7
+
8
+ public function __construct( $config ) {
9
+ $this->config = $config;
10
+ $this->config->itemWrapper = 'item';
11
+ }
12
+
13
+
14
+ public function get_grouped_attributes() {
15
+ $group['installment'] = [
16
+ 'installment_months',
17
+ 'installment_amount'
18
+ ];
19
+ $group['subscription_cost'] = [
20
+ 'subscription_period',
21
+ 'subscription_period_length',
22
+ 'subscription_amount'
23
+ ];
24
+ $group['product_detail'] = [
25
+ 'section_name',
26
+ 'attribute_name',
27
+ 'attribute_value'
28
+ ];
29
+ $group[] = [
30
+ 'product_highlight_1',
31
+ 'product_highlight_2',
32
+ 'product_highlight_3',
33
+ 'product_highlight_4',
34
+ 'product_highlight_5',
35
+ 'product_highlight_6',
36
+ 'product_highlight_7',
37
+ 'product_highlight_8',
38
+ 'product_highlight_9',
39
+ 'product_highlight_10'
40
+ ];
41
+ $group['tax'] = [
42
+ 'tax_country',
43
+ 'tax_region',
44
+ 'tax_rate',
45
+ 'tax_ship'
46
+ ];
47
+ $group['shipping'] = [
48
+ // 'country','region','service','price','postal_code',
49
+ 'location_id',
50
+ 'location_group_name',
51
+ 'min_handling_time',
52
+ 'max_handling_time',
53
+ 'min_transit_time',
54
+ 'max_transit_time'
55
+ ];
56
+
57
+ return $group;
58
+ }
59
+
60
+ public function getXMLStructure() {
61
+ $product_detail = [];
62
+ $subscription = [];
63
+ $installment = [];
64
+ $tax = [];
65
+ $group = $this->get_grouped_attributes();
66
+ $attributes = $this->config->attributes;
67
+ $mattributes = $this->config->mattributes;
68
+ $static = $this->config->default;
69
+ $type = $this->config->type;
70
+ $wrapper = $this->config->itemWrapper;
71
+ $data = [];
72
+ foreach ( $mattributes as $key => $attribute ) {
73
+ $installment_sub = str_replace( "installment_", "", $attribute );
74
+ $installment_sub = MerchantAttributeReplaceFactory::replace_attribute( $installment_sub, $this->config );
75
+
76
+ $subscription_sub = str_replace( "subscription_", "", $attribute );
77
+ $subscription_sub = MerchantAttributeReplaceFactory::replace_attribute( $subscription_sub, $this->config );
78
+
79
+ $tax_attrs = substr_count( implode( '|', $mattributes ), 'tax_' );
80
+ $attributeValue = ( $type[ $key ] === 'pattern' ) ? $static[ $key ] : $attributes[ $key ];
81
+ $replacedAttribute = MerchantAttributeReplaceFactory::replace_attribute( $attribute, $this->config );
82
+ $product_detail_label = MerchantAttributeReplaceFactory::replace_attribute( 'product_detail', $this->config );
83
+ $shipping_label = MerchantAttributeReplaceFactory::replace_attribute( 'shipping', $this->config );
84
+ $tax_label = MerchantAttributeReplaceFactory::replace_attribute( 'tax', $this->config );
85
+ // Installment Attribute
86
+ if ( in_array( $attribute, $group['installment'], true ) && count( $installment ) < 1 ) {
87
+ $installment[ $installment_sub ] = $attributeValue;
88
+ } elseif ( in_array( $attribute, $group['installment'], true ) ) {
89
+ $installment[ $installment_sub ] = $attributeValue;
90
+ $data[ $wrapper ]['installment'] = $installment;
91
+ $installment = [];
92
+ } // Subscription Attributes
93
+ elseif ( in_array( $attribute, $group['subscription_cost'], true ) && count( $subscription ) < 2 ) {
94
+ $subscription[ $subscription_sub ] = $attributeValue;
95
+ } elseif ( in_array( $attribute, $group['subscription_cost'], true ) ) {
96
+ $subscription_cost = MerchantAttributeReplaceFactory::replace_attribute( 'subscription_cost', $this->config );
97
+ $subscription[ $subscription_sub ] = $attributeValue;
98
+ $data[ $wrapper ][$subscription_cost] = $subscription;
99
+ $subscription = [];
100
+ } elseif ( strpos( $attribute, 'product_highlight' ) !== false ) {
101
+ $product_highlight = MerchantAttributeReplaceFactory::replace_attribute( 'product_highlight', $this->config );
102
+ $data[ $wrapper ][][$product_highlight] = $attributeValue;
103
+ } elseif ( strpos( $attribute, 'images_' ) !== false ) {
104
+ $replacedAttribute = MerchantAttributeReplaceFactory::replace_attribute( $attribute, $this->config );
105
+ $data[ $wrapper ][][ $replacedAttribute ] = $attributeValue;
106
+ } elseif ( in_array( $attribute, $group['tax'], true ) ) {
107
+ $sub = str_replace( [ 'tax_', 'ship' ], [ '', 'tax_ship' ], $attribute );
108
+ $sub = MerchantAttributeReplaceFactory::replace_attribute( $sub, $this->config );
109
+ if ( count( $tax ) < $tax_attrs - 1 ) {
110
+ $tax[ $sub ] = $attributeValue;
111
+
112
+ } else {
113
+ $tax[ $sub ] = $attributeValue;
114
+ $data[ $wrapper ][][$tax_label] = $tax;
115
+ $tax = [];
116
+ }
117
+ } elseif ( in_array( $attribute, $group['product_detail'], true ) ) {
118
+ if ( $attribute === 'section_name' || $attribute === 'attribute_name' ) {
119
+ $product_detail[ $replacedAttribute ] = $attributeValue;
120
+ } elseif ( $attribute === 'attribute_value' ) {
121
+ $product_detail[ $replacedAttribute ] = $attributeValue;
122
+ $data[ $wrapper ][][$product_detail_label] = $product_detail;
123
+ $product_detail = [];
124
+ }
125
+ } elseif ( in_array( $attribute, $group['shipping'], true ) ) {
126
+ $shipping[ $replacedAttribute ] = $attributeValue;
127
+ $data[ $wrapper ][$shipping_label] = $shipping;
128
+ } else {
129
+ $data[ $wrapper ][ $replacedAttribute ] = $attributeValue;
130
+ }
131
+ }
132
+
133
+ return $data;
134
+ }
135
+
136
+ public function getCSVStructure() {
137
+ $product_detail = [];
138
+ $tax = [];
139
+ $group = $this->get_grouped_attributes();
140
+ $attributes = $this->config->attributes;
141
+ $mattributes = $this->config->mattributes;
142
+ $static = $this->config->default;
143
+ $type = $this->config->type;
144
+ $data = [];
145
+
146
+ foreach ( $mattributes as $key => $attribute ) {
147
+ $installment_sub = str_replace( "installment_", "", $attribute );
148
+ $subscription_sub = str_replace( "subscription_", "", $attribute );
149
+ $tax_attrs = substr_count( implode( '|', $mattributes ), 'tax_' );
150
+ $attributeValue = ( $type[ $key ] === 'pattern' ) ? $static[ $key ] : $attributes[ $key ];
151
+
152
+ if ( strpos( $attribute, 'images_' ) !== false ) {
153
+ $data['additional_image_link'][] = $attributeValue;
154
+ } elseif ( strpos( $attribute, 'installment_' ) !== false ) {
155
+ $data['installment'][ $installment_sub ] = $attributeValue;
156
+ } elseif ( strpos( $attribute, 'subscription_' ) !== false ) {
157
+ $data['subscription_cost'][ $subscription_sub ] = $attributeValue;
158
+ } elseif ( strpos( $attribute, 'product_highlight_' ) !== false ) {
159
+ $data[]['product_highlight'] = $attributeValue;
160
+ } elseif ( in_array( $attribute, $group['product_detail'], true ) ) {
161
+ if ( $attribute === 'section_name' || $attribute === 'attribute_name' ) {
162
+ $product_detail[ $attribute ] = $attributeValue;
163
+ } elseif ( $attribute === 'attribute_value' ) {
164
+ $product_detail[ $attribute ] = $attributeValue;
165
+ $data['product_detail'][] = $product_detail;
166
+ $product_detail = [];
167
+ }
168
+ } elseif ( in_array( $attribute, $group['shipping'], true ) ) {
169
+ $shipping[ $attribute ] = $attributeValue;
170
+ $data['shipping'] = $shipping;
171
+ } elseif ( in_array( $attribute, $group['tax'], true ) ) {
172
+ $sub = str_replace( [ 'tax_', 'ship' ], [ '', 'tax_ship' ], $attribute );
173
+ if ( count( $tax ) < $tax_attrs - 1 ) {
174
+ $tax[ $sub ] = $attributeValue;
175
+ } else {
176
+ $tax[ $sub ] = $attributeValue;
177
+ $data['tax'] [] = $tax;
178
+ $tax = [];
179
+ }
180
+ } else {
181
+ $data[][ $attribute ] = $attributeValue;
182
+ }
183
+ }
184
+
185
+ if ( array_key_exists( 'shipping', $data ) && ! empty( $data['shipping'] ) ) {
186
+ $attr = 'shipping(' . implode( ':', array_keys( $data['shipping'] ) ) . ')';
187
+ $data[][ $attr ] = implode( ':', array_values( $data['shipping'] ) );
188
+ unset( $data['shipping'] );
189
+ }
190
+
191
+ if ( array_key_exists( 'subscription_cost', $data ) && ! empty( $data['subscription_cost'] ) ) {
192
+ $data[]['subscription_cost'] = implode( ':', array_values( $data['subscription_cost'] ) );
193
+ unset( $data['subscription_cost'] );
194
+ }
195
+
196
+ if ( array_key_exists( 'installment', $data ) && ! empty( $data['installment'] ) ) {
197
+ $data[]['installment'] = implode( ':', array_values( $data['installment'] ) );
198
+ }
199
+
200
+ if ( array_key_exists( 'additional_image_link', $data ) && ! empty( $data['additional_image_link'] ) ) {
201
+ $imageLinks = $data['additional_image_link'];
202
+ unset( $data['additional_image_link'] );
203
+ $data[]['additional_image_link'] = implode( ',', array_values( $imageLinks ) );
204
+ }
205
+
206
+ if ( array_key_exists( 'product_detail', $data ) && ! empty( $data['product_detail'] ) ) {
207
+ foreach ( $data['product_detail'] as $detail ) {
208
+ $product_detail[] = implode( ':', array_values( $detail ) );
209
+ }
210
+ $data[]['product_detail'] = implode( ',', array_values( $product_detail ) );
211
+ unset( $data['product_detail'] );
212
+ }
213
+
214
+
215
+ return $data;
216
+ }
217
+
218
+ public function getTSVStructure() {
219
+ return $this->getCSVStructure();
220
+ }
221
+
222
+ public function getTXTStructure() {
223
+ return $this->getCSVStructure();
224
+ }
225
+
226
+ public function getXLSStructure() {
227
+ return $this->getCSVStructure();
228
+ }
229
+
230
+ public function getJSONStructure() {
231
+ return $this->getCSVStructure();
232
+ }
233
+ }
V5/Structure/SkroutzStructure.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Structure;
3
+ class Skroutz {
4
+
5
+ }
V5/Structure/Structure.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Structure;
4
+
5
+
6
+ /**
7
+ * Class Structure
8
+ *
9
+ * @package CTXFeed\V5\Structure
10
+ * @subpackage CTXFeed\V5\Structure
11
+ */
12
+ class Structure {
13
+ private $structure;
14
+
15
+ public function __construct( StructureInterface $structure ) {
16
+ $this->structure = $structure;
17
+ }
18
+
19
+ public function getXMLStructure() {
20
+ return $this->structure->getXMLStructure();
21
+ }
22
+
23
+ public function getCSVStructure() {
24
+ return $this->structure->getCSVStructure();
25
+ }
26
+
27
+ public function getTSVStructure() {
28
+ return $this->structure->getCSVStructure();
29
+ }
30
+
31
+ public function getTXTStructure() {
32
+ return $this->structure->getCSVStructure();
33
+ }
34
+
35
+ public function getXLSStructure() {
36
+ return $this->structure->getCSVStructure();
37
+ }
38
+
39
+ public function getJSONStructure() {
40
+ return $this->structure->getCSVStructure();
41
+ }
42
+ }
V5/Structure/StructureFactory.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Structure;
4
+
5
+
6
+ /**
7
+ * Class StructureFactory
8
+ *
9
+ * @package CTXFeed\V5\Structure
10
+ * @subpackage CTXFeed\V5\Structure
11
+ */
12
+ class StructureFactory {
13
+ public static function get( $config ) {
14
+ $template = $config->get_feed_template();
15
+ $class = "\CTXFeed\V5\Structure\\" . ucfirst( $template ) . "Structure";
16
+ if ( class_exists( $class ) ) {
17
+ return new Structure(new $class($config));
18
+ }
19
+
20
+ return new Structure(new CustomStructure($config));
21
+ }
22
+ }
V5/Structure/StructureInterface.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Structure;
3
+ interface StructureInterface {
4
+ public function __construct( $config );
5
+ public function getXMLStructure();
6
+ public function getCSVStructure();
7
+ public function getTSVStructure();
8
+ public function getTXTStructure();
9
+ public function getXLSStructure();
10
+ public function getJSONStructure();
11
+ }
12
+
V5/Structure/TiktokStructure.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Structure;
3
+ class TiktokStructure {
4
+
5
+ }
V5/Tax/CustomTax.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Tax;
4
+
5
+ use CTXFeed\V5\Utility\Cache;
6
+ use WC_Tax;
7
+
8
+ class CustomTax implements TaxInterface {
9
+ private $product;
10
+ private $confg;
11
+
12
+ public function __construct( $product, $config ) {
13
+ $this->product = $product;
14
+ $this->confg = $config;
15
+ }
16
+
17
+ public function get_tax() {
18
+ $taxes = $this->get_taxes();
19
+
20
+ return $taxes[0];
21
+ }
22
+
23
+ public function get_taxes() {
24
+
25
+ $taxes = Cache::get( 'ctx_feed_tax_info' );
26
+ if ( ! $taxes ) {
27
+ $all_tax_rates = [];
28
+
29
+ // Retrieve all tax classes.
30
+ $tax_classes = WC_Tax::get_tax_classes();
31
+
32
+ // Make sure "Standard rate" (empty class name) is present.
33
+ if ( ! in_array( '', $tax_classes, true ) ) {
34
+ array_unshift( $tax_classes, '' );
35
+ }
36
+
37
+ // For each tax class, get all rates.
38
+ if ( ! empty( $tax_classes ) ) {
39
+ foreach ( $tax_classes as $tax_class ) {
40
+ $taxes = WC_Tax::get_rates_for_tax_class( $tax_class );
41
+ if ( ! empty( $taxes ) ) {
42
+ foreach ( $taxes as $key => $tax ) {
43
+ $tax_class_name = ( '' === $tax_class ) ? 'standard-rate' : $tax->tax_rate_class;
44
+ $all_tax_rates [ $tax_class_name ][ $key ]['id'] = $tax->tax_rate_id;
45
+ $all_tax_rates [ $tax_class_name ][ $key ]['country'] = $tax->tax_rate_country;
46
+ $all_tax_rates [ $tax_class_name ][ $key ]['state'] = $tax->tax_rate_state;
47
+ $all_tax_rates [ $tax_class_name ][ $key ]['postcode'] = is_array( $tax->postcode ) ? implode( ',', $tax->postcode ) : $tax->postcode;
48
+ $all_tax_rates [ $tax_class_name ][ $key ]['postcode_count'] = $tax->postcode_count;
49
+ $all_tax_rates [ $tax_class_name ][ $key ]['city'] = is_array( $tax->city ) ? implode( ',', $tax->city ) : $tax->city;
50
+ $all_tax_rates [ $tax_class_name ][ $key ]['city_count '] = $tax->city_count;
51
+ $all_tax_rates [ $tax_class_name ][ $key ]['rate'] = number_format( $tax->tax_rate, 2 );
52
+ $all_tax_rates [ $tax_class_name ][ $key ]['name'] = $tax->tax_rate_name;
53
+ $all_tax_rates [ $tax_class_name ][ $key ]['shipping'] = $tax->tax_rate_shipping;
54
+ $all_tax_rates [ $tax_class_name ][ $key ]['priority'] = $tax->tax_rate_priority;
55
+ }
56
+ }
57
+ }
58
+ }
59
+
60
+ $taxes = ! empty( $all_tax_rates ) ? $all_tax_rates : false;
61
+ Cache::set( 'ctx_feed_tax_info', $taxes );
62
+ }
63
+
64
+ return $taxes;
65
+ }
66
+
67
+ public function merchant_formatted_tax($key) {}
68
+
69
+ }
V5/Tax/GoogleTax.php ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Tax;
4
+
5
+ use CTXFeed\V5\Utility\Cache;
6
+ use WC_Tax;
7
+
8
+ class GoogleTax implements TaxInterface {
9
+
10
+ /**
11
+ * @var \WC_Product $product
12
+ */
13
+ private $product;
14
+ /**
15
+ * @var \CTXFeed\V5\Utility\Config $config
16
+ */
17
+ private $config;
18
+
19
+ public function __construct( $product, $config ) {
20
+ $this->product = $product;
21
+ $this->config = $config;
22
+ }
23
+
24
+ public function get_tax() {
25
+ $taxes = $this->get_taxes();
26
+
27
+ return $taxes[0];
28
+ }
29
+
30
+ public function get_taxes() {
31
+
32
+ $taxes = Cache::get( 'ctx_feed_tax_info' );
33
+ if ( ! $taxes ) {
34
+ $all_tax_rates = [];
35
+
36
+ // Retrieve all tax classes.
37
+ $tax_classes = WC_Tax::get_tax_classes();
38
+
39
+ // Make sure "Standard rate" (empty class name) is present.
40
+ if ( ! in_array( '', $tax_classes, true ) ) {
41
+ array_unshift( $tax_classes, '' );
42
+ }
43
+
44
+ // For each tax class, get all rates.
45
+ if ( ! empty( $tax_classes ) ) {
46
+ foreach ( $tax_classes as $tax_class ) {
47
+ $taxes = WC_Tax::get_rates_for_tax_class( $tax_class );
48
+ if ( ! empty( $taxes ) ) {
49
+ foreach ( $taxes as $key => $tax ) {
50
+ $tax_class_name = ( '' === $tax_class ) ? 'standard-rate' : $tax->tax_rate_class;
51
+ $all_tax_rates [ $tax_class_name ][ $key ]['id'] = $tax->tax_rate_id;
52
+ $all_tax_rates [ $tax_class_name ][ $key ]['country'] = $tax->tax_rate_country;
53
+ $all_tax_rates [ $tax_class_name ][ $key ]['state'] = $tax->tax_rate_state;
54
+ $all_tax_rates [ $tax_class_name ][ $key ]['postcode'] = is_array( $tax->postcode ) ? implode( ',', $tax->postcode ) : $tax->postcode;
55
+ $all_tax_rates [ $tax_class_name ][ $key ]['postcode_count'] = $tax->postcode_count;
56
+ $all_tax_rates [ $tax_class_name ][ $key ]['city'] = is_array( $tax->city ) ? implode( ',', $tax->city ) : $tax->city;
57
+ $all_tax_rates [ $tax_class_name ][ $key ]['city_count '] = $tax->city_count;
58
+ $all_tax_rates [ $tax_class_name ][ $key ]['rate'] = number_format( $tax->tax_rate, 2 );
59
+ $all_tax_rates [ $tax_class_name ][ $key ]['name'] = $tax->tax_rate_name;
60
+ $all_tax_rates [ $tax_class_name ][ $key ]['shipping'] = $tax->tax_rate_shipping;
61
+ $all_tax_rates [ $tax_class_name ][ $key ]['priority'] = $tax->tax_rate_priority;
62
+ }
63
+ }
64
+ }
65
+ }
66
+
67
+ $taxes = ! empty( $all_tax_rates ) ? $all_tax_rates : false;
68
+ Cache::set( 'ctx_feed_tax_info', $taxes );
69
+ }
70
+
71
+ return $taxes;
72
+ }
73
+
74
+ public function merchant_formatted_tax( $key = '' ) {
75
+ $all_taxes = $this->get_taxes();
76
+ $taxClass = empty( $this->product->get_tax_class() ) ? 'standard-rate' : $this->product->get_tax_class();
77
+ $feedType = $this->config->get_feed_file_type();
78
+ $str = "";
79
+ if ( $all_taxes && isset( $all_taxes[ $taxClass ] ) && ! empty( $all_taxes[ $taxClass ] ) ) {
80
+ $taxes = array_values( $all_taxes[ $taxClass ] );
81
+ if ( "xml" === $feedType ) {
82
+ $i = 1;
83
+ foreach ( $taxes as $tax ) {
84
+ $country = htmlentities( $tax['country'], ENT_XML1 | ENT_QUOTES, 'UTF-8' );
85
+ $state = htmlentities( $tax['state'], ENT_XML1 | ENT_QUOTES, 'UTF-8' );
86
+ $rate = htmlentities( $tax['rate'], ENT_XML1 | ENT_QUOTES, 'UTF-8' );
87
+ $postcode = htmlentities( $tax['postcode'], ENT_XML1 | ENT_QUOTES, 'UTF-8' );
88
+ $shipping = ( $tax['shipping'] ) ? "yes" : "no";
89
+
90
+ $str .= ( $i > 1 ) ? PHP_EOL . "<g:tax>" : PHP_EOL;
91
+ $str .= PHP_EOL . "<g:country>$country</g:country>";
92
+ $str .= PHP_EOL . "<g:region>$state</g:region>";
93
+ $str .= PHP_EOL . "<g:rate>$rate</g:rate>";
94
+ $str .= PHP_EOL . "<g:postal_code>$postcode</g:postal_code>";
95
+ $str .= PHP_EOL . "<g:tax_ship>$shipping</g:tax_ship>";
96
+ $str .= ( $i !== count( $taxes ) ) ? PHP_EOL . "</g:tax>" : PHP_EOL;
97
+ $i ++;
98
+ }
99
+ } else if ( $key !== '' && isset( $taxes[ $key ] ) ) {
100
+ $shipping = ( $taxes[ $key ]['shipping'] ) ? "yes" : "no";
101
+ $str = $taxes[ $key ]['country'] . ":" . $taxes[ $key ]['state'] . ":" . $taxes[ $key ]['rate'] . ":" . $taxes[ $key ]['postcode'] . ":" . $shipping;
102
+ }
103
+ }
104
+
105
+
106
+ return $str;
107
+ }
108
+ }
V5/Tax/Tax.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Tax;
4
+
5
+
6
+ /**
7
+ * Class Tax
8
+ *
9
+ * @package CTXFeed\V5\Tax
10
+ * @subpackage CTXFeed\V5\Tax
11
+ */
12
+ class Tax {
13
+ private $tax;
14
+
15
+ public function __construct( TaxInterface $tax ) {
16
+ $this->tax = $tax;
17
+ }
18
+
19
+ public function get_tax() {
20
+ return $this->tax->get_tax();
21
+ }
22
+
23
+ public function get_taxes() {
24
+ return $this->tax->get_taxes();
25
+ }
26
+
27
+ public function merchant_formatted_tax($key) {
28
+ return $this->tax->merchant_formatted_tax($key);
29
+ }
30
+
31
+ }
V5/Tax/TaxFactory.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Tax;
4
+
5
+
6
+ /**
7
+ * Class TaxFactory
8
+ *
9
+ * @package CTXFeed\V5\Tax
10
+ * @subpackage CTXFeed\V5\Tax
11
+ */
12
+ class TaxFactory {
13
+ public static function get( $product, $config ) {
14
+ $template = $config->get_feed_template();
15
+
16
+ $class = "\CTXFeed\V5\Tax\\" . ucfirst( $template ) . "Tax";
17
+
18
+ if ( class_exists( $class ) ) {
19
+ return new Tax( new $class( $product, $config ) );
20
+ }
21
+
22
+ return new Tax( new CustomTax( $product, $config ) );
23
+ }
24
+ }
V5/Tax/TaxInterface.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Tax;
3
+ interface TaxInterface {
4
+ public function get_tax();
5
+ public function get_taxes( );
6
+ public function merchant_formatted_tax($key );
7
+ }
V5/Tracker/FacebookTracker.php ADDED
@@ -0,0 +1,251 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Tracker;
4
+
5
+ use CTXFeed\V5\Utility\Settings;
6
+
7
+ class FacebookTracker implements TrackerInterface {
8
+ /**
9
+ * @var int
10
+ */
11
+ private $trackingId;
12
+
13
+ public function __construct() {
14
+ $this->trackingId = Settings::get( 'pixel_id' );
15
+
16
+ if ( $this->is_activated() ) {
17
+ add_action( 'wp_enqueue_scripts', [ $this, 'enqueueScript' ] );
18
+ add_action( 'wp_head', [ $this, 'loadBaseScript' ] );
19
+ }
20
+
21
+ // Ajax adds to cart
22
+ add_action( 'wp_ajax_add_to_cart_facebook_pixel', [ $this, 'ajax_add_to_cart_data' ] );
23
+ add_action( 'wp_ajax_nopriv_add_to_cart_facebook_pixel', [ $this, 'ajax_add_to_cart_data' ] );
24
+ }
25
+
26
+ /**
27
+ * Is Facebook Pixel Tracking Enabled.
28
+ *
29
+ * @return bool
30
+ */
31
+ public function is_activated() {
32
+ return ! empty( $this->trackingId ) && 'enable' === Settings::get( 'disable_pixel' );
33
+ }
34
+
35
+ /**
36
+ * Enqueue Ajax Add to Cart Event Code.
37
+ *
38
+ * @return void
39
+ */
40
+ public function enqueueScript() {
41
+ wp_enqueue_script( 'woo-feed-facebook-pixel,', WOO_FEED_PLUGIN_URL . 'admin/js/woo-feed-facebook-pixel.min.js', [
42
+ 'jquery',
43
+ 'wp-util'
44
+ ], '1.0.0', true );
45
+ }
46
+
47
+ /**
48
+ * Load Base Script.
49
+ *
50
+ * @return void
51
+ */
52
+ public function loadBaseScript() {
53
+ // @ToDo Language Code check. Currently passing all to `en_US`
54
+ ?>
55
+ <!-- Facebook Pixel Code -->
56
+ <script>
57
+ !function (f, b, e, v, n, t, s) {
58
+ if (f.fbq) return;
59
+ n = f.fbq = function () {
60
+ n.callMethod ?
61
+ n.callMethod.apply(n, arguments) : n.queue.push(arguments);
62
+ };
63
+ if (!f._fbq) f._fbq = n;
64
+ n.push = n;
65
+ n.loaded = !0;
66
+ n.version = '2.0';
67
+ n.queue = [];
68
+ t = b.createElement(e);
69
+ t.async = !0;
70
+ t.src = v;
71
+ s = b.getElementsByTagName(e)[0];
72
+ s.parentNode.insertBefore(t, s);
73
+ }(window, document, 'script',
74
+ 'https://connect.facebook.net/en_US/fbevents.js');
75
+ fbq('init', '<?php echo $this->trackingId; ?>');
76
+ <?php
77
+
78
+ // Always trigger PageView Event.
79
+ $this->PageView();
80
+
81
+ // Trigger ViewContent event on Product Page.
82
+ $this->ViewContent();
83
+
84
+ // Trigger on Product Added to Cart.
85
+ if ( isset( $_POST['add-to-cart'] ) ) {
86
+ $addToCart = sanitize_text_field( $_POST['add-to-cart'] );
87
+ $this->AddToCart( $addToCart );
88
+ }
89
+
90
+ // Trigger on Cart Page.
91
+ $this->AddToCarts();
92
+
93
+ // Trigger on Order Complete Page.
94
+ $this->Purchase();
95
+ ?>
96
+
97
+ </script>
98
+ <?php
99
+
100
+ }
101
+
102
+ /**
103
+ * Get item info by Ids.
104
+ *
105
+ * @param $ids
106
+ *
107
+ * @return array|false
108
+ */
109
+ private function get_content_info( $ids = [] ) {
110
+ if ( ! empty( $ids ) ) {
111
+ $data['content_ids'] = $ids;
112
+ $data['content_type'] = 'product';
113
+ $data['currency'] = get_woocommerce_currency();
114
+
115
+ $value = 0;
116
+ foreach ( $ids as $id ) {
117
+ $product = wc_get_product( $id );
118
+ if ( ! is_object( $product ) ) {
119
+ continue;
120
+ }
121
+ $value += (int) $product->get_price();
122
+ }
123
+
124
+ $data['value'] = $value;
125
+
126
+ return $data;
127
+ }
128
+
129
+ return false;
130
+ }
131
+
132
+ /**
133
+ * Load PageView Event Script.
134
+ *
135
+ * @return void
136
+ */
137
+ private function PageView() {
138
+ ?>
139
+ fbq( 'track', 'PageView' );
140
+ <?php
141
+ }
142
+
143
+ /**
144
+ * Load ViewContent Event Script.
145
+ *
146
+ * @return void
147
+ */
148
+ public function ViewContent() {
149
+ if ( is_product() ) {
150
+ global $post;
151
+ $_product = wc_get_product( $post->ID );
152
+
153
+ $id = $_product->get_ID();
154
+ $ids = [ $id ];
155
+
156
+ if ( "variable" === $_product->get_type() ) {
157
+ $ids = $_product->get_children();
158
+ }
159
+
160
+ $data = $this->get_content_info( $ids );
161
+ if ( $data ) {
162
+ ?>
163
+ fbq( 'track', 'ViewContent', <?php echo json_encode( $data ); ?> );
164
+ <?php
165
+ }
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Load AddToCart Event Script.
171
+ *
172
+ * @return void
173
+ */
174
+ public function AddToCart( $addToCart ) {
175
+ $product_id = $addToCart;
176
+ $data = $this->get_content_info( [ $product_id ] );
177
+ if ( $data ) {
178
+ ?>
179
+ fbq( 'track', 'AddToCart', <?php echo json_encode( $data ); ?> );
180
+ <?php
181
+ }
182
+ }
183
+
184
+ /**
185
+ * Load AddToCart Event Script.
186
+ *
187
+ * @return void
188
+ */
189
+ public function AddToCarts() {
190
+ if ( is_cart() && ! WC()->cart->is_empty() ) {
191
+ $ids = [];
192
+ foreach ( WC()->cart->get_cart() as $cart_item ) {
193
+ $ids[] = $cart_item['product_id'];
194
+ }
195
+
196
+ $data['content_ids'] = $ids;
197
+ $data['content_type'] = 'product';
198
+ $data['currency'] = get_woocommerce_currency();
199
+ $data['value'] = WC()->cart->get_cart_contents_total();
200
+
201
+ if ( $data ) {
202
+ ?>
203
+ fbq( 'track', 'AddToCart', <?php echo json_encode( $data ); ?> );
204
+ <?php
205
+ }
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Load Purchase Event Script.
211
+ *
212
+ * @return void
213
+ */
214
+ public function Purchase() {
215
+ if ( is_wc_endpoint_url( 'order-received' ) ) {
216
+ global $wp_query;
217
+ if ( isset( $wp_query->query_vars['order-received'] ) ) {
218
+ $order = wc_get_order( $wp_query->query_vars['order-received'] );
219
+ $ids = [];
220
+ foreach ( $order->get_items() as $item ) {
221
+ $ids[] = $item->get_product_id();
222
+ }
223
+ $data = $this->get_content_info( $ids );
224
+ if ( $data ) {
225
+ ?>
226
+ fbq( 'track', 'Purchase', <?php echo json_encode( $data ); ?> );
227
+ fbq( 'track', 'CompleteRegistration', <?php echo json_encode( $data ); ?> );
228
+ <?php
229
+ }
230
+ }
231
+ }
232
+ }
233
+
234
+ /**
235
+ * Sends json product details on Ajax Add to cart button.
236
+ *
237
+ * @return void
238
+ * @since 4.4.27
239
+ */
240
+ public function ajax_add_to_cart_data() {
241
+ $data = [];
242
+
243
+ $product_id = sanitize_text_field( isset( $_POST['product_id'] ) ? $_POST['product_id'] : '' );
244
+ if ( ! empty( $product_id ) ) {
245
+ $data = $this->get_content_info( [ $product_id ] );
246
+ }
247
+
248
+ wp_send_json_success( json_encode($data) );
249
+ }
250
+
251
+ }
V5/Tracker/GoogleTracker.php ADDED
@@ -0,0 +1,229 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Tracker;
4
+
5
+ use CTXFeed\V5\Utility\Settings;
6
+
7
+ class GoogleTracker implements TrackerInterface {
8
+
9
+ private $trackingId;
10
+ private $sendTo;
11
+
12
+ public function __construct() {
13
+
14
+ //TODO: Remarketing Settings not saving to DB.
15
+
16
+ $this->trackingId = Settings::get( 'remarketing_id' );
17
+ $this->sendTo = Settings::get( 'remarketing_label' );
18
+
19
+
20
+ if ( $this->is_activated() ) {
21
+ add_action( 'wp_enqueue_scripts', [ $this, 'enqueueScript' ] );
22
+ add_action( 'wp_head', [ $this, 'loadBaseScript' ] );
23
+ }
24
+
25
+ // Ajax adds to cart
26
+ add_action( 'wp_ajax_add_to_cart_facebook_pixel', [ $this, 'ajax_add_to_cart_data' ] );
27
+ add_action( 'wp_ajax_nopriv_add_to_cart_facebook_pixel', [ $this, 'ajax_add_to_cart_data' ] );
28
+ }
29
+
30
+ /**
31
+ * Is Facebook Pixel Tracking Enabled.
32
+ *
33
+ * @return bool
34
+ */
35
+ public function is_activated() {
36
+ return ! empty( $this->trackingId ) && ( 'enable' === Settings::get( 'disable_remarketing' ) );
37
+ }
38
+
39
+ /**
40
+ * Enqueue Ajax Add to Cart Event Code.
41
+ *
42
+ * @return void
43
+ */
44
+ public function enqueueScript() {
45
+ wp_enqueue_script( 'woo-feed-google-remarketing,', WOO_FEED_PLUGIN_URL . 'admin/js/woo-feed-google-remarketing.min.js', [
46
+ 'jquery',
47
+ 'wp-util'
48
+ ], '1.0.0', true );
49
+ }
50
+
51
+ /**
52
+ * Load Base Script.
53
+ *
54
+ * @return void
55
+ */
56
+ public function loadBaseScript() {
57
+ // @ToDo Language Code check. Currently passing all to `en_US`
58
+ ?>
59
+
60
+ <!-- Global site tag (gtag.js) -->
61
+ <script async src="https://www.googletagmanager.com/gtag/js?id=<?php echo $this->trackingId; ?>"></script>
62
+ <script>
63
+ window.dataLayer = window.dataLayer || [];
64
+
65
+ function gtag() {
66
+ dataLayer.push(arguments);
67
+ }
68
+
69
+ gtag('js', new Date());
70
+ gtag('config', '<?php echo $this->trackingId; ?>');
71
+
72
+ <?php
73
+ // Always trigger PageView Event.
74
+ // $this->PageView();
75
+
76
+ // Trigger ViewContent event on Product Page.
77
+ $this->ViewContent();
78
+
79
+ // Trigger on Product Added to Cart.
80
+ if ( isset( $_POST['add-to-cart'] ) ) {
81
+ $addToCart = sanitize_text_field( $_POST['add-to-cart'] );
82
+ $this->AddToCart( $addToCart );
83
+ }
84
+
85
+ // Trigger on Cart Page.
86
+ $this->AddToCarts();
87
+
88
+ // Trigger on Order Complete Page.
89
+ $this->Purchase();
90
+ ?>
91
+
92
+ </script>
93
+
94
+ <?php
95
+ }
96
+
97
+
98
+ /**
99
+ * Get item info by Ids.
100
+ *
101
+ * @param $ids
102
+ *
103
+ * @return array|false
104
+ */
105
+ private function get_content_info( $ids = [] ) {
106
+ if ( ! empty( $ids ) ) {
107
+
108
+ $data['send_to'] = $this->sendTo;
109
+ $data['aw_remarketing_only'] = true;
110
+ $value = 0;
111
+ foreach ( $ids as $id ) {
112
+ $product = wc_get_product( $id );
113
+ if ( ! is_object( $product ) ) {
114
+ continue;
115
+ }
116
+ $data['items'][]['id'] = $product->get_id();
117
+ $value += (int) $product->get_price();
118
+ }
119
+
120
+ $data['value'] = $value;
121
+
122
+ return $data;
123
+ }
124
+
125
+ return false;
126
+ }
127
+
128
+ /**
129
+ * Load ViewContent Event Script.
130
+ *
131
+ * @return void
132
+ */
133
+ public function ViewContent() {
134
+ if ( is_product() ) {
135
+ global $post;
136
+ $_product = wc_get_product( $post->ID );
137
+
138
+ $id = $_product->get_ID();
139
+ $ids = [ $id ];
140
+
141
+ if ( "variable" === $_product->get_type() ) {
142
+ $ids = $_product->get_children();
143
+ }
144
+
145
+ $data = $this->get_content_info( $ids );
146
+ if ( $data ) {
147
+ ?>
148
+ gtag( 'event', 'view_item', <?php echo json_encode( $data ); ?> );
149
+ <?php
150
+ }
151
+ }
152
+ }
153
+
154
+ /**
155
+ * Load AddToCart Event Script.
156
+ *
157
+ * @return void
158
+ */
159
+ public function AddToCart( $addToCart ) {
160
+ $product_id = $addToCart;
161
+ $data = $this->get_content_info( [ $product_id ] );
162
+ if ( $data ) {
163
+ ?>
164
+ gtag( 'event', 'add_to_cart', <?php echo json_encode( $data ); ?> );
165
+ <?php
166
+ }
167
+
168
+ }
169
+
170
+ /**
171
+ * Load AddToCart Event Script.
172
+ *
173
+ * @return void
174
+ */
175
+ public function AddToCarts() {
176
+ if ( is_cart() && ! WC()->cart->is_empty() ) {
177
+ $ids = [];
178
+ foreach ( WC()->cart->get_cart() as $cart_item ) {
179
+ $ids[] = $cart_item['product_id'];
180
+ }
181
+ $data = $this->get_content_info( $ids );
182
+ if ( $data ) {
183
+ ?>
184
+ gtag( 'event', 'add_to_cart', <?php echo json_encode( $data ); ?> );
185
+ <?php
186
+ }
187
+ }
188
+ }
189
+
190
+ /**
191
+ * Load Purchase Event Script.
192
+ *
193
+ * @return void
194
+ */
195
+ public function Purchase() {
196
+ global $wp_query;
197
+ if ( isset( $wp_query->query_vars['order-received'] ) ) {
198
+ $order = wc_get_order( $wp_query->query_vars['order-received'] );
199
+ $ids = [];
200
+ foreach ( $order->get_items() as $item ) {
201
+ $ids[] = $item->get_product_id();
202
+ }
203
+ $data = $this->get_content_info( $ids );
204
+ if ( $data ) {
205
+ ?>
206
+ gtag( 'event', 'purchase', <?php echo json_encode( $data ); ?> );
207
+ <?php
208
+ }
209
+ }
210
+ }
211
+
212
+ /**
213
+ * Sends json product details on Ajax Add to cart button.
214
+ *
215
+ * @return void
216
+ * @since 4.4.27
217
+ */
218
+ public function ajax_add_to_cart_data() {
219
+ $data = [];
220
+
221
+ $product_id = sanitize_text_field( isset( $_POST['product_id'] ) ? $_POST['product_id'] : '' );
222
+ if ( ! empty( $product_id ) ) {
223
+ $data = $this->get_content_info( [ $product_id ] );
224
+ }
225
+
226
+ wp_send_json_success( json_encode( $data ) );
227
+ }
228
+
229
+ }
V5/Tracker/PinterestTracker.php ADDED
@@ -0,0 +1,312 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Tracker;
4
+
5
+ use CTXFeed\V5\Utility\Settings;
6
+
7
+ class PinterestTracker implements TrackerInterface {
8
+ private $trackingId;
9
+
10
+ public function __construct() {
11
+
12
+ $this->trackingId = Settings::get( 'pinterest_tag_id' );
13
+
14
+ if ( $this->is_activated() ) {
15
+ add_action( 'wp_enqueue_scripts', [ $this, 'enqueueScript' ] );
16
+ add_action( 'wp_head', [ $this, 'loadBaseScript' ] );
17
+ }
18
+
19
+ // Ajax adds to cart
20
+ add_action( 'wp_ajax_add_to_cart_pinterest_tag', [ $this, 'ajax_add_to_cart_data' ] );
21
+ add_action( 'wp_ajax_nopriv_add_to_cart_pinterest_tag', [ $this, 'ajax_add_to_cart_data' ] );
22
+ }
23
+
24
+ /**
25
+ * Is Pinterest Tracking Enabled.
26
+ *
27
+ * @return bool
28
+ */
29
+ public function is_activated() {
30
+ return ! empty( $this->trackingId ) && 'enable' === Settings::get( 'pinterest_conversion_tracking' );
31
+ }
32
+
33
+ /**
34
+ * Enqueue Ajax Add to Cart Event Code.
35
+ *
36
+ * @return void
37
+ */
38
+ public function enqueueScript() {
39
+ wp_enqueue_script( 'woo-feed-pinterest-tag,', WOO_FEED_PLUGIN_URL . 'admin/js/woo-feed-pinterest-tag.min.js', [
40
+ 'jquery',
41
+ 'wp-util'
42
+ ], '1.0.0', true );
43
+ }
44
+
45
+ /**
46
+ * Load Base Script.
47
+ *
48
+ * @return void
49
+ */
50
+ public function loadBaseScript() {
51
+ $email = ' ';
52
+ $current_user = wp_get_current_user();
53
+ if ( ! is_null( $current_user ) && isset( $current_user->user_email ) && ! empty( $current_user->user_email ) ) {
54
+ $email = $current_user->user_email;
55
+ }
56
+
57
+
58
+ // @ToDo Language Code check. Currently passing all to `en_US`
59
+ ?>
60
+ <!-- Pinterest Tag -->
61
+ <script>
62
+ !function (e) {
63
+ if (!window.pintrk) {
64
+ window.pintrk = function () {
65
+ window.pintrk.queue.push(Array.prototype.slice.call(arguments));
66
+ };
67
+ var
68
+ n = window.pintrk;
69
+ n.queue = [], n.version = "3.0";
70
+ var
71
+ t = document.createElement("script");
72
+ t.async = !0, t.src = e;
73
+ var
74
+ r = document.getElementsByTagName("script")[0];
75
+ r.parentNode.insertBefore(t, r);
76
+ }
77
+ }("https://s.pinimg.com/ct/core.js");
78
+ pintrk('load', <?php echo $this->trackingId; ?>, {em: <?php echo $email; ?>});
79
+ pintrk('page');
80
+ </script>
81
+ <noscript>
82
+ <img height="1" width="1" style="display:none;" alt=""
83
+ src="https://ct.pinterest.com/v3/?event=init&tid=<?php echo $this->trackingId; ?>&pd[em]=<?php echo hash( 'sha256', $email ); ?>&noscript=1"/>
84
+ </noscript>
85
+ <!-- end Pinterest Tag -->
86
+ <?php
87
+
88
+ $this->PageView();
89
+ $this->ViewContent();
90
+ $this->AddToCart();
91
+ $this->AddToCarts();
92
+ $this->Purchase();
93
+ }
94
+
95
+ /**
96
+ * Get item info by Ids.
97
+ *
98
+ * @param array $ids
99
+ * @param string $event
100
+ *
101
+ * @return array|false
102
+ */
103
+ private function get_content_info( $ids = [], $event = '' ) {
104
+ if ( ! empty( $ids ) ) {
105
+ $data['currency'] = get_woocommerce_currency();
106
+
107
+ if ( $event === 'checkout' ) {
108
+ $data['order_quantity'] = '1';
109
+ }
110
+
111
+ $value = 0;
112
+ foreach ( $ids as $id ) {
113
+ $product = wc_get_product( $id );
114
+ if ( ! is_object( $product ) ) {
115
+ continue;
116
+ }
117
+ $data['line_items'][]['product_id'] = $product->get_id();
118
+ $value += (int) $product->get_price();
119
+ }
120
+
121
+ $data['value'] = $value;
122
+
123
+ return $data;
124
+ }
125
+
126
+ return false;
127
+ }
128
+
129
+ /**
130
+ * Load PageView Event Script.
131
+ *
132
+ * @return void
133
+ */
134
+ private function PageView() {
135
+ $url = $this->make_url( [], 'pagevisit' )
136
+ ?>
137
+ <script>
138
+ pintrk('track', 'pagevisit');
139
+ </script>
140
+ <noscript>
141
+ <img height="1" width="1" style="display:none;" alt=""
142
+ src="<?php echo $url; ?>"/>
143
+ </noscript>
144
+ <?php
145
+ }
146
+
147
+ /**
148
+ * Load ViewContent Event Script.
149
+ *
150
+ * @return void
151
+ */
152
+ public function ViewContent() {
153
+ if ( is_product() ) {
154
+ global $post;
155
+ $_product = wc_get_product( (int) $post->ID );
156
+
157
+ $id = $_product->get_ID();
158
+ $ids = [ $id ];
159
+
160
+ if ( "variable" === $_product->get_type() ) {
161
+ $ids = array_merge( $ids, $_product->get_children() );
162
+ }
163
+
164
+ $data = $this->get_content_info( $ids );
165
+
166
+ $url = $this->make_url( $data, 'pagevisit' );
167
+
168
+ if ( $data ) {
169
+ ?>
170
+ <script>
171
+ pintrk('track', 'pagevisit',<?php echo json_encode( $data ); ?>);
172
+ </script>
173
+ <noscript>
174
+ <img height="1" width="1" style="display:none;" alt=""
175
+ src="<?php echo $url; ?>"/>
176
+ </noscript>
177
+ <?php
178
+ }
179
+ }
180
+ }
181
+
182
+ /**
183
+ * Load AddToCart Event Script.
184
+ *
185
+ * @return void
186
+ */
187
+ public function AddToCart() {
188
+ if ( isset( $_POST['add-to-cart'] ) ) {
189
+ $product_id = esc_attr( sanitize_text_field( $_POST['add-to-cart'] ) );
190
+ $data = $this->get_content_info( [ $product_id ], 'addtocart' );
191
+ $url = $this->make_url( $data, 'addtocart' );
192
+ if ( $data ) {
193
+ ?>
194
+ <script>
195
+ pintrk('track', 'addtocart', <?php echo json_encode( $data ); ?> );
196
+ </script>
197
+ <noscript>
198
+ <img height="1" width="1" style="display:none;" alt=""
199
+ src="<?php echo $url; ?>"/>
200
+ </noscript>
201
+ <?php
202
+ }
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Load AddToCart Event Script.
208
+ *
209
+ * @return void
210
+ */
211
+ public function AddToCarts() {
212
+ if ( is_cart() && ! WC()->cart->is_empty() ) {
213
+ $ids = [];
214
+ foreach ( WC()->cart->get_cart() as $cart_item ) {
215
+ $ids[] = $cart_item['product_id'];
216
+ }
217
+ $data = $this->get_content_info( $ids, 'addtocart' );
218
+ $url = $this->make_url( $data, 'addtocart' );
219
+ if ( $data ) {
220
+ ?>
221
+ <script>
222
+ pintrk('track', 'addtocart', <?php echo json_encode( $data ); ?> );
223
+ </script>
224
+ <noscript>
225
+ <img height="1" width="1" style="display:none;" alt=""
226
+ src="<?php echo $url; ?>"/>
227
+ </noscript>
228
+ <?php
229
+ }
230
+ }
231
+ }
232
+
233
+ /**
234
+ * Load Purchase Event Script.
235
+ *
236
+ * @return void
237
+ */
238
+ public function Purchase() {
239
+ if ( is_wc_endpoint_url( 'order-received' ) ) {
240
+ global $wp_query;
241
+ if ( isset( $wp_query->query_vars['order-received'] ) ) {
242
+ $order = wc_get_order( $wp_query->query_vars['order-received'] );
243
+ $ids = [];
244
+ foreach ( $order->get_items() as $item ) {
245
+ $ids[] = $item->get_product_id();
246
+ }
247
+ $data = $this->get_content_info( $ids, 'checkout' );
248
+ $url = $this->make_url( $data, 'checkout' );
249
+ if ( $data ) {
250
+ ?>
251
+ <script>
252
+ pintrk('track', 'checkout', <?php echo json_encode( $data ); ?>);
253
+ pintrk('track', 'signup');
254
+ </script>
255
+ <noscript>
256
+ <img height="1" width="1" style="display:none;" alt=""
257
+ src="<?php echo $url; ?>"/>
258
+ <img height="1" width="1" style="display:none;" alt=""
259
+ src="https://ct.pinterest.com/v3/?tid=<?php echo $this->trackingId; ?>&event=signup&noscript=1"/>
260
+ </noscript>
261
+ <?php
262
+ }
263
+ }
264
+ }
265
+ }
266
+
267
+ /**
268
+ * Sends json product details on Ajax Add to cart button.
269
+ *
270
+ * @return void
271
+ * @since 4.4.27
272
+ */
273
+ public function ajax_add_to_cart_data() {
274
+ $data = [];
275
+
276
+ $product_id = sanitize_text_field( isset( $_POST['product_id'] ) ? $_POST['product_id'] : '' );
277
+ if ( ! empty( $product_id ) ) {
278
+ $data = $this->get_content_info( [ $product_id ] );
279
+ }
280
+
281
+ wp_send_json_success( json_encode( $data ) );
282
+ }
283
+
284
+ /**
285
+ * Make noscript args
286
+ *
287
+ * @param $args
288
+ * @param $event
289
+ *
290
+ * @return string
291
+ */
292
+ private function make_url( $args, $event ) {
293
+ $base_url = "https://ct.pinterest.com/v3/";
294
+ $base_args = [
295
+ 'tid' => $this->trackingId,
296
+ 'event' => $event,
297
+ 'noscript' => '1',
298
+ ];
299
+
300
+ $newArgs = [];
301
+ if ( ! empty( $args ) ) {
302
+ foreach ( $args as $key => $arg ) {
303
+ $newArgs[ "ed[" . $key . "]" ] = $arg;
304
+ }
305
+ }
306
+
307
+ $args = array_merge( $base_args, $newArgs );
308
+
309
+ return add_query_arg( array_filter( $args ), $base_url );
310
+ }
311
+
312
+ }
V5/Tracker/SkroutzTracker.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Tracker;
3
+ class SkroutzTracker {
4
+
5
+ }
V5/Tracker/SnapchatTracker.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Tracker;
3
+ class SnapchatTracker implements TrackerInterface {
4
+
5
+ public function is_activated() {
6
+ // TODO: Implement is_activated() method.
7
+ }
8
+
9
+ public function enqueueScript() {
10
+ // TODO: Implement enqueueScript() method.
11
+ }
12
+
13
+ public function loadBaseScript() {
14
+ // TODO: Implement loadBaseScript() method.
15
+ }
16
+
17
+ public function triggerEvents() {
18
+ // TODO: Implement triggerEvents() method.
19
+ }
20
+ }
V5/Tracker/TiktokTracker.php ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Tracker;
3
+ use CTXFeed\V5\Utility\Settings;
4
+
5
+ class TiktokTracker implements TrackerInterface {
6
+ private $trackingId;
7
+
8
+ public function __construct() {
9
+ $this->trackingId = Settings::get( 'pixel_id' );
10
+
11
+ if ( $this->is_activated() ) {
12
+ // add_action( 'wp_enqueue_scripts', [ &$this, 'enqueueScript' ] );
13
+ // add_action( 'wp_head', [ &$this, 'loadBaseScript' ] );
14
+ // add_action( 'ctx_after_pixel_init', [ &$this, 'trigger_event' ], 11 );
15
+
16
+ }
17
+
18
+ // Ajax adds to cart
19
+ add_action( 'wp_ajax_add_to_cart_facebook_pixel', [ &$this, 'ajax_add_to_cart_data' ] );
20
+ add_action( 'wp_ajax_nopriv_add_to_cart_facebook_pixel', [ &$this, 'ajax_add_to_cart_data' ] );
21
+ }
22
+
23
+ /**
24
+ * Is Facebook Pixel Tracking Enabled.
25
+ *
26
+ * @return bool
27
+ */
28
+ public function is_activated() {
29
+ return ! empty( $this->trackingId ) && 'enable' === Settings::get( 'disable_pixel' );
30
+ }
31
+
32
+ /**
33
+ * Enqueue Ajax Add to Cart Event Code.
34
+ *
35
+ * @return void
36
+ */
37
+ public function enqueueScript() {
38
+ wp_enqueue_script( 'woo-feed-facebook-pixel,', WOO_FEED_PLUGIN_URL . 'admin/js/woo-feed-facebook-pixel.min.js', [
39
+ 'jquery',
40
+ 'wp-util'
41
+ ], '1.0.0', true );
42
+ }
43
+
44
+ /**
45
+ * Load Base Script.
46
+ *
47
+ * @return void
48
+ */
49
+ public function loadBaseScript() {
50
+ // @ToDo Language Code check. Currently passing all to `en_US`
51
+ ?>
52
+ <script>
53
+ !function (w, d, t) {
54
+ w.TiktokAnalyticsObject=t;var ttq=w[t]=w[t]||[];ttq.methods=["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie"],ttq.setAndDefer=function(t,e){t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}};for(var i=0;i<ttq.methods.length;i++)ttq.setAndDefer(ttq,ttq.methods[i]);ttq.instance=function(t){for(var e=ttq._i[t]||[],n=0;n<ttq.methods.length;n++)ttq.setAndDefer(e,ttq.methods[n]);return e},ttq.load=function(e,n){var i="https://analytics.tiktok.com/i18n/pixel/events.js";ttq._i=ttq._i||{},ttq._i[e]=[],ttq._i[e]._u=i,ttq._t=ttq._t||{},ttq._t[e]=+new Date,ttq._o=ttq._o||{},ttq._o[e]=n||{};var o=document.createElement("script");o.type="text/javascript",o.async=!0,o.src=i+"?sdkid="+e+"&lib="+t;var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(o,a)};
55
+ ttq.load('<?php echo $this->trackingId; ?>');
56
+ ttq.page();
57
+ }(window, document, 'ttq');
58
+ <?php
59
+ /**
60
+ * Action after pixel has been initialized in a page on page header. Every event should be fired in this hook
61
+ */
62
+ do_action( 'ctx_after_pixel_init' );
63
+ ?>
64
+ </script>
65
+ <?php
66
+ }
67
+
68
+ /**
69
+ * Trigger Events.
70
+ *
71
+ * @return void
72
+ */
73
+ public function triggerEvents() {
74
+
75
+
76
+ // Trigger ViewContent event on Product Page.
77
+ if ( is_product() ) {
78
+ $this->ViewContent();
79
+ }
80
+
81
+ // Trigger AddToCart event on Add to Cart by form post.
82
+ if ( isset( $_POST['add-to-cart'] ) ) {
83
+ $this->AddToCart();
84
+ }
85
+
86
+ // Trigger on Cart Page.
87
+ if ( is_cart() ) {
88
+ $this->AddToCarts();
89
+ }
90
+
91
+ if ( is_wc_endpoint_url( 'order-received' ) ) {
92
+ $this->Purchase();
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Get item info by Ids.
98
+ *
99
+ * @param $ids
100
+ *
101
+ * @return array|false
102
+ */
103
+ private function get_content_info( $ids = [] ) {
104
+ if ( ! empty( $ids ) ) {
105
+ $data['content_ids'] = $ids;
106
+ $data['content_type'] = 'product';
107
+ $data['currency'] = get_woocommerce_currency();
108
+
109
+ $value = 0;
110
+ foreach ( $ids as $id ) {
111
+ $product = wc_get_product( $id );
112
+ if ( ! is_object( $product ) ) {
113
+ continue;
114
+ }
115
+ $value += (int) $product->get_price();
116
+ }
117
+
118
+ $data['value'] = $value;
119
+
120
+ return $data;
121
+ }
122
+
123
+ return false;
124
+ }
125
+
126
+ /**
127
+ * Load ViewContent Event Script.
128
+ *
129
+ * @return void
130
+ */
131
+ public function ViewContent() {
132
+ if ( is_product() ) {
133
+ global $post;
134
+ $_product = wc_get_product( (int) $post->ID );
135
+
136
+ $id = $_product->get_ID();
137
+ $ids = [ $id ];
138
+
139
+ if ( "variable" === $_product->get_type() ) {
140
+ $ids = $_product->get_children();
141
+ }
142
+
143
+ $data = $this->get_content_info( $ids );
144
+ if ( $data ) {
145
+ ?>
146
+ ttq.track('ViewContent', <?php echo json_encode( $data ); ?> );
147
+ <?php
148
+ }
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Load AddToCart Event Script.
154
+ *
155
+ * @return void
156
+ */
157
+ public function AddToCart() {
158
+ if ( isset( $_POST['add-to-cart'] ) ) {
159
+ $product_id = (int) esc_attr( $_POST['add-to-cart'] );
160
+ $data = $this->get_content_info( [ $product_id ] );
161
+ if ( $data ) {
162
+ ?>
163
+ ttq.track('AddToCart', <?php echo json_encode( $data ); ?> );
164
+ <?php
165
+ }
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Load AddToCart Event Script.
171
+ *
172
+ * @return void
173
+ */
174
+ public function AddToCarts() {
175
+ if ( is_cart() && ! WC()->cart->is_empty() ) {
176
+ $ids = [];
177
+ foreach ( WC()->cart->get_cart() as $cart_item ) {
178
+ $ids[] = $cart_item['product_id'];
179
+ }
180
+ $data = $this->get_content_info( $ids );
181
+ if ( $data ) {
182
+ ?>
183
+ ttq.track('AddToCart', <?php echo json_encode( $data ); ?> );
184
+ <?php
185
+ }
186
+ }
187
+ }
188
+
189
+ /**
190
+ * Load Purchase Event Script.
191
+ *
192
+ * @return void
193
+ */
194
+ public function Purchase() {
195
+ global $wp_query;
196
+ if ( isset( $wp_query->query_vars['order-received'] ) ) {
197
+ $order = wc_get_order( $wp_query->query_vars['order-received'] );
198
+ $ids = [];
199
+ foreach ( $order->get_items() as $item ) {
200
+ $ids[] = $item->get_product_id();
201
+ }
202
+ $data = $this->get_content_info( $ids );
203
+ if ( $data ) {
204
+ ?>
205
+ ttq.track('PlaceAnOrder', <?php echo json_encode( $data ); ?> );
206
+ ttq.track('InitiateCheckout')
207
+ ttq.track('CompleteRegistration');
208
+ ttq.track('CompletePayment', <?php echo json_encode( $data ); ?> );
209
+ <?php
210
+ }
211
+ }
212
+ }
213
+
214
+ /**
215
+ * Sends json product details on Ajax Add to cart button.
216
+ *
217
+ * @return void
218
+ * @since 4.4.27
219
+ */
220
+ public function ajax_add_to_cart_data() {
221
+ $data = [];
222
+
223
+ $product_id = sanitize_text_field( isset( $_POST['product_id'] ) ? $_POST['product_id'] : '' );
224
+ if ( ! empty( $product_id ) ) {
225
+ $data = $this->get_content_info( [ $product_id ] );
226
+ }
227
+
228
+ wp_send_json_success( json_encode( $data ) );
229
+ }
230
+
231
+ }
V5/Tracker/TrackerFactory.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Tracker;
3
+ class TrackerFactory {
4
+ public static function Track( ) {
5
+ new FacebookTracker();
6
+ new GoogleTracker();
7
+ new PinterestTracker();
8
+ new TiktokTracker();
9
+ }
10
+ }
V5/Tracker/TrackerInterface.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Tracker;
3
+ interface TrackerInterface {
4
+ public function is_activated( );
5
+ public function enqueueScript( );
6
+ public function loadBaseScript( );
7
+ }
V5/Utility/CTX_WC_Log_Handler.php ADDED
@@ -0,0 +1,443 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Utility;
3
+
4
+ use WC_Log_Handler;
5
+
6
+ /**
7
+ * Log file handler
8
+ *
9
+ * @package WooFeed
10
+ * @subpackage LogHandler
11
+ * @since WooFeed 3.2.1
12
+ * @version 1.0.0
13
+ * @author KD <mhaudul.hk@gmail.com>
14
+ *@copyright 2019 WebAppick
15
+ */
16
+ if ( ! defined( 'ABSPATH' ) ) {
17
+ die(); // Silence...
18
+ }
19
+
20
+ class CTX_WC_Log_Handler extends WC_Log_Handler {
21
+
22
+ /**
23
+ * Stores open file handles.
24
+ *
25
+ * @var array
26
+ */
27
+ protected $handles = array();
28
+
29
+ /**
30
+ * File size limit for log files in bytes.
31
+ *
32
+ * @var int
33
+ */
34
+ protected $log_size_limit;
35
+
36
+ /**
37
+ * Cache logs that could not be written.
38
+ *
39
+ * If a log is written too early in the request, pluggable functions may be unavailable. These
40
+ * logs will be cached and written on 'plugins_loaded' action.
41
+ *
42
+ * @var array
43
+ */
44
+ protected $cached_logs = array();
45
+
46
+ /**
47
+ * Constructor for the logger.
48
+ *
49
+ * @param int $log_size_limit Optional. Size limit for log files. Default 5mb.
50
+ */
51
+ public function __construct( $log_size_limit = null ) {
52
+ if ( null === $log_size_limit ) {
53
+ $log_size_limit = 5 * 1024 * 1024;
54
+ }
55
+
56
+ $this->log_size_limit = apply_filters( 'woo_feed_log_file_size_limit', $log_size_limit );
57
+
58
+ add_action( 'plugins_loaded', array( $this, 'write_cached_logs' ) );
59
+ }
60
+
61
+ /**
62
+ * Destructor.
63
+ *
64
+ * Cleans up open file handles.
65
+ */
66
+ public function __destruct() {
67
+ foreach ( $this->handles as $handle ) {
68
+ if ( is_resource( $handle ) ) {
69
+ fclose( $handle ); // phpcs:ignore
70
+ }
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Handle a log entry.
76
+ *
77
+ * @param int $timestamp Log timestamp.
78
+ * @param string $level emergency|alert|critical|error|warning|notice|info|debug.
79
+ * @param string $message Log message.
80
+ * @param array $context {
81
+ * Additional information for log handlers.
82
+ *
83
+ * @type string $source Optional. Determines log file to write to. Default 'log'.
84
+ * @type bool $_legacy Optional. Default false. True to use outdated log format
85
+ * originally used in deprecated WC_Logger::add calls.
86
+ * }
87
+ *
88
+ * @return bool False if value was not handled and true if value was handled.
89
+ */
90
+ public function handle( $timestamp, $level, $message, $context ) {
91
+
92
+ if ( isset( $context['source'] ) && $context['source'] ) {
93
+ $handle = $context['source'];
94
+ } else {
95
+ $handle = 'log';
96
+ }
97
+
98
+ $entry = self::format_entry( $timestamp, $level, $message, $context );
99
+
100
+ return $this->add( $entry, $handle );
101
+ }
102
+
103
+ /**
104
+ * Builds a log entry text from timestamp, level and message.
105
+ *
106
+ * @param int $timestamp Log timestamp.
107
+ * @param string $level emergency|alert|critical|error|warning|notice|info|debug.
108
+ * @param string $message Log message.
109
+ * @param array $context Additional information for log handlers.
110
+ *
111
+ * @return string Formatted log entry.
112
+ */
113
+ protected static function format_entry( $timestamp, $level, $message, $context ) {
114
+
115
+ if ( isset( $context['_legacy'] ) && true === $context['_legacy'] ) {
116
+ if ( isset( $context['source'] ) && $context['source'] ) {
117
+ $handle = $context['source'];
118
+ } else {
119
+ $handle = 'log';
120
+ }
121
+ $message = apply_filters( 'woo_feed_logger_add_message', $message, $handle );
122
+ $time = date_i18n( 'm-d-Y @ H:i:s' );
123
+ $entry = "{$time} - {$message}";
124
+ } else {
125
+ $entry = parent::format_entry( $timestamp, $level, $message, $context );
126
+ }
127
+
128
+ return $entry;
129
+ }
130
+
131
+ /**
132
+ * Open log file for writing.
133
+ *
134
+ * @param string $handle Log handle.
135
+ * @param string $mode Optional. File mode. Default 'a'.
136
+ * @return bool Success.
137
+ */
138
+ protected function open( $handle, $mode = 'a' ) {
139
+ if ( $this->is_open( $handle ) ) {
140
+ return true;
141
+ }
142
+
143
+ $file = self::get_log_file_path( $handle );
144
+
145
+ if ( $file ) {
146
+ if ( ! file_exists( $file ) ) {
147
+ $temp_handle = fopen( $file, 'w+' ); // phpcs:ignore
148
+ fclose( $temp_handle ); // phpcs:ignore
149
+
150
+ if ( defined( 'FS_CHMOD_FILE' ) ) {
151
+ chmod( $file, FS_CHMOD_FILE ); // phpcs:ignore
152
+ }
153
+ }
154
+
155
+ $resource = fopen( $file, $mode ); // phpcs:ignore
156
+
157
+ if ( $resource ) {
158
+ $this->handles[ $handle ] = $resource;
159
+ return true;
160
+ }
161
+ }
162
+
163
+ return false;
164
+ }
165
+
166
+ /**
167
+ * Check if a handle is open.
168
+ *
169
+ * @param string $handle Log handle.
170
+ * @return bool True if $handle is open.
171
+ */
172
+ protected function is_open( $handle ) {
173
+ return array_key_exists( $handle, $this->handles ) && is_resource( $this->handles[ $handle ] );
174
+ }
175
+
176
+ /**
177
+ * Close a handle.
178
+ *
179
+ * @param string $handle Log handle.
180
+ * @return bool success
181
+ */
182
+ protected function close( $handle ) {
183
+ $result = false;
184
+
185
+ if ( $this->is_open( $handle ) ) {
186
+ $result = fclose( $this->handles[ $handle ] ); // phpcs:ignore
187
+ unset( $this->handles[ $handle ] );
188
+ }
189
+
190
+ return $result;
191
+ }
192
+
193
+ /**
194
+ * Add a log entry to chosen file.
195
+ *
196
+ * @param string $entry Log entry text.
197
+ * @param string $handle Log entry handle.
198
+ *
199
+ * @return bool True if write was successful.
200
+ */
201
+ protected function add( $entry, $handle ) {
202
+
203
+ $result = false;
204
+
205
+ if ( $this->should_rotate( $handle ) ) {
206
+ $this->log_rotate( $handle );
207
+ }
208
+
209
+ if ( $this->open( $handle ) && is_resource( $this->handles[ $handle ] ) ) {
210
+ $result = fwrite( $this->handles[ $handle ], $entry . PHP_EOL ); // phpcs:ignore
211
+ } else {
212
+ $this->cache_log( $entry, $handle );
213
+ }
214
+
215
+ return false !== $result;
216
+ }
217
+
218
+ /**
219
+ * Clear entries from chosen file.
220
+ *
221
+ * @param string $handle Log handle.
222
+ *
223
+ * @return bool
224
+ */
225
+ public function clear( $handle ) {
226
+ $result = false;
227
+
228
+ // Close the file if it's already open.
229
+ $this->close( $handle );
230
+
231
+ /**
232
+ * $this->open( $handle, 'w' ) == Open the file for writing only. Place the file pointer at
233
+ * the beginning of the file, and truncate the file to zero length.
234
+ */
235
+ if ( $this->open( $handle, 'w' ) && is_resource( $this->handles[ $handle ] ) ) {
236
+ $result = true;
237
+ }
238
+
239
+ do_action( 'woo_feed_log_clear', $handle );
240
+
241
+ return $result;
242
+ }
243
+
244
+ /**
245
+ * Remove/delete the chosen file.
246
+ *
247
+ * @param string $handle Log handle.
248
+ *
249
+ * @return bool
250
+ */
251
+ public function remove( $handle ) {
252
+ $removed = false;
253
+ $logs = $this->get_log_files();
254
+ $handle = sanitize_title( $handle );
255
+ if ( isset( $logs[ $handle ] ) && $logs[ $handle ] ) {
256
+ $file = realpath( trailingslashit( WOO_FEED_LOG_DIR ) . $logs[ $handle ] );
257
+ if ( 0 === stripos( $file, realpath( trailingslashit( WOO_FEED_LOG_DIR ) ) ) && is_file( $file ) && is_writable( $file ) ) { // phpcs:ignore
258
+ $this->close( $file ); // Close first to be certain no processes keep it alive after it is unlinked.
259
+ $removed = unlink( $file ); // phpcs:ignore
260
+ }
261
+ do_action( 'woo_feed_log_remove', $handle, $removed );
262
+ }
263
+ return $removed;
264
+ }
265
+
266
+ /**
267
+ * Check if log file should be rotated.
268
+ *
269
+ * Compares the size of the log file to determine whether it is over the size limit.
270
+ *
271
+ * @param string $handle Log handle.
272
+ * @return bool True if if should be rotated.
273
+ */
274
+ protected function should_rotate( $handle ) {
275
+ $file = self::get_log_file_path( $handle );
276
+ if ( $file ) {
277
+ if ( $this->is_open( $handle ) ) {
278
+ $file_stat = fstat( $this->handles[ $handle ] );
279
+ return $file_stat['size'] > $this->log_size_limit;
280
+ } elseif ( file_exists( $file ) ) {
281
+ return filesize( $file ) > $this->log_size_limit;
282
+ } else {
283
+ return false;
284
+ }
285
+ } else {
286
+ return false;
287
+ }
288
+ }
289
+
290
+ /**
291
+ * Rotate log files.
292
+ *
293
+ * Logs are rotated by prepending '.x' to the '.log' suffix.
294
+ * The current log plus 10 historical logs are maintained.
295
+ * For example:
296
+ * base.9.log -> [ REMOVED ]
297
+ * base.8.log -> base.9.log
298
+ * ...
299
+ * base.0.log -> base.1.log
300
+ * base.log -> base.0.log
301
+ *
302
+ * @param string $handle Log handle.
303
+ */
304
+ protected function log_rotate( $handle ) {
305
+ for ( $i = 8; $i >= 0; $i-- ) {
306
+ $this->increment_log_infix( $handle, $i );
307
+ }
308
+ $this->increment_log_infix( $handle );
309
+ }
310
+
311
+ /**
312
+ * Increment a log file suffix.
313
+ *
314
+ * @param string $handle Log handle.
315
+ * @param null|int $number Optional. Default null. Log suffix number to be incremented.
316
+ * @return bool True if increment was successful, otherwise false.
317
+ */
318
+ protected function increment_log_infix( $handle, $number = null ) {
319
+ if ( null === $number ) {
320
+ $suffix = '';
321
+ $next_suffix = '.0';
322
+ } else {
323
+ $suffix = '.' . $number;
324
+ $next_suffix = '.' . ( $number + 1 );
325
+ }
326
+
327
+ $rename_from = self::get_log_file_path( "{$handle}{$suffix}" );
328
+ $rename_to = self::get_log_file_path( "{$handle}{$next_suffix}" );
329
+
330
+ if ( $this->is_open( $rename_from ) ) {
331
+ $this->close( $rename_from );
332
+ }
333
+
334
+ if ( is_writable( $rename_from ) ) { // phpcs:ignore
335
+ return rename( $rename_from, $rename_to ); // phpcs:ignore
336
+ } else {
337
+ return false;
338
+ }
339
+
340
+ }
341
+
342
+ /**
343
+ * Get a log file path.
344
+ *
345
+ * @param string $handle Log name.
346
+ * @return bool|string The log file path or false if path cannot be determined.
347
+ */
348
+ public static function get_log_file_path( $handle ) {
349
+ if ( function_exists( 'wp_hash' ) ) {
350
+ return trailingslashit( WOO_FEED_LOG_DIR ) . self::get_log_file_name( $handle );
351
+ } else {
352
+ woo_feed_doing_it_wrong( __METHOD__, __( 'This method should not be called before plugins_loaded.', 'woo-feed' ), '3.0' );
353
+ return false;
354
+ }
355
+ }
356
+
357
+ /**
358
+ * Get a log file name.
359
+ *
360
+ * File names consist of the handle, followed by the date, followed by a hash, .log.
361
+ *
362
+ * @since 3.3
363
+ * @param string $handle Log name.
364
+ * @return bool|string The log file name or false if cannot be determined.
365
+ */
366
+ public static function get_log_file_name( $handle ) {
367
+ if ( function_exists( 'wp_hash' ) ) {
368
+ $date_suffix = gmdate( 'Y-m-d', time() );
369
+ $hash_suffix = wp_hash( $handle );
370
+ return sanitize_file_name( implode( '-', array( $handle, $date_suffix, $hash_suffix ) ) . '.log' );
371
+ } else {
372
+ woo_feed_doing_it_wrong( __METHOD__, __( 'This method should not be called before plugins_loaded.', 'woo-feed' ), '3.3' );
373
+ return false;
374
+ }
375
+ }
376
+
377
+ /**
378
+ * Cache log to write later.
379
+ *
380
+ * @param string $entry Log entry text.
381
+ * @param string $handle Log entry handle.
382
+ */
383
+ protected function cache_log( $entry, $handle ) {
384
+ $this->cached_logs[] = array(
385
+ 'entry' => $entry,
386
+ 'handle' => $handle,
387
+ );
388
+ }
389
+
390
+ /**
391
+ * Write cached logs.
392
+ */
393
+ public function write_cached_logs() {
394
+ foreach ( $this->cached_logs as $log ) {
395
+ $this->add( $log['entry'], $log['handle'] );
396
+ }
397
+ }
398
+
399
+ /**
400
+ * Delete all logs older than a defined timestamp.
401
+ *
402
+ * @since 3.4.0
403
+ * @param integer $timestamp Timestamp to delete logs before.
404
+ */
405
+ public static function delete_logs_before_timestamp( $timestamp = 0 ) {
406
+ if ( ! $timestamp ) {
407
+ return;
408
+ }
409
+
410
+ $log_files = self::get_log_files();
411
+
412
+ foreach ( $log_files as $log_file ) {
413
+ $last_modified = filemtime( trailingslashit( WOO_FEED_LOG_DIR ) . $log_file );
414
+
415
+ if ( $last_modified < $timestamp ) {
416
+ unlink( trailingslashit( WOO_FEED_LOG_DIR ) . $log_file ); // phpcs:ignore
417
+ }
418
+ }
419
+ }
420
+
421
+ /**
422
+ * Get all log files in the log directory.
423
+ *
424
+ * @since 3.4.0
425
+ * @return array
426
+ */
427
+ public static function get_log_files() {
428
+ $files = scandir( WOO_FEED_LOG_DIR );
429
+ $result = array();
430
+
431
+ if ( ! empty( $files ) && is_array( $files ) ) {
432
+ foreach ( $files as $key => $value ) {
433
+ if ( ! in_array( $value, array( '.', '..' ), true ) ) {
434
+ if ( ! is_dir( $value ) && strstr( $value, '.log' ) ) {
435
+ $result[ sanitize_title( $value ) ] = $value;
436
+ }
437
+ }
438
+ }
439
+ }
440
+
441
+ return $result;
442
+ }
443
+ }
V5/Utility/Cache.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Utility;
3
+ class Cache {
4
+ /**
5
+ * Get Cached Data
6
+ *
7
+ * @param string $key Cache Name
8
+ *
9
+ * @return mixed|false false if cache not found.
10
+ * @since 3.3.10
11
+ */
12
+ public static function get( $key ) {
13
+ if ( empty( $key ) ) {
14
+ return false;
15
+ }
16
+
17
+ return get_transient( '__woo_feed_cache_' . $key );
18
+ }
19
+
20
+ /**
21
+ * Set Cached Data
22
+ *
23
+ * @param string $key Cache name. Expected to not be SQL-escaped. Must be
24
+ * 172 characters or fewer.
25
+ * @param mixed $data Data to cache. Must be serializable if non-scalar.
26
+ * Expected to not be SQL-escaped.
27
+ * @param int|bool $expiration Optional. Time until expiration in seconds. Default 0 (no expiration).
28
+ *
29
+ * @return bool
30
+ */
31
+ public static function set( $key, $data, $expiration = false ) {
32
+ if ( empty( $key ) ) {
33
+ return false;
34
+ }
35
+
36
+ if ( false === $expiration ) {
37
+ $expiration = get_option( 'woo_feed_settings', array( 'cache_ttl' => 6 * HOUR_IN_SECONDS ) );
38
+ $expiration = (int) $expiration['cache_ttl'];
39
+ }
40
+
41
+ return set_transient( '__woo_feed_cache_' . $key, $data, $expiration );
42
+ }
43
+
44
+ public static function delete( $key ) {
45
+ if ( empty( $key ) ) {
46
+ return false;
47
+ }
48
+
49
+ return delete_transient( '__woo_feed_cache_' . $key );
50
+
51
+ }
52
+
53
+ /**
54
+ * Delete All Cached Data
55
+ *
56
+ * @return bool
57
+ */
58
+ public static function flush() {
59
+ global $wpdb;
60
+
61
+ return $wpdb->query( "DELETE FROM $wpdb->options WHERE ({$wpdb->options}.option_name LIKE '_transient_timeout___woo_feed_cache_%') OR ({$wpdb->options}.option_name LIKE '_transient___woo_feed_cache_%')" ); // phpcs:ignore
62
+ }
63
+ }
V5/Utility/Config.php ADDED
@@ -0,0 +1,689 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Utility;
4
+ /**
5
+ * This class contain feed information.
6
+ */
7
+ class Config {
8
+ /**
9
+ * @var array|bool
10
+ */
11
+ private $feedInfo;
12
+
13
+ /**
14
+ * @var array|bool
15
+ */
16
+ private $config;
17
+ /**
18
+ * @var mixed
19
+ */
20
+ private $context;
21
+
22
+ /**
23
+ * @param array $feedInfo
24
+ * @param string $context
25
+ */
26
+ public function __construct( $feedInfo, $context = 'view' ) {
27
+
28
+ $this->feedInfo = $feedInfo;
29
+ $this->context = $context;
30
+ $this->config = isset( $this->feedInfo['feedrules'] ) ? $this->feedInfo['feedrules'] : $this->feedInfo;
31
+ }
32
+
33
+ public function __isset( $name ) {
34
+ if ( isset( $this->config[ $name ] ) ) {
35
+ return true;
36
+ }
37
+
38
+ return false;
39
+ }
40
+
41
+ public function __get( $name ) {
42
+ return $this->config[ $name ];
43
+ }
44
+
45
+ public function __set( $name, $value ) {
46
+ return $this->config[ $name ] = $value;
47
+ }
48
+
49
+ /**
50
+ *
51
+ * @return array
52
+ */
53
+ public function get_feed_rules() {
54
+ return isset( $this->feedInfo['feedrules'] ) ? $this->feedInfo['feedrules'] : $this->feedInfo;
55
+ }
56
+
57
+ /**
58
+ * Get Feed name.
59
+ *
60
+ * @return string
61
+ */
62
+ public function get_feed_id() {
63
+ return $this->config['feed_id'];
64
+ }
65
+
66
+ /**
67
+ * Get Feed name.
68
+ *
69
+ * @return string
70
+ */
71
+ public function get_feed_name() {
72
+ return $this->config['filename'];
73
+ }
74
+
75
+
76
+ /**
77
+ * Get Feed Template.
78
+ *
79
+ * @return string
80
+ */
81
+ public function get_feed_template() {
82
+ return $this->config['provider'];
83
+ }
84
+
85
+ /**
86
+ * Get Feed Language.
87
+ *
88
+ * @return string
89
+ */
90
+ public function get_feed_language() {
91
+ return $this->config['feedLanguage'];
92
+ }
93
+
94
+ /**
95
+ * Get Feed Currency.
96
+ *
97
+ * @return string
98
+ */
99
+ public function get_feed_currency() {
100
+ if ( $this->config['feedCurrency'] ) {
101
+ return $this->config['feedCurrency'];
102
+ }
103
+
104
+ $attributes = $this->config['attributes'];
105
+ $priceAttrs = [ 'price', 'current_price', 'price_with_tax', 'current_price_with_tax' ];
106
+ foreach ( $priceAttrs as $price_attr ) {
107
+ $key = array_search( $price_attr, $attributes, true );
108
+ if ( $key ) {
109
+ break;
110
+ }
111
+ }
112
+
113
+ return isset( $this->config['suffix'][ $key ] ) ? $this->config['suffix'][ $key ] : get_woocommerce_currency();
114
+ }
115
+
116
+ /**
117
+ * Get Feed Country.
118
+ *
119
+ * @return string
120
+ */
121
+ public function get_feed_country() {
122
+ return $this->config['feed_country'];
123
+ }
124
+
125
+ /**
126
+ * Get Feed File Type.
127
+ *
128
+ * @return string
129
+ */
130
+ public function get_feed_file_type() {
131
+ return $this->config['feedType'];
132
+ }
133
+
134
+ /**
135
+ * Get Feed File Type.
136
+ *
137
+ * @return string
138
+ */
139
+ public function get_delimiter() {
140
+
141
+ if ( 'tsv' === $this->config['feedType'] ) {
142
+ $this->config['delimiter'] = "\t";
143
+
144
+ return $this->config['delimiter'];
145
+ }
146
+
147
+ if ( ' ' === $this->config['delimiter'] ) {
148
+ $this->config['delimiter'] = "\s";
149
+ }
150
+
151
+ return $this->config['delimiter'];
152
+ }
153
+
154
+ /**
155
+ * Get Feed File Type.
156
+ *
157
+ * @return string
158
+ */
159
+ public function get_enclosure() {
160
+ if ( in_array( $this->config['enclosure'], [ 'double', 'single' ] ) ) {
161
+ return ( 'double' === $this->config['enclosure'] ) ? '"' : "'";
162
+ }
163
+
164
+ return '';
165
+ }
166
+
167
+ /**
168
+ * Get Feed items wrapper.
169
+ *
170
+ * @return string
171
+ */
172
+ public function get_feed_items_wrapper() {
173
+ return $this->config['itemsWrapper'];
174
+ }
175
+
176
+ /**
177
+ * Get Feed item wrapper.
178
+ *
179
+ * @return string
180
+ */
181
+ public function get_feed_item_wrapper() {
182
+ return $this->config['itemWrapper'];
183
+ }
184
+
185
+ /**
186
+ * Get Feed Extra Header.
187
+ *
188
+ * @return string
189
+ */
190
+ public function get_feed_extra_header() {
191
+ return $this->config['extraHeader'];
192
+ }
193
+
194
+ /**
195
+ * Get Feed Shipping Country.
196
+ *
197
+ * @return string
198
+ */
199
+ public function get_shipping_country() {
200
+ return $this->config['feed_country'];
201
+ }
202
+
203
+ /**
204
+ * Get Feed Tax Country.
205
+ *
206
+ * @return string
207
+ */
208
+ public function get_tax_country() {
209
+ return $this->config['tax_country'];
210
+ }
211
+
212
+ /**
213
+ * Get String Replace config
214
+ *
215
+ * @return array|bool
216
+ */
217
+ public function get_string_replace() {
218
+ if ( ! empty( $this->config['str_replace'] ) ) {
219
+ return $this->config['str_replace'];
220
+ }
221
+
222
+ return false;
223
+ }
224
+
225
+ /**
226
+ * Get URL campaign parameter.
227
+ *
228
+ * @return string
229
+ */
230
+ public function get_campaign_parameters() {
231
+ return $this->config['campaign_parameters'];
232
+ }
233
+
234
+ /**
235
+ * Status to remove backorder products.
236
+ *
237
+ * @return bool
238
+ */
239
+ public function remove_backorder_product() {
240
+ return 'y' === $this->config['is_backorder'];
241
+ }
242
+
243
+ /**
244
+ * Status to remove outofstock products.
245
+ *
246
+ * @return bool
247
+ */
248
+ public function remove_outofstock_product() {
249
+ return 'y' === $this->config['is_outOfStock'];
250
+ }
251
+
252
+ /**
253
+ * Status to remove empty description products.
254
+ *
255
+ * @return bool
256
+ */
257
+ public function remove_empty_description() {
258
+ return 'y' === $this->config['is_outOfStock'];
259
+ }
260
+
261
+ /**
262
+ * Status to remove empty image products.
263
+ *
264
+ * @return bool
265
+ */
266
+ public function remove_empty_image() {
267
+ return 'y' === $this->config['is_emptyImage'];
268
+ }
269
+
270
+ /**
271
+ * Status to remove empty price products.
272
+ *
273
+ * @return bool
274
+ */
275
+ public function remove_empty_price() {
276
+ return 'y' === $this->config['is_emptyPrice'];
277
+ }
278
+
279
+ /**
280
+ * Get Price Number Format.
281
+ *
282
+ * @return bool|array
283
+ */
284
+ public function get_price_format() {
285
+ if ( isset( $this->config['decimal_separator'] ) ) {
286
+ $number_format = [
287
+ 'decimal_separator' => apply_filters( 'ctx_feed_number_format_decimal_separator', $this->config['decimal_separator'], $this->config ),
288
+ 'thousand_separator' => apply_filters( 'ctx_feed_number_format_thousand_separator', $this->config['thousand_separator'], $this->config ),
289
+ 'decimals' => apply_filters( 'ctx_feed_number_format_decimals', $this->config['decimals'], $this->config ),
290
+ ];
291
+
292
+ return apply_filters( 'ctx_feed_number_format', $number_format, $this->config );
293
+ }
294
+
295
+ return false;
296
+ }
297
+
298
+ /**
299
+ * Get product Ids to exclude.
300
+ *
301
+ * @return array|bool
302
+ */
303
+ public function get_products_to_exclude() {
304
+
305
+ if ( isset( $this->config['filter_mode'] ) ) {
306
+ $mode = $this->config['filter_mode'];
307
+ if ( 'exclude' === $mode['product_ids'] && ! empty( $this->config['product_ids'] ) ) {
308
+ return explode( ',', $this->config['product_ids'] );
309
+ }
310
+ }
311
+
312
+ return false;
313
+ }
314
+
315
+ /**
316
+ * Get product Ids to include.
317
+ *
318
+ * @return array|bool
319
+ */
320
+ public function get_products_to_include() {
321
+
322
+ if ( isset( $this->config['filter_mode'] ) ) {
323
+ $mode = $this->config['filter_mode'];
324
+ if ( 'include' === $mode['product_ids'] && ! empty( $this->config['product_ids'] ) ) {
325
+ return explode( ',', $this->config['product_ids'] );
326
+ }
327
+ }
328
+
329
+ return false;
330
+ }
331
+
332
+ /**
333
+ * Get categories to exclude.
334
+ *
335
+ * @return mixed
336
+ */
337
+ public function get_categories_to_exclude() {
338
+
339
+ if ( isset( $this->config['filter_mode'] ) ) {
340
+ $mode = $this->config['filter_mode'];
341
+ if ( 'exclude' === $mode['categories'] && ! empty( $this->config['categories'] ) ) {
342
+ return $this->config['categories'];
343
+ }
344
+ }
345
+
346
+ return false;
347
+ }
348
+
349
+ /**
350
+ * Get categories to include.
351
+ *
352
+ * @return mixed
353
+ */
354
+ public function get_categories_to_include() {
355
+
356
+ if ( isset( $this->config['filter_mode'] ) ) {
357
+ $mode = $this->config['filter_mode'];
358
+ if ( 'include' === $mode['categories'] && ! empty( $this->config['categories'] ) ) {
359
+ return $this->config['categories'];
360
+ }
361
+ }
362
+
363
+ return false;
364
+ }
365
+
366
+
367
+ /**
368
+ * Get post statuses to include.
369
+ *
370
+ * @return mixed
371
+ */
372
+ public function get_post_status_to_include() {
373
+ $status = [ 'draft', 'pending', 'private', 'publish' ];
374
+ if ( isset( $this->config['filter_mode'] ) && ! empty( $this->config['post_status'] ) ) {
375
+ $mode = $this->config['filter_mode'];
376
+ if ( 'include' === $mode['post_status'] ) {
377
+ return $this->config['post_status'];
378
+ }
379
+
380
+ if ( 'exclude' === $mode['post_status'] ) {
381
+ return array_merge( array_diff( $status, $this->config['post_status'] ), array_diff( $status, $this->config['post_status'] ) );
382
+ }
383
+ }
384
+
385
+ return false;
386
+ }
387
+
388
+ /**
389
+ * Get post statuses to include.
390
+ *
391
+ * @return string|bool
392
+ */
393
+ public function get_vendors_to_include() {
394
+
395
+ if ( isset( $this->config['vendors'] ) && ! empty( $this->config['vendors'] ) ) {
396
+ return implode( ',', $this->config['vendors'] );
397
+ }
398
+
399
+ return false;
400
+ }
401
+
402
+ /**
403
+ * Get post statuses to include.
404
+ *
405
+ * @return bool
406
+ */
407
+ public function get_variations_to_include() {
408
+
409
+ return isset( $this->config['is_variations'] ) && in_array( $this->config['is_variations'], [ 'y', 'both' ] );
410
+ }
411
+
412
+ /**
413
+ * Get Advance Filter Config.
414
+ *
415
+ * @return array|bool
416
+ */
417
+ public function get_advance_filters() {
418
+ if ( isset( $this->config['concatType'] ) ) {
419
+ return [
420
+ "fattribute" => $this->config['fattribute'],
421
+ "condition" => $this->config['condition'],
422
+ "filterCompare" => $this->config['filterCompare'],
423
+ "concatType" => $this->config['concatType'],
424
+ ];
425
+ }
426
+
427
+ return false;
428
+ }
429
+
430
+ /**
431
+ * Get FTP Config.
432
+ *
433
+ * @return array|bool
434
+ */
435
+ public function get_ftp_config() {
436
+ if ( isset( $this->config['ftpenabled'] ) ) {
437
+ if ( '0' === $this->config['ftpenabled'] ) {
438
+ return false;
439
+ }
440
+
441
+ return [
442
+ "type" => $this->config['ftporsftp'],
443
+ "host" => $this->config['ftphost'],
444
+ "port" => $this->config['ftpport'],
445
+ "username" => $this->config['ftpuser'],
446
+ "password" => $this->config['ftppassword'],
447
+ "path" => $this->config['ftppath'],
448
+ "mode" => $this->config['ftpmode'],
449
+ ];
450
+ }
451
+
452
+ return false;
453
+ }
454
+
455
+ /**
456
+ * Get variable product config.
457
+ *
458
+ * @return array|bool
459
+ */
460
+ public function get_variable_config() {
461
+ if ( isset( $this->config['is_variations'] ) ) {
462
+ return [
463
+ "is_variations" => $this->config['is_variations'],
464
+ "variable_price" => $this->config['variable_price'],
465
+ "variable_quantity" => $this->config['variable_quantity'],
466
+ ];
467
+ }
468
+
469
+ return false;
470
+ }
471
+
472
+ /**
473
+ * Get composite product price settings.
474
+ *
475
+ * @return mixed
476
+ */
477
+ public function get_composite_price_type() {
478
+ return $this->config['composite_price'];
479
+ }
480
+
481
+ /**
482
+ * Get Feed Info
483
+ *
484
+ * @return array
485
+ */
486
+ public function get_feed() {
487
+ return $this->feedInfo;
488
+ }
489
+
490
+ /**
491
+ * Get Feed Info
492
+ *
493
+ * @param $feedInfo
494
+ *
495
+ * @return array|mixed
496
+ */
497
+ public function set_feed( $feedInfo ) {
498
+ return $this->feedInfo = $feedInfo;
499
+ }
500
+
501
+ /**
502
+ * Get Feed Configuration.
503
+ *
504
+ * @return object|false
505
+ */
506
+ public function get_feed_config() {
507
+ if ( $this->feedInfo ) {
508
+ return ( new Config( $this->feedInfo['feedrules'] ) );
509
+ }
510
+
511
+ return false;
512
+ }
513
+
514
+ /**
515
+ * Get Feed Configuration.
516
+ *
517
+ * @return array
518
+ */
519
+ public function get_config() {
520
+ return $this->config;
521
+ }
522
+
523
+ /**
524
+ * Set Feed Configuration.
525
+ *
526
+ * @return array
527
+ */
528
+ private function set_config( $config ) {
529
+
530
+ // if ( empty( $this->config ) ) {
531
+ // $this->config = array();
532
+ // }
533
+
534
+ $defaults = array(
535
+ 'provider' => '',
536
+ 'feed_country' => '',
537
+ 'filename' => '',
538
+ 'feedType' => '',
539
+ 'ftpenabled' => 0,
540
+ 'ftporsftp' => 'ftp',
541
+ 'ftphost' => '',
542
+ 'ftpport' => '21',
543
+ 'ftpuser' => '',
544
+ 'ftppassword' => '',
545
+ 'ftppath' => '',
546
+ 'ftpmode' => 'active',
547
+ 'is_variations' => 'y', // Only Variations (All Variations)
548
+ 'variable_price' => 'first',
549
+ 'variable_quantity' => 'first',
550
+ 'feedLanguage' => apply_filters( 'wpml_current_language', null ),
551
+ 'feedCurrency' => apply_filters( 'woocommerce_currency', get_option( 'woocommerce_currency' ) ),
552
+ 'itemsWrapper' => 'products',
553
+ 'itemWrapper' => 'product',
554
+ 'delimiter' => ',',
555
+ 'enclosure' => 'double',
556
+ 'extraHeader' => '',
557
+ 'vendors' => array(),
558
+ // Feed Config
559
+ 'mattributes' => array(), // merchant attributes
560
+ 'prefix' => array(), // prefixes
561
+ 'type' => array(), // value (attribute) types
562
+ 'attributes' => array(), // product attribute mappings
563
+ 'default' => array(), // default values (patterns) if value type set to pattern
564
+ 'suffix' => array(), // suffixes
565
+ 'output_type' => array(), // output type (output filter)
566
+ 'limit' => array(), // limit or command
567
+ // filters tab
568
+ 'composite_price' => 'all_product_price',
569
+ 'product_ids' => '',
570
+ 'categories' => array(),
571
+ 'post_status' => array( 'publish' ),
572
+ 'filter_mode' => array(),
573
+ 'campaign_parameters' => array(),
574
+ 'is_outOfStock' => 'n',
575
+ 'is_backorder' => 'n',
576
+ 'is_emptyDescription' => 'n',
577
+ 'is_emptyImage' => 'n',
578
+ 'is_emptyPrice' => 'n',
579
+ 'product_visibility' => 0,
580
+ // include hidden ? 1 yes 0 no
581
+ 'outofstock_visibility' => 0,
582
+ // override wc global option for out-of-stock product hidden from catalog? 1 yes 0 no
583
+ 'ptitle_show' => '',
584
+ 'decimal_separator' => apply_filters( 'wc_get_price_decimal_separator', get_option( 'woocommerce_price_decimal_sep' ) ),
585
+ 'thousand_separator' => stripslashes( apply_filters( 'wc_get_price_thousand_separator', get_option( 'woocommerce_price_thousand_sep' ) ) ),
586
+ 'decimals' => absint( apply_filters( 'wc_get_price_decimals', get_option( 'woocommerce_price_num_decimals', 2 ) ) ),
587
+ );
588
+
589
+ $this->config = wp_parse_args( $config, $defaults );
590
+ $this->config['filter_mode'] = wp_parse_args(
591
+ $this->config['filter_mode'],
592
+ array(
593
+ 'product_ids' => 'include',
594
+ 'categories' => 'include',
595
+ 'post_status' => 'include',
596
+ )
597
+ );
598
+
599
+ $this->config['campaign_parameters'] = wp_parse_args(
600
+ $this->config['campaign_parameters'],
601
+ array(
602
+ 'utm_source' => '',
603
+ 'utm_medium' => '',
604
+ 'utm_campaign' => '',
605
+ 'utm_term' => '',
606
+ 'utm_content' => '',
607
+ )
608
+ );
609
+
610
+ if ( ! empty( $this->config['provider'] ) && is_string( $this->config['provider'] ) ) {
611
+ /**
612
+ * filter parsed rules for provider
613
+ *
614
+ * @param array $rules
615
+ * @param string $context
616
+ *
617
+ * @since 3.3.7
618
+ */
619
+ $this->config = apply_filters( "woo_feed_{$this->config['provider']}_parsed_rules", $this->config, $this->context );
620
+ }
621
+
622
+ /**
623
+ * filter parsed rules
624
+ *
625
+ * @param array $rules
626
+ * @param string $context
627
+ *
628
+ * @since 3.3.7 $provider parameter removed
629
+ */
630
+ $this->config = apply_filters( 'woo_feed_parsed_rules', $this->config, $this->context );
631
+
632
+ return $this->config;
633
+ }
634
+
635
+ /**
636
+ * Get Feed URL.
637
+ *
638
+ * @return array|bool
639
+ */
640
+ public function get_feed_url() {
641
+ if ( isset( $this->feedInfo['url'] ) ) {
642
+ return $this->feedInfo['url'];
643
+ }
644
+
645
+ return false;
646
+ }
647
+
648
+ /**
649
+ * Get Feed File Path.
650
+ *
651
+ * @return string|bool
652
+ */
653
+ public function get_feed_path() {
654
+ $upload_dir = wp_get_upload_dir();
655
+ $url = $this->get_feed_url();
656
+ $file_name = basename( $url );
657
+
658
+ if ( ! isset( $this->config['provider'] ) && ! isset( $this->config['feedType'] ) ) {
659
+ return false;
660
+ }
661
+
662
+ return sprintf( '%s/woo-feed/%s/%s/%s', $upload_dir['basedir'], $this->config['provider'], $this->config['feedType'], $file_name );
663
+ }
664
+
665
+ /**
666
+ * Get Feed name.
667
+ *
668
+ * @return string
669
+ */
670
+ public function get_feed_file_name() {
671
+ $path = $this->get_feed_path();
672
+
673
+ return basename( $path );
674
+ }
675
+
676
+
677
+ /**
678
+ * Get Feed Status.
679
+ *
680
+ * @return array|bool
681
+ */
682
+ public function get_feed_status() {
683
+ if ( isset( $this->feedInfo['status'] ) ) {
684
+ return $this->feedInfo['status'];
685
+ }
686
+
687
+ return false;
688
+ }
689
+ }
V5/Utility/DropDown.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Utility;
3
+ class DropDown
4
+ {
5
+ /**
6
+ * Create Dropdown from array.
7
+ *
8
+ * @param array $data Array to Create Dropdown.
9
+ * @param string $cache_key Cache Key if dropdown need to be cached or get the dropdown from cache.
10
+ * @param string $selected Option value that need to be selected.
11
+ * @param bool $cache Cache Status.
12
+ *
13
+ * @return array|false|mixed|string|string[]
14
+ */
15
+ public static function Create($data, $selected = null, $cache_key = null, $cache = false)
16
+ {
17
+ //TODO: Option to set disabled options.
18
+
19
+ $options = "";
20
+ if (empty($data) || !is_array($data)) {
21
+ return "<option class='disabled' selected>No data available.</option>";
22
+ }
23
+
24
+ // If $cache true then return cached data.
25
+ if ($cache) {
26
+ $options = Cache::get($cache_key);
27
+ if ($options) {
28
+ if ($selected !== '') {
29
+ $selected = esc_attr($selected);
30
+ $options = str_replace("value=\"{$selected}\"", "value=\"{$selected}\" selected", $options);
31
+ }
32
+ return $options;
33
+ }
34
+ }
35
+
36
+ // Create Cache.
37
+ if (array_key_exists('optionGroup', $data) && array_key_exists('option', $data)) {
38
+ foreach ($data as $value) {
39
+ if (isset($value['optionGroup'])) {
40
+ $options .= "<optgroup label=\"{$value['optionGroup']}\">";
41
+ }
42
+
43
+ if (isset($value['options']) && !empty($value['options'])) {
44
+ foreach ($value['options'] as $optionKey => $option) {
45
+ $options .= sprintf('<option value="%s">%s</option>', $optionKey, $option);
46
+ }
47
+
48
+ $options .= isset($value['optionGroup']) ? '</optgroup>' : '';
49
+ }
50
+ }
51
+ } else {
52
+ foreach ($data as $optionKey => $option) {
53
+ $options .= sprintf('<option value="%s">%s</option>', $optionKey, $option);
54
+ }
55
+ }
56
+
57
+ // If $cache true then set cache.
58
+ if ($cache) {
59
+ Cache::set($cache_key, $options);
60
+ }
61
+
62
+ if ($selected !== '') {
63
+ $selected = esc_attr($selected);
64
+ $options = str_replace("value=\"{$selected}\"", "value=\"{$selected}\" selected", $options);
65
+ }
66
+
67
+ return $options;
68
+ }
69
+ }
V5/Utility/FileSystem.php ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace CTXFeed\V5\Utility;
3
+ use WP_Error;
4
+
5
+ class FileSystem {
6
+
7
+ /**
8
+ * Check Filesystem connection.
9
+ *
10
+ * @param $url
11
+ * @param $method
12
+ * @param $context
13
+ * @param $fields
14
+ *
15
+ * @return bool
16
+ */
17
+ public static function connect_fs( $url, $method, $context, $fields = null ) {
18
+ global $wp_filesystem;
19
+ if ( false === ( $credentials = request_filesystem_credentials( $url, $method, false, $context, $fields ) ) ) {
20
+ return false;
21
+ }
22
+
23
+ //check if credentials are correct or not.
24
+ if ( ! WP_Filesystem( $credentials ) ) {
25
+ request_filesystem_credentials( $url, $method, true, $context );
26
+
27
+ return false;
28
+ }
29
+
30
+ return true;
31
+ }
32
+
33
+ /**
34
+ * @param $content
35
+ * @param $path
36
+ * @param $filename
37
+ * @param string $admin_url
38
+ * @param string $nonce
39
+ *
40
+ * @return mixed|WP_Error
41
+ */
42
+ public static function WriteFile( $content, $path, $filename, $admin_url = 'admin.php?page=webappick-manage-feeds', $nonce = 'wpf_feed_nonce' ) {
43
+ global $wp_filesystem;
44
+
45
+ $url = wp_nonce_url( $admin_url, $nonce );
46
+ if ( self::connect_fs( $url, "", $path ) ) {
47
+ $dir = $wp_filesystem->find_folder( $path );
48
+ $file = trailingslashit( $dir ) . $filename;
49
+ // print_r($content);die();
50
+ // Delete the file first when possible.
51
+ // self::DeleteFile( $path, $filename );
52
+
53
+ return $wp_filesystem->put_contents( $file, $content, FS_CHMOD_FILE );
54
+ }
55
+
56
+ return new WP_Error( "filesystem_error", "Cannot initialize filesystem" );
57
+ }
58
+
59
+ /**
60
+ * Read file from directory.
61
+ *
62
+ * @param $path
63
+ * @param $filename
64
+ * @param string $admin_url
65
+ * @param string $nonce
66
+ *
67
+ * @return string|WP_Error
68
+ */
69
+ public static function ReadFile( $path, $filename, $admin_url = 'admin.php?page=webappick-new-feed', $nonce = 'wpf_feed_nonce' ) {
70
+ global $wp_filesystem;
71
+
72
+ $url = wp_nonce_url( $admin_url, $nonce );
73
+
74
+ if ( self::connect_fs( $url, "", $path ) ) {
75
+ $dir = $wp_filesystem->find_folder( $path );
76
+ $file = trailingslashit( $dir ) . $filename;
77
+
78
+ if ( $wp_filesystem->exists( $file ) ) {
79
+ $text = $wp_filesystem->get_contents( $file );
80
+ if ( ! $text ) {
81
+ return "";
82
+ }
83
+
84
+ return $text;
85
+ }
86
+
87
+ return new WP_Error( "filesystem_error", "File doesn't exist" );
88
+ }
89
+
90
+ return new WP_Error( "filesystem_error", "Cannot initialize filesystem" );
91
+ }
92
+
93
+ /**
94
+ * Delete file from directory.
95
+ *
96
+ * @param $path
97
+ * @param $filename
98
+ * @param string $admin_url
99
+ * @param string $nonce
100
+ *
101
+ * @return string|WP_Error
102
+ */
103
+ public static function DeleteFile( $path, $filename, $admin_url = 'admin.php?page=webappick-new-feed', $nonce = 'wpf_feed_nonce' ) {
104
+ global $wp_filesystem;
105
+
106
+ $url = wp_nonce_url( $admin_url, $nonce );
107
+
108
+ if ( self::connect_fs( $url, "", $path ) ) {
109
+ $dir = $wp_filesystem->find_folder( $path );
110
+ $file = trailingslashit( $dir ) . $filename;
111
+
112
+ if ( $wp_filesystem->exists( $file ) ) {
113
+ return $wp_filesystem->delete( $file );
114
+ }
115
+
116
+ return new WP_Error( "filesystem_error", "File doesn't exist" );
117
+ }
118
+
119
+ return new WP_Error( "filesystem_error", "Cannot initialize filesystem" );
120
+ }
121
+
122
+ }
V5/Utility/Logs.php ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Utility;
4
+
5
+ use Exception;
6
+ use WC_Logger;
7
+
8
+ /**
9
+ * Log Helper Functions
10
+ *
11
+ * @package CTXFeed
12
+ * @subpackage CTX_WC_Log_Handler
13
+ * @since WooFeed 3.3.0
14
+ * @version 1.0.0
15
+ * @author KD <mhamudul.hk@gmail.com>
16
+ * @copyright WebAppick
17
+ */
18
+ class Logs {
19
+
20
+ private static $is_debug_enabled;
21
+
22
+ public function __construct() {
23
+ self::$is_debug_enabled = woo_feed_get_options( 'enable_error_debugging', false ) === 'on';
24
+
25
+ }
26
+
27
+ public static function get_logger() {
28
+ if ( ! class_exists( CTX_WC_Log_Handler::class ) ) {
29
+ return false;
30
+ }
31
+
32
+ static $logger = null;
33
+ if ( $logger instanceof \WC_Logger ) {
34
+ return $logger;
35
+ }
36
+
37
+ if ( ! class_exists( 'WC_Logger' ) ) {
38
+ return $logger;
39
+ }
40
+
41
+
42
+ return new WC_Logger( [ new CTX_WC_Log_Handler() ] );
43
+ }
44
+
45
+
46
+ /**
47
+ * Write message to log file.
48
+ * Write log message if debugging is enabled
49
+ *
50
+ * @param string $source will be use for log file name.
51
+ * @param string $message Log message.
52
+ * @param string $level One of the following:
53
+ * 'emergency': System is unusable.
54
+ * 'alert': Action must be taken immediately.
55
+ * 'critical': Critical conditions.
56
+ * 'error': Error conditions.
57
+ * 'warning': Warning conditions.
58
+ * 'notice': Normal but significant condition.
59
+ * 'info': Informational messages.
60
+ * 'debug': Debug-level messages.
61
+ * @param mixed $data Extra data for the log handler.
62
+ * @param bool $force_log ignore debugging settings
63
+ * @param bool $wc_log log data in wc-logs directory
64
+ *
65
+ * @return void
66
+ * @since 3.2.1
67
+ *
68
+ */
69
+ public static function write_log( $source, $message, $level = 'debug', $data = null, $force_log = true, $wc_log = false ) {
70
+ if ( true === $force_log || woo_feed_is_debugging_enabled() ) {
71
+
72
+ if ( ! in_array( $level, [
73
+ 'emergency',
74
+ 'alert',
75
+ 'critical',
76
+ 'critical',
77
+ 'error',
78
+ 'warning',
79
+ 'notice',
80
+ 'info',
81
+ 'debug',
82
+ ], true ) ) {
83
+ return;
84
+ }
85
+ $context = [ 'source' => $source ];
86
+ if ( is_array( $data ) ) {
87
+ if ( isset( $data['source'] ) ) {
88
+ unset( $data['source'] );
89
+ }
90
+ $context = array_merge( $context, $data );
91
+ } else {
92
+ $context['data'] = $data;
93
+ }
94
+
95
+ $loggers = [ self::get_logger() ];
96
+ if ( true === $wc_log && function_exists( 'wc_get_logger' ) ) {
97
+ $loggers[] = wc_get_logger();
98
+ }
99
+
100
+
101
+ foreach ( $loggers as $logger ) {
102
+ if ( is_callable( [ $logger, $level ] ) ) {
103
+ $logger->$level( $message . PHP_EOL, $context );
104
+ }
105
+ }
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Log Fatal Errors in both wc-logs and woo-feed/logs
111
+ *
112
+ * @param string $message The log message.
113
+ * @param mixed $data Extra data for the log handler.
114
+ */
115
+ public static function write_fatal_log( $message, $data = null ) {
116
+ // woocommerce use 'fatal-errors' as log handler...
117
+ // make no conflicts with woocommerce fatal-errors logs
118
+ self::write_log( 'woo-feed-fatal-errors', $message, 'critical', $data, true, true );
119
+ }
120
+
121
+ /**
122
+ * Log Fatal Errors in both wc-logs and woo-feed/logs
123
+ *
124
+ * @param string $message The log message.
125
+ * @param mixed $data Extra data for the log handler.
126
+ */
127
+ public static function write_debug_log( $message, $data = null ) {
128
+ // woocommerce use 'fatal-errors' as log handler...
129
+ // make no conflicts with woocommerce fatal-errors logs
130
+ self::write_log( 'woo-feed-fatal-errors', $message, 'debug', $data, true, true );
131
+ }
132
+
133
+ /**
134
+ * Delete Log file by source or handle name
135
+ *
136
+ * @param string $source log source or handle name
137
+ * @param bool $handle use source as handle
138
+ *
139
+ * @return bool
140
+ */
141
+ public static function delete_log( $source, $handle = false ) {
142
+ if ( ! class_exists( "CTX_WC_Log_Handler" ) ) {
143
+ return false;
144
+ }
145
+
146
+ try {
147
+ if ( 'woo-feed-fatal-errors' === $source ) {
148
+ // fatal error are also logged in wc-logs dir.
149
+ if ( class_exists( 'WC_Log_Handler_File', false ) ) {
150
+ $log_handler = new WC_Log_Handler_File();
151
+ $log_handler->remove( false === $handle ? WC_Log_Handler_File::get_log_file_name( $source ) : $source );
152
+ }
153
+ } elseif ( class_exists( 'CTX_WC_Log_Handler', false ) ) {
154
+ return ( new CTX_WC_Log_Handler() )->remove( ! $handle ? CTX_WC_Log_Handler::get_log_file_name( $source ) : $source );
155
+ }
156
+ } catch ( Exception $e ) {
157
+ return false;
158
+ }
159
+
160
+ return false;
161
+ }
162
+
163
+ /**
164
+ * Delete all log files.
165
+ *
166
+ * @return void
167
+ */
168
+ public static function delete_all_logs() {
169
+ // delete the fatal error log
170
+ self::delete_log( 'woo-feed-fatal-errors' );
171
+ // get all logs
172
+ $logs = CTX_WC_Log_Handler::get_log_files();
173
+ foreach ( $logs as $log ) {
174
+ self::delete_log( $log, true );
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Log Feed Generation Progress to individual log file.
180
+ *
181
+ * @param string $feed_name Feed name, will be use for log file name.
182
+ * @param string $message Log message.
183
+ * @param mixed $data Extra data for the log handler.
184
+ * @param bool $force_log ignore debugging settings
185
+ *
186
+ * @return void
187
+ * @since 3.2.1
188
+ *
189
+ */
190
+ public static function log_feed_process( $feed_name, $message, $data = null, $force_log = false ) {
191
+ self::write_log( $feed_name, $message, 'debug', $data, $force_log, false );
192
+ }
193
+
194
+ /**
195
+ * Trigger logging cleanup using the logging class.
196
+ *
197
+ * @return void
198
+ */
199
+ public static function cleanup_logs() {
200
+ $logger = self::get_logger();
201
+ if ( is_callable( array( $logger, 'clear_expired_logs' ) ) ) {
202
+ $logger->clear_expired_logs();
203
+ }
204
+ }
205
+
206
+
207
+ }
208
+ // End of file logs class.
V5/Utility/Settings.php ADDED
@@ -0,0 +1,273 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace CTXFeed\V5\Utility;
4
+ /**
5
+ * @class Settings
6
+ *
7
+ * @package CTXFeed
8
+ * @subpackage CTXFeed\V5\Utility
9
+ */
10
+ class Settings {
11
+ /**
12
+ * Get saved settings.
13
+ *
14
+ * @param string $key Option name.
15
+ * All default values will be returned if this set to 'defaults',
16
+ * all settings will be return if set to 'all'.
17
+ * @param bool $default value to return if no matching data found for the key (option)
18
+ *
19
+ * @return array|bool|string|mixed
20
+ * @since 3.3.11
21
+ */
22
+ public static function get( $key = 'all', $default = false ) {
23
+ $defaults = [
24
+ 'per_batch' => 200,
25
+ 'product_query_type' => 'wc',
26
+ 'variation_query_type' => 'individual',
27
+ 'enable_error_debugging' => 'off',
28
+ 'cache_ttl' => 6 * HOUR_IN_SECONDS,
29
+ 'overridden_structured_data' => 'off',
30
+ 'disable_mpn' => 'enable',
31
+ 'disable_brand' => 'enable',
32
+ 'disable_pixel' => 'enable',
33
+ 'pixel_id' => '',
34
+ 'disable_remarketing' => 'disable',
35
+ 'remarketing_id' => '',
36
+ 'remarketing_label' => '',
37
+ 'pinterest_tag_id' => '',
38
+ 'pinterest_conversion_tracking' => 'disable',
39
+ 'allow_all_shipping' => 'no',
40
+ 'only_free_shipping' => 'yes',
41
+ 'only_local_pickup_shipping' => 'no',
42
+ 'enable_ftp_upload' => 'no',
43
+ 'woo_feed_taxonomy' => array(
44
+ 'brand' => 'disable',
45
+ ),
46
+ 'woo_feed_identifier' => array(
47
+ 'gtin' => 'disable',
48
+ 'ean' => 'disable',
49
+ 'mpn' => 'disable',
50
+ 'isbn' => 'disable',
51
+ 'age_group' => 'disable',
52
+ 'material' => 'disable',
53
+ 'gender' => 'disable',
54
+ 'cost_of_good_sold' => 'disable',
55
+ 'availability_date' => 'enable',
56
+ 'unit' => 'disable',
57
+ 'unit_pricing_measure' => 'disable',
58
+ 'unit_pricing_base_measure' => 'disable',
59
+ 'custom_field_0' => 'disable',
60
+ 'custom_field_1' => 'disable',
61
+ 'custom_field_2' => 'disable',
62
+ 'custom_field_3' => 'disable',
63
+ 'custom_field_4' => 'disable',
64
+ ),
65
+ ];
66
+
67
+ /**
68
+ * Add defaults without chainging the core values.
69
+ *
70
+ * @param array $defaults
71
+ *
72
+ * @since 3.3.11
73
+ */
74
+ $defaults = wp_parse_args( apply_filters( 'woo_feed_settings_extra_defaults', [] ), $defaults );
75
+
76
+ if ( 'defaults' === $key ) {
77
+ return $defaults;
78
+ }
79
+
80
+ $settings = wp_parse_args( get_option( 'woo_feed_settings', [] ), $defaults );
81
+
82
+ if ( 'all' === $key ) {
83
+ return $settings;
84
+ }
85
+
86
+ if ( array_key_exists( $key, $settings ) ) {
87
+ return $settings[ $key ];
88
+ }
89
+
90
+ return $default;
91
+ }
92
+
93
+ /**
94
+ * Update Settings.
95
+ *
96
+ * @param $key
97
+ * @param $value
98
+ *
99
+ * @return bool
100
+ */
101
+ public static function set( $key, $value ) {
102
+ $setting = self::get();
103
+
104
+ if ( isset( $setting[ $key ] ) ) {
105
+ $setting[ $key ] = $value;
106
+ }
107
+
108
+ return self::save( $setting );
109
+ }
110
+
111
+ /**
112
+ * Save Settings.
113
+ *
114
+ * @param array $args Required. option key value paired array to save.
115
+ *
116
+ * @return bool
117
+ * @since 3.3.11
118
+ */
119
+ public static function save( $args ) {
120
+ $data = woo_feed_get_options( 'all' );
121
+ $defaults = woo_feed_get_options( 'defaults' );
122
+ $_data = $data;
123
+
124
+ if ( array_key_exists( 'per_batch', $args ) ) {
125
+ $data['per_batch'] = absint( $args['per_batch'] );
126
+ if ( $data['per_batch'] <= 0 ) {
127
+ $data['per_batch'] = $_data['per_batch'] > 0 ? $_data['per_batch'] : $defaults['per_batch'];
128
+ }
129
+ unset( $args['unset'] );
130
+ }
131
+ if ( array_key_exists( 'product_query_type', $args ) ) {
132
+ $data['product_query_type'] = strtolower( $args['product_query_type'] );
133
+ $query_types = array_keys( woo_feed_get_query_type_options() );
134
+ if ( ! in_array( $data['product_query_type'], $query_types, true ) ) {
135
+ $data['product_query_type'] = in_array( $_data['product_query_type'], $query_types, true ) ? $_data['product_query_type'] : $defaults['product_query_type'];
136
+ }
137
+ unset( $args['product_query_type'] );
138
+ }
139
+ if ( array_key_exists( 'variation_query_type', $args ) ) {
140
+ $data['variation_query_type'] = strtolower( $args['variation_query_type'] );
141
+ $query_types = array_keys( woo_feed_get_query_type_options( 'variation' ) );
142
+ if ( ! in_array( $data['variation_query_type'], $query_types, true ) ) {
143
+ $data['variation_query_type'] = in_array( $_data['variation_query_type'], $query_types, true ) ? $_data['variation_query_type'] : $defaults['variation_query_type'];
144
+ }
145
+ unset( $args['variation_query_type'] );
146
+ }
147
+ if ( array_key_exists( 'enable_error_debugging', $args ) ) {
148
+ $data['enable_error_debugging'] = strtolower( $args['enable_error_debugging'] );
149
+ if ( ! in_array( $data['enable_error_debugging'], [ 'on', 'off' ] ) ) {
150
+ $data['enable_error_debugging'] = in_array( $_data['enable_error_debugging'], [
151
+ 'on',
152
+ 'off'
153
+ ] ) ? $_data['enable_error_debugging'] : $defaults['enable_error_debugging'];
154
+ }
155
+ unset( $args['enable_error_debugging'] );
156
+ }
157
+ if ( array_key_exists( 'cache_ttl', $args ) ) {
158
+ $data['cache_ttl'] = absint( $args['cache_ttl'] ); // cache ttl can be zero.
159
+ unset( $args['cache_ttl'] );
160
+ }
161
+ if ( array_key_exists( 'overridden_structured_data', $args ) ) {
162
+ $data['overridden_structured_data'] = strtolower( $args['overridden_structured_data'] );
163
+ if ( ! in_array( $data['overridden_structured_data'], array( 'on', 'off' ) ) ) {
164
+ $data['overridden_structured_data'] = in_array( $_data['overridden_structured_data'], array(
165
+ 'on',
166
+ 'off'
167
+ ) ) ? $_data['overridden_structured_data'] : $defaults['overridden_structured_data'];
168
+ }
169
+ unset( $args['overridden_structured_data'] );
170
+ }
171
+
172
+ if ( array_key_exists( 'disable_pixel', $args ) ) {
173
+ $data['disable_pixel'] = strtolower( $args['disable_pixel'] );
174
+ if ( ! in_array( $data['disable_pixel'], array( 'enable', 'disable' ) ) ) {
175
+ $data['disable_pixel'] = in_array( $_data['disable_pixel'], array(
176
+ 'enable',
177
+ 'disable'
178
+ ) ) ? $_data['disable_pixel'] : $defaults['disable_pixel'];
179
+ }
180
+ unset( $args['disable_pixel'] );
181
+ }
182
+ if ( array_key_exists( 'pixel_id', $args ) ) {
183
+ if ( isset( $args['pixel_id'] ) && ! empty( $args['pixel_id'] ) ) {
184
+ $data['pixel_id'] = absint( $args['pixel_id'] );
185
+ } else {
186
+ $data['pixel_id'] = $defaults['pixel_id'];
187
+ }
188
+ unset( $args['pixel_id'] );
189
+ }
190
+
191
+ if ( array_key_exists( 'disable_remarketing', $args ) ) {
192
+ $data['disable_remarketing'] = strtolower( $args['disable_remarketing'] );
193
+ if ( ! in_array( $data['disable_remarketing'], array( 'enable', 'disable' ) ) ) {
194
+ $data['disable_remarketing'] = in_array( $_data['disable_remarketing'], array(
195
+ 'enable',
196
+ 'disable'
197
+ ) ) ? $_data['disable_remarketing'] : $defaults['disable_remarketing'];
198
+ }
199
+ unset( $args['disable_remarketing'] );
200
+ }
201
+ if ( array_key_exists( 'remarketing_id', $args ) ) {
202
+ if ( isset( $args['remarketing_id'] ) && ! empty( $args['remarketing_id'] ) ) {
203
+ $data['remarketing_id'] = $args['remarketing_id'];
204
+ } else {
205
+ $data['remarketing_id'] = $defaults['remarketing_id'];
206
+ }
207
+ unset( $args['remarketing_id'] );
208
+ }
209
+ if ( array_key_exists( 'remarketing_label', $args ) ) {
210
+ if ( isset( $args['remarketing_label'] ) && ! empty( $args['remarketing_label'] ) ) {
211
+ $data['remarketing_label'] = $args['remarketing_label'];
212
+ } else {
213
+ $data['remarketing_label'] = $defaults['remarketing_label'];
214
+ }
215
+ unset( $args['remarketing_label'] );
216
+ }
217
+
218
+ if ( array_key_exists( 'allow_all_shipping', $args ) ) {
219
+ $data['allow_all_shipping'] = strtolower( $args['allow_all_shipping'] );
220
+ if ( ! in_array( $data['allow_all_shipping'], array( 'yes', 'no' ) ) ) {
221
+ $data['allow_all_shipping'] = in_array( $_data['allow_all_shipping'], array(
222
+ 'yes',
223
+ 'no'
224
+ ) ) ? $_data['allow_all_shipping'] : $defaults['allow_all_shipping'];
225
+ }
226
+ unset( $args['allow_all_shipping'] );
227
+ }
228
+
229
+ if ( array_key_exists( 'only_free_shipping', $args ) ) {
230
+ $data['only_free_shipping'] = strtolower( $args['only_free_shipping'] );
231
+ if ( ! in_array( $data['only_free_shipping'], array( 'yes', 'no' ) ) ) {
232
+ $data['only_free_shipping'] = in_array( $_data['only_free_shipping'], array(
233
+ 'yes',
234
+ 'no'
235
+ ) ) ? $_data['only_free_shipping'] : $defaults['only_free_shipping'];
236
+ }
237
+ unset( $args['only_free_shipping'] );
238
+ }
239
+
240
+ if ( array_key_exists( 'only_local_pickup_shipping', $args ) ) {
241
+ $data['only_local_pickup_shipping'] = strtolower( $args['only_local_pickup_shipping'] );
242
+ if ( ! in_array( $data['only_local_pickup_shipping'], array( 'yes', 'no' ) ) ) {
243
+ $data['only_local_pickup_shipping'] = in_array( $_data['only_local_pickup_shipping'], array(
244
+ 'yes',
245
+ 'no'
246
+ ) ) ? $_data['only_local_pickup_shipping'] : $defaults['only_local_pickup_shipping'];
247
+ }
248
+ unset( $args['only_local_pickup_shipping'] );
249
+ }
250
+
251
+
252
+ if ( array_key_exists( 'enable_ftp_upload', $args ) ) {
253
+ $data['enable_ftp_upload'] = strtolower( $args['enable_ftp_upload'] );
254
+ if ( ! in_array( $data['enable_ftp_upload'], array( 'yes', 'no' ) ) ) {
255
+ $data['enable_ftp_upload'] = in_array( $_data['enable_ftp_upload'], array(
256
+ 'yes',
257
+ 'no'
258
+ ) ) ? $_data['enable_ftp_upload'] : $defaults['enable_ftp_upload'];
259
+ }
260
+ unset( $args['enable_ftp_upload'] );
261
+ }
262
+
263
+ if ( ! empty( $args ) ) {
264
+ foreach ( $args as $key => $value ) {
265
+ if ( has_filter( "woo_feed_save_{$key}_option" ) ) {
266
+ $data[ $key ] = apply_filters( "woo_feed_save_{$key}_option", sanitize_text_field( $value ) );
267
+ }
268
+ }
269
+ }
270
+
271
+ return update_option( 'woo_feed_settings', $data, false );
272
+ }
273
+ }
V5/autoload.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ defined( 'ABSPATH' ) || die();
3
+
4
+ spl_autoload_register( 'ctx_feed_v5_autoloader' );
5
+
6
+ function ctx_feed_v5_autoloader( $class ) {
7
+
8
+
9
+ if ( strpos( $class, 'CTXFeed\V5' ) !== false ) {
10
+ $path = str_replace( [ "CTXFeed\\V5\\", "\\" ], [ '', '/' ], $class );
11
+
12
+ $file_path = __DIR__ . DIRECTORY_SEPARATOR . $path . '.php';
13
+
14
+ $file_path = str_replace( 'WebAppick' . DIRECTORY_SEPARATOR . 'Feed', '', $file_path );
15
+
16
+ if ( file_exists( $file_path ) ) {
17
+ require_once $file_path;
18
+ }
19
+ }
20
+ }
admin/class-woo-feed-manage-list.php CHANGED
@@ -102,14 +102,15 @@ class Woo_Feed_Manage_list extends Woo_Feed_List_Table {
102
  case 'last_updated':
103
  return $itemInfo[ $column_name ];
104
  case 'view':
105
- $export_url = wp_nonce_url( admin_url( 'admin-post.php?action=wf_export_feed&feed=' . $getItem ), 'wpf-export' );
106
- $log_download_url = wp_nonce_url( admin_url( 'admin-post.php?action=wf_download_feed_log&feed=' . $getItem ), 'wpf-log-download' );
107
-
 
108
  /** @noinspection HtmlUnknownTarget */
109
  return sprintf(
110
  '<a href="%1$s" title="%2$s" aria-label="%2$s" target="_blank"><span class="dashicons dashicons-external" aria-hidden="true"></span></a>
111
  <a id="%3$s" class="wpf_regenerate%6$s" href="#" title="%4$s" aria-label="%4$s"><span class="dashicons dashicons-update-alt%7$s" aria-hidden="true"></span></a>
112
- <a href="%1$s" title="%5$s" aria-label="%5$s" download><span class="dashicons dashicons-download" aria-hidden="true"></span></a>
113
  <a href="%9$s" title="%8$s" aria-label="%8$s"><span class="dashicons dashicons-migrate" aria-hidden="true"></span></a>
114
  <a href="%10$s" title="%11$s" aria-label="%11$s"><span class="dashicons dashicons-media-text" aria-hidden="true"></span></a>',
115
  $itemInfo['url'],
@@ -121,12 +122,10 @@ class Woo_Feed_Manage_list extends Woo_Feed_List_Table {
121
  $spinIcon,
122
  esc_html__( 'Export Feed Config', 'woo-feed' ),
123
  esc_url( $export_url ),
124
- esc_url( $log_download_url ),
125
- esc_html__( 'Download Feed Log', 'woo-feed'
126
- )
127
-
128
-
129
- );
130
  default:
131
  return false;
132
  }
102
  case 'last_updated':
103
  return $itemInfo[ $column_name ];
104
  case 'view':
105
+ $export_url = wp_nonce_url( admin_url( 'admin-post.php?action=wf_export_feed&feed=' . $getItem ), 'wpf-export' );
106
+ $download_url = wp_nonce_url( admin_url( 'admin-post.php?action=wf_download_feed&feed=' . $getItem ), 'wpf-download-feed' );
107
+ $log_download_url = wp_nonce_url( admin_url( 'admin-post.php?action=wf_download_feed_log&feed=' . $getItem ), 'wpf-log-download' );
108
+
109
  /** @noinspection HtmlUnknownTarget */
110
  return sprintf(
111
  '<a href="%1$s" title="%2$s" aria-label="%2$s" target="_blank"><span class="dashicons dashicons-external" aria-hidden="true"></span></a>
112
  <a id="%3$s" class="wpf_regenerate%6$s" href="#" title="%4$s" aria-label="%4$s"><span class="dashicons dashicons-update-alt%7$s" aria-hidden="true"></span></a>
113
+ <a href="%12$s" title="%5$s" aria-label="%5$s"><span class="dashicons dashicons-download" aria-hidden="true"></span></a>
114
  <a href="%9$s" title="%8$s" aria-label="%8$s"><span class="dashicons dashicons-migrate" aria-hidden="true"></span></a>
115
  <a href="%10$s" title="%11$s" aria-label="%11$s"><span class="dashicons dashicons-media-text" aria-hidden="true"></span></a>',
116
  $itemInfo['url'],
122
  $spinIcon,
123
  esc_html__( 'Export Feed Config', 'woo-feed' ),
124
  esc_url( $export_url ),
125
+ esc_url( $log_download_url ),
126
+ esc_html__( 'Download Feed Log', 'woo-feed'),
127
+ esc_url( $download_url )
128
+ );
 
 
129
  default:
130
  return false;
131
  }
admin/css/fancy-select.scss DELETED
@@ -1,201 +0,0 @@
1
- /**!
2
- * WooFeed Fancy Select
3
- * @version 1.0.0
4
- * @copyright 2020 Webappick
5
- * @author Kudratullah <mhamudul.hk@gmail.com>
6
- */
7
-
8
- .fancy-picker, .fancy-picker * {
9
- box-sizing: border-box;
10
- cursor: default;
11
- user-select: none;
12
- }
13
-
14
- .fancy-picker {
15
- position: relative;
16
- display: block;
17
- width: 100%;
18
- height: 30px;
19
- margin: 0 !important;
20
- padding: 0 !important;
21
- }
22
-
23
- .fancy-picker-picked {
24
- width: 100%;
25
- height: 100%;
26
- overflow: hidden;
27
- display: block;
28
- position: relative;
29
- border: 1px solid #7e8993;
30
- border-radius: 4px;
31
- padding: 3.5px 0;
32
- box-shadow: 0 0 4px -1px rgba(0, 0, 0, 0.45);
33
- }
34
-
35
- .fancy-picker-placeholder,
36
- .fancy-picker-data {
37
- display: block;
38
- width: calc( 100% - 25px );
39
- float: left;
40
- font-weight: 500;
41
- padding: 1px 5px;
42
- overflow: hidden;
43
- text-overflow: ellipsis;
44
- white-space: pre;
45
- top: -1px;
46
- > span {
47
- display: inline;
48
- position: relative;
49
- &:empty {
50
- display: none;
51
- }
52
- }
53
- &:empty {
54
- display: none;
55
- }
56
- }
57
-
58
- .fancy-picker-separator {
59
- margin-right: 3px;
60
- }
61
-
62
- .fancy-picker-count {
63
- position: absolute;
64
- display: block;
65
- top: 50%;
66
- transform: translateY(-50%);
67
- right: 21px;
68
- color: #ffffff;
69
- background: rgba(35, 40, 45, 0.7);
70
- z-index: 1;
71
- padding: 1px 3px;
72
- font-size: 12px;
73
- line-height: normal;
74
- border-radius: 5px;
75
- &:empty {
76
- display: none;
77
- }
78
- }
79
- .fancy-picker-option {
80
- font-weight: 500;
81
- width: 100%;
82
- display: block;
83
- float: left;
84
- cursor: default;
85
- padding: 2px 8px;
86
- transition: background 300ms linear;
87
- &:nth-child(odd) {
88
- background: #f3f3f3;
89
- }
90
- &.selected {
91
- color: #000;
92
- background: #acf;
93
- }
94
- &.disabled {
95
- color: #464646;
96
- background: #e8e8e8;
97
- cursor: not-allowed;
98
- }
99
- &:not(.disabled) {
100
- &:hover {
101
- background: #00a1ff;
102
- color: #FFF;
103
- }
104
- }
105
- }
106
-
107
- .fancy-picker-content {
108
- overflow-y: auto;
109
- overflow-x: hidden;
110
- max-height: 200px;
111
- width: 100%;
112
- -webkit-overflow-scrolling: touch;
113
- padding: 3px 0 20px 0;
114
- background: #FFF;
115
- }
116
-
117
- .fancy-picker-ui {
118
- position: absolute;
119
- display: none;
120
- background: #FFF;
121
- z-index: 999;
122
- border: 1px solid #7e8993;
123
- top: 36px;
124
- padding: 0;
125
- margin: 0;
126
- box-shadow: 0 0 10px -1px rgba(0, 0, 0, 0.96);
127
- &:before {
128
- content: "";
129
- position: absolute;
130
- width: 10px;
131
- height: 10px;
132
- border-top: 1px solid #4f555a;
133
- border-left: 1px solid #4f555a;
134
- top: -6px;
135
- left: 10px;
136
- transform: rotate(45deg);
137
- z-index: -1;background: #4f555a;
138
- }
139
- }
140
-
141
- .fancy-picker-picked {
142
- &:after {
143
- content: "";
144
- display: block;
145
- position: absolute;
146
- width: 0;
147
- height: 0;
148
- float: right;
149
- background: transparent;
150
- border-style: solid;
151
- border-color: #7e8993 transparent;
152
- border-width: 7px 5px 0 5px;
153
- top: 50%;
154
- transform: translateY(-50%) rotate(0deg);
155
- right: 5px;
156
- transition: all 350ms linear;
157
- cursor: pointer;
158
- }
159
- &:before {
160
- position: relative;
161
- display: block;
162
- content: "";
163
- width: 5px;
164
- height: 15px;
165
- padding: 1px 0;
166
- background: transparent;
167
- border-left-width: 4px;
168
- border-left-color: #7e8993;
169
- border-left-style: dotted;
170
- float: left;
171
- left: 5px;
172
- top: 2px;
173
- transition: all 350ms linear;
174
- }
175
- }
176
-
177
- .fancy-picker {
178
- &.active {
179
- .fancy-picker-ui {
180
- display: block;
181
- }
182
- .fancy-picker-picked {
183
- box-shadow: 0 0 3px -1px rgba(0, 0, 0, 0.45),
184
- inset 0 0 4px -1px rgba(0, 0, 0, 0.27);
185
- &:after {
186
- border-color: #31363a transparent;
187
- transform:translateY(-50%) rotate3d(1, 0, 0, 180deg);
188
- }
189
- &:before {
190
- border-left-color: #31363a;
191
- }
192
- }
193
- }
194
- &:hover {
195
- .fancy-picker-picked {
196
- &:before {
197
- border-left-color: #31363a;
198
- }
199
- }
200
- }
201
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/css/woo-feed-admin-pro.css CHANGED
@@ -383,7 +383,6 @@ table.wf-info-table th a.support {
383
  float: none;
384
  margin: 0 auto;
385
  }
386
-
387
  .wapk-feed-buy-now-product-meta {
388
  float: none;
389
  clear: both;
@@ -391,48 +390,40 @@ table.wf-info-table th a.support {
391
  text-align: center;
392
  display: block;
393
  }
394
-
395
  .wapk-feed-buy-now-wrapper {
396
  max-width: 1035px;
397
  margin: 0 auto;
398
  display: block;
399
  }
400
-
401
  .wapk-feed-buy-now-thumbnail {
402
  float: none;
403
  margin: 0 auto;
404
  }
405
-
406
  .wapk-feed-buy-now-product-container {
407
  float: none;
408
  display: block;
409
  text-align: center;
410
  }
411
-
412
  .wapk-feed-buy-now-product-meta {
413
  float: none;
414
  margin-top: 1.5rem;
415
  }
416
-
417
  .wapk-feed-buy-now-product-description {
418
  max-width: 500px;
419
  line-height: 1.5;
420
  margin: 0 auto;
421
  }
422
-
423
  .wapk-feed-buy-now-details {
424
  float: none;
425
  margin-top: 10px;
426
  text-align: center;
427
  }
428
-
429
  .wapk-feed-buy-now-title {
430
  float: none;
431
  clear: both;
432
  max-width: 100%;
433
  margin: 1rem 0;
434
  }
435
-
436
  .wapk-feed-buy-now-product-description {
437
  float: none;
438
  margin-top: 10px;
@@ -446,7 +437,6 @@ table.wf-info-table th a.support {
446
  -ms-flex-pack: center;
447
  justify-content: center;
448
  }
449
-
450
  .wapk-feed-buy-now-price:before {
451
  position: unset;
452
  margin-top: -6px;
@@ -923,12 +913,10 @@ span.wapk-price__table__feature span.dashicons {
923
  padding-left: 15%;
924
  padding-right: 15%;
925
  }
926
-
927
  .wapk-admin .feed-pro-comparison {
928
  padding-left: 21.2%;
929
  padding-right: 21.2%;
930
  }
931
-
932
  .wapk-admin .wapk-testimonial-wrapper {
933
  width: 55%;
934
  }
@@ -937,7 +925,6 @@ span.wapk-price__table__feature span.dashicons {
937
  .wapk-admin .wapk-feed-features {
938
  display: block;
939
  }
940
-
941
  .wapk-feed-feature__item {
942
  -ms-flex: 0 0 80%;
943
  flex: 0 0 80%;
383
  float: none;
384
  margin: 0 auto;
385
  }
 
386
  .wapk-feed-buy-now-product-meta {
387
  float: none;
388
  clear: both;
390
  text-align: center;
391
  display: block;
392
  }
 
393
  .wapk-feed-buy-now-wrapper {
394
  max-width: 1035px;
395
  margin: 0 auto;
396
  display: block;
397
  }
 
398
  .wapk-feed-buy-now-thumbnail {
399
  float: none;
400
  margin: 0 auto;
401
  }
 
402
  .wapk-feed-buy-now-product-container {
403
  float: none;
404
  display: block;
405
  text-align: center;
406
  }
 
407
  .wapk-feed-buy-now-product-meta {
408
  float: none;
409
  margin-top: 1.5rem;
410
  }
 
411
  .wapk-feed-buy-now-product-description {
412
  max-width: 500px;
413
  line-height: 1.5;
414
  margin: 0 auto;
415
  }
 
416
  .wapk-feed-buy-now-details {
417
  float: none;
418
  margin-top: 10px;
419
  text-align: center;
420
  }
 
421
  .wapk-feed-buy-now-title {
422
  float: none;
423
  clear: both;
424
  max-width: 100%;
425
  margin: 1rem 0;
426
  }
 
427
  .wapk-feed-buy-now-product-description {
428
  float: none;
429
  margin-top: 10px;
437
  -ms-flex-pack: center;
438
  justify-content: center;
439
  }
 
440
  .wapk-feed-buy-now-price:before {
441
  position: unset;
442
  margin-top: -6px;
913
  padding-left: 15%;
914
  padding-right: 15%;
915
  }
 
916
  .wapk-admin .feed-pro-comparison {
917
  padding-left: 21.2%;
918
  padding-right: 21.2%;
919
  }
 
920
  .wapk-admin .wapk-testimonial-wrapper {
921
  width: 55%;
922
  }
925
  .wapk-admin .wapk-feed-features {
926
  display: block;
927
  }
 
928
  .wapk-feed-feature__item {
929
  -ms-flex: 0 0 80%;
930
  flex: 0 0 80%;
admin/css/woo-feed-admin-pro.scss DELETED
@@ -1,968 +0,0 @@
1
- table.wf-info-table th a,
2
- table.wf-rate-table th strong {
3
- font-weight: bold;
4
- }
5
-
6
- table.wf-info-table th a,
7
- table.wf-rate-table a {
8
- color: #0073aa;
9
- }
10
-
11
- table.wf-info-table th a.get-woo-feed-pro {
12
- display: inline-block;
13
- text-decoration: none;
14
- background: #f3f5f6;
15
- color: #ff3355;
16
- vertical-align: top;
17
- font-size: 14px;
18
- line-height: 3.14285714;
19
- box-sizing: border-box;
20
- margin: 0;
21
- border-radius: 35px;
22
- box-shadow: 1px 2px 10px 1px rgba(255, 51, 85, 0.5);
23
- }
24
-
25
- table.wf-info-table th a.get-woo-feed-pro img {
26
- display: block;
27
- position: relative;
28
- margin: -2px;
29
- width: 180px;
30
- height: auto;
31
- }
32
-
33
- table.wf-info-table th a.button {
34
- border-color: #0073aa;
35
- border-radius: 35px;
36
- }
37
-
38
- table.wf-info-table th a.documentation {
39
- color: #0073aa;
40
- }
41
-
42
- table.wf-info-table th a.tutorial {
43
- color: #ee264a;
44
- }
45
-
46
- table.wf-info-table th a.support {
47
- color: #0DD41E;
48
- }
49
-
50
- /**
51
- * Premium Page Design
52
- */
53
- .wp-submenu li span.woo-feed-premium {
54
- font-weight: bold;
55
- color: #28e499;
56
- }
57
-
58
- .wp-submenu li:hover span.woo-feed-premium,
59
- .wp-submenu li.current span.woo-feed-premium {
60
- color: #1dc381;
61
- }
62
-
63
- .woo_feed_free_manage_attribute {
64
- margin: 0 auto;
65
- width: 100%;
66
- }
67
-
68
- .woo_feed_screenshort {
69
- max-width: 100%;
70
- width: 1000px;
71
- border: 3px solid #00b9eb;
72
- display: block;
73
- margin: 0 auto;
74
- }
75
-
76
- .woo-feed-screen-shot-title {
77
- font-size: 36px;
78
- text-align: center;
79
- box-sizing: content-box;
80
- color: #00b9eb;
81
- }
82
-
83
- .woo_feed_screen {
84
- background: #fff;
85
- padding: 25px 20px;
86
- margin-bottom: 20px;
87
- }
88
-
89
- .woo_feed_screen_des {
90
- text-align: center;
91
- margin: 20px 50px 20px 50px;
92
- font-size: 16px;
93
- color: #666;
94
- }
95
-
96
- .woo_feed_screen_des_2 {
97
- text-align: center;
98
- margin: 20px 50px 5px 50px;
99
- font-size: 14px;
100
- color: #32373c;
101
- }
102
-
103
-
104
- .wapk-admin .wapk-feed-upgrade {
105
- font-family: 'Open Sans', sans-serif;
106
- margin: -10px -20px 0 -22px;
107
- }
108
-
109
- .wapk-admin .wapk-feed-upgrade a {
110
- transition: all 0.2s ease;
111
- }
112
-
113
- .wapk-admin .section-title {
114
- text-align: center;
115
- font-size: 30px;
116
- line-height: 1.5em;
117
- font-weight: 400;
118
- position: relative;
119
- margin: 0 0 58px;
120
- }
121
-
122
- .wapk-admin .section-title:after {
123
- content: '';
124
- position: absolute;
125
- bottom: -21px;
126
- left: 50%;
127
- transform: translateX(-50%);
128
- width: 38px;
129
- height: 5px;
130
- border-radius: 3px;
131
- background-color: #00D4D4;
132
- }
133
-
134
- .wapk-admin .section-title .section-sub-title {
135
- font-size: 22px;
136
- font-weight: 300;
137
- }
138
-
139
- .wapk-admin .wapk-banner {
140
- background-color: #f2f2f2;
141
- font-size: 16px;
142
- display: flex;
143
- align-items: center;
144
- padding: 50px 8%;
145
- border-bottom: 1px solid #eee;
146
- }
147
-
148
- .wapk-admin .wapk-banner .wapk-banner__graphics {
149
- width: 100%;
150
- }
151
-
152
- .wapk-admin .wapk-banner .wapk-banner__content h1 {
153
- font-size: 27px;
154
- line-height: 1.5em;
155
- }
156
-
157
- .wapk-admin .wapk-banner .wapk-banner__content p {
158
- font-size: 16px;
159
- line-height: 1.5em;
160
- font-weight: 300;
161
- margin: 0;
162
- /*noinspection CssFloatPxLength*/
163
- letter-spacing: 0.5px;
164
- }
165
-
166
- .wapk-admin .wapk-feed-features .wapk-feed-feature__list {
167
- display: flex;
168
- flex-wrap: wrap;
169
- align-items: flex-start;
170
- justify-content: center;
171
- }
172
-
173
- .wapk-admin .wapk-feed-features .wapk-feed-features__more {
174
- margin-top: 25px;
175
- }
176
-
177
- .wapk-feed-feature__item {
178
- flex: 0 0 47%;
179
- //margin: 0 2.2% 4.4% 2.2%;
180
- text-align: center;
181
- border-radius: 5px;
182
- background-color: #ffffff;
183
- overflow: hidden;
184
- margin-bottom: 40px;
185
- padding: 40px;
186
- box-shadow: 0 0 5px rgba(115, 115, 166, 0.15);
187
- position: relative;
188
- transition: all 0.3s ease-in-out;
189
-
190
- &:nth-child(2n+1) {
191
- margin-right: 20px;
192
- }
193
-
194
- &:nth-child(2n+2) {
195
- margin-left: 20px;
196
- }
197
-
198
- &:hover {
199
- box-shadow: 0px 10px 10px rgba(17, 17, 85, 0.15);
200
- }
201
- }
202
-
203
- .wapk-feed-feature__thumb {
204
- overflow: hidden;
205
- }
206
- .wapk-feed-feature__links {
207
- a {
208
- display: inline-block;
209
- background: linear-gradient(67.36deg, #3D41DA 3.09%, #0088F7 64.97%);;
210
- font-weight: 600;
211
- padding: 12px 32px 12px 48px;
212
- border-radius: 5px;
213
- margin-top: 24px;
214
- color: white;
215
- text-decoration: none;
216
- position: relative;
217
-
218
- &:before {
219
- content: "";
220
- position: absolute;
221
- width: 16px;
222
- height: 16px;
223
- background-size: 16px;
224
- margin-left: -20px;
225
- background: url("data:image/svg+xml,%3Csvg%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%3Cpath%20d%3D%22M12%208.66667V12.6667C12%2013.0203%2011.8595%2013.3594%2011.6095%2013.6095C11.3594%2013.8595%2011.0203%2014%2010.6667%2014H3.33333C2.97971%2014%202.64057%2013.8595%202.39052%2013.6095C2.14048%2013.3594%202%2013.0203%202%2012.6667V5.33333C2%204.97971%202.14048%204.64057%202.39052%204.39052C2.64057%204.14048%202.97971%204%203.33333%204H7.33333%22%20stroke%3D%22white%22%20stroke-width%3D%221.5%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%2F%3E%0A%3Cpath%20d%3D%22M10%202H14V6%22%20stroke%3D%22white%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%2F%3E%0A%3Cpath%20d%3D%22M6.66699%209.33333L14.0003%202%22%20stroke%3D%22white%22%20stroke-width%3D%221.5%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%2F%3E%0A%3C%2Fsvg%3E%0A");
226
- }
227
- }
228
- }
229
- .wapk-feed-feature__item {
230
- &:hover {
231
- .wapk-feed-feature__links {
232
- a {
233
- opacity: 1;
234
- }
235
- }
236
- }
237
- }
238
- .wapk-feed-feature__item .wapk-feed-feature__thumb img {
239
- max-width: 100%;
240
- width: 100%;
241
- height: auto;
242
- -webkit-transition: all 100ms linear;
243
- -moz-transition: all 100ms linear;
244
- -ms-transition: all 100ms linear;
245
- -o-transition: all 100ms linear;
246
- transition: all 100ms linear;
247
- }
248
- .wapk-feed-feature__item .wapk-feed-feature__description h3 {
249
- font-size: 18px;
250
- line-height: 1.5em;
251
- font-weight: 500;
252
- margin-top: 20px;
253
- }
254
- .wapk-feed-feature__item .wapk-feed-feature__description p {
255
- margin: 20px auto 0;
256
- }
257
- .wapk-admin .feed-pro-comparison {
258
- background-color: #f1f1f1;
259
- padding: 75px;
260
- }
261
-
262
- .wapk-admin .wapk-feed-features {
263
- text-align: center;
264
- max-width: 1320px;
265
- margin: 40px auto 0;
266
- }
267
- .wapk-feed-buy-now {
268
- margin-bottom: 40px;
269
- }
270
- .wapk-feed-buy-now-container {
271
- background: #ffffff;
272
- padding: 0.75rem;
273
- z-index: 999999999;
274
- left: 160px;
275
- right: 0;
276
- bottom: -100%;
277
-
278
- &.fixed {
279
- bottom: 0;
280
- position: fixed;
281
- }
282
- }
283
- .wapk-feed-buy-now-wrapper {
284
- max-width: 1320px;
285
- margin: 0 auto;
286
- display: flex;
287
- align-items: center;
288
- justify-content: center;
289
- }
290
- .wapk-feed-buy-now-thumbnail {
291
- float: left;
292
- img {
293
- width: 3.75rem;
294
- height: auto;
295
- padding: 0.1875rem;
296
- }
297
- }
298
- .wapk-feed-buy-now-product-container {
299
- display: flex;
300
- align-items: center;
301
- }
302
- .wapk-feed-buy-now-product-meta {
303
- float: right;
304
- }
305
- .wapk-feed-buy-now-product-description {
306
- max-width: 460px;
307
- line-height: 1.5;
308
- }
309
- .wapk-feed-buy-now-details {
310
- float: left;
311
- margin-top: 9px;
312
- }
313
- .wapk-feed-buy-now-title {
314
- float: left;
315
- margin-left: 1.5rem;
316
- max-width: 180px;
317
- line-height: 1.15;
318
- }
319
- .wapk-feed-buy-now-product-name {
320
- font-size: 16px;
321
- font-weight: 700;
322
- }
323
- .wapk-feed-buy-now-product-description {
324
- float: right;
325
- font-size: 1rem;
326
- margin-left: 1.5rem;
327
- }
328
- .wapk-feed-buy-now-price {
329
- position: relative;
330
- font-weight: 400;
331
- line-height: 1.5;
332
- margin-top: 6px;
333
- }
334
- .wapk-feed-buy-now-product-meta{
335
- margin: 0 0 0 42px;
336
- div {
337
- display: inline-block;
338
- margin-left: 20px;
339
- }
340
- }
341
- .wapk-feed-buy-now-btn {
342
- @extend .wapk-feed-feature__links;
343
- a {
344
- margin-top: 0;
345
-
346
- &:before {
347
- background: url("data:image/svg+xml,%3Csvg%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%3Cg%20clip-path%3D%22url%28%23clip0%29%22%3E%0A%3Cpath%20d%3D%22M5.99967%2014.6668C6.36786%2014.6668%206.66634%2014.3684%206.66634%2014.0002C6.66634%2013.632%206.36786%2013.3335%205.99967%2013.3335C5.63148%2013.3335%205.33301%2013.632%205.33301%2014.0002C5.33301%2014.3684%205.63148%2014.6668%205.99967%2014.6668Z%22%20stroke%3D%22white%22%20stroke-width%3D%221.5%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%2F%3E%0A%3Cpath%20d%3D%22M13.3337%2014.6668C13.7018%2014.6668%2014.0003%2014.3684%2014.0003%2014.0002C14.0003%2013.632%2013.7018%2013.3335%2013.3337%2013.3335C12.9655%2013.3335%2012.667%2013.632%2012.667%2014.0002C12.667%2014.3684%2012.9655%2014.6668%2013.3337%2014.6668Z%22%20stroke%3D%22white%22%20stroke-width%3D%221.5%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%2F%3E%0A%3Cpath%20d%3D%22M0.666992%200.666504H3.33366L5.12033%209.59317C5.18129%209.9001%205.34826%2010.1758%205.59202%2010.372C5.83578%2010.5683%206.14079%2010.6725%206.45366%2010.6665H12.9337C13.2465%2010.6725%2013.5515%2010.5683%2013.7953%2010.372C14.0391%2010.1758%2014.206%209.9001%2014.267%209.59317L15.3337%203.99984H4.00033%22%20stroke%3D%22white%22%20stroke-width%3D%221.5%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%2F%3E%0A%3C%2Fg%3E%0A%3Cdefs%3E%0A%3CclipPath%20id%3D%22clip0%22%3E%0A%3Crect%20width%3D%2216%22%20height%3D%2216%22%20fill%3D%22white%22%2F%3E%0A%3C%2FclipPath%3E%0A%3C%2Fdefs%3E%0A%3C%2Fsvg%3E%0A");
348
- }
349
- }
350
- }
351
- .folded.sticky-menu {
352
- .wapk-feed-buy-now-container {
353
- left: 36px;
354
- }
355
- @media ( max-width: 780px) {
356
- .wapk-feed-buy-now-container {
357
- left: 0;
358
- }
359
- }
360
- }
361
-
362
- @media ( max-width: 780px) {
363
- .wapk-feed-buy-now-container {
364
- left: 0;
365
- }
366
- }
367
- @media ( min-width: 781px ) and ( max-width: 960px) {
368
- .wapk-feed-buy-now-container {
369
- left: 36px;
370
- }
371
- }
372
- // Medium Device
373
- @media (max-width: 1120px) {
374
- .wapk-feed-buy-now-product-container {
375
- float: none;
376
- margin: 0 auto;
377
- }
378
- .wapk-feed-buy-now-product-meta {
379
- float: none;
380
- clear: both;
381
- margin: 10px auto 0;
382
- text-align: center;
383
- display: block;
384
- }
385
- .wapk-feed-buy-now-wrapper {
386
- max-width: 1035px;
387
- margin: 0 auto;
388
- display: block;
389
- }
390
- .wapk-feed-buy-now-thumbnail {
391
- float: none;
392
- margin: 0 auto;
393
- }
394
- .wapk-feed-buy-now-product-container {
395
- float: none;
396
- display: block;
397
- text-align: center;
398
- }
399
- .wapk-feed-buy-now-product-meta {
400
- float: none;
401
- margin-top: 1.5rem;
402
- }
403
- .wapk-feed-buy-now-product-description {
404
- max-width: 500px;
405
- line-height: 1.5;
406
- margin: 0 auto;
407
- }
408
- .wapk-feed-buy-now-details {
409
- float: none;
410
- margin-top: 10px;
411
- text-align: center;
412
- }
413
- .wapk-feed-buy-now-title {
414
- float: none;
415
- clear: both;
416
- max-width: 100%;
417
- margin: 1rem 0;
418
- }
419
- .wapk-feed-buy-now-product-description {
420
- float: none;
421
- margin-top: 10px;
422
- }
423
- }
424
- // Small Device
425
- @media (max-width: 449px) {
426
- .wapk-feed-buy-now-product-meta{
427
- div {
428
- display: flex;
429
- margin: 20px auto 0;
430
- justify-content: center;
431
- }
432
- }
433
- .wapk-feed-buy-now-price {
434
- &:before {
435
- position: unset;
436
- margin-top: -6px;
437
- margin-right: 6px;
438
- }
439
- }
440
- }
441
-
442
- .wapk-admin .wapk-feed-features .section-title h2,
443
- .wapk-admin .wapk-testimonial .section-title h2,
444
- .wapk-admin .feed-pro-comparison .section-title h2,
445
- .wapk-admin .feed-pricing .section-title h2 {
446
- margin-top: 0;
447
- margin-bottom: 0;
448
- }
449
-
450
- .wapk-admin .comparison-table {
451
- display: flex;
452
- justify-content: space-between;
453
- }
454
-
455
- .wapk-admin .comparison-table .comparison {
456
- flex: 0 0 48%;
457
- background-color: #fff;
458
- border: 1px solid #e0e9ec;
459
- border-radius: 5px;
460
- box-shadow: 0 1px 2px 0 rgba(0, 0, 0, .05);
461
- padding: 50px;
462
- box-sizing: border-box;
463
- }
464
-
465
- .wapk-admin .comparison .product-header {
466
- margin-bottom: 58px;
467
- position: relative;
468
- }
469
-
470
- .wapk-admin .comparison .product-header:after {
471
- content: "";
472
- position: absolute;
473
- bottom: -23px;
474
- left: 0;
475
- width: 38px;
476
- height: 5px;
477
- border-radius: 3px;
478
- background-color: #d7d7d7;
479
- }
480
-
481
- .wapk-admin .comparison .product-header img {
482
- max-width: 160px;
483
- width: 100%;
484
- }
485
-
486
- .wapk-admin .comparison .product-features {
487
- margin: 0;
488
- }
489
-
490
- .wapk-admin .comparison li {
491
- position: relative;
492
- display: flex;
493
- margin-bottom: 15px;
494
- padding-left: 30px;
495
- font-size: 14px;
496
- line-height: 1.3em;
497
- font-weight: 300;
498
- align-items: center;
499
- }
500
-
501
- .wapk-admin .comparison li.unavailable {
502
- color: #CED2D6;
503
- }
504
-
505
- .wapk-admin .comparison li span.dashicons {
506
- position: absolute;
507
- top: 1px;
508
- left: 6px;
509
- width: 18px;
510
- height: 18px;
511
- border-radius: 100%;
512
- background: #00D4D4;
513
- color: #FFF;
514
- line-height: 22px;
515
- font-size: 14px;
516
- text-align: center;
517
- }
518
-
519
- .wapk-admin .comparison li.unavailable {
520
- color: #CED2D6;
521
- }
522
-
523
- .wapk-admin .comparison li.unavailable span.dashicons {
524
- background: #CED2D6;
525
- }
526
-
527
- .wapk-admin .comparison li span.dashicons-no {
528
- font-size: 12px;
529
- }
530
-
531
- .wapk-admin .comparison li span.dashicons-no:before {
532
- left: 0;
533
- }
534
-
535
- .wapk-admin .comparison li span.dashicons:before {
536
- position: relative;
537
- left: -0.5px;
538
- top: -2px;
539
- }
540
-
541
- .wapk-admin .comparison li img {
542
- width: 18px;
543
- margin-right: 12px;
544
- }
545
-
546
- .wapk-admin .feed-pricing {
547
- }
548
-
549
- .wapk-pricing__table {
550
- width: 100%;
551
- display: -webkit-box;
552
- display: -webkit-flex;
553
- display: -ms-flexbox;
554
- display: flex;
555
- -webkit-flex-wrap: wrap;
556
- -ms-flex-wrap: wrap;
557
- flex-wrap: wrap;
558
- -webkit-align-content: flex-start;
559
- -ms-flex-line-pack: start;
560
- align-content: flex-start;
561
- justify-content: center;
562
- }
563
-
564
- .wapk-pricing__table__item {
565
- position: relative;
566
- flex: 0 0 23%;
567
- }
568
-
569
- .wapk-price__table__wrapper {
570
- position: relative;
571
- padding: 10px;
572
- }
573
-
574
- .wapk-price__table {
575
- text-align: center;
576
- display: block;
577
- width: 100%;
578
- padding: 10px;
579
- background-color: #fff;
580
- border-radius: 8px 8px 8px 8px;
581
- box-shadow: 0 0 25px 0 rgba(0, 0, 0, .1);
582
- overflow: hidden;
583
- -webkit-transition: background .3s, border .3s, -webkit-border-radius .3s, -webkit-box-shadow .3s;
584
- transition: background .3s, border .3s, -webkit-border-radius .3s, -webkit-box-shadow .3s;
585
- -o-transition: background .3s, border .3s, border-radius .3s, box-shadow .3s;
586
- transition: background .3s, border .3s, border-radius .3s, box-shadow .3s;
587
- transition: background .3s, border .3s, border-radius .3s, box-shadow .3s, -webkit-border-radius .3s, -webkit-box-shadow .3s;
588
- }
589
-
590
- .wapk-price__table__header {
591
- background-color: #fff;
592
- padding: 40px 0 0;
593
- }
594
-
595
- .wapk-price__table__heading {
596
- color: #6d7882;
597
- font-size: 17px;
598
- font-weight: 500;
599
- text-transform: uppercase;
600
- letter-spacing: 10px;
601
- font-family: sans-serif;
602
- margin: 0;
603
- padding: 0;
604
- line-height: 1.2;
605
- }
606
-
607
- .wapk-price__table__price {
608
- font-family: sans-serif;
609
- font-weight: 600;
610
- padding: 30px 0 10px;
611
- display: -webkit-box;
612
- display: -ms-flexbox;
613
- display: flex;
614
- -webkit-box-pack: center;
615
- -ms-flex-pack: center;
616
- justify-content: center;
617
- -webkit-box-align: center;
618
- -ms-flex-align: center;
619
- align-items: center;
620
- -ms-flex-wrap: wrap;
621
- flex-wrap: wrap;
622
- -webkit-box-orient: horizontal;
623
- -webkit-box-direction: normal;
624
- -ms-flex-direction: row;
625
- flex-direction: row;
626
- color: #434363;
627
- font-size: 45px;
628
- }
629
-
630
- .wapk-price__table__amount {
631
- }
632
-
633
- .wapk-price__table__currency {
634
- align-self: flex-start;
635
- color: #434363;
636
- line-height: 1;
637
- font-size: .3em;
638
- margin-right: 3px;
639
- }
640
-
641
- .wapk-price__table__amount .free,
642
- .wapk-price__table__amount .integer-part {
643
- color: #434363;
644
- line-height: .8;
645
- }
646
-
647
- .wapk-price__table__amount .decimal-part {
648
- font-size: 14px;
649
- font-weight: 400;
650
- }
651
-
652
- .wapk-price__table__amount .period {
653
- font-size: 14px;
654
- font-weight: 400;
655
- }
656
-
657
- .wapk-price__table__amount___legend {
658
- width: 100%;
659
- color: #FF4B4B;
660
- font-size: 18px;
661
- font-weight: 500;
662
- line-height: 2.5em;
663
- }
664
-
665
- .wapk-price__table__features {
666
- list-style-type: none;
667
- margin: 0;
668
- padding: 0;
669
- line-height: 1;
670
- color: #697279;
671
- text-align: left;
672
- }
673
-
674
- .wapk-price__table__features li.item {
675
- list-style-type: none;
676
- margin: 0;
677
- padding: 0;
678
- font-size: 13px;
679
- line-height: 1.5em;
680
- }
681
-
682
- .wapk-price__table__features li:not(:first-child):before {
683
- content: "";
684
- display: block;
685
- /* border: 0 solid hsla(0,0%,48%,.3); */
686
- margin: 10px 12.5%;
687
- }
688
-
689
- .wapk-price__table__feature {
690
- display: block;
691
- margin-left: calc(((100% - 80%) / 2) + 20px);
692
- margin-right: calc((100% - 80%) / 2);
693
- }
694
-
695
- span.wapk-price__table__feature span.dashicons {
696
- margin-left: -20px;
697
- top: 2px;
698
- position: relative;
699
- }
700
-
701
- .wapk-price__table__footer {
702
- padding: 40px 0;
703
- }
704
-
705
- .wapk-price__table__footer a {
706
- font-size: 14px;
707
- text-transform: uppercase;
708
- letter-spacing: 3px;
709
- border-radius: 100px 100px 100px 100px;
710
- padding: 16px 42px;
711
- transition: all 250ms;
712
- }
713
-
714
- .wapk-price__table__footer a:hover,
715
- .wapk-price__table__footer a:focus,
716
- .wapk-price__table__footer a:active {
717
- transform: scale(1.02) !important;
718
- }
719
-
720
- .wapk-price__table__ribbon {
721
- pointer-events: none;
722
- touch-action: none;
723
- -webkit-user-select: none;
724
- -moz-user-select: none;
725
- -ms-user-select: none;
726
- user-select: none;
727
- position: absolute;
728
- top: 10px;
729
- left: auto;
730
- right: 10px;
731
- -webkit-transform: rotate(90deg);
732
- -ms-transform: rotate(90deg);
733
- transform: rotate(90deg);
734
- width: 150px;
735
- overflow: hidden;
736
- height: 150px;
737
- }
738
-
739
- .wapk-price__table__ribbon__inner {
740
- background: #FF4B4B;
741
- font-family: sans-serif;
742
- font-weight: 500;
743
- color: #fff;
744
- font-size: 11px;
745
- /*noinspection CssFloatPxLength*/
746
- letter-spacing: 1.1px;
747
- box-shadow: 0 0 30px 0 rgba(0, 0, 0, .21);
748
- text-align: center;
749
- left: 0;
750
- width: 200%;
751
- -webkit-transform: translateY(-50%) translateX(-50%) translateX(35px) rotate(-45deg);
752
- -ms-transform: translateY(-50%) translateX(-50%) translateX(35px) rotate(-45deg);
753
- transform: translateY(-50%) translateX(-50%) translateX(35px) rotate(-45deg);
754
- margin-top: 35px;
755
- line-height: 2;
756
- text-transform: uppercase;
757
- }
758
-
759
- .wapk-admin .wapk-payment {
760
- display: flex;
761
- background: #fff;
762
- justify-content: space-between;
763
- padding: 85px 65px 85px;
764
- align-items: center;
765
- }
766
-
767
- .wapk-payment .payment-guarantee {
768
- display: flex;
769
- flex: 0 0 63%;
770
- align-content: center;
771
- align-items: center;
772
- position: relative;
773
- }
774
-
775
- .wapk-payment .payment-guarantee:after {
776
- content: "";
777
- position: absolute;
778
- right: -18px;
779
- top: 50%;
780
- transform: translateY(-50%);
781
- width: 5px;
782
- height: 38px;
783
- border-radius: 3px;
784
- background: #00D4D4;
785
- }
786
-
787
- .wapk-payment .payment-guarantee .guarantee-seal img {
788
- max-width: 100%;
789
- width: 280px;
790
- }
791
-
792
- .wapk-payment .payment-guarantee .guarantee-detail {
793
- padding-left: 25px;
794
- }
795
-
796
- .wapk-payment .payment-guarantee .guarantee-detail h2 {
797
- font-size: 24px;
798
- line-height: 1.5em;
799
- font-weight: 400;
800
- margin: 0;
801
- }
802
-
803
- .wapk-payment .payment-guarantee .guarantee-detail p {
804
- font-size: 15px;
805
- line-height: 1.5em;
806
- font-weight: 300;
807
- margin: 5px 0 20px;
808
- }
809
-
810
- .wapk-payment .payment-guarantee .guarantee-detail a {
811
- color: #00D4D4;
812
- font-size: 15px;
813
- line-height: 1.5em;
814
- text-decoration: none;
815
- }
816
-
817
- .wapk-payment .payment-guarantee .guarantee-detail a span.dashicons,
818
- .wapk-payment .payment-guarantee .guarantee-detail a img {
819
- width: 18px;
820
- margin-right: 4px;
821
- margin-top: 1px;
822
- }
823
-
824
- .wapk-payment .payment-options {
825
- flex-grow: 0.5;
826
- }
827
-
828
- .wapk-payment .payment-options h3 {
829
- font-size: 15px;
830
- font-weight: 300;
831
- margin: 0 0 17px;
832
- }
833
-
834
- .wapk-payment .payment-options .options {
835
- }
836
-
837
- .wapk-payment .payment-options .options h4 {
838
- color: #CED2D6;
839
- }
840
-
841
- .wapk-payment .payment-options .options li {
842
- float: left;
843
- overflow: hidden;
844
- }
845
-
846
- .wapk-payment .payment-options .options li img {
847
- height: 20px;
848
- margin-right: 5px;
849
- }
850
-
851
- /** Testimonial **/
852
- .wapk-admin .wapk-testimonials {
853
- }
854
-
855
- .wapk-admin .wapk-testimonial-wrapper:before {
856
- content: '';
857
- position: absolute;
858
- left: 79px;
859
- top: -15px;
860
- width: 80px;
861
- height: 56px;
862
- border-radius: 3px;
863
- background: transparent url(../images/block-quote.svg) no-repeat;
864
- background-size: cover;
865
- }
866
-
867
- .wapk-admin .wapk-testimonial-wrapper {
868
- position: relative;
869
- display: block;
870
- width: 80%;
871
- margin: 0 auto;
872
- padding: 0;
873
- text-align: center;
874
- }
875
-
876
- .testimonial-item__user .avatar {
877
- width: 100px;
878
- height: 100px;
879
- margin: 0 auto;
880
- border-radius: 100%;
881
- border: 3px solid #efefef;
882
- overflow: hidden;
883
- }
884
-
885
- .testimonial-item {
886
- margin-bottom: 25px;
887
- }
888
-
889
- .testimonial-item__user .avatar img {
890
- max-width: 100%;
891
- width: 100%;
892
- margin: 0 auto;
893
- padding: 0;
894
- display: block;
895
- }
896
-
897
- .testimonial-item__comment {
898
- position: relative;
899
- display: block;
900
- width: 70%;
901
- margin: 0 auto 30px;
902
- }
903
-
904
- .testimonial-item__user h4.author-name {
905
- font-size: 25px;
906
- font-weight: 300;
907
- margin: 10px auto;
908
- }
909
-
910
- .testimonial-item__user span.author-meta {
911
- font-size: 16px;
912
- font-weight: 300;
913
- }
914
-
915
- @media screen and (min-width: 1281px) {
916
- .wapk-admin .wapk-banner,
917
- .wapk-admin .wapk-feed-features {
918
- //padding-left: 20%;
919
- //padding-right: 20%;
920
- }
921
-
922
- .wapk-admin .wapk-payment {
923
- padding-left: 15%;
924
- padding-right: 15%;
925
- }
926
-
927
- .wapk-admin .feed-pro-comparison {
928
- padding-left: 21.2%;
929
- padding-right: 21.2%;
930
- }
931
-
932
- .wapk-admin .wapk-testimonial-wrapper {
933
- width: 55%;
934
- }
935
- }
936
-
937
- @media screen and (max-width: 782px) {
938
- .wapk-admin .wapk-feed-features {
939
- display: block;
940
- }
941
- .wapk-feed-feature__item {
942
- flex: 0 0 80%;
943
- width: 80%;
944
- //margin: 40px auto 0;
945
-
946
- &:nth-child(2n+1) {
947
- margin-right: initial;
948
- }
949
-
950
- &:nth-child(2n+2) {
951
- margin-left: initial;
952
- }
953
- }
954
- }
955
-
956
- .wapk-feed-pro-upgrade .wapk-feed-cta,
957
- .wapk-feed-docs .wapk-feed-cta,
958
- .wapk-admin .feed-pro-comparison,
959
- .wapk-admin .wapk-payment,
960
- .wapk-admin .wapk-testimonial,
961
- .wapk-admin .wapk-feed-banner {
962
- margin: 0;
963
- }
964
-
965
- .wapk-feed-banner .wapk-banner {
966
- margin: 0;
967
- padding: 0;
968
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/css/woo-feed-admin.css CHANGED
@@ -186,7 +186,7 @@
186
  }
187
 
188
  .woo-feed-light-btn-bg-gradient-blue {
189
- background: linear-gradient(125deg, #3cb0fd 0px, #6c5ce7 140%) !important;
190
  }
191
 
192
  #wf_newRow {
@@ -1555,23 +1555,18 @@ table.wf-rate-table a.review-star:after {
1555
  th#provider {
1556
  width: 80px;
1557
  }
1558
-
1559
  th#type {
1560
  width: 50px;
1561
  }
1562
-
1563
  th#option_name {
1564
  width: 100px;
1565
  }
1566
-
1567
  td.option_name.column-option_name > span:first-child {
1568
  display: none;
1569
  }
1570
-
1571
  th#last_updated {
1572
  width: 90px;
1573
  }
1574
-
1575
  th#view {
1576
  width: 135px;
1577
  }
@@ -1580,15 +1575,12 @@ th#provider {
1580
  th#status, th#provider {
1581
  width: 100px;
1582
  }
1583
-
1584
  th#type {
1585
  width: 80px;
1586
  }
1587
-
1588
  th#option_name {
1589
  width: 150px;
1590
  }
1591
-
1592
  th#last_updated {
1593
  width: 140px;
1594
  }
@@ -1601,7 +1593,6 @@ th#provider {
1601
  margin: 0 auto;
1602
  display: block;
1603
  }
1604
-
1605
  .wapk-button.wapk-button-xl {
1606
  padding: 6px 14px;
1607
  line-height: normal;
186
  }
187
 
188
  .woo-feed-light-btn-bg-gradient-blue {
189
+ background: linear-gradient(125deg, rgb(60, 176, 253) 0px, rgb(108, 92, 231) 140%) !important;
190
  }
191
 
192
  #wf_newRow {
1555
  th#provider {
1556
  width: 80px;
1557
  }
 
1558
  th#type {
1559
  width: 50px;
1560
  }
 
1561
  th#option_name {
1562
  width: 100px;
1563
  }
 
1564
  td.option_name.column-option_name > span:first-child {
1565
  display: none;
1566
  }
 
1567
  th#last_updated {
1568
  width: 90px;
1569
  }
 
1570
  th#view {
1571
  width: 135px;
1572
  }
1575
  th#status, th#provider {
1576
  width: 100px;
1577
  }
 
1578
  th#type {
1579
  width: 80px;
1580
  }
 
1581
  th#option_name {
1582
  width: 150px;
1583
  }
 
1584
  th#last_updated {
1585
  width: 140px;
1586
  }
1593
  margin: 0 auto;
1594
  display: block;
1595
  }
 
1596
  .wapk-button.wapk-button-xl {
1597
  padding: 6px 14px;
1598
  line-height: normal;
admin/css/woo-feed-admin.scss DELETED
@@ -1,2319 +0,0 @@
1
- /**
2
- * All of the CSS for your admin-specific functionality should be
3
- * included in this file.
4
- */
5
- .wpf_spin {
6
- -webkit-animation: spin 1000ms infinite linear;
7
- animation: spin 1000ms infinite linear;
8
- &.reverse_spin {
9
- animation-direction: reverse;
10
- }
11
- }
12
- .wpf_regenerate {
13
- &.disabled {
14
- color: #737373;
15
- box-shadow: none;
16
- cursor: not-allowed;
17
- }
18
- }
19
-
20
- @keyframes spin {
21
- 0% {
22
- transform: rotate(0deg);
23
- }
24
- 100% {
25
- transform: rotate(359deg);
26
- }
27
- }
28
-
29
- .webappick-info{
30
- color: #42a5fa;
31
- }
32
-
33
- .wfbtn {
34
- background: #3498db;
35
- background-image: -webkit-linear-gradient(125deg, #3cb0fd 0%, #152f8c 140%);
36
- background-image: -moz-linear-gradient(125deg, #3cb0fd 0%, #152f8c 140%);
37
- background-image: -ms-linear-gradient(125deg, #3cb0fd 0%, #152f8c 140%);
38
- background-image: -o-linear-gradient(125deg, #3cb0fd 0%, #152f8c 140%);
39
- background-image: linear-gradient(125deg, #3cb0fd 0%, #152f8c 140%);
40
- -webkit-border-radius: 3px;
41
- -moz-border-radius: 3px;
42
- border-radius: 3px;
43
- -webkit-box-shadow: 0 1px 3px #666666;
44
- -moz-box-shadow: 0 1px 3px #666666;
45
- box-shadow: inset 0 1px 3px #666666;
46
- font-family: Arial, sans-serif;
47
- color: #ffffff;
48
- font-size: 20px;
49
- padding: 10px 20px 10px 20px;
50
- border: solid #2b698f 0px;
51
- text-decoration: none;
52
- &:hover {
53
- background: #3cb0fd;
54
- background-image: -webkit-linear-gradient(top, #3cb0fd, #3498db);
55
- background-image: -moz-linear-gradient(top, #3cb0fd, #3498db);
56
- background-image: -ms-linear-gradient(top, #3cb0fd, #3498db);
57
- background-image: -o-linear-gradient(top, #3cb0fd, #3498db);
58
- background-image: linear-gradient(to bottom, #3cb0fd, #3498db);
59
- text-decoration: none;
60
- }
61
- }
62
- .woo-feed-ctx-startup-notice {
63
- min-height: 168px;
64
- background-size: contain !important;
65
- border: none;
66
- display: block;
67
- margin-left: 0;
68
- margin-top: 40px;
69
-
70
- button {
71
- &::before {
72
- color: #fbfbfb;
73
- font-size: 18px;
74
- }
75
- }
76
- }
77
- .woo_feed_manage_list_table {
78
- .wf_update_interval_btn {
79
- background: -webkit-linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%);
80
- background: -moz-linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%);
81
- background: -ms-linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%);
82
- background: -o-linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%);
83
- background: linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%);
84
- border: none;
85
-
86
- &:hover {
87
- background: linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%);
88
- }
89
- }
90
- }
91
-
92
- .woo-feed-promotion {
93
- position: relative;
94
- display: none;
95
- .woo-feed-campaign-close-button {
96
- position: absolute;
97
- top: 50%;
98
- transform: translateY(-50%);
99
- right: 15px;
100
- width: 24px;
101
- height: 24px;
102
- border-radius: 12px;
103
- background: #595d6b;
104
- line-height: 24px;
105
- color: #fff;
106
- cursor: pointer;
107
- transition: .3s ease;
108
-
109
- &:hover {
110
- background: #fff;
111
- color: #d61e48;
112
- }
113
- }
114
- }
115
-
116
- .wftooltip {
117
- display: none;
118
- position: absolute;
119
- border: 1px solid #333;
120
- background-color: #161616;
121
- border-radius: 5px;
122
- padding: 10px;
123
- color: #fff;
124
- font-size: 12px;
125
- }
126
-
127
- .feed-actions {
128
- .makeFeedResponse {
129
- width: 70%;
130
- color: green;
131
- }
132
- }
133
-
134
- .woo-feed-mapping-input {
135
- width: 100%;
136
- }
137
-
138
- .requiredIn {
139
- color: red;
140
- }
141
-
142
- .generalInput {
143
- width: 200px;
144
- &:not(.selectize-control) {
145
- margin: 5px auto;
146
- }
147
- }
148
-
149
- .error {
150
- color: red;
151
- }
152
-
153
- .widefat {
154
- td {
155
- select, input {
156
- max-width: 100%;
157
- }
158
- }
159
- }
160
-
161
- .woo-feed-btn-bg-gradient-blue, [data-class="woo-feed-btn-bg-gradient-blue"] {
162
- background: linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%) !important;
163
- border: none;
164
- outline: 0;
165
- border-width: 0 !important;
166
- box-shadow: none !important;
167
- transition: 1s lenear;
168
- font-weight: 500;
169
- color: #fff !important;
170
-
171
- &:hover {
172
- background: #3cb0fd !important;
173
- }
174
- }
175
-
176
- .woo-feed-btn-bg-gradient-red {
177
- background: linear-gradient(125deg,#eb4d4b 0,#ff9671 140%) !important;
178
- border: none;
179
- outline: 0;
180
- border-width: 0 !important;
181
- box-shadow: none !important;
182
- transition: 1s lenear;
183
- font-weight: 500;
184
- color: #fff !important;
185
-
186
- &:hover {
187
- background: #fc5c65 !important;
188
- }
189
- }
190
-
191
- .woo-feed-btn-bg-gradient-purple {
192
- background: linear-gradient(67.36deg,#9733ee 3.09%,#da22ff 64.97%) !important;
193
- border: none;
194
- outline: 0;
195
- border-width: 0 !important;
196
- box-shadow: none !important;
197
- transition: 1s lenear;
198
- font-weight: 500;
199
- color: #fff !important;
200
-
201
- &:hover {
202
- background: #a203fb !important;
203
- }
204
- }
205
-
206
- .woo-feed-light-btn-bg-gradient-blue {
207
- background: linear-gradient(125deg, rgb(60, 176, 253) 0px, rgb(108, 92, 231) 140%) !important;
208
- }
209
-
210
- #wf_newRow {
211
- margin-left: 0;
212
- }
213
-
214
- .mtable {
215
- tbody {
216
- tr {
217
- height: 25px;
218
- border: 1px solid #CCC;
219
- text-align: left;
220
- align-items: baseline;
221
- font-weight: bold;
222
- }
223
- }
224
- th {
225
- &:nth-child(1) {
226
- width: 17px;
227
- }
228
- &:nth-child(2) {
229
- width: 160px;
230
- }
231
- &:nth-child(3) {
232
- width: 100px;
233
- }
234
- &:nth-child(4) {
235
- width: 100px;
236
- }
237
- &:nth-child(5) {
238
- width: 150px;
239
- }
240
- &:nth-child(6) {
241
- width: 100px;
242
- }
243
- &:nth-child(7) {
244
- width: 150px;
245
- }
246
- &:nth-child(8) {
247
- width: 90px;
248
- }
249
- &:nth-child(9) {
250
- width: 29px;
251
- }
252
- }
253
- }
254
-
255
- .mtable2 {
256
- tbody {
257
- tr {
258
- height: 25px;
259
- border: 1px solid #CCC;
260
- text-align: left;
261
- align-items: baseline;
262
- font-weight: bold;
263
- }
264
- }
265
- th {
266
- &:nth-child(1) {
267
- width: 30px;
268
- }
269
- &:nth-child(2) {
270
- width: 150px;
271
- }
272
- &:nth-child(3) {
273
- width: 230px;
274
- }
275
- &:nth-child(4) {
276
- width: 220px;
277
- }
278
- &:nth-child(7) {
279
- width: 50px;
280
- }
281
- &:nth-child(8) {
282
- width: 50px;
283
- }
284
- &:nth-child(9) {
285
- width: 29px;
286
- }
287
- }
288
- }
289
-
290
-
291
- .wp-admin {
292
- select.wf_mattributes {
293
- width: 150px;
294
- left: 0;
295
- height: 25px;
296
- }
297
- }
298
-
299
- div#wf-tab-content1 {
300
- select {
301
- &:not([name^="output_type"]) {
302
- width: 100%;
303
- }
304
- }
305
- input {
306
- width: 100%;
307
- }
308
- .dashicons {
309
- vertical-align: middle;
310
- }
311
- }
312
-
313
-
314
- .wf_attributes {
315
- width: 150px;
316
- left: 0
317
- }
318
-
319
- .wf_compare {
320
- max-width: 245px;
321
- left: 0
322
- }
323
-
324
- .wf_ps {
325
- width: 100px;
326
- left: 0
327
- }
328
-
329
- .wf_sortedtable {
330
- cursor: move;
331
- }
332
-
333
- .sorted_table {
334
- position: relative;
335
- .dragged {
336
- position: absolute;
337
- opacity: 0.8;
338
- z-index: 9999;
339
- background: #fff;
340
- width: 100%;
341
- display: table;
342
- }
343
- tbody {
344
- tr.placeholder {
345
- td {
346
- border: 1px dashed #2cc185;
347
- height: 46px;
348
- }
349
- }
350
- }
351
- }
352
-
353
- .wfnoempty {
354
- width: 120px;
355
- }
356
-
357
- /*==================Tab Design=======================*/
358
-
359
- .woofeed-body-content #providerPage {
360
- display: flex;
361
- flex-direction: column-reverse;
362
- }
363
- #providerPageWrapper {
364
- display: flex;
365
- flex-direction: column-reverse;
366
- .wf_tabs {
367
- position: relative;
368
- margin: 0 auto;
369
- width: 100%;
370
- list-style: none;
371
- /*bottom: 50px;*/
372
-
373
- &:after {
374
- display: table;
375
- clear: both;
376
- content: "";
377
- }
378
-
379
- li {
380
- background: #fff;
381
- float: left;
382
- //width: 20%;
383
- display: none;
384
- border: 2px solid #CCC;
385
-
386
- &.active {
387
- display: block;
388
- }
389
-
390
- .wf-tab-content {
391
- z-index: 2;
392
- width: 100%;
393
- font-size: 0.9rem;
394
- display: block;
395
- //position: absolute;
396
- left: 0;
397
-
398
- .feed-actions {
399
- border: none;
400
- border-top: 2px solid #ccc;
401
- }
402
- }
403
- }
404
- }
405
-
406
- #tabName {
407
- display: flex;
408
- justify-content: flex-start;
409
- align-items: flex-start;
410
-
411
- .tab-name {
412
- min-width: 300px;
413
- border: 2px solid #ccc;
414
- border-bottom: none;
415
-
416
- input[type=radio] {
417
- display: none;
418
- }
419
-
420
- label {
421
- &.activate {
422
- background: #2cc185;
423
- color: #fff;
424
- }
425
- }
426
- }
427
- }
428
- }
429
-
430
-
431
- //#tabName input[type="radio"][name="wf_tabs"] {
432
- // position: absolute;
433
- // top: auto;
434
- // left: -9999px;
435
- //}
436
-
437
- .wf-tab-name {
438
- display: block;
439
- padding: 15px;
440
- font-size: 15px;
441
- font-weight: bold;
442
- line-height: 1;
443
- background: #fff;
444
- cursor: pointer;
445
- position: relative;
446
- text-align: center;
447
- text-transform: uppercase;
448
- color: #2CC185;
449
- }
450
-
451
- .wf-tab-name:hover {
452
- background: #2CC185;
453
- color: white;
454
- }
455
-
456
- .wf_tabs [id^="tab"]:checked + label {
457
- background: #2CC185;
458
- color: white;
459
- }
460
-
461
- .wf_tabs [id^="tab"]:checked ~ [id^="wf-tab-content"] {
462
- display: block;
463
- }
464
-
465
- div#wf-tab-content2 table:first-child {
466
- padding: 10px 0;
467
- }
468
-
469
- div#wf-tab-content2 table:first-child td:nth-child(1) {
470
- width: 260px;
471
- }
472
-
473
- div#wf-tab-content2 table:first-child td:nth-child(2) {
474
- width: 260px;
475
- }
476
-
477
- table.feed-actions tr td:last-child {
478
- text-align: right;
479
- }
480
-
481
- /* Selectize */
482
- select.selectize {
483
- display: none;
484
- }
485
-
486
- body.no-js select.selectize {
487
- display: block !important;
488
- }
489
-
490
- .wp-list-table {
491
- .option_name {
492
- .wf_feed_option_name_link {
493
- font-weight: 700;
494
- color: #30336b;
495
- }
496
- }
497
-
498
- #option_name {
499
- a {
500
- color: #32373c;
501
- }
502
- }
503
- }
504
-
505
- /* fallback combat */
506
- .selectize-dropdown .active {
507
- background-color: #edf9ff;
508
- }
509
-
510
- .selectize-dropdown .create {
511
- padding: 5px 8px;
512
- }
513
-
514
- .wapk-selectize-item {
515
- background: #0073aa !important;
516
- color: #f1f1f1 !important;
517
- border-color: #0073aa !important;
518
- padding-left: 5px;
519
- padding-right: 5px;
520
- border-radius: 3px;
521
- }
522
-
523
- .selectize-google-category{
524
- .selectize-input{
525
- padding-right: 30px;
526
- }
527
- .selectize-dropdown-content{
528
- padding: 0 8px;
529
- .wapk-selectize-item{
530
- color: #000 !important;
531
- background-color: #edf0f2 !important;
532
- margin-bottom: 3px !important;
533
- padding: 3px 8px !important;
534
- transition-duration: 0.6s;
535
- &.active{
536
- background-color: #a2c8e1 !important;
537
- transition-duration: 0.6s;
538
- }
539
- }
540
- }
541
- }
542
- //.selectize-dropdown .active {
543
- // background-color: #edf9ff;
544
- // .selectize-dropdown-content{
545
- // .wapk-selectize-item{
546
- //
547
- // background: #fff !important;
548
- // border-color: #000 !important;
549
- // color: #303030 !important;
550
- // font-weight: 400 !important;
551
- // }
552
- // }
553
- //
554
- //}
555
-
556
- .selectize-input.full #googleTaxonomyId-selectized {
557
- opacity: 0;
558
- position: absolute;
559
- left: -10000px;
560
- }
561
-
562
- .selectize-dropdown [data-selectable].option {
563
- cursor: default;
564
- }
565
-
566
- .selectize-control.plugin-remove_button [data-value] .remove {
567
- border-left: 1px solid #f1f1f1 !important;
568
- }
569
-
570
- .selectize-dropdown .optgroup-header {
571
- font-weight: 700;
572
- background: #efefef;
573
- color: #5a5a5a;
574
- }
575
-
576
- .selectize-dropdown [data-selectable].option {
577
- cursor: pointer;
578
- }
579
-
580
- /* Feed active and inactive button CSS */
581
- .wf_status_wrap label {
582
- width: 55px;
583
- height: 28px;
584
- box-sizing: border-box;
585
- float: left;
586
- border-radius: 100px;
587
- position: relative;
588
- cursor: pointer;
589
- transition: .3s ease;
590
- background: linear-gradient(125deg,#e2e2e2 0,#ccc 140%);
591
- }
592
-
593
- input[class=woo_feed_status_input]:checked + label {
594
- background: linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%);
595
- }
596
-
597
- input[class=woo_feed_status_input]:checked + label:before {
598
- left: 29px;
599
- }
600
-
601
- .wf_status_wrap label:before {
602
- transition: .3s ease;
603
- content: '';
604
- width: 20px;
605
- height: 20px;
606
- position: absolute;
607
- background: white;
608
- left: 6px;
609
- top: 4px;
610
- box-sizing: border-box;
611
- color: black;
612
- border-radius: 100px;
613
- box-shadow: 0px 1.5px 2px 0px #000;
614
- }
615
-
616
- .view {
617
- span {
618
- &.dashicons {
619
- &.dashicons-external {
620
- color: #22a6b3;
621
- }
622
-
623
- &.dashicons-sos {
624
- color: #22a6b3;
625
- }
626
-
627
- &.dashicons-download {
628
- color: #ee5253;
629
- }
630
-
631
- &.dashicons-media-code {
632
- color: #576574;
633
- }
634
- }
635
- }
636
- }
637
-
638
-
639
- /* list table style */
640
- .widefat td.column-url, .widefat th.column-url,
641
- .column-url {
642
- color: #1e8f9a;
643
- font-weight: bold;
644
- }
645
-
646
- /** Feed Progress **/
647
- .feed-progress-container {
648
- width: 100%;
649
- color: white;
650
- text-align: center;
651
- font-weight: 300;
652
- }
653
-
654
- .feed-progress-bar {
655
- width: 100%;
656
- background: #eee;
657
- padding: 3px;
658
- border-radius: 50px;
659
- box-shadow: inset 0 1px 3px rgba(0, 0, 0, .2);
660
- }
661
-
662
- .feed-progress-bar-fill {
663
- height: 20px;
664
- display: block;
665
- background: linear-gradient(to right top, #10ac84, #13b389, #15ba8f, #18c194, #1ac89a, #13cba1, #0acfa9, #00d2b0, #00d2ba, #00d2c3, #00d2cb, #00d2d3);
666
- width: 0;
667
- border-radius: 50px;
668
- -webkit-transition: width 0.8s ease;
669
- transition: width 0.8s ease;
670
- }
671
-
672
- .feed-progress-status {
673
- float: left;
674
- font-weight: bold;
675
- color: darkblue;
676
- }
677
-
678
- .feed-progress-percentage {
679
- text-align: right;
680
- font-weight: bolder;
681
- color: #1dd1a1;
682
- font-family: 'Arial Black', sans-serif;
683
- font-size: large;
684
- }
685
-
686
- #wpbody-content.woofeed-body-content {
687
- overflow: visible !important;
688
- }
689
-
690
- .clippy {
691
- position: relative;
692
- width: 13px;
693
- margin-top: -3px;
694
- margin-left: 3px;
695
- top: 3px;
696
- }
697
-
698
- .column-url .clippy {
699
- display: none;
700
- }
701
-
702
- .column-url:hover .clippy {
703
- display: inline-block;
704
- }
705
-
706
- /**
707
- * Primer Tooltip
708
- */
709
- .tooltipped {
710
- position: relative;
711
- &:after {
712
- position: absolute;
713
- z-index: 1000000;
714
- display: none;
715
- padding: 5px 8px;
716
- font: normal normal 11px/1.5 Helvetica, arial, nimbussansl, liberationsans, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol";
717
- color: #fff;
718
- text-align: center;
719
- text-decoration: none;
720
- text-shadow: none;
721
- text-transform: none;
722
- letter-spacing: normal;
723
- word-wrap: break-word;
724
- white-space: pre;
725
- pointer-events: none;
726
- content: attr(aria-label);
727
- background: rgba(0, 0, 0, .8);
728
- border-radius: 3px;
729
- -webkit-font-smoothing: subpixel-antialiased;
730
- }
731
- &:before {
732
- position: absolute;
733
- z-index: 1000001;
734
- display: none;
735
- width: 0;
736
- height: 0;
737
- color: rgba(0, 0, 0, .8);
738
- pointer-events: none;
739
- content: "";
740
- border: 5px solid transparent;
741
- }
742
- &:hover {
743
- &:before {
744
- display: inline-block;
745
- text-decoration: none;
746
- }
747
- &:after {
748
- display: inline-block;
749
- text-decoration: none;
750
- }
751
- }
752
- &:active {
753
- &:before {
754
- display: inline-block;
755
- text-decoration: none;
756
- }
757
- &:after {
758
- display: inline-block;
759
- text-decoration: none;
760
- }
761
- }
762
- &:focus {
763
- &:before {
764
- display: inline-block;
765
- text-decoration: none;
766
- }
767
- &:after {
768
- display: inline-block;
769
- text-decoration: none;
770
- }
771
- }
772
- &-multiline {
773
- &:hover {
774
- &:after {
775
- display: table-cell;
776
- }
777
- }
778
- &:active {
779
- &:after {
780
- display: table-cell;
781
- }
782
- }
783
- &:focus {
784
- &:after {
785
- display: table-cell;
786
- }
787
- }
788
- &:after {
789
- //noinspection CssInvalidPropertyValue
790
- width: -webkit-max-content;
791
- width: -moz-max-content;
792
- width: max-content;
793
- max-width: 250px;
794
- word-break: break-word;
795
- word-wrap: normal;
796
- white-space: pre-line;
797
- border-collapse: separate;
798
- }
799
- }
800
- &-s {
801
- &:after {
802
- top: 100%;
803
- right: 50%;
804
- margin-top: 5px;
805
- -webkit-transform: translateX(50%);
806
- -ms-transform: translateX(50%);
807
- transform: translateX(50%);
808
- }
809
- &:before {
810
- top: auto;
811
- right: 50%;
812
- bottom: -5px;
813
- margin-right: -5px;
814
- border-bottom-color: rgba(0, 0, 0, .8);
815
- }
816
- }
817
- &-se {
818
- &:after {
819
- top: 100%;
820
- margin-top: 5px;
821
- right: auto;
822
- left: 50%;
823
- margin-left: -15px;
824
- }
825
- &:before {
826
- top: auto;
827
- right: 50%;
828
- bottom: -5px;
829
- margin-right: -5px;
830
- border-bottom-color: rgba(0, 0, 0, .8);
831
- }
832
- }
833
- &-sw {
834
- &:after {
835
- top: 100%;
836
- right: 50%;
837
- margin-top: 5px;
838
- margin-right: -15px;
839
- }
840
- &:before {
841
- top: auto;
842
- right: 50%;
843
- bottom: -5px;
844
- margin-right: -5px;
845
- border-bottom-color: rgba(0, 0, 0, .8);
846
- }
847
- }
848
- &-n {
849
- &:after {
850
- right: 50%;
851
- bottom: 100%;
852
- margin-bottom: 5px;
853
- -webkit-transform: translateX(50%);
854
- -ms-transform: translateX(50%);
855
- transform: translateX(50%);
856
- }
857
- &:before {
858
- top: -5px;
859
- right: 50%;
860
- bottom: auto;
861
- margin-right: -5px;
862
- border-top-color: rgba(0, 0, 0, .8);
863
- }
864
- }
865
- &-ne {
866
- &:after {
867
- bottom: 100%;
868
- margin-bottom: 5px;
869
- right: auto;
870
- left: 50%;
871
- margin-left: -15px;
872
- }
873
- &:before {
874
- top: -5px;
875
- right: 50%;
876
- bottom: auto;
877
- margin-right: -5px;
878
- border-top-color: rgba(0, 0, 0, .8);
879
- }
880
- }
881
- &-nw {
882
- &:after {
883
- right: 50%;
884
- bottom: 100%;
885
- margin-bottom: 5px;
886
- margin-right: -15px;
887
- }
888
- &:before {
889
- top: -5px;
890
- right: 50%;
891
- bottom: auto;
892
- margin-right: -5px;
893
- border-top-color: rgba(0, 0, 0, .8);
894
- }
895
- }
896
- &-w {
897
- &:after {
898
- right: 100%;
899
- bottom: 50%;
900
- margin-right: 5px;
901
- -webkit-transform: translateY(50%);
902
- -ms-transform: translateY(50%);
903
- transform: translateY(50%);
904
- }
905
- &:before {
906
- top: 50%;
907
- bottom: 50%;
908
- left: -5px;
909
- margin-top: -5px;
910
- border-left-color: rgba(0, 0, 0, .8);
911
- }
912
- }
913
- &-e {
914
- &:after {
915
- bottom: 50%;
916
- left: 100%;
917
- margin-left: 5px;
918
- -webkit-transform: translateY(50%);
919
- -ms-transform: translateY(50%);
920
- transform: translateY(50%);
921
- }
922
- &:before {
923
- top: 50%;
924
- right: -5px;
925
- bottom: 50%;
926
- margin-top: -5px;
927
- border-right-color: rgba(0, 0, 0, .8);
928
- }
929
- }
930
- &-multiline {
931
- &.tooltipped-s {
932
- &:after {
933
- right: auto;
934
- left: 50%;
935
- -webkit-transform: translateX(-50%);
936
- -ms-transform: translateX(-50%);
937
- transform: translateX(-50%);
938
- }
939
- }
940
- &.tooltipped-n {
941
- &:after {
942
- right: auto;
943
- left: 50%;
944
- -webkit-transform: translateX(-50%);
945
- -ms-transform: translateX(-50%);
946
- transform: translateX(-50%);
947
- }
948
- }
949
- &.tooltipped-w {
950
- &:after {
951
- right: 100%;
952
- }
953
- }
954
- &.tooltipped-e {
955
- &:after {
956
- right: 100%;
957
- }
958
- }
959
- }
960
- &-sticky {
961
- &:before {
962
- display: inline-block;
963
- }
964
- &:after {
965
- display: inline-block;
966
- }
967
- &.tooltipped-multiline {
968
- &:after {
969
- display: table-cell;
970
- }
971
- }
972
- }
973
- }
974
-
975
- .fullscreen-overlay-enabled {
976
- &.dark-theme {
977
- .tooltipped {
978
- &:after {
979
- color: #000;
980
- background: rgba(255, 255, 255, .8);
981
- }
982
- .tooltipped-s {
983
- &:before {
984
- border-bottom-color: rgba(255, 255, 255, .8);
985
- }
986
- }
987
- .tooltipped-se {
988
- &:before {
989
- border-bottom-color: rgba(255, 255, 255, .8);
990
- }
991
- }
992
- .tooltipped-sw {
993
- &:before {
994
- border-bottom-color: rgba(255, 255, 255, .8);
995
- }
996
- }
997
- &.tooltipped-n {
998
- &:before {
999
- border-top-color: rgba(255, 255, 255, .8);
1000
- }
1001
- }
1002
- &.tooltipped-ne {
1003
- &:before {
1004
- border-top-color: rgba(255, 255, 255, .8);
1005
- }
1006
- }
1007
- &.tooltipped-nw {
1008
- &:before {
1009
- border-top-color: rgba(255, 255, 255, .8);
1010
- }
1011
- }
1012
- &.tooltipped-e {
1013
- &:before {
1014
- border-right-color: rgba(255, 255, 255, .8);
1015
- }
1016
- }
1017
- &.tooltipped-w {
1018
- &:before {
1019
- border-left-color: rgba(255, 255, 255, .8);
1020
- }
1021
- }
1022
- }
1023
- }
1024
- }
1025
- @media screen and (min-width: 0\0) {
1026
- .tooltipped-multiline {
1027
- &:after {
1028
- width: 250px;
1029
- }
1030
- }
1031
- }
1032
-
1033
-
1034
- ul {
1035
- &.tracker_collection_list {
1036
- list-style: initial;
1037
- padding: initial;
1038
- margin: -10px 0 0 30px;
1039
- font-size: 11px !important;
1040
- li {
1041
- margin: 0;
1042
- }
1043
- }
1044
- }
1045
-
1046
-
1047
- /** Info Message Table **/
1048
- table {
1049
- &.wf-info-table, &.wf-rate-table {
1050
- vertical-align: middle;
1051
- text-align: center;
1052
- max-width: 100%;
1053
- font-weight: 500;
1054
- margin-top: 10px;
1055
- th {
1056
- text-align: center;
1057
-
1058
- .woo-feed-top-header {
1059
- display: flex;
1060
- justify-content: space-between;
1061
- align-items: center;
1062
-
1063
- .get-woo-feed-pro {
1064
- margin-left: 20px;
1065
-
1066
- img {
1067
- width: 172px;
1068
- }
1069
- }
1070
-
1071
- .woo-feed-top-buttons {
1072
- float: right;
1073
- display: flex;
1074
- border-radius: 7px;
1075
- justify-content: center;
1076
- align-items: center;
1077
- a {
1078
- padding: 8px 20px;
1079
- background: #576574;
1080
- color: #fff;
1081
- box-sizing: border-box;
1082
- display: inline-block;
1083
- transition: .3s ease;
1084
-
1085
- &.woo-feed-doc-link {
1086
- background: #576574;
1087
- border-top-left-radius: 5px;
1088
- border-bottom-left-radius: 5px;
1089
- }
1090
-
1091
- &.woo-feed-video-link {
1092
- background: #ee5253;
1093
- }
1094
-
1095
- &.woo-feed-support-link {
1096
- background: #22a6b3;
1097
- border-top-right-radius: 5px;
1098
- border-bottom-right-radius: 5px;
1099
- }
1100
-
1101
- span.dashicons {
1102
- font-size: 18px;
1103
- line-height: 1.2;
1104
- }
1105
-
1106
- &:hover {
1107
- background: #30336b;
1108
- box-shadow: 0px 0px 33px 0px rgba(0,0,0,0.12);
1109
- }
1110
-
1111
- }
1112
- }
1113
- }
1114
- }
1115
- strong {
1116
- font-weight: bold;
1117
- }
1118
- }
1119
- &.wf-info-table {
1120
- th {
1121
- &:first-child {
1122
- img {
1123
- margin: 0 0 -5px 5px;
1124
- }
1125
- }
1126
- }
1127
- }
1128
- &.wf-rate-table {
1129
- a {
1130
- color: #0073aa;
1131
- }
1132
- a.review-star {
1133
- &:after {
1134
- content: "\f155\f155\f155\f155\f155" !important;
1135
- //noinspection CssNoGenericFontName
1136
- font-family: dashicons;
1137
- font-size: 10px;
1138
- font-weight: 100;
1139
- text-rendering: auto;
1140
- -webkit-font-smoothing: antialiased;
1141
- -moz-osx-font-smoothing: grayscale;
1142
- color: #0073aa;
1143
- text-decoration: underline;
1144
- }
1145
- }
1146
- }
1147
- }
1148
-
1149
-
1150
- /** Admin Menu Icon **/
1151
- #adminmenu {
1152
- #toplevel_page_webappick-manage-feeds {
1153
- div.wp-menu-image {
1154
- &::before {
1155
- content: "";
1156
- background: url(../images/woo-feed-icon.svg) no-repeat center center;
1157
- background-size: 20px 20px;
1158
- opacity: 0.6;
1159
- filter: alpha(opacity=60);
1160
- }
1161
- }
1162
- &:hover {
1163
- div.wp-menu-image {
1164
- &::before {
1165
- opacity: 1;
1166
- filter: alpha(opacity=100);
1167
- }
1168
- }
1169
- }
1170
- }
1171
- #toplevel_page_webappick-manage-feeds.wp-has-current-submenu {
1172
- div.wp-menu-image {
1173
- &::before {
1174
- opacity: 1;
1175
- filter: alpha(opacity=100);
1176
- }
1177
- }
1178
- }
1179
- }
1180
-
1181
-
1182
- /** Admin Page Wrapper **/
1183
- .wapk-admin, .wapk-admin * {
1184
- -webkit-box-sizing: border-box;
1185
- -moz-box-sizing: border-box;
1186
- box-sizing: border-box;
1187
- }
1188
-
1189
- .wapk-admin {
1190
- position: relative;
1191
- display: block;
1192
- -webkit-hyphens: manual;
1193
- -ms-hyphens: manual;
1194
- hyphens: manual;
1195
- color: #1B2730;
1196
- /* reset .warp margin to use full width except menu area */
1197
- margin: 0 0 0 -10px;
1198
- }
1199
-
1200
- @media screen and (min-width: 783px) {
1201
- .wapk-admin {
1202
- margin: 0 0 0 -20px;
1203
- }
1204
- }
1205
-
1206
- .text-center {
1207
- text-align: center;
1208
- }
1209
- .wapk-admin {
1210
- h1, h2, h3,
1211
- h4, h5, h6,
1212
- p {
1213
- color: #1B2730;
1214
- }
1215
- sup {
1216
- vertical-align: baseline;
1217
- position: relative;
1218
- top: -6px;
1219
- }
1220
- sub {
1221
- vertical-align: baseline;
1222
- position: relative;
1223
- top: 4px;
1224
- }
1225
- }
1226
-
1227
-
1228
- /* WP.Core.UI Compat */
1229
- .wapk-admin {
1230
- .wapk-section {
1231
- [class$=icon32] {
1232
- + {
1233
- h2 {
1234
- font-size: 23px;
1235
- font-weight: 400;
1236
- margin: 0;
1237
- padding: 9px 0 4px 0;
1238
- line-height: 1.3;
1239
- }
1240
- }
1241
- }
1242
- h1 {
1243
- font-size: 23px;
1244
- font-weight: 400;
1245
- margin: 0;
1246
- padding: 9px 0 4px 0;
1247
- line-height: 1.3;
1248
- }
1249
- >h2 {
1250
- &:first-child {
1251
- font-size: 23px;
1252
- font-weight: 400;
1253
- margin: 0;
1254
- padding: 9px 0 4px 0;
1255
- line-height: 1.3;
1256
- }
1257
- }
1258
- margin: 10px 20px 0 22px;
1259
- position: relative;
1260
- display: block;
1261
- }
1262
- >.notice {
1263
- margin: 10px 20px 0 22px;
1264
- position: relative;
1265
- display: block;
1266
- }
1267
- span.help {
1268
- display: block;
1269
- float: left;
1270
- width: 100%;
1271
- font-size: 0.9em;
1272
- color: #636363;
1273
- margin-top: 5px;
1274
- font-weight: 500;
1275
- .dashicons {
1276
- width: 11px;
1277
- height: 12px;
1278
- font-size: inherit;
1279
- vertical-align: middle;
1280
- }
1281
- }
1282
- }
1283
- .clear {
1284
- &:after {
1285
- content: "";
1286
- display: table;
1287
- clear: both;
1288
- }
1289
- }
1290
-
1291
-
1292
- /*.wapk-admin .help a { color: inherit; text-decoration: underline; }*/
1293
- /** Extend WP Core UI PostBox For Docs **/
1294
- .wapk-feed-docs {
1295
- .postbox {
1296
- width: 355px;
1297
- margin-right: 20px;
1298
- display: inline-block;
1299
- vertical-align: top;
1300
- .hndle {
1301
- font-size: 14px;
1302
- padding: 8px 12px;
1303
- margin: 0;
1304
- line-height: 1.4;
1305
- cursor: pointer;
1306
- }
1307
- .dashicons {
1308
- color: #ccc;
1309
- }
1310
- a {
1311
- text-decoration: none;
1312
- }
1313
- .inside {
1314
- margin-bottom: 0;
1315
- }
1316
- ul {
1317
- margin-bottom: 0;
1318
- }
1319
- .toggle-indicator {
1320
- &:before {
1321
- content: "\F142";
1322
- display: inline-block;
1323
- font: 400 20px/1 dashicons;
1324
- speak: none;
1325
- -webkit-font-smoothing: antialiased;
1326
- -moz-osx-font-smoothing: grayscale;
1327
- text-decoration: none !important;
1328
- }
1329
- }
1330
- li {
1331
- width: 100%;
1332
- display: block;
1333
- float: left;
1334
- span {
1335
- display: inline-block;
1336
- float: left;
1337
- margin-right: 4px;
1338
- }
1339
- a {
1340
- display: inline-block;
1341
- float: left;
1342
- width: calc(100% - 24px);
1343
- }
1344
- }
1345
- }
1346
- .postbox.closed {
1347
- .toggle-indicator {
1348
- &:before {
1349
- content: "\F140";
1350
- }
1351
- }
1352
- }
1353
- }
1354
- .wapk-section {
1355
- #post-body.columns-2 {
1356
- #side-sortables {
1357
- min-height: 196px;
1358
- }
1359
- }
1360
- }
1361
- #poststuff {
1362
- #feed_merchant_info {
1363
- .inside {
1364
- margin: 0;
1365
- padding: 0;
1366
- }
1367
- }
1368
- }
1369
- #feed_merchant_info {
1370
- ul.data {
1371
- margin-left: 24px;
1372
- margin-top: 5px;
1373
- li {
1374
- margin-bottom: 5px;
1375
- }
1376
- }
1377
- }
1378
- .merchant-info-section {
1379
- padding: 6px 10px 8px;
1380
-
1381
- &.woo-feed-open-file {
1382
- text-align: center;
1383
-
1384
- a {
1385
- line-height: 1.5;
1386
- text-decoration: none;
1387
- }
1388
- }
1389
- }
1390
-
1391
- .generateFeed {
1392
- .wf-tab-content {
1393
- table {
1394
- &:first-child {
1395
- border: none;
1396
- box-shadow: none;
1397
- }
1398
- }
1399
- }
1400
- table {
1401
- th {
1402
- font-weight: bold;
1403
- }
1404
- }
1405
- }
1406
- @media only screen and (max-width: 850px) {
1407
- .wapk-feed-docs {
1408
- .postbox {
1409
- display: block;
1410
- width: auto;
1411
- float: none;
1412
- margin-right: auto;
1413
- }
1414
- }
1415
- }
1416
-
1417
- /** Admin Feed Help Docs **/
1418
- .wp-submenu {
1419
- li {
1420
- span.woo-feed-docs {
1421
- font-weight: bold;
1422
- color: #f18500;
1423
- }
1424
- &:hover {
1425
- span.woo-feed-docs {
1426
- color: #ce7304;
1427
- }
1428
- }
1429
- }
1430
- li.current {
1431
- span.woo-feed-docs {
1432
- color: #ce7304;
1433
- }
1434
- }
1435
- }
1436
- .wapk-admin {
1437
- .wapk-feed-docs {
1438
- .postbox {
1439
- .hndle {
1440
- cursor: default;
1441
- }
1442
- }
1443
- }
1444
- }
1445
-
1446
- /** Admin Call-To-Action **/
1447
- .wapk-cta {
1448
- position: relative;
1449
- display: flex;
1450
- width: 100%;
1451
- padding: 100px 15px;
1452
- background: linear-gradient(45deg, #6CD5FF 33%, #c2efef 100%);
1453
- justify-content: center;
1454
- align-items: center;
1455
- &-icon {
1456
- .dashicons {
1457
- font-size: 100px;
1458
- width: 100px;
1459
- height: auto;
1460
- margin: 0 10px -8px 0;
1461
- color: #02658c;
1462
- }
1463
- }
1464
- &-content {
1465
- width: 50%;
1466
- h2 {
1467
- font-size: 2em;
1468
- margin: 0.5em 0;
1469
- }
1470
- }
1471
- &-action {
1472
- a.wapk-button {
1473
- font-size: 24px;
1474
- height: auto !important;
1475
- padding: 10px 20px;
1476
- }
1477
- }
1478
- }
1479
-
1480
- @media (max-width: 600px) {
1481
- .wapk-cta {
1482
- display: block;
1483
- text-align: center;
1484
- padding: 4em 0;
1485
- &-content {
1486
- width: 100%;
1487
- margin: 2em 0;
1488
- }
1489
- }
1490
- }
1491
-
1492
- /** Override .wp-core-ui .wapk-button styles with prefix .wapk-admin **/
1493
- /* Button Skin */
1494
- .wapk-button {
1495
- color: #00D4D4;
1496
- border-color: #00D4D4;
1497
- display: inline-block;
1498
- text-decoration: none;
1499
- font-size: 13px;
1500
- line-height: 2.15384615;
1501
- min-height: 30px;
1502
- margin: 0;
1503
- padding: 0 10px;
1504
- cursor: pointer;
1505
- border-width: 1px;
1506
- border-style: solid;
1507
- -webkit-appearance: none;
1508
- border-radius: 3px;
1509
- white-space: nowrap;
1510
- box-sizing: border-box;
1511
- >svg {
1512
- width: 15px;
1513
- margin-left: 5px;
1514
- fill: #00D4D4;
1515
- }
1516
- >.dashicons {
1517
- color: #00D4D4;
1518
- }
1519
- &:hover {
1520
- border-color: #00bbbb;
1521
- color: #00bbbb;
1522
- >svg {
1523
- fill: #00bbbb;
1524
- }
1525
- >.dashicons {
1526
- color: #00bbbb;
1527
- }
1528
- }
1529
- &:focus {
1530
- border-color: #00D4D4;
1531
- color: #00bbbb;
1532
- box-shadow: 0 0 0 1px #00D4D4;
1533
- >svg {
1534
- fill: #00bbbb;
1535
- }
1536
- >.dashicons {
1537
- color: #00bbbb;
1538
- }
1539
- }
1540
- &:active {
1541
- background: #00bbbb;
1542
- border-color: #00bbbb;
1543
- }
1544
- &-secondary {
1545
- color: #00D4D4;
1546
- border-color: #00D4D4;
1547
- display: inline-block;
1548
- text-decoration: none;
1549
- font-size: 13px;
1550
- line-height: 2.15384615;
1551
- min-height: 30px;
1552
- margin: 0;
1553
- padding: 0 10px;
1554
- cursor: pointer;
1555
- border-width: 1px;
1556
- border-style: solid;
1557
- -webkit-appearance: none;
1558
- border-radius: 3px;
1559
- white-space: nowrap;
1560
- box-sizing: border-box;
1561
- >svg {
1562
- width: 15px;
1563
- margin-left: 5px;
1564
- fill: #00D4D4;
1565
- }
1566
- >.dashicons {
1567
- color: #00D4D4;
1568
- }
1569
- &:hover {
1570
- border-color: #00bbbb;
1571
- color: #00bbbb;
1572
- >svg {
1573
- fill: #00bbbb;
1574
- }
1575
- >.dashicons {
1576
- color: #00bbbb;
1577
- }
1578
- }
1579
- &:focus {
1580
- border-color: #00D4D4;
1581
- color: #00bbbb;
1582
- box-shadow: 0 0 0 1px #00D4D4;
1583
- >svg {
1584
- fill: #00bbbb;
1585
- }
1586
- >.dashicons {
1587
- color: #00bbbb;
1588
- }
1589
- }
1590
- }
1591
- &-primary {
1592
- display: inline-block;
1593
- text-decoration: none;
1594
- font-size: 13px;
1595
- line-height: 2.15384615;
1596
- min-height: 30px;
1597
- margin: 0;
1598
- padding: 0 10px;
1599
- cursor: pointer;
1600
- border-width: 1px;
1601
- border-style: solid;
1602
- -webkit-appearance: none;
1603
- border-radius: 3px;
1604
- white-space: nowrap;
1605
- box-sizing: border-box;
1606
- background: #00D4D4;
1607
- border-color: #00D4D4;
1608
- color: #fff;
1609
- box-shadow: 0 1px 0 #00bbbb;
1610
- text-shadow: 0 -1px 1px #00bbbb, 1px 0 1px #00bbbb, 0 1px 1px #00bbbb, -1px 0 1px #00bbbb;
1611
- >svg {
1612
- fill: #fff;
1613
- }
1614
- &:hover {
1615
- background: #00e3e3;
1616
- border-color: #00c5c5;
1617
- color: #fff;
1618
- >svg {
1619
- fill: #fff;
1620
- }
1621
- }
1622
- &:focus {
1623
- background: #00e3e3;
1624
- border-color: #00c5c5;
1625
- color: #fff;
1626
- box-shadow: 0 0 0 1px #fff, 0 0 0 3px #00D4D4;
1627
- >svg {
1628
- fill: #fff;
1629
- }
1630
- }
1631
- &:active {
1632
- background: #00bbbb;
1633
- border-color: #00bbbb;
1634
- color: #fff;
1635
- >svg {
1636
- fill: #fff;
1637
- }
1638
- }
1639
- &:disabled {
1640
- color: #c7d1d1 !important;
1641
- background: #22ffff !important;
1642
- border-color: #22ffff !important;
1643
- text-shadow: none !important;
1644
- >svg {
1645
- fill: #c7d1d1 !important;
1646
- }
1647
- }
1648
- }
1649
- &.hover {
1650
- border-color: #00bbbb;
1651
- color: #00bbbb;
1652
- >svg {
1653
- fill: #00bbbb;
1654
- }
1655
- >.dashicons {
1656
- color: #00bbbb;
1657
- }
1658
- }
1659
- &.focus {
1660
- border-color: #00D4D4;
1661
- color: #00bbbb;
1662
- box-shadow: 0 0 0 1px #00D4D4;
1663
- >svg {
1664
- fill: #00bbbb;
1665
- }
1666
- >.dashicons {
1667
- color: #00bbbb;
1668
- }
1669
- }
1670
- &.active {
1671
- border-color: #00bbbb;
1672
- color: #00bbbb;
1673
- box-shadow: inset 0 2px 5px -3px #00bbbb;
1674
- &:focus {
1675
- border-color: #00bbbb;
1676
- color: #00bbbb;
1677
- box-shadow: inset 0 2px 5px -3px #00bbbb;
1678
- >svg {
1679
- fill: #00bbbb;
1680
- }
1681
- >.dashicons {
1682
- color: #00bbbb;
1683
- }
1684
- }
1685
- &:hover {
1686
- border-color: #00bbbb;
1687
- color: #00bbbb;
1688
- box-shadow: inset 0 2px 5px -3px #00bbbb;
1689
- >svg {
1690
- fill: #00bbbb;
1691
- }
1692
- >.dashicons {
1693
- color: #00bbbb;
1694
- }
1695
- }
1696
- >svg {
1697
- fill: #00bbbb;
1698
- }
1699
- >.dashicons {
1700
- color: #00bbbb;
1701
- }
1702
- }
1703
- &-primary {
1704
- &.active {
1705
- background: #00D4D4;
1706
- color: #fff;
1707
- border-color: #008888;
1708
- box-shadow: inset 0 2px 5px -3px black;
1709
- &:focus {
1710
- background: #00D4D4;
1711
- color: #fff;
1712
- border-color: #008888;
1713
- box-shadow: inset 0 2px 5px -3px black;
1714
- >svg {
1715
- fill: #fff;
1716
- }
1717
- }
1718
- &:hover {
1719
- background: #00D4D4;
1720
- color: #fff;
1721
- border-color: #008888;
1722
- box-shadow: inset 0 2px 5px -3px black;
1723
- >svg {
1724
- fill: #fff;
1725
- }
1726
- }
1727
- >svg {
1728
- fill: #fff;
1729
- }
1730
- }
1731
- &[disabled] {
1732
- color: #c7d1d1 !important;
1733
- background: #22ffff !important;
1734
- border-color: #22ffff !important;
1735
- text-shadow: none !important;
1736
- >svg {
1737
- fill: #c7d1d1 !important;
1738
- }
1739
- }
1740
- &.wapk-button-primary-disabled {
1741
- color: #c7d1d1 !important;
1742
- background: #22ffff !important;
1743
- border-color: #22ffff !important;
1744
- text-shadow: none !important;
1745
- >svg {
1746
- fill: #c7d1d1 !important;
1747
- }
1748
- }
1749
- &.disabled {
1750
- color: #c7d1d1 !important;
1751
- background: #22ffff !important;
1752
- border-color: #22ffff !important;
1753
- text-shadow: none !important;
1754
- >svg {
1755
- fill: #c7d1d1 !important;
1756
- }
1757
- }
1758
- &.wapk-button-hero {
1759
- box-shadow: 0 2px 0 #00bbbb;
1760
- &:focus {
1761
- box-shadow: 0 2px 0 #00bbbb, 0 1px 0 #00c5c5, 0 0 2px 1px #00eeee;
1762
- }
1763
- &:active {
1764
- box-shadow: inset 0 3px 0 #00a1a1;
1765
- }
1766
- &.active {
1767
- box-shadow: inset 0 3px 0 #00a1a1;
1768
- &:hover, &:focus {
1769
- box-shadow: inset 0 3px 0 #00a1a1;
1770
- }
1771
- }
1772
- }
1773
- }
1774
- &-group {
1775
- >.wapk-button.active {
1776
- border-color: #00D4D4;
1777
- }
1778
- }
1779
- }
1780
-
1781
- /* Button Sizes */
1782
- .wapk-button.wapk-button-xl {
1783
- height: 30px;
1784
- line-height: 28px;
1785
- padding: 0 12px 2px;
1786
- }
1787
- .wapk-button-group.wapk-button-xl {
1788
- .wapk-button {
1789
- height: 30px;
1790
- line-height: 28px;
1791
- padding: 0 12px 2px;
1792
- }
1793
- }
1794
- .wapk-button.wapk-button-hero {
1795
- font-size: 18px;
1796
- height: 50px;
1797
- line-height: 48px;
1798
- padding: 0 36px;
1799
- min-height: 46px;
1800
- }
1801
- .wapk-button-group.wapk-button-hero {
1802
- .wapk-button {
1803
- font-size: 18px;
1804
- height: 50px;
1805
- line-height: 48px;
1806
- padding: 0 36px;
1807
- min-height: 46px;
1808
- }
1809
- }
1810
-
1811
- @media screen and (min-width: 782px) {
1812
- th#status,
1813
- th#provider {
1814
- width: 80px;
1815
- }
1816
- th#type {
1817
- width: 50px;
1818
- }
1819
- th#option_name {
1820
- width: 100px;
1821
- }
1822
- td.option_name.column-option_name {
1823
- >span {
1824
- &:first-child {
1825
- display: none;
1826
- }
1827
- }
1828
- }
1829
- th#last_updated {
1830
- width: 90px;
1831
- }
1832
- th#view {
1833
- width: 135px;
1834
- }
1835
- }
1836
- @media screen and (min-width: 960px) {
1837
- th#status, th#provider {
1838
- width: 100px;
1839
- }
1840
- th#type {
1841
- width: 80px;
1842
- }
1843
- th#option_name {
1844
- width: 150px;
1845
- }
1846
- th#last_updated {
1847
- width: 140px;
1848
- }
1849
- }
1850
- @media screen and (max-width: 782px) {
1851
- table.wf-info-table {
1852
- margin-top: 10px;
1853
- th {
1854
- &:first-child {
1855
- img {
1856
- margin: 0 auto;
1857
- display: block;
1858
- }
1859
- }
1860
- }
1861
- }
1862
- .wapk-button.wapk-button-xl {
1863
- padding: 6px 14px;
1864
- line-height: normal;
1865
- font-size: 14px;
1866
- vertical-align: middle;
1867
- height: auto;
1868
- margin-bottom: 4px;
1869
- }
1870
- }
1871
-
1872
- .wapk-feed-docs .wapk-feed-cta {
1873
- margin: 0;
1874
- }
1875
-
1876
- .campaign_configurator {
1877
- background: #FFF;
1878
- padding: 20px 0;
1879
- table {
1880
- margin: 0 auto;
1881
- width: 51%;
1882
- min-width: 574px;
1883
- border: none;
1884
- box-shadow: none;
1885
- }
1886
- th {
1887
- min-width: 120px;
1888
- }
1889
- }
1890
-
1891
- @media screen and (max-width: 782px) {
1892
- .campaign_configurator {
1893
- padding: 0;
1894
- table {
1895
- width: auto;
1896
- min-width: auto;
1897
- max-width: 100%;
1898
- }
1899
- th {
1900
- min-width: auto;
1901
- }
1902
- }
1903
- }
1904
-
1905
-
1906
- #wf-tab-content-config {
1907
- td {
1908
- > input:not([type="checkbox"]):not([type="radio"]),
1909
- > select,
1910
- > textarea {
1911
- width: 100% !important;
1912
- }
1913
- }
1914
- }
1915
-
1916
- .woo-feed-filters {
1917
- td {
1918
- > div {
1919
- &:nth-child(2n):not(.clear):not(.selectize):not(.counter) {
1920
- width: 120px;
1921
- display: block;
1922
- }
1923
- &:not(.clear) {
1924
- float: left;
1925
- margin-right: 10px;
1926
- }
1927
- }
1928
- }
1929
- tr {
1930
- > td {
1931
- &:first-child {
1932
- width: 290px;
1933
- padding-left: 40px;
1934
- }
1935
- }
1936
- }
1937
- }
1938
-
1939
- .woo-feed-filters,
1940
- .woo-feed-ftp {
1941
- margin: 15px auto 25px;
1942
- }
1943
- .wf_clean_cache_wrapper {
1944
- display: flex;
1945
- margin-left: auto;
1946
- }
1947
- @keyframes LoaderClockWise {
1948
- from {
1949
- transform: rotate(0deg);
1950
- }
1951
- to {
1952
- transform: rotate(360deg);
1953
- }
1954
- }
1955
- .woo-feed-cache-loader {
1956
- width: 18px;
1957
- margin-right: 5px;
1958
- animation: LoaderClockWise 1s linear infinite;
1959
- -webkit-animation: LoaderClockWise 1s linear infinite;
1960
- display: none;
1961
- }
1962
- .woo-feed-table-heading .woo-feed-table-heading-title {
1963
- float: left;
1964
- margin-right: auto;
1965
- display: inline-block;
1966
- line-height: 30px;
1967
- }
1968
- .woo-feed-table-heading .wf_clean_cache_wrapper {
1969
- float: right;
1970
- font-weight: normal;
1971
- }
1972
- .wf_clean_cache_wrapper button {
1973
- background: linear-gradient(125deg,#eb4d4b 0,#ff9671 140%);
1974
- color: #fff;
1975
- border: none;
1976
- font-weight: 500;
1977
- display: inline-block;
1978
- text-decoration: none;
1979
- font-size: 13px;
1980
- line-height: 2.15384615;
1981
- min-height: 30px;
1982
- margin: 0;
1983
- padding: 0 10px;
1984
- border-radius: 3px;
1985
- cursor: pointer;
1986
- outline: none;
1987
- }
1988
-
1989
- .wf_clean_cache_wrapper button:hover {
1990
- background: #ff7979;
1991
- color: #fff;
1992
- }
1993
-
1994
- input {
1995
- &[type="submit"] {
1996
- &[data-id="wf_action_submit"] {
1997
- background: linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%);
1998
- color: #fff;
1999
- border: 1px;
2000
- padding: 0 20px;
2001
- &:hover {
2002
- background: linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%);
2003
- color: #fff;
2004
- }
2005
- }
2006
- }
2007
- }
2008
-
2009
- //thickbox Style
2010
- .woo-import-popup-body {
2011
- #TB_window {
2012
- width: 500px !important;
2013
-
2014
- #TB_title {
2015
- border: none;
2016
- background: #fff;
2017
- text-align: center;
2018
- display: flex;
2019
- justify-content: center;
2020
- align-items: center;
2021
- height: 35px !important;
2022
- #TB_ajaxWindowTitle {
2023
- color: #30336b;
2024
- font-weight: 700;
2025
- }
2026
- }
2027
-
2028
- #TB_closeWindowButton {
2029
- top: -14.5px;
2030
- right: -14.5px;
2031
- border: none;
2032
- outline: 0;
2033
- .tb-close-icon {
2034
- background: #ff5e55;
2035
- color: #fff;
2036
- border-radius: 50%;
2037
- }
2038
-
2039
- &:focus {
2040
- outline: 0;
2041
- border: 0;
2042
- }
2043
- }
2044
-
2045
- #TB_ajaxContent {
2046
- position: relative;
2047
- width: 100% !important;
2048
- height: auto !important;
2049
- border: none;
2050
- box-sizing: border-box;
2051
- overflow: hidden;
2052
- background: #f7fcff;
2053
- padding: 30px 20px;
2054
- &:before {
2055
- content: '';
2056
- width: 115%;
2057
- display: block;
2058
- background: #4bcffa;
2059
- position: absolute;
2060
- height: 130%;
2061
- z-index: 0;
2062
- left: -36%;
2063
- top: -85px;
2064
- transform: rotate(115deg);
2065
- }
2066
-
2067
- table {
2068
- border: none;
2069
- position: relative;
2070
- z-index: 1;
2071
- border-radius: 3px;
2072
- text-align: center;
2073
- padding: 20px;
2074
- box-shadow: 0px 12px 20px -17px #000;
2075
-
2076
- input {
2077
- width: 60%;
2078
- &:focus {
2079
- outline: 2px solid #68B8F7;
2080
- }
2081
- &[type="file"] {
2082
- padding: 3px 0;
2083
- cursor: pointer;
2084
- }
2085
- &[type="text"] {
2086
- border-radius: 25px;
2087
- font-size: 14px;
2088
- padding: 1px 20px;
2089
- text-align: center;
2090
- }
2091
- &[type="submit"] {
2092
- background: #17c0eb;
2093
- border-radius: 25px;
2094
- border: 0;
2095
- box-shadow: 1px 4px 7px -3px #45364A;
2096
- font-weight: 600;
2097
- transition: .3s ease;
2098
-
2099
- &:hover {
2100
- transform: translateY(-2px);
2101
- }
2102
- }
2103
- }
2104
- }
2105
- }
2106
- }
2107
- }
2108
-
2109
- /* Woo Feed Notice Style */
2110
- .woo-feed-notice {
2111
- position: relative;
2112
- .woo-feed-review-notice-logo {
2113
- width: 90px;
2114
- height: 90px;
2115
- float: left;
2116
- margin-right: 5px;
2117
- background: url("../images/woo-feed-logo.svg") no-repeat;
2118
- }
2119
-
2120
- .woo-feed-review-btn-dismiss {
2121
- display: flex;
2122
- justify-content: center;
2123
- align-content: center;
2124
- position: absolute;
2125
- top: 7px;
2126
- right: 7px;
2127
- background: transparent;
2128
- border: none;
2129
- cursor: pointer;
2130
-
2131
- span {
2132
- line-height: 18px;
2133
- }
2134
-
2135
- &:before {
2136
- background: 0 0;
2137
- color: #787c82;
2138
- content: "\f153";
2139
- display: block;
2140
- font: normal 16px/20px dashicons;
2141
- speak: never;
2142
- height: 20px;
2143
- text-align: center;
2144
- width: 20px;
2145
- -webkit-font-smoothing: antialiased;
2146
- }
2147
-
2148
- &:hover:before {
2149
- color: #d63638;
2150
- }
2151
- }
2152
- }
2153
-
2154
- /* Status Page Style */
2155
- .woo-feed-status-table-wrapper {
2156
- .woo-feed-status-table {
2157
- width: 100%;
2158
- max-width: 900px;
2159
- border-collapse: collapse;
2160
- border-spacing: 0.5rem;
2161
- box-shadow: 0px 0px 20px rgba(0,0,0,0.10);
2162
-
2163
- tr {
2164
- &:nth-child(even) {
2165
- background: #f1f1f1;
2166
- }
2167
-
2168
- &:nth-child(odd) {
2169
- background: #fafafc;
2170
- }
2171
-
2172
- th {
2173
- background: #353b48;
2174
- color: #fff;
2175
-
2176
- &.woo-feed-status-message-header {
2177
- display: flex;
2178
- justify-content: space-between;
2179
- align-items: center;
2180
-
2181
- #woo-feed-copy-status-btn {
2182
- background: linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%);
2183
- border: none;
2184
- }
2185
- }
2186
-
2187
- }
2188
-
2189
- th,td {
2190
- padding: 0.5rem 20px;
2191
- text-align: left;
2192
- }
2193
-
2194
- td {
2195
- &.woo-feed-status-page-btn-group {
2196
- display: flex;
2197
- justify-content: space-between;
2198
- align-items: center;
2199
-
2200
- .wf_clean_cache_wrapper {
2201
- margin: initial;
2202
- }
2203
-
2204
- button, input[type="button"] {
2205
- height: 38px;
2206
- padding: 0 30px;
2207
- font-size: 16px;
2208
- font-weight: 500;
2209
- border: none;
2210
- outline: 0;
2211
- }
2212
- }
2213
- }
2214
- }
2215
- }
2216
- }
2217
-
2218
- input[id^="woo_feed_identifier_"] {
2219
- display: block;
2220
- width: 100% !important;
2221
- }
2222
-
2223
-
2224
- // Brand taxonomy styles
2225
-
2226
- #taxonomy-woo-feed-brand #newwoo-feed-brand_parent,
2227
- .taxonomy-woo-feed-brand .form-field.term-parent-wrap {
2228
- display: none;
2229
- }
2230
-
2231
- .wapk-admin {
2232
- .switch {
2233
- position: relative;
2234
- display: inline-block;
2235
- width: 55px;
2236
- height: 28px;
2237
- }
2238
-
2239
- .switch input {
2240
- opacity: 0;
2241
- width: 0;
2242
- height: 0;
2243
- }
2244
-
2245
- .slider {
2246
- position: absolute;
2247
- cursor: pointer;
2248
- top: 0;
2249
- left: 0;
2250
- right: 0;
2251
- bottom: 0;
2252
- background-color: #ccc;
2253
- -webkit-transition: .4s;
2254
- transition: .4s;
2255
- }
2256
-
2257
- .slider:before {
2258
- position: absolute;
2259
- content: "";
2260
- height: 20px;
2261
- width: 20px;
2262
- left: 4px;
2263
- bottom: 4px;
2264
- background-color: white;
2265
- -webkit-transition: .4s;
2266
- transition: .4s;
2267
- }
2268
-
2269
- input:checked + .slider {
2270
- background: linear-gradient(125deg,#3cb0fd 0,#6c5ce7 140%);
2271
- }
2272
-
2273
- input:focus + .slider {
2274
- box-shadow: 0 0 1px #2196F3;
2275
- }
2276
-
2277
- input:checked + .slider:before {
2278
- -webkit-transform: translateX(26px);
2279
- -ms-transform: translateX(26px);
2280
- transform: translateX(26px);
2281
- }
2282
-
2283
- .slider.round {
2284
- border-radius: 34px;
2285
- }
2286
-
2287
- .slider.round:before {
2288
- border-radius: 50%;
2289
- }
2290
- }
2291
-
2292
- .woo-feed-category-mapping-config-table {
2293
- position: relative;
2294
-
2295
- .woo-feed-cat-map-spinner {
2296
- display: flex;
2297
- justify-content: center;
2298
- width: 100%;
2299
- height: 100%;
2300
- position: absolute;
2301
- top: 0;
2302
- left: 0;
2303
- background: rgb(235, 235, 235 , 0.90);
2304
- z-index: 999;
2305
- padding-top: 250px;
2306
- }
2307
- }
2308
-
2309
- span[id*="cat-map-"] {
2310
- cursor: pointer;
2311
- position: relative;
2312
- top: 5px;
2313
- }
2314
- //.wapk-selectize-item {
2315
- // background: #fff !important;
2316
- // border-color: #000 !important;
2317
- // color: #303030 !important;
2318
- // font-weight: 400 !important;
2319
- //}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/images/features/3rd-party-plugin-support.svg CHANGED
@@ -1,5 +1,5 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <svg width="594px" height="340px" viewBox="0 0 594 340" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
  <!-- Generator: Sketch 59 (86127) - https://sketch.com -->
4
  <title>3rd Party Plugin Support</title>
5
  <desc>Created with Sketch.</desc>
1
  <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="594px" height="340px" viewBox="0 0 594 340" version="1.1" xmlns="http://www.w3.org/2000/svg">
3
  <!-- Generator: Sketch 59 (86127) - https://sketch.com -->
4
  <title>3rd Party Plugin Support</title>
5
  <desc>Created with Sketch.</desc>
admin/images/features/category-mapping.svg CHANGED
@@ -1,5 +1,5 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <svg width="594px" height="340px" viewBox="0 0 594 340" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
  <!-- Generator: Sketch 59 (86127) - https://sketch.com -->
4
  <title>Category Mapping</title>
5
  <desc>Created with Sketch.</desc>
1
  <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="594px" height="340px" viewBox="0 0 594 340" version="1.1" xmlns="http://www.w3.org/2000/svg">
3
  <!-- Generator: Sketch 59 (86127) - https://sketch.com -->
4
  <title>Category Mapping</title>
5
  <desc>Created with Sketch.</desc>
admin/images/features/customer-support.svg CHANGED
@@ -1,5 +1,5 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <svg width="594px" height="340px" viewBox="0 0 594 340" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
  <!-- Generator: Sketch 59 (86127) - https://sketch.com -->
4
  <title>Premium customer support</title>
5
  <desc>Created with Sketch.</desc>
1
  <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="594px" height="340px" viewBox="0 0 594 340" version="1.1" xmlns="http://www.w3.org/2000/svg">
3
  <!-- Generator: Sketch 59 (86127) - https://sketch.com -->
4
  <title>Premium customer support</title>
5
  <desc>Created with Sketch.</desc>
admin/images/features/multilingual-feed.svg CHANGED
@@ -1,5 +1,5 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <svg width="594px" height="340px" viewBox="0 0 594 340" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
  <!-- Generator: Sketch 59 (86127) - https://sketch.com -->
4
  <title>Multilingual Feed</title>
5
  <desc>Created with Sketch.</desc>
1
  <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="594px" height="340px" viewBox="0 0 594 340" version="1.1" xmlns="http://www.w3.org/2000/svg">
3
  <!-- Generator: Sketch 59 (86127) - https://sketch.com -->
4
  <title>Multilingual Feed</title>
5
  <desc>Created with Sketch.</desc>
admin/images/get-woo-feed-pro.svg CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0" encoding="utf-8"?>
2
  <!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
- <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
- viewBox="0 0 180 42" style="enable-background:new 0 0 180 42;" xml:space="preserve">
5
  <style type="text/css">
6
  .st0{fill:url(#SVGID_1_);}
7
  .st1{fill:#FFFFFF;}
1
  <?xml version="1.0" encoding="utf-8"?>
2
  <!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
4
+ viewBox="0 0 180 42" style="enable-background:new 0 0 180 42;" xml:space="preserve">
5
  <style type="text/css">
6
  .st0{fill:url(#SVGID_1_);}
7
  .st1{fill:#FFFFFF;}
admin/images/payment-options/amex.svg CHANGED
@@ -1,5 +1,6 @@
1
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
- <svg viewBox="0 0 752 471" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" preserveAspectRatio="xMidYMid meet">
 
3
  <!-- Generator: Sketch 3.3.1 (12005) - http://www.bohemiancoding.com/sketch -->
4
  <title>Slice 1</title>
5
  <desc>Created with Sketch.</desc>
1
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg viewBox="0 0 752 471" version="1.1" xmlns="http://www.w3.org/2000/svg"
3
+ xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" preserveAspectRatio="xMidYMid meet">
4
  <!-- Generator: Sketch 3.3.1 (12005) - http://www.bohemiancoding.com/sketch -->
5
  <title>Slice 1</title>
6
  <desc>Created with Sketch.</desc>
admin/images/payment-options/diners.svg CHANGED
@@ -1,5 +1,6 @@
1
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
- <svg viewBox="0 0 750 471" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" preserveAspectRatio="xMidYMid meet">
 
3
  <!-- Generator: Sketch 3.3.2 (12043) - http://www.bohemiancoding.com/sketch -->
4
  <title>diners</title>
5
  <desc>Created with Sketch.</desc>
1
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg viewBox="0 0 750 471" version="1.1" xmlns="http://www.w3.org/2000/svg"
3
+ xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" preserveAspectRatio="xMidYMid meet">
4
  <!-- Generator: Sketch 3.3.2 (12043) - http://www.bohemiancoding.com/sketch -->
5
  <title>diners</title>
6
  <desc>Created with Sketch.</desc>
admin/images/payment-options/discover.svg CHANGED
@@ -1,5 +1,6 @@
1
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
- <svg viewBox="0 0 780 501" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" preserveAspectRatio="xMidYMid meet">
 
3
  <!-- Generator: Sketch 3.3.2 (12043) - http://www.bohemiancoding.com/sketch -->
4
  <title>discover</title>
5
  <desc>Created with Sketch.</desc>
1
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg viewBox="0 0 780 501" version="1.1" xmlns="http://www.w3.org/2000/svg"
3
+ xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" preserveAspectRatio="xMidYMid meet">
4
  <!-- Generator: Sketch 3.3.2 (12043) - http://www.bohemiancoding.com/sketch -->
5
  <title>discover</title>
6
  <desc>Created with Sketch.</desc>
admin/images/payment-options/jcb.svg CHANGED
@@ -1,5 +1,6 @@
1
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
- <svg viewBox="0 0 750 471" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" preserveAspectRatio="xMidYMid meet">
 
3
  <!-- Generator: Sketch 3.3.1 (12005) - http://www.bohemiancoding.com/sketch -->
4
  <title>Slice 1</title>
5
  <desc>Created with Sketch.</desc>
1
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg viewBox="0 0 750 471" version="1.1" xmlns="http://www.w3.org/2000/svg"
3
+ xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" preserveAspectRatio="xMidYMid meet">
4
  <!-- Generator: Sketch 3.3.1 (12005) - http://www.bohemiancoding.com/sketch -->
5
  <title>Slice 1</title>
6
  <desc>Created with Sketch.</desc>
admin/images/payment-options/mastercard.svg CHANGED
@@ -1,5 +1,5 @@
1
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
- <svg viewBox="0 0 750 471" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet">
3
  <!-- Generator: Sketch 39.1 (31720) - http://www.bohemiancoding.com/sketch -->
4
  <title>Slice 1</title>
5
  <desc>Created with Sketch.</desc>
1
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg viewBox="0 0 750 471" version="1.1" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet">
3
  <!-- Generator: Sketch 39.1 (31720) - http://www.bohemiancoding.com/sketch -->
4
  <title>Slice 1</title>
5
  <desc>Created with Sketch.</desc>
admin/images/payment-options/visa.svg CHANGED
@@ -1,5 +1,6 @@
1
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
- <svg viewBox="0 0 750 471" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" preserveAspectRatio="xMidYMid meet">
 
3
  <!-- Generator: Sketch 3.3.1 (12005) - http://www.bohemiancoding.com/sketch -->
4
  <title>Slice 1</title>
5
  <desc>Created with Sketch.</desc>
1
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg viewBox="0 0 750 471" version="1.1" xmlns="http://www.w3.org/2000/svg"
3
+ xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" preserveAspectRatio="xMidYMid meet">
4
  <!-- Generator: Sketch 3.3.1 (12005) - http://www.bohemiancoding.com/sketch -->
5
  <title>Slice 1</title>
6
  <desc>Created with Sketch.</desc>
admin/images/woo-feed-black-friday.svg CHANGED
@@ -1,4 +1,4 @@
1
- <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1221 72.32">
2
  <defs>
3
  <style>
4
  .cls-1 {
1
+ <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1221 72.32">
2
  <defs>
3
  <style>
4
  .cls-1 {
admin/images/woo-feed-icon.svg CHANGED
@@ -1,5 +1,5 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <svg width="58px" height="75px" viewBox="0 0 58 75" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
  <!-- Generator: Sketch 61 (89581) - https://sketch.com -->
4
  <title>file-icon copy</title>
5
  <desc>Created with Sketch.</desc>
1
  <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="58px" height="75px" viewBox="0 0 58 75" version="1.1" xmlns="http://www.w3.org/2000/svg">
3
  <!-- Generator: Sketch 61 (89581) - https://sketch.com -->
4
  <title>file-icon copy</title>
5
  <desc>Created with Sketch.</desc>
admin/images/woo-feed-lite.svg CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0" encoding="utf-8"?>
2
  <!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
- <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
- viewBox="0 0 106.3 25" style="enable-background:new 0 0 106.3 25;" xml:space="preserve">
5
  <style type="text/css">
6
  .st0{fill:#0088F7;}
7
  .st1{fill:#FFFFFF;}
1
  <?xml version="1.0" encoding="utf-8"?>
2
  <!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
4
+ viewBox="0 0 106.3 25" style="enable-background:new 0 0 106.3 25;" xml:space="preserve">
5
  <style type="text/css">
6
  .st0{fill:#0088F7;}
7
  .st1{fill:#FFFFFF;}
admin/images/woo-feed-logo.svg CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0" encoding="utf-8"?>
2
  <!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
- <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
- viewBox="0 0 128 128" style="enable-background:new 0 0 128 128;" xml:space="preserve">
5
  <style type="text/css">
6
  .st0{fill:#FFFFFF;}
7
  .st1{fill:#464D56;}
1
  <?xml version="1.0" encoding="utf-8"?>
2
  <!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
4
+ viewBox="0 0 128 128" style="enable-background:new 0 0 128 128;" xml:space="preserve">
5
  <style type="text/css">
6
  .st0{fill:#FFFFFF;}
7
  .st1{fill:#464D56;}
admin/images/woo-feed-pro.svg CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0" encoding="utf-8"?>
2
  <!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
- <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
- viewBox="0 0 104.1 25" style="enable-background:new 0 0 104.1 25;" xml:space="preserve">
5
  <style type="text/css">
6
  .st0{fill:#0088F7;}
7
  .st1{fill:#2F3C50;}
1
  <?xml version="1.0" encoding="utf-8"?>
2
  <!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
4
+ viewBox="0 0 104.1 25" style="enable-background:new 0 0 104.1 25;" xml:space="preserve">
5
  <style type="text/css">
6
  .st0{fill:#0088F7;}
7
  .st1{fill:#2F3C50;}
admin/js/fancy-select.min.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";!function(g,h,v){function f(e,t){var r=this,s=g.extend(!0,{},{options:[],optgroups:[],items:[],placeholder:"",delimiter:",",splitOn:null,persist:!0,diacritics:!0,create:!1,createOnBlur:!1,createFilter:null,highlight:!0,openOnFocus:!0,maxOptions:1e3,maxItems:null,maxItemShow:3,hideSelected:null,addPrecedence:!1,selectOnTab:!1,preload:!1,allowEmptyOption:!1,closeAfterSelect:!1,scrollDuration:60,loadThrottle:300,loadingClass:"loading",dataAttr:"data-data",optgroupField:"optgroup",valueField:"value",labelField:"text",disabledField:"disabled",optgroupLabelField:"label",optgroupValueField:"value",lockOptgroupOrder:!1,sortField:"$order",searchField:["text"],searchConjunction:"and",mode:null,wrapperClass:"selectize-control",inputClass:"selectize-input",dropdownClass:"selectize-dropdown",dropdownContentClass:"selectize-dropdown-content",dropdownParent:null,copyClassesToDropdown:!0,render:{}},t),n=e[0];(n.fancySelect=r).order=0,t=h.getComputedStyle&&h.getComputedStyle(n,null),n=(n=t?t.getPropertyValue("direction"):n.currentStyle&&n.currentStyle.direction)||e.parents("[dir]:first").attr("dir")||"",r.computedStyle=t,/android/i.test(h.navigator.userAgent)||v.createElement("input").validity;var i,l,a,o={},d={readData:function(e){e=r.dataAttr&&e.attr(r.dataAttr);return"string"==typeof e&&e.length?JSON.parse(e):null},addOption:function(e,t){e=g(e);var n,i=r.hash_key(e.val());(i||s.allowEmptyOption)&&(o.hasOwnProperty(i)?t&&((n=o[i][field_optgroup])?g.isArray(n)?n.push(t):o[i][field_optgroup]=[n,t]:o[i][field_optgroup]=t):((n=d.readData(e)||{})[r.settings.labelField]=n[r.settings.labelField]||e.text(),n[r.settings.valueField]=n[r.settings.valueField]||i,n[r.settings.disabledField]=n[r.settings.disabledField]||e.prop("disabled"),n[r.settings.optgroupField]=n[r.settings.optgroupField]||t,n.$order=++r.order,o[i]=n,r.settings.options.push(n),e.is(":selected")&&r.settings.items.push(n)))},addGroup:function(e){var t,n,i,s,l;for((i=(e=g(e)).attr("label"))&&((s=d.readData(e)||{})[r.settings.optgroupLabelField]=i,s[r.settings.optgroupValueField]=i,s[r.settings.disabledField]=e.prop("disabled"),s.$order=++r.order,r.settings.optgroups.push(s)),t=0,n=(l=g("option",e)).length;t<n;t++)d.addOption(l[t],i)}};g.extend(r,{settings:s,$select:e,tabIndex:e.attr("tabindex")||"",tagType:1,rtl:/rtl/i.test(n),multiple:e.attr("multiple"),eventNS:".FancySelect"+ ++f.count,highlightedValue:null,isBlurring:!1,isOpen:!1,isDisabled:!1,isRequired:e.is("[required]"),isInvalid:!1,isLocked:!1,isFocused:!1,isInputHidden:!1,isSetup:!1,isRendered:!1,isShiftDown:!1,isCmdDown:!1,isCtrlDown:!1,ignoreFocus:!1,ignoreBlur:!1,ignoreHover:!1,hasOptions:!1,currentResults:null,lastValue:"",caretPos:0,loading:0,loadedSearches:{},$activeOption:null,$activeItems:[],optgroups:{},options:{},userOptions:{},items:{},renderCache:{},onSearchChange:null===s.loadThrottle?r.onSearchChange:(i=r.onSearchChange,l=s.loadThrottle,function(){var e=this,t=arguments;h.clearTimeout(a),a=h.setTimeout(function(){i.apply(e,t)},l)})}),""===r.settings.placeholder&&(r.settings.placeholder=e.attr("placeholder")||e.attr("data-placeholder"),r.settings.placeholder||r.settings.allowEmptyOption||(r.settings.placeholder=e.children('option[value=""]').text())),r.settings.maxItems=r.multiple?null:1;for(var c=0,p=r.$select.children().length;c<p;c++){var u=r.$select.children()[c].tagName.toLowerCase();"optgroup"===u?d.addGroup(r.$select.children()[c]):"option"===u&&d.addOption(r.$select.children()[c])}r.$wrapper=g('<div class="fancy-picker">').addClass(e.attr("class")),r.computedStyle.hasOwnProperty("width")&&r.$wrapper.css({width:r.computedStyle.width}),r.$outputWrapper=g('<div class="fancy-picker-picked">').appendTo(r.$wrapper),r.originalPlaceholder=g('<span class="fancy-picker-placeholder">').appendTo(r.$outputWrapper),r.dataPlaceholder=g('<span class="fancy-picker-data">').appendTo(r.$outputWrapper),r.dataCountPlaceholder=g('<span class="fancy-picker-count">').appendTo(r.$outputWrapper),r.$dropdown=g('<div class="fancy-picker-ui">').appendTo(r.$wrapper),r.$dropdownContent=g('<div class="fancy-picker-content">').appendTo(r.$dropdown),r.setup()}f.count=0,g.extend(f.prototype,{setup:function(){var i=this;i.revertSettings={$children:i.$select.children().detach(),tabindex:i.$select.attr("tabindex")},i.$select.attr("tabindex",-1).hide().after(i.$wrapper),i.$select.data("FancySelect",i),i.$select.addClass("FancySelectInit"),i.settings.items.sort(function(e,t){return e[i.settings.sortField]-t[i.settings.sortField]}),i.preload&&i.render(),i.updatePlaceholder(),i.updateOriginalInput(),i.$wrapper.on("click"+i.eventNS,".fancy-picker-picked",function(e){i.$select.trigger("show"),i.isRendered||i.render(),i.$wrapper.toggleClass("active"),i.$select.trigger("shown")}),g(v).on("click"+i.eventNS,function(e){g(e.target).closest(i.$wrapper).length||(i.$select.trigger("hide"),i.$wrapper.removeClass("active"),i.$select.trigger("hidden"))}),i.$wrapper.on("click"+i.eventNS,".fancy-picker-option:not(.disabled)",function(e){e.preventDefault();var t=g(this),e=!1,n=i.hash_key(t.data("value"));i.multiple?(t.hasClass("selected")?t.removeClass("selected"):(e=!0,t.addClass("selected")),e?i.settings.items.push(i.getSelectedOptionData(n)):i.settings.items=i.settings.items.filter(function(e){return e[i.settings.valueField]!==n}),i.settings.items.sort(function(e,t){return e[i.settings.sortField]-t[i.settings.sortField]})):(i.$dropdownContent.find(".fancy-picker-option").not(t).removeClass("selected"),t.addClass("selected"),e=!0,i.settings.items=[i.getSelectedOptionData(n)],i.$wrapper.removeClass("active")),i.updatePlaceholder(),i.updateOriginalInput()}),g(h).on("resize"+i.eventNS,function(){var e=h.getComputedStyle&&h.getComputedStyle(i.$select[0],null);e.hasOwnProperty("width")&&i.$wrapper.css({width:e.width})}),i.$select.trigger("initialize")},render:function(){function s(e){return l.isSelected(e)?"fancy-picker-option selected":"fancy-picker-option"}var l=this,r=[],a=l.settings.optgroups,o=l.settings.options;if(a.length)for(var e=0;e<a.length;e++)!function(t){r.push('<div class="fancy-picker-option-group">'),r.push('<div class="fancy-picker-option-group-label">'.concat(a[t][l.settings.labelField],"</div>"));for(var e=o.filter(function(e){return e[l.settings.optgroupField]===a[t][l.settings.valueField]}),n=0;n<e.length;n++){var i=e[t];r.push('<div class="'.concat(s(i[l.settings.valueField]),'" data-value="').concat(i[l.settings.valueField],'">').concat(i[l.settings.labelField],"</div>"))}r.push("</div>")}(e);else for(var t=0;t<o.length;t++){var n=o[t];r.push('<div class="'.concat(s(n[l.settings.valueField]),'" data-value="').concat(n[l.settings.valueField],'">').concat(n[l.settings.labelField],"</div>"))}l.$dropdownContent.html(r.join("")),l.$select.trigger("rendered"),l.isRendered=!0},updatePlaceholder:function(){var t,n=this,i=[],e=n.settings.items,s=e.length>n.settings.maxItemShow?n.settings.maxItemShow-1:n.settings.maxItemShow;return n.originalPlaceholder.text(n.settings.placeholder),e.length?n.originalPlaceholder.hide():n.originalPlaceholder.show(),e.slice(0,s).forEach(function(e){i.push("<span>".concat(e[n.settings.labelField],"</span>"))}),n.dataPlaceholder.html(i.join('<span class="fancy-picker-separator">'.concat(n.settings.delimiter,"</span>"))),e.length>n.settings.maxItemShow?(t=[],e.forEach(function(e){t.push(e[n.settings.labelField])}),n.dataCountPlaceholder.attr("title",t.join(n.settings.delimiter.trim()+" ")),n.dataCountPlaceholder.html("+"+(e.length-s)+" More &hellip;")):(n.dataCountPlaceholder.removeAttr("title"),n.dataCountPlaceholder.html("")),n.$select.trigger("placeholderChanged"),n},updateOriginalInput:function(e){var t=this,n=[],i=!1;e=!0===e;for(var s=t.settings.items,l=0;l<s.length;l++)n.push('<option value="'+s[l][t.settings.valueField]+'" selected="selected">'+s[l][t.settings.labelField]||"</option>"),i=!0;return t.$select.html(n.join("")),!e&&i&&t.$select.trigger("change"),t},getSelectedOptionData:function(t){var n=this,e=n.settings.options.filter(function(e){return e[n.settings.valueField]===t});return!!e.length&&e[0]},isSelected:function(t){var n=this;return 0<n.settings.items.filter(function(e){return e[n.settings.valueField]===t}).length},hash_key:function(e){return e+""},destroy:function(){var e=this;e.$select.trigger("destroy"),e.trigger("destroy"),e.off(),e.$select.html("").append(e.revertSettings.$children).removeAttr("tabindex").removeClass("FancySelectInit").attr({tabindex:e.revertSettings.tabindex}).show(),e.$select.removeData("FancySelect"),e.$wrapper.remove(),0==--f.count&&f.$testInput&&(f.$testInput.remove(),f.$testInput=void 0),g(h).off(e.eventNS),g(v).off(e.eventNS),g(v.body).off(e.eventNS),delete e.$select[0].fancySelect}}),g.extend(f.prototype,{bind:function(e,t){this._events=this._events||{},this._events[e]=this._events[e]||[],this._events[e].push(t)},unbind:function(e,t){this._events=this._events||{},e in this._events!=!1&&this._events[e].splice(this._events[e].indexOf(t),1)},trigger:function(e){if(this._events=this._events||{},e in this._events!=!1)for(var t=0;t<this._events[e].length;t++)this._events[e][t].apply(this,Array.prototype.slice.call(arguments,1))}}),g.fn.fancySelect=function(e){return this.each(function(){this.fancySelect||"select"===this.tagName.toLowerCase()&&new f(g(this),e)})}}(jQuery,window,document);
2
  //# sourceMappingURL=fancy-select.min.js.map
1
+ "use strict";!function(g,h,v){function f(e,t){var n,i,s,r=this,l=g.extend(!0,{},{options:[],optgroups:[],items:[],placeholder:"",delimiter:",",splitOn:null,persist:!0,diacritics:!0,create:!1,createOnBlur:!1,createFilter:null,highlight:!0,openOnFocus:!0,maxOptions:1e3,maxItems:null,maxItemShow:3,hideSelected:null,addPrecedence:!1,selectOnTab:!1,preload:!1,allowEmptyOption:!1,closeAfterSelect:!1,scrollDuration:60,loadThrottle:300,loadingClass:"loading",dataAttr:"data-data",optgroupField:"optgroup",valueField:"value",labelField:"text",disabledField:"disabled",optgroupLabelField:"label",optgroupValueField:"value",lockOptgroupOrder:!1,sortField:"$order",searchField:["text"],searchConjunction:"and",mode:null,wrapperClass:"selectize-control",inputClass:"selectize-input",dropdownClass:"selectize-dropdown",dropdownContentClass:"selectize-dropdown-content",dropdownParent:null,copyClassesToDropdown:!0,render:{}},t),a=(((t=e[0]).fancySelect=r).order=0,h.getComputedStyle&&h.getComputedStyle(t,null)),t=(a?a.getPropertyValue("direction"):t.currentStyle&&t.currentStyle.direction)||e.parents("[dir]:first").attr("dir")||"",o=(r.computedStyle=a,/android/i.test(h.navigator.userAgent)||v.createElement("input").validity,{}),d={readData:function(e){e=r.dataAttr&&e.attr(r.dataAttr);return"string"==typeof e&&e.length?JSON.parse(e):null},addOption:function(e,t){e=g(e);var n,i=r.hash_key(e.val());(i||l.allowEmptyOption)&&(o.hasOwnProperty(i)?t&&((n=o[i][field_optgroup])?g.isArray(n)?n.push(t):o[i][field_optgroup]=[n,t]:o[i][field_optgroup]=t):((n=d.readData(e)||{})[r.settings.labelField]=n[r.settings.labelField]||e.text(),n[r.settings.valueField]=n[r.settings.valueField]||i,n[r.settings.disabledField]=n[r.settings.disabledField]||e.prop("disabled"),n[r.settings.optgroupField]=n[r.settings.optgroupField]||t,n.$order=++r.order,o[i]=n,r.settings.options.push(n),e.is(":selected")&&r.settings.items.push(n)))},addGroup:function(e){var t,n,i,s,l;for((i=(e=g(e)).attr("label"))&&((s=d.readData(e)||{})[r.settings.optgroupLabelField]=i,s[r.settings.optgroupValueField]=i,s[r.settings.disabledField]=e.prop("disabled"),s.$order=++r.order,r.settings.optgroups.push(s)),t=0,n=(l=g("option",e)).length;t<n;t++)d.addOption(l[t],i)}};g.extend(r,{settings:l,$select:e,tabIndex:e.attr("tabindex")||"",tagType:1,rtl:/rtl/i.test(t),multiple:e.attr("multiple"),eventNS:".FancySelect"+ ++f.count,highlightedValue:null,isBlurring:!1,isOpen:!1,isDisabled:!1,isRequired:e.is("[required]"),isInvalid:!1,isLocked:!1,isFocused:!1,isInputHidden:!1,isSetup:!1,isRendered:!1,isShiftDown:!1,isCmdDown:!1,isCtrlDown:!1,ignoreFocus:!1,ignoreBlur:!1,ignoreHover:!1,hasOptions:!1,currentResults:null,lastValue:"",caretPos:0,loading:0,loadedSearches:{},$activeOption:null,$activeItems:[],optgroups:{},options:{},userOptions:{},items:{},renderCache:{},onSearchChange:null===l.loadThrottle?r.onSearchChange:(n=r.onSearchChange,i=l.loadThrottle,function(){var e=this,t=arguments;h.clearTimeout(s),s=h.setTimeout(function(){n.apply(e,t)},i)})}),""===r.settings.placeholder&&(r.settings.placeholder=e.attr("placeholder")||e.attr("data-placeholder"),r.settings.placeholder||r.settings.allowEmptyOption||(r.settings.placeholder=e.children('option[value=""]').text())),r.settings.maxItems=r.multiple?null:1;for(var c=0,p=r.$select.children().length;c<p;c++){var u=r.$select.children()[c].tagName.toLowerCase();"optgroup"===u?d.addGroup(r.$select.children()[c]):"option"===u&&d.addOption(r.$select.children()[c])}r.$wrapper=g('<div class="fancy-picker">').addClass(e.attr("class")),r.computedStyle.hasOwnProperty("width")&&r.$wrapper.css({width:r.computedStyle.width}),r.$outputWrapper=g('<div class="fancy-picker-picked">').appendTo(r.$wrapper),r.originalPlaceholder=g('<span class="fancy-picker-placeholder">').appendTo(r.$outputWrapper),r.dataPlaceholder=g('<span class="fancy-picker-data">').appendTo(r.$outputWrapper),r.dataCountPlaceholder=g('<span class="fancy-picker-count">').appendTo(r.$outputWrapper),r.$dropdown=g('<div class="fancy-picker-ui">').appendTo(r.$wrapper),r.$dropdownContent=g('<div class="fancy-picker-content">').appendTo(r.$dropdown),r.setup()}f.count=0,g.extend(f.prototype,{setup:function(){var i=this;i.revertSettings={$children:i.$select.children().detach(),tabindex:i.$select.attr("tabindex")},i.$select.attr("tabindex",-1).hide().after(i.$wrapper),i.$select.data("FancySelect",i),i.$select.addClass("FancySelectInit"),i.settings.items.sort(function(e,t){return e[i.settings.sortField]-t[i.settings.sortField]}),i.preload&&i.render(),i.updatePlaceholder(),i.updateOriginalInput(),i.$wrapper.on("click"+i.eventNS,".fancy-picker-picked",function(e){i.$select.trigger("show"),i.isRendered||i.render(),i.$wrapper.toggleClass("active"),i.$select.trigger("shown")}),g(v).on("click"+i.eventNS,function(e){g(e.target).closest(i.$wrapper).length||(i.$select.trigger("hide"),i.$wrapper.removeClass("active"),i.$select.trigger("hidden"))}),i.$wrapper.on("click"+i.eventNS,".fancy-picker-option:not(.disabled)",function(e){e.preventDefault();var e=g(this),t=!1,n=i.hash_key(e.data("value"));i.multiple?(e.hasClass("selected")?e.removeClass("selected"):(t=!0,e.addClass("selected")),t?i.settings.items.push(i.getSelectedOptionData(n)):i.settings.items=i.settings.items.filter(function(e){return e[i.settings.valueField]!==n}),i.settings.items.sort(function(e,t){return e[i.settings.sortField]-t[i.settings.sortField]})):(i.$dropdownContent.find(".fancy-picker-option").not(e).removeClass("selected"),e.addClass("selected"),t=!0,i.settings.items=[i.getSelectedOptionData(n)],i.$wrapper.removeClass("active")),i.updatePlaceholder(),i.updateOriginalInput()}),g(h).on("resize"+i.eventNS,function(){var e=h.getComputedStyle&&h.getComputedStyle(i.$select[0],null);e.hasOwnProperty("width")&&i.$wrapper.css({width:e.width})}),i.$select.trigger("initialize")},render:function(){function s(e){return l.isSelected(e)?"fancy-picker-option selected":"fancy-picker-option"}var l=this,r=[],a=l.settings.optgroups,o=l.settings.options;if(a.length)for(var e=0;e<a.length;e++)!function(t){r.push('<div class="fancy-picker-option-group">'),r.push('<div class="fancy-picker-option-group-label">'.concat(a[t][l.settings.labelField],"</div>"));for(var e=o.filter(function(e){return e[l.settings.optgroupField]===a[t][l.settings.valueField]}),n=0;n<e.length;n++){var i=e[t];r.push('<div class="'.concat(s(i[l.settings.valueField]),'" data-value="').concat(i[l.settings.valueField],'">').concat(i[l.settings.labelField],"</div>"))}r.push("</div>")}(e);else for(var t=0;t<o.length;t++){var n=o[t];r.push('<div class="'.concat(s(n[l.settings.valueField]),'" data-value="').concat(n[l.settings.valueField],'">').concat(n[l.settings.labelField],"</div>"))}l.$dropdownContent.html(r.join("")),l.$select.trigger("rendered"),l.isRendered=!0},updatePlaceholder:function(){var t,n=this,i=[],e=n.settings.items,s=e.length>n.settings.maxItemShow?n.settings.maxItemShow-1:n.settings.maxItemShow;return n.originalPlaceholder.text(n.settings.placeholder),e.length?n.originalPlaceholder.hide():n.originalPlaceholder.show(),e.slice(0,s).forEach(function(e){i.push("<span>".concat(e[n.settings.labelField],"</span>"))}),n.dataPlaceholder.html(i.join('<span class="fancy-picker-separator">'.concat(n.settings.delimiter,"</span>"))),e.length>n.settings.maxItemShow?(t=[],e.forEach(function(e){t.push(e[n.settings.labelField])}),n.dataCountPlaceholder.attr("title",t.join(n.settings.delimiter.trim()+" ")),n.dataCountPlaceholder.html("+"+(e.length-s)+" More &hellip;")):(n.dataCountPlaceholder.removeAttr("title"),n.dataCountPlaceholder.html("")),n.$select.trigger("placeholderChanged"),n},updateOriginalInput:function(e){for(var t=this,n=[],i=!1,s=(e=!0===e,t.settings.items),l=0;l<s.length;l++)n.push('<option value="'+s[l][t.settings.valueField]+'" selected="selected">'+s[l][t.settings.labelField]||"</option>"),i=!0;return t.$select.html(n.join("")),!e&&i&&t.$select.trigger("change"),t},getSelectedOptionData:function(t){var n=this,e=n.settings.options.filter(function(e){return e[n.settings.valueField]===t});return!!e.length&&e[0]},isSelected:function(t){var n=this;return 0<n.settings.items.filter(function(e){return e[n.settings.valueField]===t}).length},hash_key:function(e){return e+""},destroy:function(){var e=this;e.$select.trigger("destroy"),e.trigger("destroy"),e.off(),e.$select.html("").append(e.revertSettings.$children).removeAttr("tabindex").removeClass("FancySelectInit").attr({tabindex:e.revertSettings.tabindex}).show(),e.$select.removeData("FancySelect"),e.$wrapper.remove(),0==--f.count&&f.$testInput&&(f.$testInput.remove(),f.$testInput=void 0),g(h).off(e.eventNS),g(v).off(e.eventNS),g(v.body).off(e.eventNS),delete e.$select[0].fancySelect}}),g.extend(f.prototype,{bind:function(e,t){this._events=this._events||{},this._events[e]=this._events[e]||[],this._events[e].push(t)},unbind:function(e,t){this._events=this._events||{},e in this._events!=!1&&this._events[e].splice(this._events[e].indexOf(t),1)},trigger:function(e){if(this._events=this._events||{},e in this._events!=!1)for(var t=0;t<this._events[e].length;t++)this._events[e][t].apply(this,Array.prototype.slice.call(arguments,1))}}),g.fn.fancySelect=function(e){return this.each(function(){this.fancySelect||"select"===this.tagName.toLowerCase()&&new f(g(this),e)})}}(jQuery,window,document);
2
  //# sourceMappingURL=fancy-select.min.js.map
admin/js/fancy-select.min.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["fancy-select.js"],"names":["$","window","document","FancySelect","$select","options","self","settings","extend","defaults","optgroups","items","placeholder","delimiter","splitOn","persist","diacritics","create","createOnBlur","createFilter","highlight","openOnFocus","maxOptions","maxItems","maxItemShow","hideSelected","addPrecedence","selectOnTab","preload","allowEmptyOption","closeAfterSelect","scrollDuration","loadThrottle","loadingClass","dataAttr","optgroupField","valueField","labelField","disabledField","optgroupLabelField","optgroupValueField","lockOptgroupOrder","sortField","searchField","searchConjunction","mode","wrapperClass","inputClass","dropdownClass","dropdownContentClass","dropdownParent","copyClassesToDropdown","render","select","computedStyle","dir","attr","test","navigator","createElement","debounce","delay","timeout","optionsMap","optHelper","readData","$el","data","JSON","addOption","$option","group","option","value","hash_key","arr","isArray","field_optgroup","addGroup","$optgroup","i","n","id","optgroup","$options","tabIndex","tagType","rtl","multiple","eventNS","highlightedValue","isBlurring","isOpen","isDisabled","isRequired","isInvalid","isLocked","isFocused","isInputHidden","isSetup","isRendered","isShiftDown","isCmdDown","isCtrlDown","ignoreFocus","ignoreBlur","ignoreHover","hasOptions","currentResults","lastValue","caretPos","loading","loadedSearches","$activeOption","$activeItems","userOptions","renderCache","onSearchChange","args","fn","apply","children","length","tagName","addClass","$wrapper","width","appendTo","setup","$children","tabindex","hide","after","a","b","e","trigger","target","closest","preventDefault","current","selected","removeClass","getSelectedOptionData","filter","x","sort","$dropdownContent","find","updatePlaceholder","updateOriginalInput","getComputedStyle","hasOwnProperty","optClass","isSelected","this","dropdownItems","push","concat","group_options","item","ii","_loop","_i","html","join","title","placeholderData","originalPlaceholder","text","slice","forEach","dataPlaceholder","dataCountPlaceholder","removeAttr","changed","silent","input","destroy","append","revertSettings","removeData","$testInput","off","body","fancySelect","prototype","bind","event","fct","_events","unbind","indexOf","Array","call","arguments","user_options","jQuery"],"mappings":"cAQA,SAACA,EAAAC,EAAAC,GAWIC,SAAJA,EAAeC,EAAAC,GACd,IAAAC,EAAIA,KAAJC,EAAAA,EA+CCA,QAAQC,EAAKA,GA/CdC,CAEEJ,QAAAA,GACAK,UAAAA,GACAC,MAAAA,GACAC,YAAAA,GACAC,UAAAA,IACAC,QAAAA,KACAC,SAAAA,EACAC,YAAAA,EACAC,QAAAA,EACAC,cAAAA,EACAC,aAAAA,KACAC,WAAAA,EACAC,aAAAA,EACAC,WAAAA,IACAC,SAAAA,KACAC,YAAAA,EACAC,aAAAA,KACAC,eAAAA,EACAC,aAAAA,EACAC,SAAAA,EACAC,kBAAAA,EACAC,kBAAAA,EACAC,eAAAA,GACAC,aAAAA,IACAC,aAAAA,UACAC,SAAAA,YACAC,cAAAA,WACAC,WAAAA,QACAC,WAAAA,OACAC,cAAAA,WACAC,mBAAAA,QACAC,mBAAAA,QACAC,mBAAAA,EACAC,UAAAA,SACAC,YAAAA,CAAAA,QACAC,kBAAAA,MACAC,KAAAA,KACAC,aAAAA,oBACAC,WAAAA,kBACAC,cAAAA,qBACAC,qBAAAA,6BACAC,eAAAA,KACAC,uBAAAA,EACAC,OAAAA,IAEU3C,GA/CZ4C,EAAAA,EAgDCA,IACDA,EAAAA,YAAAA,GACA/C,MAAAA,EACAgD,EAAIA,EAAarD,kBAAAA,EAAGA,iBAA2BA,EAA3B,MAEpBsD,GADAA,EAAIA,EAAMD,EAAaA,iBAAGA,aAAhBA,EAAaD,cAAAA,EAAiDA,aAAuBA,YACzFE,EAAGnD,QAAIA,eAAJoD,KAAIA,QAAV,GACHlD,EAAAA,cAAAA,EAE2B,WAAImD,KAAWA,EAAKxD,UAAOyD,YAAyBxD,EAAWyD,cAATzD,SAAAA,SAAjF,IAEM0D,EAAWC,EAChBC,EAWDC,EAAIA,GAAJC,EAAAA,CAEEC,SAAAA,SAAQC,GACPC,EAAIA,EAAI7D,UAAA4D,EAAGA,KAAiBA,EAAIV,UAEhC,MAAA,iBAAAW,GAAAA,EAAIA,OACHC,KAAAA,MAAOA,GAGR,MAEDC,UAAAA,SAASC,EAAAC,GACRD,EAAAA,EAAAA,GACA,IAsBAE,EAtBAC,EAAIA,EAAKnE,SAAGA,EAAKoE,QACjBD,GAAAlE,EAAIA,oBAKJwD,EAAAA,eAAIA,GACHQ,KACCI,EAAAA,EAAIA,GAAMZ,iBAEV/D,EAAA4E,QAEOA,GAGND,EAAAA,KAAAA,GAFAZ,EAAAA,GAAAA,gBAAWU,CAAAA,EAAOI,GAFlBd,EAAAA,GAAAA,gBAAWU,KAWdD,EAAIA,EAAMR,SAAGA,IAAH,IACVQ,EAAAA,SAAOlE,YAAPkE,EAAAA,EAAmCA,SAAOlE,aAA1CgE,EAAmCA,OACnCE,EAAAA,EAAAA,SAAOlE,YAAPkE,EAAAA,EAAmCA,SAAOlE,aAA1CmE,EACAD,EAAAA,EAAAA,SAAOlE,eAAPkE,EAAAA,EAAsCA,SAAOlE,gBAA7CgE,EAAsCA,KAAuCA,YAC7EE,EAAAA,EAAAA,SAAOlE,eAAPkE,EAAAA,EAAsCA,SAAOlE,gBAA7CiE,EACAC,EAAAA,SAAAA,EAAAlE,MACAyD,EAAAA,GAAAA,EACAzD,EAAAA,SAAAA,QAAKC,KAASF,GAEdiE,EAAAA,GAAIA,cACHhE,EAAAA,SAAAA,MAAKC,KAASI,MAGhBmE,SAAAA,SAAQC,GACP,IAAAC,EAAAA,EAAIA,EAAGC,EAAGC,EAeV,KAbAA,GADAH,EAAAA,EAAAA,IACEA,KAAGA,aAGJI,EAAAA,EAAAA,SAAWnB,IAAXmB,IACAA,EAAAA,SAAS7E,oBAAT6E,EACAA,EAAAA,EAAAA,SAAS7E,oBAAT6E,EACAA,EAAAA,EAAAA,SAAS7E,eAAT6E,EAAQJ,KAAgCA,YACxCI,EAAAA,SAAAA,EAAA7E,MACAA,EAAAA,SAAAA,UAAKC,KAASG,IAKfsE,EAAA,EAAMC,GAFNG,EAAAA,EAAAA,SAAQL,IAEKK,OAAGA,EAAhBH,EAAkCA,IACjCjB,EAAAA,UAAAA,EAAUK,GAAUe,KAKxBpF,EAAAA,OAAAA,EAAAA,CACCO,SAAAA,EACAH,QAAAA,EACAiF,SAAAA,EAAAA,KAAUjF,aAAViF,GACAC,QAAAA,EACAC,IAAAA,OAAAA,KAAK9B,GACL+B,SAAAA,EAAAA,KAAUpF,YACVqF,QAAAA,kBAAAA,EAAStF,MACTuF,iBAAAA,KACAC,YAAAA,EACAC,QAAAA,EACAC,YAAAA,EACAC,WAAAA,EAAAA,GAAY1F,cACZ2F,WAAAA,EACAC,UAAAA,EACAC,WAAAA,EACAC,eAAAA,EACAC,SAAAA,EACAC,YAAAA,EACAC,aAAAA,EACAC,WAAAA,EACAC,YAAAA,EACAC,aAAAA,EACAC,YAAAA,EACAC,aAAAA,EACAC,YAAAA,EACAC,eAAAA,KACAC,UAAAA,GACAC,SAAAA,EACAC,QAAAA,EACAC,eAAAA,GACAC,cAAAA,KACAC,aAAAA,GACAxG,UAAAA,GACAL,QAAAA,GACA8G,YAAAA,GACAxG,MAAAA,GACAyG,YAAAA,GACAC,eAAAA,OAAAA,EAAAA,aAAAA,EAAgB/G,gBAxHXsD,EAwHWA,EAAuDA,eAxHvDC,EAwHgEvD,EAAK+G,aAtHrF,WACC,IAAA/G,EAAAA,KACAgH,EAAAA,UACArH,EAAAA,aAAAA,GACA6D,EAAAA,EAAAA,WAAU7D,WACTsH,EAAAA,MAAAA,EAAGC,IACH3D,OAmHH,KAAAvD,EAAIA,SAAOA,cACVA,EAAAA,SAAAA,YAAAA,EAAAF,KAA4BA,gBAA5BA,EAA4BA,KAA+BA,oBAE3DE,EAAAA,SAAKA,aAALA,EAAIA,SAA+BA,mBAClCA,EAAAA,SAAAA,YAAKC,EAASK,SAAcR,oBAAQqH,SAItCnH,EAAAA,SAAAA,SAAAA,EAAAA,SAAA,KAAA,EAEA,IAAA,IAAA0E,EAAK,EAALC,EAAK3E,EAAYA,QAAGA,WAAHoH,OAAjB1C,EAAAC,EAAAD,IAAA,CACC,IAAA2C,EAAIA,EAAOrH,QAAGA,WAAH0E,GAAGA,QAAwBA,cAElC2C,aAAJA,EACC3D,EAAAA,SAAAA,EAAUc,QAASxE,WAAKF,IACduH,WAFXA,GAGC3D,EAAAA,UAAAA,EAAUK,QAAU/D,WAAKF,IAI3BE,EAAAA,SAAAA,EAAAN,8BAAA4H,SAAiBA,EAA+BA,KAASxH,UAEzDE,EAAAA,cAAIA,eAAKgD,UACRhD,EAAAA,SAAAA,IAAKuH,CACJC,MAAAA,EAAAA,cAAOxH,QAITA,EAAAA,eAAAA,EAAAN,qCAAA+H,SAAuBA,EAAsCA,UAC7DzH,EAAAA,oBAAAA,EAAAN,2CAAA+H,SAA4BA,EAA4CA,gBACxEzH,EAAAA,gBAAAA,EAAAN,oCAAA+H,SAAwBA,EAAqCA,gBAC7DzH,EAAAA,qBAAAA,EAAAN,qCAAA+H,SAA6BA,EAAsCA,gBACnEzH,EAAAA,UAAAA,EAAAN,iCAAA+H,SAAkBA,EAAkCA,UACpDzH,EAAAA,iBAAAA,EAAAN,sCAAA+H,SAAyBA,EAAuCA,WAChEzH,EAAAA,QAGDH,EAAAA,MAAAA,EAEAH,EAAAA,OAAAA,EAASG,UAATH,CAKCgI,MAAAA,WACC,IAAA1H,EAAIA,KACJA,EAAAA,eAAAA,CACC2H,UAAAA,EAAAA,QAAW3H,WAAKF,SAChB8H,SAAAA,EAAAA,QAAU5H,KAAKF,aAEhBE,EAAAA,QAAAA,KAAKF,YAALE,GAAA6H,OAAA7H,MAAA8H,EAAyCA,UACzC9H,EAAAA,QAAAA,KAAKF,cAAQ+D,GACb7D,EAAAA,QAAAA,SAAKF,mBAEsBE,EAAAA,SAAAC,MAAcD,KAAKC,SAAL8H,EAAAC,GAAA,OAAAD,EAAA/H,EAA2BgI,SAAEhI,WAA/BgI,EAAAhI,EAAZA,SAAAC,aAG3BD,EAAAA,SACCA,EAAAA,SAGDA,EAAAA,oBACAA,EAAAA,sBAGCA,EAAAA,SAAAA,GAAKF,QAALE,EAAqBA,QAArBmF,uBAAA,SAAA8C,GAAAjI,EAAAA,QAAKF,QAAQoI,QAGZlI,EAAAA,YACAA,EAAAA,SAGDA,EAAAA,SAAAA,YAAKF,UACLE,EAAAA,QATDF,QAAAoI,WAWCxI,EAAAA,GAAAE,GAAOqI,QAAEE,EAAQC,QAAQpI,SAAKuH,GAC7BvH,EAAAA,EAAAA,QAAAA,QAAKF,EAAQoI,UAAQX,SACrBvH,EAAAA,QAAAA,QAAKuH,QACLvH,EAAAA,SAAAA,YAAKF,UACLE,EAAAA,QAAAF,QAAAoI,aAGDD,EAAAA,SAAAA,GAAEI,QAAAA,EAAFrI,QAAAmF,sCAAA,SAAA8C,GACAA,EAAAA,iBAAA,IAAAK,EAAAA,EACCC,MADDA,GAAAA,EAAApE,EAECA,EAAKC,SAAQA,EAASkE,KAAAA,UAGtBtI,EAAAA,UACCuI,EAAAA,SAAAA,YAAAA,EAEMD,YAAQE,aADdF,GAAAA,EACAA,EAAAA,SAHDhB,aAMCtH,EACAA,EAAAA,SAFDC,MAEOI,KAANL,EAAAyI,sBAAMA,IAC6CzI,EAAAA,SAAAC,MAAAI,EAAAJ,SAAWA,MAAS6B,OAAhB4G,SAAgCvE,GAAAA,OAAAA,EAAAA,EAApCwE,SAAA1I,cAAA6B,IAGpD9B,EAAAA,SAAKC,MAASI,KAAMuI,SAAOb,EAAAC,GAAA,OAAAD,EAAA/H,EAAaC,SAAMA,WAASmC,EAAfpC,EAA6BC,SAAMA,eAAhDD,EAAAA,iBAAA6I,KAAmB5I,wBAAAA,IAAnBqI,GAAgDrI,YAASmC,YAAzDkG,EAAAA,SAA3BhB,YACAiB,GAAAA,EACAvI,EAAAA,SAAAA,MAAK6I,CAAAA,EAAAA,sBAAiBC,IACtBR,EAAAA,SAAAA,YAAQhB,WAGRtH,EAAAA,oBACAA,EAAAA,wBAEDA,EAAAA,GAAAA,GAAK+I,SAAAA,EAAAA,QAAL5D,WACAnF,IAAAA,EAAAA,EAAKgJ,kBAAAA,EAALrJ,iBAAAsJ,EAAAjJ,QAAAF,GAAA,MAEDJ,EAAEC,eAAWuJ,UACZlJ,EAAAA,SAAAuH,IAAA,CAIEC,MAAAA,EAAOxE,UADUhD,EAAAA,QAAAF,QAAlBoI,eAOHpF,OAAA,WAKY,SAAXqG,EAAAA,GAAW,OAAAnJ,EAAXA,WAAAoJ,GAAA,+BAAA,sBAJH,IAAApJ,EAAAqJ,KAAAC,EACAA,GACAzE,EAAA7E,EAAAA,SAAAC,UACE6C,EAAQ9C,EAAAA,SAAAC,QACP,GAAA4E,EAAAA,OAEA,IADiB,IACXA,EAAAA,EAAAA,EAAW7E,EAAI6E,OAAJuC,KADA,SAAA1C,GAEjB4E,EAAAA,KAAaC,2CAKXD,EAAAA,KAAcC,gDAAdC,OAAA3E,EAAoEA,GAAAA,EAAY7E,SAAKC,YAAS8B,WAJ/E,IAAjB,IAAA0H,EAAMN,EAAWpJ,OAAXoJ,SAAahF,GAAF,OAAAuF,EAAA1J,EAAAC,SAAAA,iBAAA4E,EAAAA,GAAAA,EAAA5E,SAAAA,cAAA0J,EAAAA,EAAa3J,EAAKoJ,EAAAA,OAAoBhC,IAAAuC,CAAtC,IAAAzF,EAAjBA,EAAAuF,GAQGH,EAAAA,KAAa,eAAbE,OAAAL,EAAmCA,EAAUjF,EAAMjE,SAAMA,aAAS6B,kBAAlE0H,OAAAtF,EAAgGA,EAAMjE,SAAMA,YAAS6B,MAArH0H,OAAAtF,EAAqIA,EAAMjE,SAAMA,YAAS8B,WAPtIuH,EAAAA,KAAAC,UAHvBK,CAAAlF,QAOE,IAAA,IAAAmF,EAAAnF,EAAM+E,EAAAA,EAAAA,OAAgB1J,IAAQ2I,CAAY,IAAAxE,EAAAA,EAAAnE,GAAAuJ,EAAAA,KAA1CC,eAA0CC,OAAAL,EAA1CA,EAAAjF,EAAAlE,SAAAC,aAAA6B,kBAA0C0H,OAAAtF,EAA1CA,EAAAlE,SAAAC,YAAA6B,MAA0C0H,OAAAtF,EAA1CA,EAAAlE,SAAAC,YAAA8B,WAGCuH,EAAAA,iBAAAA,KAAaQ,EAAbR,KAAAS,KACA/J,EAAAA,QAAAF,QAAAoI,YAYHlI,EAAAA,YAAA,GAVE+I,kBAAA,WACD,IAgBDiB,EAhBChK,EAXDqJ,KAWCY,EACAA,GACC5J,EAAI6D,EAAAA,SAAMjE,MACVqJ,EAAAA,EAAajJ,OAAAL,EAAbA,SAAAC,YAAaD,EAAgCkE,SAAOlE,YAAPkE,EAAhClE,EAAbA,SAAAC,YA0BDgK,OAzBCjK,EAAAA,oBAAAkK,KAAAC,EAAAnK,SAAAC,aAkBFI,EAAIA,OAfJL,EAAAA,oBAAAA,OAEAA,EAAAA,oBAAAA,OAEDK,EAAAA,MAAA+J,EAAAlJ,GAAAA,QAAAmJ,SAAAX,GACFO,EAAAA,KAAAV,SAAAC,OAAAE,EAAAA,EAAA1J,SAAAC,YAAA8B,cAEA/B,EAAAA,gBAAAsK,KAAAR,EAAAG,KAAAF,wCAAAP,OAAAxJ,EAAAA,SAAAC,UAAAM,aAEGF,EAAAA,OAAAL,EAAAA,SAAAC,aAAA+J,EAAAA,GAEA3J,EAAAA,QAAMA,SAAQL,GACdgK,EAAAA,KAAM9I,EAAAA,EAAWlB,SAAGK,eAmBnBL,EAAAA,qBAAKuK,KAAqBrH,QAAK8G,EAASA,KAAMD,EAAK/J,SAAKC,UAASM,OAAd,MAhBpDP,EAAAA,qBAAAuK,KAAkBT,KAAAzJ,EAAAA,OAAA+G,GAAA,oBAEjBpH,EAAAA,qBAFDuK,WAEOC,SACNxK,EAAAA,qBAAAA,KAAKkK,KAGN7J,EAAAA,QAAAA,QAAM+J,sBACLH,GAOCD,oBAAWN,SAAAA,GACX,IAAA1J,EAFDqJ,KAECtJ,EACDC,GADCyK,GAEDzK,EACA0K,GAPD,IAAAA,EASC1K,IADAA,IAAAA,EAAKuK,EAAAA,SAAAA,MACLvK,EAAKuK,EAAAA,EAAAA,EAAAA,OAAAA,IACLxK,EAAAA,KAAAwJ,kBAAAlJ,EAAAA,GAAAL,EAAAA,SAAAC,YAAA,yBAAAI,EAAAA,GAAAL,EAAAA,SAAAC,aAAA,aAkBAwK,GAAAA,EAVJ,OAJGzK,EAAAA,QAvJ8BF,KAAAgK,EAAA/J,KAAAgK,MAwJ/BW,GAAAD,GACFzK,EAAAA,QAAAF,QAAAoI,UAEAlI,GAOGyI,sBAAmBxI,SAAAA,GAmBnB,IAAAD,EAAQqJ,KAARd,EAlBAA,EAAKtI,SAALA,QAAoBI,OAAM+G,SAAauB,GAAA,OAAAA,EAAA3I,EAAAA,SAAAC,cAAAmE,IACtCrE,QAAAA,EAAAA,QAAAA,EAAawI,IAObvI,WAAI,SAACF,GACL,IAAAE,EAAAqJ,KAoBD,OAAO,EAAPrJ,EAAOA,SAAKC,MAASI,OAAMqI,SAAQC,GAAC,OAAAA,EAAA3I,EAAMA,SAAKC,cAAPmE,IAAJgD,QAdvChD,SAAA,SAAAuG,GAAA,OAAAA,EAAA,IAI8CC,QAD3C,WAEA,IAAA5K,EAAAqJ,KACArJ,EAAAA,QAxL8BF,QAAAoI,WAgN9BlI,EAAAA,QAAKkI,WAvBNlI,EAAAA,MACFA,EAAAA,QAAAF,KACAgK,IAAAe,OACAA,EAAA7K,eAAA8K,WAAAnD,WACA6C,YAAAhC,YACEY,mBAAYlG,KACXA,CAAIlD,SAAAA,EAAJA,eAAA8K,WAAI9K,OACgCA,EAAAA,QAAAF,WAAKiL,eAAL/K,EAAAA,SAA7BuH,SA4BH,KAAJ1H,EAAMA,OAAFA,EAA6BA,aA1BlCA,EAAAA,WAAAmL,SACFnL,EAAAA,gBAAAmL,GAMAtL,EAAAA,GAAAC,IAAAsL,EAAAjL,SACAN,EAAAA,GAAAE,IAAAqL,EAAAjL,SACAN,EAAAA,EAAAE,MAAAsL,IAAAD,EAAAjL,gBACAA,EAAAA,QAAAF,GAAAqL,eAmBIzL,EAAAQ,OAAAL,EAACuL,UAAD,CACDC,KAAA,SAAAC,EAAAC,GACAlC,KAAAmC,QAAAnC,KAAAmC,SAAA,GACAnC,KAAAmC,QAAAA,GAAAnC,KAAAmC,QAAAA,IAAA,GACAnC,KAAAmC,QAAAA,GAAAF,KAAA/B,IA4BDkC,OAAM,SAAGH,EAAAC,GACRlC,KAAAmC,QAAAnC,KAAemC,SAAA,GAzBf9L,KAAEC,KAAQsL,UAAT,GACDvL,KAAAA,QAAEE,GAAD0L,OAAetL,KAAKmF,QAArBqG,GAAAF,QAAAI,GAAqBvG,IAErB+C,QAAA,SAAAoD,GA1OF,GA2OEjC,KAAAmC,QAAAnC,KAAAmC,SAAA,GA3OFF,KAAAjC,KAAAmC,UAAA,EA+OA,IAAA,IAAA9G,EAAA,EAAAA,EAAA2E,KAAAmC,QAAAA,GAAAF,OAAAlE,IACDiC,KAAAmC,QAAAA,GAAAF,GAAApE,MAAAA,KAAAyE,MAAAA,UAAAP,MAAAhB,KAAAwB,UAAAC,OAiCCnM,EAACuH,GAADkE,YAAA,SAAmBW,GAxBnBpM,OAAAA,KAAEQ,KAAOL,WACRwL,KAAAA,aACC,WAAAhC,KAAAhC,QAAeA,eACf,IAAAxH,EAAAA,EAAAwJ,MAAaiC,MApehB,CAseGS,OAL8BpM,OAAAC","file":"fancy-select.min.js","sourcesContent":["\"use strict\";\n/**!\n * WooFeed Fancy Select\n * @version 1.0.0\n * @copyright 2020 WebAppick\n * @author Kudratullah <mhamudul.hk@gmail.com>\n */\n\n(function($, window, document) {\n\t// @TODO if multiple select has required attribute and only one item is selected then return false (user should not able to deselect the last one).\n\t// @TODO make the place holder with input field like selectize so we can set the required attribute if the select has required attribute, which can be useful for showing required warning.\n\t\"use strict\";\n\t\n\t/**\n\t * FancySelect Constructor\n\t * @param {jQuery|HTMLElement} $select\n\t * @param {Object} [options]\n\t * @constructor\n\t */\n\tlet FancySelect = function FancySelect($select, options) {\n\t\tlet self = this,\n\t\t\tdefaults = {\n\t\t\t\toptions: [],\n\t\t\t\toptgroups: [],\n\t\t\t\titems: [],\n\t\t\t\tplaceholder: '',\n\t\t\t\tdelimiter: ',',\n\t\t\t\tsplitOn: null,\n\t\t\t\tpersist: !0,\n\t\t\t\tdiacritics: !0,\n\t\t\t\tcreate: !1,\n\t\t\t\tcreateOnBlur: !1,\n\t\t\t\tcreateFilter: null,\n\t\t\t\thighlight: !0,\n\t\t\t\topenOnFocus: !0,\n\t\t\t\tmaxOptions: 1e3,\n\t\t\t\tmaxItems: null,\n\t\t\t\tmaxItemShow: 3,\n\t\t\t\thideSelected: null,\n\t\t\t\taddPrecedence: !1,\n\t\t\t\tselectOnTab: !1,\n\t\t\t\tpreload: !1,\n\t\t\t\tallowEmptyOption: !1,\n\t\t\t\tcloseAfterSelect: !1,\n\t\t\t\tscrollDuration: 60,\n\t\t\t\tloadThrottle: 300,\n\t\t\t\tloadingClass: \"loading\",\n\t\t\t\tdataAttr: \"data-data\",\n\t\t\t\toptgroupField: \"optgroup\",\n\t\t\t\tvalueField: \"value\",\n\t\t\t\tlabelField: \"text\",\n\t\t\t\tdisabledField: \"disabled\",\n\t\t\t\toptgroupLabelField: \"label\",\n\t\t\t\toptgroupValueField: \"value\",\n\t\t\t\tlockOptgroupOrder: !1,\n\t\t\t\tsortField: \"$order\",\n\t\t\t\tsearchField: [\"text\"],\n\t\t\t\tsearchConjunction: \"and\",\n\t\t\t\tmode: null,\n\t\t\t\twrapperClass: \"selectize-control\",\n\t\t\t\tinputClass: \"selectize-input\",\n\t\t\t\tdropdownClass: \"selectize-dropdown\",\n\t\t\t\tdropdownContentClass: \"selectize-dropdown-content\",\n\t\t\t\tdropdownParent: null,\n\t\t\t\tcopyClassesToDropdown: !0,\n\t\t\t\trender: {}\n\t\t\t},\n\t\t\tsettings = $.extend(true, {}, defaults, options),\n\t\t\tselect = $select[0];\n\t\tselect.fancySelect = self;\n\t\tself.order = 0;\n\t\tlet computedStyle = window.getComputedStyle && window.getComputedStyle(select, null);\n\t\tlet dir = computedStyle ? computedStyle.getPropertyValue('direction') : select.currentStyle && select.currentStyle.direction;\n\t\tdir = dir || $select.parents('[dir]:first').attr('dir') || '';\n\t\tself.computedStyle = computedStyle; // for now, android support in general is too spotty to support validity\n\n\t\tconst SUPPORTS_VALIDITY_API = !/android/i.test(window.navigator.userAgent) && !! document.createElement('input').validity; // helper (private) methods\n\n\t\tconst debounce = function (fn, delay) {\n\t\t\tlet timeout;\n\t\t\treturn function() {\n\t\t\t\tlet self = this;\n\t\t\t\tlet args = arguments;\n\t\t\t\twindow.clearTimeout(timeout);\n\t\t\t\ttimeout = window.setTimeout(function() {\n\t\t\t\t\tfn.apply(self, args);\n\t\t\t\t}, delay);\n\t\t\t};\n\t\t};\n\t\t\n\t\tlet optionsMap = {},\n\t\t\toptHelper = {\n\t\t\t\treadData: function ($el) {\n\t\t\t\t\tlet data = self.dataAttr && $el.attr(self.dataAttr);\n\n\t\t\t\t\tif (typeof data === 'string' && data.length) {\n\t\t\t\t\t\treturn JSON.parse(data);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t},\n\t\t\t\taddOption: function ($option, group) {\n\t\t\t\t\t$option = $($option);\n\t\t\t\t\tlet value = self.hash_key($option.val());\n\t\t\t\t\tif (!value && !settings.allowEmptyOption) return; // if the option already exists, it's probably been\n\t\t\t\t\t// duplicated in another optgroup. in this case, push\n\t\t\t\t\t// the current group to the \"optgroup\" property on the\n\t\t\t\t\t// existing option so that it's rendered in both places.\n\n\t\t\t\t\tif (optionsMap.hasOwnProperty(value)) {\n\t\t\t\t\t\tif (group) {\n\t\t\t\t\t\t\tlet arr = optionsMap[value][field_optgroup];\n\n\t\t\t\t\t\t\tif (!arr) {\n\t\t\t\t\t\t\t\toptionsMap[value][field_optgroup] = group;\n\t\t\t\t\t\t\t} else if (!$.isArray(arr)) {\n\t\t\t\t\t\t\t\toptionsMap[value][field_optgroup] = [arr, group];\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tarr.push(group);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet option = optHelper.readData($option) || {};\n\t\t\t\t\toption[self.settings.labelField] = option[self.settings.labelField] || $option.text();\n\t\t\t\t\toption[self.settings.valueField] = option[self.settings.valueField] || value;\n\t\t\t\t\toption[self.settings.disabledField] = option[self.settings.disabledField] || $option.prop('disabled');\n\t\t\t\t\toption[self.settings.optgroupField] = option[self.settings.optgroupField] || group;\n\t\t\t\t\toption.$order = ++self.order;\n\t\t\t\t\toptionsMap[value] = option;\n\t\t\t\t\tself.settings.options.push(option);\n\n\t\t\t\t\tif ($option.is(':selected')) {\n\t\t\t\t\t\tself.settings.items.push(option);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\taddGroup: function ($optgroup) {\n\t\t\t\t\tlet i, n, id, optgroup, $options;\n\t\t\t\t\t$optgroup = $($optgroup);\n\t\t\t\t\tid = $optgroup.attr('label');\n\n\t\t\t\t\tif (id) {\n\t\t\t\t\t\toptgroup = optHelper.readData($optgroup) || {};\n\t\t\t\t\t\toptgroup[self.settings.optgroupLabelField] = id;\n\t\t\t\t\t\toptgroup[self.settings.optgroupValueField] = id;\n\t\t\t\t\t\toptgroup[self.settings.disabledField] = $optgroup.prop('disabled');\n\t\t\t\t\t\toptgroup.$order = ++self.order;\n\t\t\t\t\t\tself.settings.optgroups.push(optgroup);\n\t\t\t\t\t}\n\n\t\t\t\t\t$options = $('option', $optgroup);\n\n\t\t\t\t\tfor (i = 0, n = $options.length; i < n; i++) {\n\t\t\t\t\t\toptHelper.addOption($options[i], id);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}; // setup default state\n\t\t\n\t\t$.extend(self, {\n\t\t\tsettings: settings,\n\t\t\t$select: $select,\n\t\t\ttabIndex: $select.attr('tabindex') || '',\n\t\t\ttagType: 1,\n\t\t\trtl: /rtl/i.test(dir),\n\t\t\tmultiple: $select.attr('multiple'),\n\t\t\teventNS: '.FancySelect' + ++FancySelect.count,\n\t\t\thighlightedValue: null,\n\t\t\tisBlurring: false,\n\t\t\tisOpen: false,\n\t\t\tisDisabled: false,\n\t\t\tisRequired: $select.is('[required]'),\n\t\t\tisInvalid: false,\n\t\t\tisLocked: false,\n\t\t\tisFocused: false,\n\t\t\tisInputHidden: false,\n\t\t\tisSetup: false,\n\t\t\tisRendered: false,\n\t\t\tisShiftDown: false,\n\t\t\tisCmdDown: false,\n\t\t\tisCtrlDown: false,\n\t\t\tignoreFocus: false,\n\t\t\tignoreBlur: false,\n\t\t\tignoreHover: false,\n\t\t\thasOptions: false,\n\t\t\tcurrentResults: null,\n\t\t\tlastValue: '',\n\t\t\tcaretPos: 0,\n\t\t\tloading: 0,\n\t\t\tloadedSearches: {},\n\t\t\t$activeOption: null,\n\t\t\t$activeItems: [],\n\t\t\toptgroups: {},\n\t\t\toptions: {},\n\t\t\tuserOptions: {},\n\t\t\titems: {},\n\t\t\trenderCache: {},\n\t\t\tonSearchChange: settings.loadThrottle === null ? self.onSearchChange : debounce(self.onSearchChange, settings.loadThrottle)\n\t\t});\n\n\t\tif ('' === self.settings.placeholder) {\n\t\t\tself.settings.placeholder = $select.attr('placeholder') || $select.attr('data-placeholder');\n\n\t\t\tif (!self.settings.placeholder && !self.settings.allowEmptyOption) {\n\t\t\t\tself.settings.placeholder = $select.children('option[value=\"\"]').text();\n\t\t\t}\n\t\t}\n\n\t\tself.settings.maxItems = self.multiple ? null : 1;\n\n\t\tfor (let i = 0, n = self.$select.children().length; i < n; i++) {\n\t\t\tlet tagName = self.$select.children()[i].tagName.toLowerCase();\n\n\t\t\tif (tagName === 'optgroup') {\n\t\t\t\toptHelper.addGroup(self.$select.children()[i]);\n\t\t\t} else if (tagName === 'option') {\n\t\t\t\toptHelper.addOption(self.$select.children()[i]);\n\t\t\t}\n\t\t}\n\n\t\tself.$wrapper = $('<div class=\"fancy-picker\">').addClass($select.attr('class'));\n\n\t\tif (self.computedStyle.hasOwnProperty('width')) {\n\t\t\tself.$wrapper.css({\n\t\t\t\twidth: self.computedStyle.width\n\t\t\t});\n\t\t}\n\t\t\n\t\tself.$outputWrapper = $('<div class=\"fancy-picker-picked\">').appendTo(self.$wrapper);\n\t\tself.originalPlaceholder = $('<span class=\"fancy-picker-placeholder\">').appendTo(self.$outputWrapper);\n\t\tself.dataPlaceholder = $('<span class=\"fancy-picker-data\">').appendTo(self.$outputWrapper);\n\t\tself.dataCountPlaceholder = $('<span class=\"fancy-picker-count\">').appendTo(self.$outputWrapper);\n\t\tself.$dropdown = $('<div class=\"fancy-picker-ui\">').appendTo(self.$wrapper);\n\t\tself.$dropdownContent = $('<div class=\"fancy-picker-content\">').appendTo(self.$dropdown);\n\t\tself.setup();\n\t};\n\n\tFancySelect.count = 0;\n\t// public methods.\n\t$.extend(FancySelect.prototype, {\n\t\t/**\n\t\t * Creates all elements and sets up event bindings.\n\t\t * @return {void}\n\t\t */\n\t\tsetup: function () {\n\t\t\tlet self = this;\n\t\t\tself.revertSettings = {\n\t\t\t\t$children: self.$select.children().detach(),\n\t\t\t\ttabindex: self.$select.attr('tabindex')\n\t\t\t};\n\t\t\tself.$select.attr('tabindex', -1).hide().after(self.$wrapper);\n\t\t\tself.$select.data('FancySelect', self);\n\t\t\tself.$select.addClass('FancySelectInit');\n\t\t\t\n\t\t\tself.settings.items.sort( ( a, b ) => a[self.settings.sortField] - b[self.settings.sortField] );\n\t\t\t\n\t\t\t\n\t\t\tif (self.preload) {\n\t\t\t\tself.render();\n\t\t\t}\n\t\t\t\n\t\t\tself.updatePlaceholder();\n\t\t\tself.updateOriginalInput();\n\t\t\t\n\t\t\tself.$wrapper.on('click' + self.eventNS, '.fancy-picker-picked', function(e) {\n\t\t\t\tself.$select.trigger('show');\n\t\t\t\t\n\t\t\t\tif (!self.isRendered) {\n\t\t\t\t\tself.render();\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tself.$wrapper.toggleClass('active');\n\t\t\t\tself.$select.trigger('shown');\n\t\t\t});\n\t\t\t$(document).on('click' + self.eventNS, function(e) {\n\t\t\t\tif (!$(e.target).closest(self.$wrapper).length) {\n\t\t\t\t\tself.$select.trigger('hide');\n\t\t\t\t\tself.$wrapper.removeClass('active');\n\t\t\t\t\tself.$select.trigger('hidden');\n\t\t\t\t}\n\t\t\t});\n\t\t\tself.$wrapper.on('click' + self.eventNS, '.fancy-picker-option:not(.disabled)', function(e) {\n\t\t\t\te.preventDefault();\n\t\t\t\tlet current = $(this),\n\t\t\t\t\tselected = false,\n\t\t\t\t\tvalue = self.hash_key(current.data('value'));\n\t\t\t\t\n\t\t\t\tif (self.multiple) {\n\t\t\t\t\tif (!current.hasClass('selected')) {\n\t\t\t\t\t\tselected = true;\n\t\t\t\t\t\tcurrent.addClass('selected');\n\t\t\t\t\t} else current.removeClass('selected');\n\t\t\t\t\t\n\t\t\t\t\tif (selected) {\n\t\t\t\t\t\tself.settings.items.push( self.getSelectedOptionData( value ) );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.settings.items = self.settings.items.filter( x => x[self.settings.valueField] !== value );\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tself.settings.items.sort( ( a, b ) => a[self.settings.sortField] - b[self.settings.sortField] );\n\t\t\t\t} else {\n\t\t\t\t\tself.$dropdownContent.find('.fancy-picker-option').not(current).removeClass('selected');\n\t\t\t\t\tcurrent.addClass('selected');\n\t\t\t\t\tselected = true;\n\t\t\t\t\tself.settings.items = [ self.getSelectedOptionData( value ) ];\n\t\t\t\t\tself.$wrapper.removeClass('active');\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tself.updatePlaceholder();\n\t\t\t\tself.updateOriginalInput();\n\t\t\t});\n\t\t\t$(window).on('resize' + self.eventNS, function() {\n\t\t\t\tlet computedStyle = window.getComputedStyle && window.getComputedStyle(self.$select[0], null);\n\t\t\t\t\n\t\t\t\tif (computedStyle.hasOwnProperty('width')) {\n\t\t\t\t\tself.$wrapper.css({\n\t\t\t\t\t\twidth: computedStyle.width\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t\tself.$select.trigger('initialize');\n\t\t},\n\t\t/**\n\t\t * Render The FancySelect UI\n\t\t * @return {void}\n\t\t */\n\t\trender: function () {\n\t\t\tlet self = this,\n\t\t\t\tdropdownItems = [];\n\t\t\tconst optgroup = self.settings.optgroups;\n\t\t\tconst options = self.settings.options;\n\t\t\tconst optClass = ( value ) => self.isSelected(value) ? 'fancy-picker-option selected' : 'fancy-picker-option';\n\t\t\tif ( optgroup.length ) {\n\t\t\t\tfor ( let i = 0; i < optgroup.length; i++ ) {\n\t\t\t\t\tdropdownItems.push( `<div class=\"fancy-picker-option-group\">` );\n\t\t\t\t\tdropdownItems.push( `<div class=\"fancy-picker-option-group-label\">${optgroup[i][self.settings.labelField]}</div>` );\n\t\t\t\t\tconst group_options = options.filter( item => item[self.settings.optgroupField] === optgroup[i][self.settings.valueField]);\n\t\t\t\t\tfor (let ii = 0; ii < group_options.length; ii++ ) {\n\t\t\t\t\t\tlet option = group_options[i];\n\t\t\t\t\t\tdropdownItems.push( `<div class=\"${optClass( option[self.settings.valueField] )}\" data-value=\"${option[self.settings.valueField]}\">${option[self.settings.labelField]}</div>` );\n\t\t\t\t\t}\n\t\t\t\t\tdropdownItems.push( `</div>` );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (let i = 0; i < options.length; i++) {\n\t\t\t\t\tlet option = options[i];\n\t\t\t\t\tdropdownItems.push( `<div class=\"${optClass( option[self.settings.valueField] )}\" data-value=\"${option[self.settings.valueField]}\">${option[self.settings.labelField]}</div>` );\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tself.$dropdownContent.html(dropdownItems.join(''));\n\t\t\tself.$select.trigger('rendered');\n\t\t\tself.isRendered = true;\n\t\t},\n\t\t/**\n\t\t * Set Placeholder & Update Selected Data Placeholder\n\t\t * @return {FancySelect}\n\t\t */\n\t\tupdatePlaceholder: function () {\n\t\t\tlet self = this,\n\t\t\t\tplaceholderData = [];\n\t\t\tconst items = self.settings.items;\n\t\t\tconst maxItemShow = items.length > self.settings.maxItemShow ? self.settings.maxItemShow - 1 : self.settings.maxItemShow;\n\t\t\tself.originalPlaceholder.text(self.settings.placeholder);\n\t\t\t\n\t\t\tif (items.length) {\n\t\t\t\tself.originalPlaceholder.hide();\n\t\t\t} else {\n\t\t\t\tself.originalPlaceholder.show();\n\t\t\t}\n\t\t\t\n\t\t\titems.slice(0, maxItemShow).forEach( (item) => {\n\t\t\t\tplaceholderData.push( `<span>${item[self.settings.labelField]}</span>` );\n\t\t\t});\n\t\t\tself.dataPlaceholder.html( placeholderData.join( `<span class=\"fancy-picker-separator\">${self.settings.delimiter}</span>` ) );\n\t\t\t\n\t\t\tif (items.length > self.settings.maxItemShow) {\n\t\t\t\tlet title = [];\n\t\t\t\titems.forEach( (item) => {\n\t\t\t\t\ttitle.push(item[self.settings.labelField]);\n\t\t\t\t});\n\t\t\t\tself.dataCountPlaceholder.attr('title', title.join(self.settings.delimiter.trim() + ' '));\n\t\t\t\tself.dataCountPlaceholder.html('+' + (items.length - maxItemShow) + ' More &hellip;');\n\t\t\t} else {\n\t\t\t\tself.dataCountPlaceholder.removeAttr('title');\n\t\t\t\tself.dataCountPlaceholder.html('');\n\t\t\t}\n\t\t\t\n\t\t\tself.$select.trigger('placeholderChanged');\n\t\t\treturn self;\n\t\t},\n\t\t/**\n\t\t * Update The Original Select Tag\n\t\t * @param {boolean} ?silent\n\t\t * @return {FancySelect}\n\t\t */\n\t\tupdateOriginalInput: function (silent) {\n\t\t\tlet self = this,\n\t\t\t\toptions = [],\n\t\t\t\tchanged = false;\n\t\t\tsilent = true === silent ? true : false;\n\t\t\tconst items = self.settings.items;\n\t\t\tfor (let i = 0; i < items.length; i++) {\n\t\t\t\toptions.push('<option value=\"' + items[i][self.settings.valueField] + '\" selected=\"selected\">' + items[i][self.settings.labelField] || '' + '</option>');\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t\t\n\t\t\tself.$select.html(options.join(''));\n\t\t\t\n\t\t\tif (!silent && changed) {\n\t\t\t\tself.$select.trigger('change');\n\t\t\t}\n\t\t\treturn self;\n\t\t},\n\t\t/**\n\t\t * Get Selected Option Data (value, label, etc.)\n\t\t * @param {string} hash_key\n\t\t * @return {object|boolean}\n\t\t */\n\t\tgetSelectedOptionData: function (hash_key) {\n\t\t\tlet self = this,\n\t\t\t\tselected = self.settings.options.filter( x => x[self.settings.valueField] === hash_key );\n\t\t\treturn selected.length ? selected[0] : false;\n\t\t},\n\t\t/**\n\t\t * Check if input is selected (in the items list )\n\t\t * @param {string} hash_key\n\t\t * @return {boolean}\n\t\t */\n\t\tisSelected: function (hash_key) {\n\t\t\tlet self = this;\n\t\t\treturn self.settings.items.filter( x => x[self.settings.valueField] === hash_key ).length > 0;\n\t\t},\n\t\t/**\n\t\t * Convert input to it's best string representation.\n\t\t * @param {string|*} input\n\t\t * @return {string}\n\t\t */\n\t\thash_key: (input) => input + '',\n\t\t/**\n\t\t * Completely destroys the control and\n\t\t * unbinds all event listeners so that it can\n\t\t * be garbage collected.\n\t\t */\n\t\tdestroy: function () {\n\t\t\tlet self = this;\n\t\t\tself.$select.trigger('destroy');\n\t\t\tself.trigger('destroy');\n\t\t\tself.off();\n\t\t\tself.$select\n\t\t\t\t.html('')\n\t\t\t\t.append(self.revertSettings.$children)\n\t\t\t\t.removeAttr('tabindex')\n\t\t\t\t.removeClass('FancySelectInit')\n\t\t\t\t.attr({tabindex: self.revertSettings.tabindex})\n\t\t\t\t.show();\n\t\t\tself.$select.removeData('FancySelect');\n\t\t\tself.$wrapper.remove();\n\t\t\t\n\t\t\tif (--FancySelect.count === 0 && FancySelect.$testInput) {\n\t\t\t\tFancySelect.$testInput.remove();\n\t\t\t\tFancySelect.$testInput = undefined;\n\t\t\t} // this doesn't fire on create feed. as fields are loaded via ajax.\n\t\t\t// add custom event with the form object (with namespace)\n\t\t\t// trigger event on form.init()\n\t\t\t// remove previous listener on from.init(). first. so multiple listener not executed.\n\t\t\t// see selectize https://github.com/selectize/selectize.js/blob/master/src/selectize.js#L2097\n\t\t\t// add event listener here...\n\t\t\t\n\t\t\t\n\t\t\t$(window).off(self.eventNS);\n\t\t\t$(document).off(self.eventNS);\n\t\t\t$(document.body).off(self.eventNS);\n\t\t\tdelete self.$select[0].fancySelect;\n\t\t},\n\t\t\n\t});\n\t\n\t/**\n\t * MicroEvent - to make any js object an event emitter\n\t *\n\t * - pure javascript - server compatible, browser compatible\n\t * - dont rely on the browser doms\n\t * - super simple - you get it immediatly, no mistery, no magic involved\n\t *\n\t * @author Jerome Etienne (https://github.com/jeromeetienne)\n\t * @link https://github.com/jeromeetienne/microevent.js\n\t */\n\t$.extend(FancySelect.prototype, {\n\t\tbind\t: function(event, fct){\n\t\t\tthis._events = this._events || {};\n\t\t\tthis._events[event] = this._events[event]\t|| [];\n\t\t\tthis._events[event].push(fct);\n\t\t},\n\t\tunbind\t: function(event, fct){\n\t\t\tthis._events = this._events || {};\n\t\t\tif( event in this._events === false )\treturn;\n\t\t\tthis._events[event].splice(this._events[event].indexOf(fct), 1);\n\t\t},\n\t\ttrigger\t: function(event /* , args... */){\n\t\t\tthis._events = this._events || {};\n\t\t\tif( event in this._events === false )\treturn;\n\t\t\tfor(let i = 0; i < this._events[event].length; i++){\n\t\t\t\tthis._events[event][i].apply(this, Array.prototype.slice.call(arguments, 1));\n\t\t\t}\n\t\t}\n\t});\n\t/**\n\t * jQuery Wrapper\n\t * @param {Object} [user_options]\n\t * @returns {jquery|HTMLElement}\n\t */\n\t$.fn.fancySelect = function(user_options) {\n\t\treturn this.each(function() {\n\t\t\tif (this.fancySelect) return;\n\t\t\tif ('select' !== this.tagName.toLowerCase()) return;\n\t\t\tnew FancySelect($(this), user_options);\n\t\t});\n\t};\n})(jQuery, window, document);\n"]}
 
admin/js/jquery-sortable.min.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";function _typeof(t){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}!function(l,s,r){var i={drag:!0,drop:!0,exclude:"",nested:!0,vertical:!0},o={afterMove:function(t,e,i){},containerPath:"",containerSelector:"ol, ul",distance:0,delay:0,handle:"",itemPath:"",itemSelector:"li",bodyClass:"dragging",draggedClass:"dragged",isValidTarget:function(t,e){return!0},onCancel:function(t,e,i,o){},onDrag:function(t,e,i,o){t.css(e)},onDragStart:function(t,e,i,o){t.css({height:t.outerHeight(),width:t.outerWidth()}),t.addClass(e.group.options.draggedClass),l("body").addClass(e.group.options.bodyClass)},onDrop:function(t,e,i,o){t.removeClass(e.group.options.draggedClass).removeAttr("style"),l("body").removeClass(e.group.options.bodyClass)},onMousedown:function(t,e,i){if(!i.target.nodeName.match(/^(input|select|textarea)$/i))return i.preventDefault(),!0},placeholderClass:"placeholder",placeholder:'<li class="placeholder"></li>',pullPlaceholder:!0,serialize:function(t,e,i){t=l.extend({},t.data());return i?[e]:(e[0]&&(t.children=e),delete t.subContainers,delete t.sortable,t)},tolerance:0},e={},n=0,c={left:0,top:0,bottom:0,right:0},a={start:"touchstart.sortable mousedown.sortable",drop:"touchend.sortable touchcancel.sortable mouseup.sortable",drag:"touchmove.sortable mousemove.sortable",scroll:"scroll.sortable"},h="subContainers";function u(t,e){return Math.max(0,t[0]-e[0],e[0]-t[1])+Math.max(0,t[2]-e[1],e[1]-t[3])}function t(t,e,i,o){var s=t.length,n=o?"offset":"position";for(i=i||0;s--;){var r=t[s].el||l(t[s]),a=r[n]();a.left+=parseInt(r.css("margin-left"),10),a.top+=parseInt(r.css("margin-top"),10),e[s]=[a.left-i,a.left+r.outerWidth()+i,a.top-i,a.top+r.outerHeight()+i]}}function p(t,e){e=e.offset();return{left:t.left-e.left,top:t.top-e.top}}function f(t,e,i){e=[e.left,e.top],i=i&&[i.left,i.top];for(var o,s=t.length,n=[];s--;)o=t[s],n[s]=[s,u(o,e),i&&u(o,i)];return n=n.sort(function(t,e){return e[1]-t[1]||e[2]-t[2]||e[0]-t[0]})}function d(t){this.options=l.extend({},o,t),this.containers=[],this.options.rootGroup||(this.scrollProxy=l.proxy(this.scroll,this),this.dragProxy=l.proxy(this.drag,this),this.dropProxy=l.proxy(this.drop,this),this.placeholder=l(this.options.placeholder),t.isValidTarget||(this.options.isValidTarget=r))}function g(t,e){this.el=t,this.options=l.extend({},i,e),this.group=d.get(this.options),this.rootGroup=this.options.rootGroup||this.group,this.handle=this.rootGroup.options.handle||this.rootGroup.options.itemSelector;e=this.rootGroup.options.itemPath;this.target=e?this.el.find(e):this.el,this.target.on(a.start,this.handle,l.proxy(this.dragInit,this)),this.options.drop&&this.group.containers.push(this)}d.get=function(t){return e[t.group]||(t.group===r&&(t.group=n++),e[t.group]=new d(t)),e[t.group]},d.prototype={dragInit:function(t,e){this.$document=l(e.el[0].ownerDocument);var i=l(t.target).closest(this.options.itemSelector);i.length&&(this.item=i,this.itemContainer=e,!this.item.is(this.options.exclude)&&this.options.onMousedown(this.item,o.onMousedown,t)&&(this.setPointer(t),this.toggleListeners("on"),this.setupDelayTimer(),this.dragInitDone=!0))},drag:function(t){if(!this.dragging){if(!this.distanceMet(t)||!this.delayMet)return;this.options.onDragStart(this.item,this.itemContainer,o.onDragStart,t),this.item.before(this.placeholder),this.dragging=!0}this.setPointer(t),this.options.onDrag(this.item,p(this.pointer,this.item.offsetParent()),o.onDrag,t);var e=this.getPointer(t),i=this.sameResultBox,t=this.options.tolerance;(!i||i.top-t>e.top||i.bottom+t<e.top||i.left-t>e.left||i.right+t<e.left)&&(this.searchValidTarget()||(this.placeholder.detach(),this.lastAppendedItem=r))},drop:function(t){this.toggleListeners("off"),this.dragInitDone=!1,this.dragging&&(this.placeholder.closest("html")[0]?this.placeholder.before(this.item).detach():this.options.onCancel(this.item,this.itemContainer,o.onCancel,t),this.options.onDrop(this.item,this.getContainer(this.item),o.onDrop,t),this.clearDimensions(),this.clearOffsetParent(),this.lastAppendedItem=this.sameResultBox=r,this.dragging=!1)},searchValidTarget:function(t,e){t||(t=this.relativePointer||this.pointer,e=this.lastRelativePointer||this.lastPointer);for(var i=f(this.getContainerDimensions(),t,e),o=i.length;o--;){var s=i[o][0];if(!i[o][1]||this.options.pullPlaceholder){var n=this.containers[s];if(!n.disabled)if(this.$getOffsetParent()||(t=p(t,s=n.getItemOffsetParent()),e=p(e,s)),n.searchValidTarget(t,e))return!0}}this.sameResultBox&&(this.sameResultBox=r)},movePlaceholder:function(t,e,i,o){var s=this.lastAppendedItem;!o&&s&&s[0]===e[0]||(e[i](this.placeholder),this.lastAppendedItem=e,this.sameResultBox=o,this.options.afterMove(this.placeholder,t,e))},getContainerDimensions:function(){return this.containerDimensions||t(this.containers,this.containerDimensions=[],this.options.tolerance,!this.$getOffsetParent()),this.containerDimensions},getContainer:function(t){return t.closest(this.options.containerSelector).data(s)},$getOffsetParent:function(){if(this.offsetParent===r){var t=this.containers.length-1,e=this.containers[t].getItemOffsetParent();if(!this.options.rootGroup)for(;t--;)if(e[0]!=this.containers[t].getItemOffsetParent()[0]){e=!1;break}this.offsetParent=e}return this.offsetParent},setPointer:function(t){var e=this.getPointer(t);this.$getOffsetParent()&&(t=p(e,this.$getOffsetParent()),this.lastRelativePointer=this.relativePointer,this.relativePointer=t),this.lastPointer=this.pointer,this.pointer=e},distanceMet:function(t){t=this.getPointer(t);return Math.max(Math.abs(this.pointer.left-t.left),Math.abs(this.pointer.top-t.top))>=this.options.distance},getPointer:function(t){var e=t.originalEvent||t.originalEvent.touches&&t.originalEvent.touches[0];return{left:t.pageX||e.pageX,top:t.pageY||e.pageY}},setupDelayTimer:function(){var t=this;this.delayMet=!this.options.delay,this.delayMet||(clearTimeout(this._mouseDelayTimer),this._mouseDelayTimer=setTimeout(function(){t.delayMet=!0},this.options.delay))},scroll:function(t){this.clearDimensions(),this.clearOffsetParent()},toggleListeners:function(i){var o=this;l.each(["drag","drop","scroll"],function(t,e){o.$document[i](a[e],o[e+"Proxy"])})},clearOffsetParent:function(){this.offsetParent=r},clearDimensions:function(){this.traverse(function(t){t._clearDimensions()})},traverse:function(t){t(this);for(var e=this.containers.length;e--;)this.containers[e].traverse(t)},_clearDimensions:function(){this.containerDimensions=r},_destroy:function(){e[this.options.group]=r}},g.prototype={dragInit:function(t){var e=this.rootGroup;!this.disabled&&!e.dragInitDone&&this.options.drag&&this.isValidDrag(t)&&e.dragInit(t,this)},isValidDrag:function(t){return 1==t.which||"touchstart"==t.type&&1==t.originalEvent.touches.length},searchValidTarget:function(t,e){var i=f(this.getItemDimensions(),t,e),o=i.length,s=this.rootGroup,n=!s.options.isValidTarget||s.options.isValidTarget(s.item,this);if(!o&&n)return s.movePlaceholder(this,this.target,"append"),!0;for(;o--;){var r=i[o][0],a=i[o][1];if(!a&&this.hasChildGroup(r)){if(this.getContainerGroup(r).searchValidTarget(t,e))return!0}else if(n)return this.movePlaceholder(r,t),!0}},movePlaceholder:function(t,e){var i=l(this.items[t]),o=this.itemDimensions[t],s="after",n=i.outerWidth(),r=i.outerHeight(),a=i.offset(),h={left:a.left,right:a.left+n,top:a.top,bottom:a.top+r};this.options.vertical?(a=(o[2]+o[3])/2,e.top<=a?(s="before",h.bottom-=r/2):h.top+=r/2):(o=(o[0]+o[1])/2,e.left<=o?(s="before",h.right-=n/2):h.left+=n/2),this.hasChildGroup(t)&&(h=c),this.rootGroup.movePlaceholder(this,i,s,h)},getItemDimensions:function(){return this.itemDimensions||(this.items=this.$getChildren(this.el,"item").filter(":not(."+this.group.options.placeholderClass+", ."+this.group.options.draggedClass+")").get(),t(this.items,this.itemDimensions=[],this.options.tolerance)),this.itemDimensions},getItemOffsetParent:function(){var t=this.el,t="relative"===t.css("position")||"absolute"===t.css("position")||"fixed"===t.css("position")?t:t.offsetParent();return t},hasChildGroup:function(t){return this.options.nested&&this.getContainerGroup(t)},getContainerGroup:function(t){var e,i,o=l.data(this.items[t],h);return o===r&&(o=!1,(e=this.$getChildren(this.items[t],"container"))[0]&&(i=l.extend({},this.options,{rootGroup:this.rootGroup,group:n++}),o=e[s](i).data(s).group),l.data(this.items[t],h,o)),o},$getChildren:function(t,e){var i=this.rootGroup.options,o=i[e+"Path"],e=i[e+"Selector"];return t=l(t),(t=o?t.find(o):t).children(e)},_serialize:function(t,e){var i=this,o=this.$getChildren(t,e?"item":"container").not(this.options.exclude).map(function(){return i._serialize(l(this),!e)}).get();return this.rootGroup.options.serialize(t,o,e)},traverse:function(i){l.each(this.items||[],function(t){var e=l.data(this,h);e&&e.traverse(i)}),i(this)},_clearDimensions:function(){this.itemDimensions=r},_destroy:function(){var e=this;this.target.off(a.start,this.handle),this.el.removeData(s),this.options.drop&&(this.group.containers=l.grep(this.group.containers,function(t){return t!=e})),l.each(this.items||[],function(){l.removeData(this,h)})}};var m={enable:function(){this.traverse(function(t){t.disabled=!1})},disable:function(){this.traverse(function(t){t.disabled=!0})},serialize:function(){return this._serialize(this.el,!0)},refresh:function(){this.traverse(function(t){t._clearDimensions()})},destroy:function(){this.traverse(function(t){t._destroy()})}};l.extend(g.prototype,m),l.fn[s]=function(i){var o=Array.prototype.slice.call(arguments,1);return this.map(function(){var t=l(this),e=t.data(s);return e&&m[i]?m[i].apply(e,o)||this:(e||i!==r&&"object"!==_typeof(i)||t.data(s,new g(t,i)),this)})}}(jQuery,(window,"wf_sortable"));
2
  //# sourceMappingURL=jquery-sortable.min.js.map
1
+ "use strict";function _typeof(t){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}!function(l,s,r){var i={drag:!0,drop:!0,exclude:"",nested:!0,vertical:!0},o={afterMove:function(t,e,i){},containerPath:"",containerSelector:"ol, ul",distance:0,delay:0,handle:"",itemPath:"",itemSelector:"li",bodyClass:"dragging",draggedClass:"dragged",isValidTarget:function(t,e){return!0},onCancel:function(t,e,i,o){},onDrag:function(t,e,i,o){t.css(e)},onDragStart:function(t,e,i,o){t.css({height:t.outerHeight(),width:t.outerWidth()}),t.addClass(e.group.options.draggedClass),l("body").addClass(e.group.options.bodyClass)},onDrop:function(t,e,i,o){t.removeClass(e.group.options.draggedClass).removeAttr("style"),l("body").removeClass(e.group.options.bodyClass)},onMousedown:function(t,e,i){if(!i.target.nodeName.match(/^(input|select|textarea)$/i))return i.preventDefault(),!0},placeholderClass:"placeholder",placeholder:'<li class="placeholder"></li>',pullPlaceholder:!0,serialize:function(t,e,i){t=l.extend({},t.data());return i?[e]:(e[0]&&(t.children=e),delete t.subContainers,delete t.sortable,t)},tolerance:0},e={},n=0,c={left:0,top:0,bottom:0,right:0},a={start:"touchstart.sortable mousedown.sortable",drop:"touchend.sortable touchcancel.sortable mouseup.sortable",drag:"touchmove.sortable mousemove.sortable",scroll:"scroll.sortable"},h="subContainers";function u(t,e){return Math.max(0,t[0]-e[0],e[0]-t[1])+Math.max(0,t[2]-e[1],e[1]-t[3])}function t(t,e,i,o){var s=t.length,n=o?"offset":"position";for(i=i||0;s--;){var r=t[s].el||l(t[s]),a=r[n]();a.left+=parseInt(r.css("margin-left"),10),a.top+=parseInt(r.css("margin-top"),10),e[s]=[a.left-i,a.left+r.outerWidth()+i,a.top-i,a.top+r.outerHeight()+i]}}function p(t,e){e=e.offset();return{left:t.left-e.left,top:t.top-e.top}}function f(t,e,i){e=[e.left,e.top],i=i&&[i.left,i.top];for(var o,s=t.length,n=[];s--;)o=t[s],n[s]=[s,u(o,e),i&&u(o,i)];return n=n.sort(function(t,e){return e[1]-t[1]||e[2]-t[2]||e[0]-t[0]})}function d(t){this.options=l.extend({},o,t),this.containers=[],this.options.rootGroup||(this.scrollProxy=l.proxy(this.scroll,this),this.dragProxy=l.proxy(this.drag,this),this.dropProxy=l.proxy(this.drop,this),this.placeholder=l(this.options.placeholder),t.isValidTarget||(this.options.isValidTarget=r))}function g(t,e){this.el=t,this.options=l.extend({},i,e),this.group=d.get(this.options),this.rootGroup=this.options.rootGroup||this.group,this.handle=this.rootGroup.options.handle||this.rootGroup.options.itemSelector;t=this.rootGroup.options.itemPath;this.target=t?this.el.find(t):this.el,this.target.on(a.start,this.handle,l.proxy(this.dragInit,this)),this.options.drop&&this.group.containers.push(this)}d.get=function(t){return e[t.group]||(t.group===r&&(t.group=n++),e[t.group]=new d(t)),e[t.group]},d.prototype={dragInit:function(t,e){this.$document=l(e.el[0].ownerDocument);var i=l(t.target).closest(this.options.itemSelector);i.length&&(this.item=i,this.itemContainer=e,!this.item.is(this.options.exclude)&&this.options.onMousedown(this.item,o.onMousedown,t)&&(this.setPointer(t),this.toggleListeners("on"),this.setupDelayTimer(),this.dragInitDone=!0))},drag:function(t){if(!this.dragging){if(!this.distanceMet(t)||!this.delayMet)return;this.options.onDragStart(this.item,this.itemContainer,o.onDragStart,t),this.item.before(this.placeholder),this.dragging=!0}this.setPointer(t),this.options.onDrag(this.item,p(this.pointer,this.item.offsetParent()),o.onDrag,t);var t=this.getPointer(t),e=this.sameResultBox,i=this.options.tolerance;(!e||e.top-i>t.top||e.bottom+i<t.top||e.left-i>t.left||e.right+i<t.left)&&!this.searchValidTarget()&&(this.placeholder.detach(),this.lastAppendedItem=r)},drop:function(t){this.toggleListeners("off"),this.dragInitDone=!1,this.dragging&&(this.placeholder.closest("html")[0]?this.placeholder.before(this.item).detach():this.options.onCancel(this.item,this.itemContainer,o.onCancel,t),this.options.onDrop(this.item,this.getContainer(this.item),o.onDrop,t),this.clearDimensions(),this.clearOffsetParent(),this.lastAppendedItem=this.sameResultBox=r,this.dragging=!1)},searchValidTarget:function(t,e){t||(t=this.relativePointer||this.pointer,e=this.lastRelativePointer||this.lastPointer);for(var i=f(this.getContainerDimensions(),t,e),o=i.length;o--;){var s=i[o][0];if(!i[o][1]||this.options.pullPlaceholder){var n,s=this.containers[s];if(!s.disabled)if(this.$getOffsetParent()||(t=p(t,n=s.getItemOffsetParent()),e=p(e,n)),s.searchValidTarget(t,e))return!0}}this.sameResultBox&&(this.sameResultBox=r)},movePlaceholder:function(t,e,i,o){var s=this.lastAppendedItem;!o&&s&&s[0]===e[0]||(e[i](this.placeholder),this.lastAppendedItem=e,this.sameResultBox=o,this.options.afterMove(this.placeholder,t,e))},getContainerDimensions:function(){return this.containerDimensions||t(this.containers,this.containerDimensions=[],this.options.tolerance,!this.$getOffsetParent()),this.containerDimensions},getContainer:function(t){return t.closest(this.options.containerSelector).data(s)},$getOffsetParent:function(){if(this.offsetParent===r){var t=this.containers.length-1,e=this.containers[t].getItemOffsetParent();if(!this.options.rootGroup)for(;t--;)if(e[0]!=this.containers[t].getItemOffsetParent()[0]){e=!1;break}this.offsetParent=e}return this.offsetParent},setPointer:function(t){var e,t=this.getPointer(t);this.$getOffsetParent()&&(e=p(t,this.$getOffsetParent()),this.lastRelativePointer=this.relativePointer,this.relativePointer=e),this.lastPointer=this.pointer,this.pointer=t},distanceMet:function(t){t=this.getPointer(t);return Math.max(Math.abs(this.pointer.left-t.left),Math.abs(this.pointer.top-t.top))>=this.options.distance},getPointer:function(t){var e=t.originalEvent||t.originalEvent.touches&&t.originalEvent.touches[0];return{left:t.pageX||e.pageX,top:t.pageY||e.pageY}},setupDelayTimer:function(){var t=this;this.delayMet=!this.options.delay,this.delayMet||(clearTimeout(this._mouseDelayTimer),this._mouseDelayTimer=setTimeout(function(){t.delayMet=!0},this.options.delay))},scroll:function(t){this.clearDimensions(),this.clearOffsetParent()},toggleListeners:function(i){var o=this;l.each(["drag","drop","scroll"],function(t,e){o.$document[i](a[e],o[e+"Proxy"])})},clearOffsetParent:function(){this.offsetParent=r},clearDimensions:function(){this.traverse(function(t){t._clearDimensions()})},traverse:function(t){t(this);for(var e=this.containers.length;e--;)this.containers[e].traverse(t)},_clearDimensions:function(){this.containerDimensions=r},_destroy:function(){e[this.options.group]=r}};var m={enable:function(){this.traverse(function(t){t.disabled=!1})},disable:function(){this.traverse(function(t){t.disabled=!0})},serialize:function(){return this._serialize(this.el,!0)},refresh:function(){this.traverse(function(t){t._clearDimensions()})},destroy:function(){this.traverse(function(t){t._destroy()})}};l.extend(g.prototype={dragInit:function(t){var e=this.rootGroup;!this.disabled&&!e.dragInitDone&&this.options.drag&&this.isValidDrag(t)&&e.dragInit(t,this)},isValidDrag:function(t){return 1==t.which||"touchstart"==t.type&&1==t.originalEvent.touches.length},searchValidTarget:function(t,e){var i=f(this.getItemDimensions(),t,e),o=i.length,s=this.rootGroup,n=!s.options.isValidTarget||s.options.isValidTarget(s.item,this);if(!o&&n)return s.movePlaceholder(this,this.target,"append"),!0;for(;o--;){var r=i[o][0],a=i[o][1];if(!a&&this.hasChildGroup(r)){if(this.getContainerGroup(r).searchValidTarget(t,e))return!0}else if(n)return this.movePlaceholder(r,t),!0}},movePlaceholder:function(t,e){var i,o=l(this.items[t]),s=this.itemDimensions[t],n="after",r=o.outerWidth(),a=o.outerHeight(),h=o.offset(),h={left:h.left,right:h.left+r,top:h.top,bottom:h.top+a};this.options.vertical?(i=(s[2]+s[3])/2,e.top<=i?(n="before",h.bottom-=a/2):h.top+=a/2):(i=(s[0]+s[1])/2,e.left<=i?(n="before",h.right-=r/2):h.left+=r/2),this.hasChildGroup(t)&&(h=c),this.rootGroup.movePlaceholder(this,o,n,h)},getItemDimensions:function(){return this.itemDimensions||(this.items=this.$getChildren(this.el,"item").filter(":not(."+this.group.options.placeholderClass+", ."+this.group.options.draggedClass+")").get(),t(this.items,this.itemDimensions=[],this.options.tolerance)),this.itemDimensions},getItemOffsetParent:function(){var t=this.el,t="relative"===t.css("position")||"absolute"===t.css("position")||"fixed"===t.css("position")?t:t.offsetParent();return t},hasChildGroup:function(t){return this.options.nested&&this.getContainerGroup(t)},getContainerGroup:function(t){var e,i,o=l.data(this.items[t],h);return o===r&&(o=!1,(e=this.$getChildren(this.items[t],"container"))[0]&&(i=l.extend({},this.options,{rootGroup:this.rootGroup,group:n++}),o=e[s](i).data(s).group),l.data(this.items[t],h,o)),o},$getChildren:function(t,e){var i=this.rootGroup.options,o=i[e+"Path"],i=i[e+"Selector"];return t=l(t),(t=o?t.find(o):t).children(i)},_serialize:function(t,e){var i=this,o=this.$getChildren(t,e?"item":"container").not(this.options.exclude).map(function(){return i._serialize(l(this),!e)}).get();return this.rootGroup.options.serialize(t,o,e)},traverse:function(i){l.each(this.items||[],function(t){var e=l.data(this,h);e&&e.traverse(i)}),i(this)},_clearDimensions:function(){this.itemDimensions=r},_destroy:function(){var e=this;this.target.off(a.start,this.handle),this.el.removeData(s),this.options.drop&&(this.group.containers=l.grep(this.group.containers,function(t){return t!=e})),l.each(this.items||[],function(){l.removeData(this,h)})}},m),l.fn[s]=function(i){var o=Array.prototype.slice.call(arguments,1);return this.map(function(){var t=l(this),e=t.data(s);return e&&m[i]?m[i].apply(e,o)||this:(e||i!==r&&"object"!==_typeof(i)||t.data(s,new g(t,i)),this)})}}(jQuery,(window,"wf_sortable"));
2
  //# sourceMappingURL=jquery-sortable.min.js.map
admin/js/jquery-sortable.min.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["jquery-sortable.js"],"names":["_typeof","Symbol","iterator","obj","constructor","prototype","nested","$","pluginName","undefined","containerDefaults","drag","groupDefaults","exclude","containerPath","containerSelector","afterMove","$placeholder","container","$closestItemOrContainer","distance","draggedClass","handle","itemPath","itemSelector","bodyClass","onDrag","isValidTarget","$item","css","_super","event","position","addClass","onDragStart","removeClass","onMousedown","preventDefault","group","options","placeholderClass","removeAttr","target","nodeName","match","placeholder","pullPlaceholder","parentIsContainer","result","sortable","serialize","$parent","$children","extend","data","containerGroups","groupCounter","emptyBox","subContainers","drop","subContainerKey","left","top","bottom","x","Math","i","length","d","a","b","offsetMethod","parseInt","el","getRelativePosition","element","sortByDistanceDesc","tolerance","offset","pointer","pos","distances","dimensions","outerWidth","outerHeight","dim","dropProxy","dragProxy","sort","proxy","ContainerGroup","get","this","containers","rootGroup","closestItem","item","disabled","itemDimensions","right","which","find","originalEvent","on","eventNames","start","dragInit","searchValidTarget","push","setPointer","dragInitDone","dragging","setupDelayTimer","box","itemContainer","e","toggleListeners","onCancel","detach","delayMet","clearDimensions","clearOffsetParent","relativePointer","lastPointer","sameResultBox","t","offsetParent","lastRelativePointer","getContainer","getContainerDimensions","onDrop","movePlaceholder","lastAppendedItem","$getOffsetParent","containerDimensions","setDimensions","closest","method","getPointer","getItemOffsetParent","that","distanceMet","events","$document","pageX","pageY","currentPointer","clearTimeout","abs","_mouseDelayTimer","o","touches","scroll","_clearDimensions","delay","each","setTimeout","callback","traverse","object","isValidDrag","Container","validTarget","_destroy","inUpperHalf","xCenter","inLeftHalf","index","getItemDimensions","hasChildGroup","items","getContainerGroup","childGroup","childContainers","yCenter","height","path","_serialize","width","removeData","enable","parent","$getChildren","type","isContainer","childType","children","selector","not","map","disable","off","grep","val","destroy","refresh","args","$t","API"],"mappings":"iCAKA,OAJAA,QADA,mBAAAC,QAAA,iBAAAA,OAAAC,SACA,SAAAC,GACA,cAAAA,GADA,SAAAA,GACA,OAAAA,GAAA,mBAAAF,QAAAE,EAAAC,cAAAH,QAAAE,IAAAF,OAAAI,UAAA,gBAAAF,IAGAA,IA+BYG,SAAAC,EAVZC,EAAAC,GAWmB,IAAAC,EAAA,CAXnBC,MAAA,EAcYC,MAAAA,EAGQC,QAAA,GAIRC,QAAAA,EAEAC,UAAAA,GAIAD,EAAAA,CAKAE,UAAA,SAAAC,EAAAC,EAAAC,KAbYL,cAAA,GAiBJC,kBAAA,SAERK,SAAA,EAGAC,MAAAA,EAEAC,OAAA,GAIAC,SAjCA,GAmCAC,aAAA,KA9BYC,UAAA,WAmCZC,aAAA,UAKQC,cAAA,SAAAC,EAAAV,GACEW,OAAAA,GAIVD,SAAAC,SAAAD,EAAAV,EAAAY,EAAAC,KAAAL,OAAA,SAAAE,EAAAI,EAAAF,EAAAC,GAIcH,EAAAA,IAAAK,IAOdC,YA7DA,SAAAN,EAAAV,EAAAY,EAAAC,GA8DQH,EAAAC,IAAA,CACEM,OAAAA,EAAAA,cACJC,MAAAA,EAAQD,eAEdJ,EAAAA,SAAAM,EAAAC,MAAAC,QAAAlB,cACAd,EAAA,QAAA0B,SAAAf,EAAAoB,MAAAC,QAAAd,YAGQM,OAAAA,SAAAA,EAAAA,EAAAA,EAAAA,GACAS,EAAAA,YAAAtB,EAAAoB,MAvERC,QAAAlB,cAAAoB,WAAA,SAwEKlC,EAAA,QAAA4B,YAAAjB,EAAAoB,MAAAC,QAAAd,YAILW,YAAA,SAAAR,EAAAE,EAAAC,GACA,IAAAA,EAAAW,OAAAC,SAAAC,MAAA,8BAEAC,OADAC,EAAAA,kBACAD,GAKAL,iBAAAO,cAWWC,YAAOC,gCAKlBH,iBAAA,EAlHZI,UAAA,SAAAC,EAAAC,EAAAL,GAoHWC,EAAAzC,EAAA8C,OAAA,GAAAF,EAAAG,QACHC,OAAAA,EArHR,CAAAH,IAsHQI,EAtHR,KAAAR,EAuHQS,SAAWL,UAAAJ,EAAAU,qBAAAV,EAAAC,SAIDD,IAIAW,UAAA,GAFGJ,EA7HrB,GAAAC,EAmIQI,EAGRH,EAAA,CACAI,KAAA,EACAC,IAAA,EAAAC,OAAA,E,SAEYC,EAAQC,CAARD,MACIC,yCACRN,KAAA,0DACHhD,KAAA,wC,0BAGOuD,EAAUC,gBAKJ,SACNC,EAAAC,EAAAC,GAGIR,OAFSS,KAAAA,IAAAA,EAAAA,EAAAA,GAAAA,EAFP,GAAAD,EAAA,GAAAD,EAAA,IAGFR,KAAJA,IAAIA,EAAQW,EAAAA,GAAY3C,EAAH4C,GAAO5C,EAAA,GAAAwC,EAAA,IAc5BR,SAAAA,EAAAA,EAAAA,EAAAA,EAAAA,G,eADGU,EAAPG,EAAO,SAAPC,WAMKC,IAFRC,EAAAA,GAAAC,EAEQF,KAAAA,CACEd,IAAAA,EAAIiB,EAAQlB,GAAAA,IAAcC,EAAAA,EAAAA,IAGjCkB,EAAAP,EAAAF,K,0CAAAS,EAAAlB,KAEImB,SAAAA,EAAAA,IAFJC,cAAAH,IAHAA,EAAUb,GAACa,CAAAA,EAAQlB,KAAMkB,EAAzBC,EAAAnB,KAAAY,EAAAU,aAAAN,EAAAG,EAAAlB,IAAAe,EAAAG,EAAAlB,IAAAW,EAAAW,cAAAP,IASII,SAJAA,EAIAA,EAAAA,G,aAGA,MAAA,CAGJI,KAAAN,EAAAG,KAAAJ,EAAAjB,KANIoB,IAAAA,EAAUf,IAAMA,EAAImB,KAGpB,SAAAT,EAAuBM,EAAhBH,EAAqCV,GAOpDU,EAEI,CAAAA,EAAAlB,KAAAkB,EAAAjB,K,oBAKI,IAVJ,IAAAuB,EAOAnB,EAAAgB,EAAAf,O,KAGSmB,KACLD,EAAKxC,EAALqB,G,0BAIH,OANGe,EAAKM,EAAaC,KAACC,SAAW9E,EAAb2D,GASzBoB,OAAAA,EAAeC,GAAAA,EAAAA,IAAMF,EAAAA,GAAWlD,EAAAA,IAAX+B,EAAoB,GAAzCoB,EAAAA,KAAAA,SAAAA,EAAqBnD,GAWrBmD,KAAAA,QAAAA,EAAAA,OAAAnD,GAAAA,EAA2BA,GACfqD,KAAAC,WAAEvD,GAMNsD,KAAArD,QAAAuD,Y,2CACAF,KAAAL,UAAIQ,EAAAA,MAAoBxD,KAAAA,KAAAD,MAnBhCsD,KAAAN,UAAA/E,EAAAkF,MAAAG,KAAAjC,KAAAiC,M,6CAWAF,EAAc/D,gBAAaiE,KAAArD,QAAAZ,cAAAlB,IAsOL,SAAAqF,EAAAnB,EAAAmB,G,UA2CVE,KAAAA,QAASC,EAAAA,OAAL,GACEH,EAAKI,GAGLJ,KAAAA,MAAAA,EAJVH,IAIUC,KAAArD,SACNuC,KAAAA,UAAAA,KAAAA,QAAAA,WAAAA,KAAAA,MALJc,KAJStE,OAAAsE,KAAAE,UAAAvD,QAAAjB,QAAAsE,KAAAE,UAAAvD,QAAAf,aAWDqC,EAAaA,KAAAA,UAAAA,QAAAA,SACbsC,KAAAA,OAAaC,EAANtB,KACFA,GAAFuB,KAASvC,GAAT8B,KAHSU,GAIZvC,KAdCrB,OAAA6D,GAAAC,EAAAC,MAAAb,KAAAtE,OAAAf,EAAAkF,MAAAG,KAAAc,SAAAd,OAITe,KAAAA,QAAAA,MAAAf,KAAAtD,MAAAuD,WAAAe,KAAA7B,MAnQIW,EAAKmB,IAAL,SAAAnE,G,OAEAa,EAAAhB,EAAAD,S,2BACAiB,EAAKuD,EAAe3C,OAApB,IAAAuB,EAAAnD,I,YAKImD,EAAArF,UAAA,C,uBAGCkC,KAAAA,UAAQL,EAAAA,EAARK,GAAAA,GAAAA,eAEAwE,IAAAA,EAALC,EAAAA,EAAAA,QAAKD,QAAAA,KAAAA,QAAAA,cA3BUhB,EAAA5B,SAoBvBxD,KAAIqF,KAAED,EAYGxD,KAAAA,cAAAA,GASFqD,KAAWrD,KAAAA,GAAHL,KAAAA,QAAuB+E,UAAArB,KAAAsB,QAAAA,YAA8BrD,KAAaA,KAAAA,EAA1EzB,YAAA+E,K,mBAMDvB,KAAAwB,gBA3Bc,M,uBA8BXN,KAAAA,cAALpF,KAKQf,KAAA,SAEa0G,GAhBrB,IAAAzB,KAAIqB,SAAWnD,CAEP,IAAA8B,KAAK/C,YAAYyE,KAAjB1B,KAAA2B,SAAA,OAmBCC,KAAAA,QAAAA,YAAAA,KAAL/G,KAAAA,KAAK+G,cAAAA,EAAAA,YAAAA,GACAC,KAAAA,KAAAA,OAAAA,KAAAA,aACL7B,KAhEemB,UAAA,EAoEvBJ,KAAAA,WAAAA,GAEQ5B,KAAAA,QAAUgC,OAAVhC,KAAe2C,KAAAA,EAAAA,KAAAA,QAAAA,KAAAA,KAAAA,gBAAAA,EAAAA,OAAAA,GACfC,IAAAA,EAAAA,KAAAA,WAAAA,GACHV,EAAArB,KAAAgC,cAjBOC,EAAAjC,KAAArD,QAAKM,YAmBToC,GAAYL,EAAAA,IAAAA,EAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,EAAAA,KAAAA,EAAAA,KAAAA,EAAAA,EAAAA,MAAAA,EAAAA,MAAAA,EAAAA,EAAAA,QAGRK,KAAAA,sBAnBHW,KAAA/C,YAAAyE,S,2BAID3D,KAAA,SAAK6D,GAqBDpG,KAAAA,gBAADqG,OACKvG,KAAAA,cAAAA,EACJ0E,KAAAmB,WAEQJ,KAAAA,YAAImB,QAAAA,QAAAA,GACJ/C,KAAAA,YAAUL,OAAAA,KAAAA,MAAAA,SAEbiD,KAAAA,QAAAA,SAAAI,KAAAA,KAAAA,KAAAA,cAAAJ,EAAAN,SAAAF,GAGJvB,KAAArD,QAAA0C,OAAAL,KAAAA,KAAAA,KAAAoD,aAAAC,KAAAA,MAAAA,EAAAC,OAERP,G,uBA/FkB/B,KAAA6B,oBAmGvBU,KAAAA,iBAAiBlD,KAAA2C,cAAjBO,EAAAA,KAAAA,UACwB,IAKfC,kBAAAA,SAAAA,EAAAA,G,IACAR,EAAAA,KAAL1G,iBAAA0E,KAAAb,QACa/D,EAAb4E,KAAuByC,qBAAkBnH,KAAAA,aA3GtB,IA8GVoH,IAAAA,EAAAA,EACLC,KAAAA,yBAAoCD,EAD/BA,GAEGA,EAAAA,EAAAA,OAhHOpE,KAAA,CAmHJsE,IAAAA,EAAAA,EAAAA,GAAAA,G,IAnHIvD,EAAAf,GAAA,I,8BAsHhB,IAAAhD,EAAK4G,KAAAA,WACSjC,GApBrBsC,IAAAA,EAAelC,SAnGQ,GA0HXmC,KAAAA,qBAIQpC,EAAAtB,EAAAK,EAHR6C,EAAA1G,EAAUkH,uBAIFT,EAAAS,EAAAT,EAAAG,IA/HG5G,EAAAyF,kBAAA5B,EAAA4C,GAAA,OAAA,GAwIlBK,KAAAA,gBAAApC,KAAAgC,cAAAnH,IACD0H,gBAzImB,SAAAjH,EAAA8E,EAAAyC,EAAAb,GAAAS,IAAAA,EAAAzC,KAAAwC,kBA2IvBvB,GAAYiB,GAAaM,EAAA,KAAApC,EAAA,KACjBjB,EAAAA,GAAUa,KAAK8C,aAAf3D,KAAAA,iBApBmBiB,E,qBAuBf0B,KAAAA,QAAAA,UAAkBhD,KAAAA,YAAAA,EAAAA,KAEjBgD,uBAAAA,WAnBO,OAoBf9B,KAAA0C,qBAAAC,EAAA3C,KAAAC,WAAAD,KAAA0C,oBAAA,GAAA1C,KAAArD,QAAAsC,WAAAe,KAAAyC,oBApBezC,KAAA0C,qBAuBhBN,aAAA,SAAArD,GArJmBmD,OAAAA,EAAAA,QAAAlC,KAAArD,QAAAxB,mBAAAuC,KAAA9C,IAwJD6H,iBAAA,WACV,GAAAzC,KAAAkC,eAAArH,EAAA,CAzJW,IAAAyD,EAAA0B,KAAAC,WAAA1B,OAAA,E,2CAgKZ,IAAAyB,KAAArD,QAAAuD,U,UACC,GAAAgC,EAAEA,IAAAA,KAAFjC,WAAA3B,GAAAyE,sBAAA,GAAA,CAKJC,GAAOP,EACNd,MAMGqB,KAAAA,aAAAA,EA7KWC,OAAAA,KAAAf,cAkLdN,WAAAA,SACAC,GAGL,IAtLmB1C,EAAAa,KAAA8C,WAAAvB,GAyLnBvB,KAAOkD,qBACCpB,EAACqB,EAAAA,EAAAA,KAAAA,oBADTlF,KAAAA,oBAAAmF,KACSD,gBA1LUjF,KAAAA,gBAAAmF,GAAAjC,KAAAA,YAAApB,KAAAb,QAgMvBa,KAAAb,QAAAA,G,wBAEImE,EAAAtD,KAAA8C,WAAAvB,GAlMmBgC,OAAAA,KAAAA,IAAAA,KAAAC,IAAAC,KAAAA,QAAAA,KAAAH,EAAArF,MAAAI,KAAAmF,IAAAxD,KAAAb,QAAAjB,IAAAoF,EAAApF,OAAA8B,KAAArD,QAAAnB,UAuMnBwH,WAAA,SAAAzB,GACQ,IAAAmC,EAAKzD,EAAAA,eAFPsB,EAAAb,cAAAiD,SAAApC,EAAAb,cAAAiD,QAAA,GAvBL,MAAA,CA0BD1F,KAzMmBsD,EAAA6B,OAAAM,EAAAN,MA0MfQ,IAAAA,EAAK3D,OAAAA,EAAAA,QAGb4D,gBA7MuB,WA8MnBrC,IAAAA,EAAAA,KA9MmBxB,KAAA2B,UAAA3B,KAAArD,QAAAmH,MAkNtBC,KAAAb,WAlNLF,aAAAG,KAAAM,kBA2LSzD,KAuBJyD,iBAAAO,WAAA,WAlNsBhB,EAAArB,UAAA,GAsNvBE,KAAAA,QAAAA,SAIA+B,OAAA,SAAArC,GACAK,KAAAA,kBAEIjG,KAAAA,qBAGCmB,gBAHDnB,SAAAA,GAKD,IAlOoBqH,EAAAhD,KAuMnBiE,EAAAA,KA6BP,CAAA,OAAA,OAAA,UA7BgB,SAAT3F,EAAAnC,GA+BE1B,EAAAA,UAAYwF,GAAAA,EAAZxF,GAAAA,EAAAA,EAAAA,aAEEyF,kBAASD,WA7BZD,KAAAkC,aAAArH,GAoCA+G,gBAAAc,WATa1C,KAtOKkE,SAAA,SAAAC,GAiPvBC,EAAAA,sBAjPuBF,SAA3B,SAAAD,G,QAsPQ,IAAA,IAAA3F,EAGK+F,KAAAA,WAAYtF,OAEbuF,KAGJtE,KAAGtD,WAAM4H,GAAAA,SAAYvE,IAKb8D,iBAAYxE,WAAZW,KAAA0C,oBACyBpE,GAGrBiG,SAAA,WAIA5G,EAAAqC,KAAArD,QAAAD,OAAA7B,IArBZwJ,EAIInE,UAAY,CAJhBY,SA0CO0D,SAAYtE,G,sBAKZA,KAAAA,WAAAqC,EAAArB,cAAAlB,KAAArD,QAAA5B,MAAAiF,KAAAoE,YAAA7C,IACCkD,EAAAA,SAAAA,EAAAA,OAEDC,YACUlJ,SAAT+F,G,4EAGAS,kBAAA,SAAA2C,EAAA5D,GACP,IAAA1B,EAAAL,EArCegB,KAAA4E,oBAAAzF,EAAA4C,GAsCR8C,EAAAA,EAEOtC,OA1EDrC,EAAAqC,KAAAA,UA4EC+B,GAAApE,EAAAvD,QAAAZ,eAAAmE,EAAAvD,QAAAZ,cAAAmE,EAAAE,KAAAJ,MAEN8E,IAAAA,GAAAA,EAIRvC,OADGI,EA1CKJ,gBAAAvC,KAAAA,KAAAlD,OAAA,WA2CRyF,EAvCD,KAwCO9C,KAAKa,CAxCZ,IAAAqE,EA3CctF,EA2Cdf,GAAA,GAAA9C,EA0CJuH,EAAqBxD,GAAAA,GA1CjB,IA4CSL,GACTkB,KAAAlB,cA7CAyF,IAOQ1G,GAuCR+D,KAAA+C,kBAAAJ,GAAA5D,kBAAA5B,EAAA4C,GAvCc7C,OAAOjB,OAwCXsC,GAAPrB,EA1FWf,OA8FP+D,KAAAA,gBALPyC,EAAAxF,IAzFchB,IAAAoE,gBAAA,SAAAoC,EAAAxF,GAAA,IAAAiB,EAmGlB2E,EAAAA,KAAAA,MAAmB5F,I,yBACX6F,EAAAA,QAzCInC,EAAAA,EAAMtD,aA0CAyC,EAAAA,EAAAA,cACNiD,EAFJD,EAGUhD,SAxCbA,EAAM,CA0CAiD,KAAAA,EAAAA,KAAAA,MACKtI,EAAAA,KAAmBwC,E,UACnBe,OAAAA,EAAAA,IAAgBA,GAGpB8E,KAHI9E,QAIP8B,UAxCJkD,GAAAzF,EAAA,GAAAA,EAAA,IAAA,E,UAhCQoD,EAAA,SAvCK+B,EAAAA,QAAAO,EAAA,GAoHNnD,EAAE1B,KAAA6E,EAAA,IAKAxC,GAAAA,EAAV,GAAAmC,EAAA,IAAA,EACGM,EAAAA,MAAAA,GAnFMvC,EAAA,SAwFbwC,EAAAA,OAAYC,EAAA,GACApD,EAAJc,MAAAA,EAAAA,G,6BAGWhD,KAAAE,UAHfqC,gBAAAvC,KAAAI,EAAAyC,EAAAb,IAWI4C,kBApGK,W,OAqGLC,KAAAA,iBAFJ7E,KAAA8E,MAAA9E,KAAArD,aAAAqD,KAAAnB,GAAAkG,QAAAA,OAAAJ,SAAA3E,KAAAtD,MAAAC,QAAAC,iBAAA,MAAAoD,KAAAtD,MAAAC,QAAAlB,aAAA,KAAAsE,MAMAkE,EAzGSjE,KAAA8E,MAAA9E,KAAAM,eAAA,GAAAN,KAAArD,QAAAsC,Y,qBAvCK8D,oBAAAkC,WAqJRD,I,UAIN9C,EAGejC,aADClC,EAAAA,IAAAA,aAFhB,aAAAc,EAAA5C,IAAA,aAAA,UAAA4C,EAAA5C,IAAA,YAAA4C,EAIQjB,EAAAA,eAJR,OAAAsE,GAQMqD,cAAAA,SAAAA,G,uDAETR,kBAAA,SAAAJ,G,IAIDa,EAKOC,E,0BAcEvB,OAnJIc,IAAAnK,IAiIJqJ,GAAS,GADlBsB,EAAQxF,KAAA0F,aAAWD,KAAAE,MAAAhB,GAAA,cACfhI,KAIG8I,EAAEA,EAAAA,OAAF,GAAAzF,KAAArD,QAAA,CACEuH,UACM7D,KAAAA,UART3D,MAAA+I,MAYFJ,EAAYA,EAAAA,GAAoBO,GAApBP,KAAZzK,GAAA8B,OAZE/B,EAAA+C,KAgBSmG,KAAAA,MAAAA,GAAP6B,EAAAG,IAIC3B,GAALA,aAAA,SAAAD,EAAA0B,GAGHhL,IAAAgC,EAAAqD,KAAA8E,UAAAnI,QAvBLyI,EAAAzI,EAAAgJ,EAAA,QA0BStB,EAAAA,EAET3H,EAAAwH,YAIJ,OAHAuB,EANS9K,EAAA8K,IAQTxB,EAAAA,EAAAwB,EAAAhF,KAAA2E,GA9JqBK,GAAAK,SAAAC,IAiKrBV,WAAA/E,SAAAzF,EAAA+K,GApDS,IA7GY5C,EAAAhD,KAmKL8F,EAAQ9F,KAACvF,aAATgL,EADZG,EAAA,OAAmB,aACPI,IAAAhG,KAAArD,QAAA1B,SAAAgL,IAAA,WAGE,OAAKnJ,EAALuI,WAANzE,EAAAA,OAAMgF,KACFzB,MAQJ,OAAOnE,KAAPrD,UAAAoB,QAVJT,UAAA2C,EAAA6F,EAAAF,IAxoBP1B,SAwoBO,SAAAD,GA5CItJ,EAAAA,KAAEoJ,KAAKe,OAAA,GAAc,SAAI1E,GACrBzF,IAAAA,EAAE4K,EAAAA,KAAWvF,KAAMhC,GADvBtB,GAAAA,EAAAwH,SAAAD,KAzHSA,EAAAjE,OAgIbwF,iBAAQ,WACJxF,KAAAM,eAAczF,GAEb0J,SAFD,WAGH,IALKvB,EAAAhD,KAMNkG,KAAAA,OAASC,IAAAvF,EAAAC,MAAWb,KAAAtE,QAChBsE,KAAAnB,GAAKqF,WAAStJ,GACVuJ,KAAAA,QAAO9D,OAAWL,KAAlBtD,MAAAuD,WAAAtF,EAAAyL,KAAApG,KAAAtD,MAAAuD,WAAA,SAAAoG,GACH,OAFDA,GAAArD,KAIJ1F,EAAAA,KAAAA,KAAWwH,OAAA,GAAA,WACPnK,EAAA4K,WAAOvF,KAAKqF,OAIRlB,IAAAA,EAAAA,CACHqB,OAFD,WAGHxF,KAlBKkE,SAAA,SAAAC,GAmBNmC,EAAOjG,UAAE,KAGJ6F,QAFD,WAGHlG,KAAAkE,SAAA,SAAAC,GAvBLA,EAAA9D,UAAA,KA6BJ/C,UAAA,WACA,OAAA0C,KAAAqF,WAAArF,KAAAnB,IAAA,IAEA0H,QAAA,WACAvG,KAAAkE,SAAA,SAAAC,GACAA,EAAAN,sBAEQyC,QAAIE,WAEJxG,KAAAkE,SAAY+B,SAAI9B,GACZA,EAAIsC,eAUP9L,EAAA8C,OAXD4G,EAAA5J,UAAAiM,+NAjoBIhM","file":"jquery-sortable.min.js","sourcesContent":["/* ===================================================\n * jquery-sortable.js v0.9.13\n * http://johnny.github.com/jquery-sortable/\n * ===================================================\n * Copyright (c) 2012 Jonas von Andrian\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * * The name of the author may not be used to endorse or promote products\n * derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * ========================================================== */\n/* eslint-disable */\n!function ( $, window, pluginName, undefined){\n var containerDefaults = {\n // If true, items can be dragged from this container\n drag: true,\n // If true, items can be droped onto this container\n drop: true,\n // Exclude items from being draggable, if the\n // selector matches the item\n exclude: \"\",\n // If true, search for nested containers within an item.If you nest containers,\n // either the original selector with which you call the plugin must only match the top containers,\n // or you need to specify a group (see the bootstrap nav example)\n nested: true,\n // If true, the items are assumed to be arranged vertically\n vertical: true\n }, // end container defaults\n groupDefaults = {\n // This is executed after the placeholder has been moved.\n // $closestItemOrContainer contains the closest item, the placeholder\n // has been put at or the closest empty Container, the placeholder has\n // been appended to.\n afterMove: function ($placeholder, container, $closestItemOrContainer) {\n },\n // The exact css path between the container and its items, e.g. \"> tbody\"\n containerPath: \"\",\n // The css selector of the containers\n containerSelector: \"ol, ul\",\n // Distance the mouse has to travel to start dragging\n distance: 0,\n // Time in milliseconds after mousedown until dragging should start.\n // This option can be used to prevent unwanted drags when clicking on an element.\n delay: 0,\n // The css selector of the drag handle\n handle: \"\",\n // The exact css path between the item and its subcontainers.\n // It should only match the immediate items of a container.\n // No item of a subcontainer should be matched. E.g. for ol>div>li the itemPath is \"> div\"\n itemPath: \"\",\n // The css selector of the items\n itemSelector: \"li\",\n // The class given to \"body\" while an item is being dragged\n bodyClass: \"dragging\",\n // The class giving to an item while being dragged\n draggedClass: \"dragged\",\n // Check if the dragged item may be inside the container.\n // Use with care, since the search for a valid container entails a depth first search\n // and may be quite expensive.\n isValidTarget: function ($item, container) {\n return true\n },\n // Executed before onDrop if placeholder is detached.\n // This happens if pullPlaceholder is set to false and the drop occurs outside a container.\n onCancel: function ($item, container, _super, event) {\n },\n // Executed at the beginning of a mouse move event.\n // The Placeholder has not been moved yet.\n onDrag: function ($item, position, _super, event) {\n $item.css(position)\n },\n // Called after the drag has been started,\n // that is the mouse button is being held down and\n // the mouse is moving.\n // The container is the closest initialized container.\n // Therefore it might not be the container, that actually contains the item.\n onDragStart: function ($item, container, _super, event) {\n $item.css({\n height: $item.outerHeight(),\n width: $item.outerWidth()\n })\n $item.addClass(container.group.options.draggedClass)\n $(\"body\").addClass(container.group.options.bodyClass)\n },\n // Called when the mouse button is being released\n onDrop: function ($item, container, _super, event) {\n $item.removeClass(container.group.options.draggedClass).removeAttr(\"style\")\n $(\"body\").removeClass(container.group.options.bodyClass)\n },\n // Called on mousedown. If falsy value is returned, the dragging will not start.\n // Ignore if element clicked is input, select or textarea\n onMousedown: function ($item, _super, event) {\n if (!event.target.nodeName.match(/^(input|select|textarea)$/i)) {\n event.preventDefault()\n return true\n }\n },\n // The class of the placeholder (must match placeholder option markup)\n placeholderClass: \"placeholder\",\n // Template for the placeholder. Can be any valid jQuery input\n // e.g. a string, a DOM element.\n // The placeholder must have the class \"placeholder\"\n placeholder: '<li class=\"placeholder\"></li>',\n // If true, the position of the placeholder is calculated on every mousemove.\n // If false, it is only calculated when the mouse is above a container.\n pullPlaceholder: true,\n // Specifies serialization of the container group.\n // The pair $parent/$children is either container/items or item/subcontainers.\n serialize: function ($parent, $children, parentIsContainer) {\n var result = $.extend({}, $parent.data())\n\n if(parentIsContainer)\n return [$children]\n else if ($children[0]){\n result.children = $children\n }\n\n delete result.subContainers\n delete result.sortable\n\n return result\n },\n // Set tolerance while dragging. Positive values decrease sensitivity,\n // negative values increase it.\n tolerance: 0\n }, // end group defaults\n containerGroups = {},\n groupCounter = 0,\n emptyBox = {\n left: 0,\n top: 0,\n bottom: 0,\n right:0\n },\n eventNames = {\n start: \"touchstart.sortable mousedown.sortable\",\n drop: \"touchend.sortable touchcancel.sortable mouseup.sortable\",\n drag: \"touchmove.sortable mousemove.sortable\",\n scroll: \"scroll.sortable\"\n },\n subContainerKey = \"subContainers\"\n\n /*\n * a is Array [left, right, top, bottom]\n * b is array [left, top]\n */\n function d(a,b) {\n var x = Math.max(0, a[0] - b[0], b[0] - a[1]),\n y = Math.max(0, a[2] - b[1], b[1] - a[3])\n return x+y;\n }\n\n function setDimensions(array, dimensions, tolerance, useOffset) {\n var i = array.length,\n offsetMethod = useOffset ? \"offset\" : \"position\"\n tolerance = tolerance || 0\n\n while(i--){\n var el = array[i].el ? array[i].el : $(array[i]),\n // use fitting method\n pos = el[offsetMethod]()\n pos.left += parseInt(el.css('margin-left'), 10)\n pos.top += parseInt(el.css('margin-top'),10)\n dimensions[i] = [\n pos.left - tolerance,\n pos.left + el.outerWidth() + tolerance,\n pos.top - tolerance,\n pos.top + el.outerHeight() + tolerance\n ]\n }\n }\n\n function getRelativePosition(pointer, element) {\n var offset = element.offset()\n return {\n left: pointer.left - offset.left,\n top: pointer.top - offset.top\n }\n }\n\n function sortByDistanceDesc(dimensions, pointer, lastPointer) {\n pointer = [pointer.left, pointer.top]\n lastPointer = lastPointer && [lastPointer.left, lastPointer.top]\n\n var dim,\n i = dimensions.length,\n distances = []\n\n while(i--){\n dim = dimensions[i]\n distances[i] = [i,d(dim,pointer), lastPointer && d(dim, lastPointer)]\n }\n distances = distances.sort(function (a,b) {\n return b[1] - a[1] || b[2] - a[2] || b[0] - a[0]\n })\n\n // last entry is the closest\n return distances\n }\n\n function ContainerGroup(options) {\n this.options = $.extend({}, groupDefaults, options)\n this.containers = []\n\n if(!this.options.rootGroup){\n this.scrollProxy = $.proxy(this.scroll, this)\n this.dragProxy = $.proxy(this.drag, this)\n this.dropProxy = $.proxy(this.drop, this)\n this.placeholder = $(this.options.placeholder)\n\n if(!options.isValidTarget)\n this.options.isValidTarget = undefined\n }\n }\n\n ContainerGroup.get = function (options) {\n if(!containerGroups[options.group]) {\n if(options.group === undefined)\n options.group = groupCounter ++\n\n containerGroups[options.group] = new ContainerGroup(options)\n }\n\n return containerGroups[options.group]\n }\n\n ContainerGroup.prototype = {\n dragInit: function (e, itemContainer) {\n this.$document = $(itemContainer.el[0].ownerDocument)\n\n // get item to drag\n var closestItem = $(e.target).closest(this.options.itemSelector);\n // using the length of this item, prevents the plugin from being started if there is no handle being clicked on.\n // this may also be helpful in instantiating multidrag.\n if (closestItem.length) {\n this.item = closestItem;\n this.itemContainer = itemContainer;\n if (this.item.is(this.options.exclude) || !this.options.onMousedown(this.item, groupDefaults.onMousedown, e)) {\n return;\n }\n this.setPointer(e);\n this.toggleListeners('on');\n this.setupDelayTimer();\n this.dragInitDone = true;\n }\n },\n drag: function (e) {\n if(!this.dragging){\n if(!this.distanceMet(e) || !this.delayMet)\n return\n\n this.options.onDragStart(this.item, this.itemContainer, groupDefaults.onDragStart, e)\n this.item.before(this.placeholder)\n this.dragging = true\n }\n\n this.setPointer(e)\n // place item under the cursor\n this.options.onDrag(this.item,\n getRelativePosition(this.pointer, this.item.offsetParent()),\n groupDefaults.onDrag,\n e)\n\n var p = this.getPointer(e),\n box = this.sameResultBox,\n t = this.options.tolerance\n\n if(!box || box.top - t > p.top || box.bottom + t < p.top || box.left - t > p.left || box.right + t < p.left)\n if(!this.searchValidTarget()){\n this.placeholder.detach()\n this.lastAppendedItem = undefined\n }\n },\n drop: function (e) {\n this.toggleListeners('off')\n\n this.dragInitDone = false\n\n if(this.dragging){\n // processing Drop, check if placeholder is detached\n if(this.placeholder.closest(\"html\")[0]){\n this.placeholder.before(this.item).detach()\n } else {\n this.options.onCancel(this.item, this.itemContainer, groupDefaults.onCancel, e)\n }\n this.options.onDrop(this.item, this.getContainer(this.item), groupDefaults.onDrop, e)\n\n // cleanup\n this.clearDimensions()\n this.clearOffsetParent()\n this.lastAppendedItem = this.sameResultBox = undefined\n this.dragging = false\n }\n },\n searchValidTarget: function (pointer, lastPointer) {\n if(!pointer){\n pointer = this.relativePointer || this.pointer\n lastPointer = this.lastRelativePointer || this.lastPointer\n }\n\n var distances = sortByDistanceDesc(this.getContainerDimensions(),\n pointer,\n lastPointer),\n i = distances.length\n\n while(i--){\n var index = distances[i][0],\n distance = distances[i][1]\n\n if(!distance || this.options.pullPlaceholder){\n var container = this.containers[index]\n if(!container.disabled){\n if(!this.$getOffsetParent()){\n var offsetParent = container.getItemOffsetParent()\n pointer = getRelativePosition(pointer, offsetParent)\n lastPointer = getRelativePosition(lastPointer, offsetParent)\n }\n if(container.searchValidTarget(pointer, lastPointer))\n return true\n }\n }\n }\n if(this.sameResultBox)\n this.sameResultBox = undefined\n },\n movePlaceholder: function (container, item, method, sameResultBox) {\n var lastAppendedItem = this.lastAppendedItem\n if(!sameResultBox && lastAppendedItem && lastAppendedItem[0] === item[0])\n return;\n\n item[method](this.placeholder)\n this.lastAppendedItem = item\n this.sameResultBox = sameResultBox\n this.options.afterMove(this.placeholder, container, item)\n },\n getContainerDimensions: function () {\n if(!this.containerDimensions)\n setDimensions(this.containers, this.containerDimensions = [], this.options.tolerance, !this.$getOffsetParent())\n return this.containerDimensions\n },\n getContainer: function (element) {\n return element.closest(this.options.containerSelector).data(pluginName)\n },\n $getOffsetParent: function () {\n if(this.offsetParent === undefined){\n var i = this.containers.length - 1,\n offsetParent = this.containers[i].getItemOffsetParent()\n\n if(!this.options.rootGroup){\n while(i--){\n if(offsetParent[0] != this.containers[i].getItemOffsetParent()[0]){\n // If every container has the same offset parent,\n // use position() which is relative to this parent,\n // otherwise use offset()\n // compare #setDimensions\n offsetParent = false\n break;\n }\n }\n }\n\n this.offsetParent = offsetParent\n }\n return this.offsetParent\n },\n setPointer: function (e) {\n var pointer = this.getPointer(e)\n\n if(this.$getOffsetParent()){\n var relativePointer = getRelativePosition(pointer, this.$getOffsetParent())\n this.lastRelativePointer = this.relativePointer\n this.relativePointer = relativePointer\n }\n\n this.lastPointer = this.pointer\n this.pointer = pointer\n },\n distanceMet: function (e) {\n var currentPointer = this.getPointer(e)\n return (Math.max(\n Math.abs(this.pointer.left - currentPointer.left),\n Math.abs(this.pointer.top - currentPointer.top)\n ) >= this.options.distance)\n },\n getPointer: function(e) {\n var o = e.originalEvent || e.originalEvent.touches && e.originalEvent.touches[0]\n return {\n left: e.pageX || o.pageX,\n top: e.pageY || o.pageY\n }\n },\n setupDelayTimer: function () {\n var that = this\n this.delayMet = !this.options.delay\n\n // init delay timer if needed\n if (!this.delayMet) {\n clearTimeout(this._mouseDelayTimer);\n this._mouseDelayTimer = setTimeout(function() {\n that.delayMet = true\n }, this.options.delay)\n }\n },\n scroll: function (e) {\n this.clearDimensions()\n this.clearOffsetParent() // TODO is this needed?\n },\n toggleListeners: function (method) {\n var that = this,\n events = ['drag','drop','scroll']\n\n $.each(events,function (i,event) {\n that.$document[method](eventNames[event], that[event + 'Proxy'])\n })\n },\n clearOffsetParent: function () {\n this.offsetParent = undefined\n },\n // Recursively clear container and item dimensions\n clearDimensions: function () {\n this.traverse(function(object){\n object._clearDimensions()\n })\n },\n traverse: function(callback) {\n callback(this)\n var i = this.containers.length\n while(i--){\n this.containers[i].traverse(callback)\n }\n },\n _clearDimensions: function(){\n this.containerDimensions = undefined\n },\n _destroy: function () {\n containerGroups[this.options.group] = undefined\n }\n }\n\n function Container(element, options) {\n this.el = element\n this.options = $.extend( {}, containerDefaults, options)\n\n this.group = ContainerGroup.get(this.options)\n this.rootGroup = this.options.rootGroup || this.group\n this.handle = this.rootGroup.options.handle || this.rootGroup.options.itemSelector\n\n var itemPath = this.rootGroup.options.itemPath\n this.target = itemPath ? this.el.find(itemPath) : this.el\n\n this.target.on(eventNames.start, this.handle, $.proxy(this.dragInit, this))\n\n if(this.options.drop)\n this.group.containers.push(this)\n }\n\n Container.prototype = {\n dragInit: function (e) {\n var rootGroup = this.rootGroup\n\n if( !this.disabled &&\n !rootGroup.dragInitDone &&\n this.options.drag &&\n this.isValidDrag(e)) {\n rootGroup.dragInit(e, this)\n }\n },\n isValidDrag: function(e) {\n return e.which == 1 ||\n e.type == \"touchstart\" && e.originalEvent.touches.length == 1\n },\n searchValidTarget: function (pointer, lastPointer) {\n var distances = sortByDistanceDesc(this.getItemDimensions(),\n pointer,\n lastPointer),\n i = distances.length,\n rootGroup = this.rootGroup,\n validTarget = !rootGroup.options.isValidTarget ||\n rootGroup.options.isValidTarget(rootGroup.item, this)\n\n if(!i && validTarget){\n rootGroup.movePlaceholder(this, this.target, \"append\")\n return true\n } else\n while(i--){\n var index = distances[i][0],\n distance = distances[i][1]\n if(!distance && this.hasChildGroup(index)){\n var found = this.getContainerGroup(index).searchValidTarget(pointer, lastPointer)\n if(found)\n return true\n }\n else if(validTarget){\n this.movePlaceholder(index, pointer)\n return true\n }\n }\n },\n movePlaceholder: function (index, pointer) {\n var item = $(this.items[index]),\n dim = this.itemDimensions[index],\n method = \"after\",\n width = item.outerWidth(),\n height = item.outerHeight(),\n offset = item.offset(),\n sameResultBox = {\n left: offset.left,\n right: offset.left + width,\n top: offset.top,\n bottom: offset.top + height\n }\n if(this.options.vertical){\n var yCenter = (dim[2] + dim[3]) / 2,\n inUpperHalf = pointer.top <= yCenter\n if(inUpperHalf){\n method = \"before\"\n sameResultBox.bottom -= height / 2\n } else\n sameResultBox.top += height / 2\n } else {\n var xCenter = (dim[0] + dim[1]) / 2,\n inLeftHalf = pointer.left <= xCenter\n if(inLeftHalf){\n method = \"before\"\n sameResultBox.right -= width / 2\n } else\n sameResultBox.left += width / 2\n }\n if(this.hasChildGroup(index))\n sameResultBox = emptyBox\n this.rootGroup.movePlaceholder(this, item, method, sameResultBox)\n },\n getItemDimensions: function () {\n if(!this.itemDimensions){\n this.items = this.$getChildren(this.el, \"item\").filter(\n \":not(.\" + this.group.options.placeholderClass + \", .\" + this.group.options.draggedClass + \")\"\n ).get()\n setDimensions(this.items, this.itemDimensions = [], this.options.tolerance)\n }\n return this.itemDimensions\n },\n getItemOffsetParent: function () {\n var offsetParent,\n el = this.el\n // Since el might be empty we have to check el itself and\n // can not do something like el.children().first().offsetParent()\n if(el.css(\"position\") === \"relative\" || el.css(\"position\") === \"absolute\" || el.css(\"position\") === \"fixed\")\n offsetParent = el\n else\n offsetParent = el.offsetParent()\n return offsetParent\n },\n hasChildGroup: function (index) {\n return this.options.nested && this.getContainerGroup(index)\n },\n getContainerGroup: function (index) {\n var childGroup = $.data(this.items[index], subContainerKey)\n if( childGroup === undefined){\n var childContainers = this.$getChildren(this.items[index], \"container\")\n childGroup = false\n\n if(childContainers[0]){\n var options = $.extend({}, this.options, {\n rootGroup: this.rootGroup,\n group: groupCounter ++\n })\n childGroup = childContainers[pluginName](options).data(pluginName).group\n }\n $.data(this.items[index], subContainerKey, childGroup)\n }\n return childGroup\n },\n $getChildren: function (parent, type) {\n var options = this.rootGroup.options,\n path = options[type + \"Path\"],\n selector = options[type + \"Selector\"]\n\n parent = $(parent)\n if(path)\n parent = parent.find(