Version Description
- Fix: A PHP warning was shown on a product bundle page on the front end (when using WooCommerce Product Bundles)
- Fix: Added possibility to filter available Currency Switcher templates paths via "wcml_cs_directories_to_scan" filter
- Fix: The "Copy to a new draft" link was showing two times on the product edit page
- Fix: For taxonomies having the term_id distinct from term_taxonomy_id, the translations could have been accidentally overwritten
- Fix: In some conditions, a fatal error could come up when editing a product
- Fix: In some circustances, disabling currency switcher on product page produced a fatal error
- Fix: Custom attributes in the translations were reset after editing the original product
- Fix: Sometimes, the translated product category pages were returning a 404 error
- Fix: It was not possible to filter products by price on the shop page using the WooCommerce Price Filter widget
Download this release
Release Info
Developer | mihaimihai |
Plugin | WooCommerce Multilingual – run WooCommerce with WPML |
Version | 4.1.4 |
Comparing to | |
See all releases |
Code changes from version 4.1.3 to 4.1.4
- changelog/4.1.1.md +6 -0
- changelog/4.1.2.md +6 -0
- changelog/4.1.4.md +10 -0
- compatibility/class-wcml-product-bundles.php +320 -312
- inc/class-wcml-emails.php +1 -1
- inc/class-wcml-url-translation.php +7 -14
- inc/class-woocommerce-wpml.php +2 -0
- inc/currencies/class-wcml-price-filter.php +52 -0
- inc/currencies/currency-switcher/class-wcml-currency-switcher-templates.php +8 -8
- inc/translation-editor/class-wcml-editor-ui-product-job.php +44 -30
- inc/translation-editor/class-wcml-wc-admin-duplicate-product.php +6 -4
- readme.txt +21 -8
- vendor/autoload.php +1 -1
- vendor/autoload_52.php +1 -1
- vendor/composer/autoload_classmap.php +1 -0
- vendor/composer/autoload_real.php +4 -4
- vendor/composer/autoload_real_52.php +3 -3
- vendor/composer/autoload_static.php +6 -5
- vendor/otgs/installer/includes/class-installer-dependencies.php +1 -1
- vendor/otgs/installer/includes/installer.class.php +39 -60
- vendor/otgs/installer/installer.php +1 -1
- vendor/otgs/installer/loader.php +1 -1
- vendor/twig/twig/CHANGELOG +10 -1
- vendor/twig/twig/ext/twig/php_twig.h +1 -1
- vendor/twig/twig/lib/Twig/Cache/Filesystem.php +7 -2
- vendor/twig/twig/lib/Twig/Environment.php +3 -3
- vendor/twig/twig/lib/Twig/Extension/Core.php +28 -3
- vendor/twig/twig/lib/Twig/Loader/Array.php +1 -1
- vendor/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php +1 -1
- vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php +4 -0
- wpml-config.xml +1 -0
- wpml-woocommerce.php +19 -17
changelog/4.1.1.md
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Fixes
|
2 |
+
* [wcml-1858] Fixed a pre PHP 5.4 compatibility issue
|
3 |
+
* [wcml-1856] Fixed `Notice: Undefined index: switcher_id`
|
4 |
+
* [wcml-1855] Fixed `Fatal error: Class ‘WPML_File’ not found` when using an old version of WPML
|
5 |
+
* [wcml-1854] Fixed "Invalid or duplicated SKU" error when saving or updating a product with SKU
|
6 |
+
* [wcml-1853] Fixed `Fatal error: Call to undefined function WC()` when disabling WooCommerce while WCML is running
|
changelog/4.1.2.md
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Fixes
|
2 |
+
* [wcml-1867] Fixed `Fatal error: Call to undefined method WPML_WP_API::defined`
|
3 |
+
* [wcml-1864] Fixed the currency switcher not being displayed correctly when using the Storefront theme
|
4 |
+
* [wcml-1863] Fixed `Fatal error: Call to undefined function wc_format_decimal()`
|
5 |
+
* [wcml-1862] Fixed a bug causing an error when upgrading WooCommerce Multilingual to version 4.1 with WooCommerce inactive.
|
6 |
+
* [wcml-1860] ixed the currency switcher css being loaded when no currency switcher was displayed
|
changelog/4.1.4.md
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Fixes
|
2 |
+
* [wcml-1954] A PHP warning was shown on a product bundle page on the front end (when using WooCommerce Product Bundles)
|
3 |
+
* [wcml-1949] Added possibility to filter available Currency Switcher templates paths via "wcml_cs_directories_to_scan" filter
|
4 |
+
* [wcml-1948] The "Copy to a new draft" link was showing two times on the product edit page
|
5 |
+
* [wcml-1947] For taxonomies having the term_id distinct from term_taxonomy_id, the translations could have been accidentally overwritten
|
6 |
+
* [wcml-1945] In some conditions, a fatal error could come up when editing a product
|
7 |
+
* [wcml-1944] In some circustances, disabling currency switcher on product page produced a fatal error
|
8 |
+
* [wcml-1938] Custom attributes in the translations were reset after editing the original product
|
9 |
+
* [wcml-1935] Sometimes, the translated product category pages were returning a 404 error
|
10 |
+
* [wcml-1931] It was not possible to filter products by price on the shop page using the WooCommerce Price Filter widget
|
compatibility/class-wcml-product-bundles.php
CHANGED
@@ -1,91 +1,94 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class WCML_Product_Bundles{
|
4 |
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
|
20 |
/**
|
21 |
* @var WCML_WC_Product_Bundles_Items
|
22 |
*/
|
23 |
private $product_bundles_items;
|
24 |
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
|
34 |
add_action( 'woocommerce_get_cart_item_from_session', array( $this, 'resync_bundle' ), 5, 3 );
|
35 |
add_filter( 'woocommerce_cart_loaded_from_session', array( $this, 'resync_bundle_clean' ), 10 );
|
36 |
|
37 |
-
|
38 |
-
|
39 |
|
40 |
-
|
41 |
-
|
|
|
|
|
|
|
42 |
|
43 |
-
|
44 |
-
|
45 |
|
46 |
-
|
47 |
-
|
48 |
|
49 |
-
|
50 |
|
51 |
-
|
52 |
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
|
58 |
-
|
59 |
|
60 |
-
private function get_product_bundle_data( $bundle_id ){
|
61 |
$product_bundle_data = array();
|
62 |
|
63 |
$bundle_items = $this->product_bundles_items->get_items( $bundle_id );
|
64 |
-
foreach( $bundle_items as $key => $bundle_item ){
|
65 |
$product_bundle_data[ $bundle_item->item_id ] = $this->product_bundles_items->get_item_data( $bundle_item );
|
66 |
}
|
67 |
|
68 |
return $product_bundle_data;
|
69 |
}
|
70 |
|
71 |
-
private function save_product_bundle_data( $bundle_id, $product_bundle_data ){
|
72 |
|
73 |
$bundle_items = $this->product_bundles_items->get_items( $bundle_id );
|
74 |
|
75 |
-
foreach( $bundle_items as $item_id => $bundle_item ){
|
76 |
$bundled_item_data = $this->product_bundles_items->get_item_data_object( $item_id );
|
77 |
|
78 |
-
foreach( $product_bundle_data[ $item_id ] as $key => $value ){
|
79 |
-
$this->product_bundles_items->update_item_meta( $bundled_item_data,
|
80 |
}
|
81 |
$this->product_bundles_items->save_item_meta( $bundled_item_data );
|
82 |
}
|
83 |
|
84 |
}
|
85 |
|
86 |
-
private function sync_product_bundle_meta( $bundle_id, $translated_bundle_id ){
|
87 |
|
88 |
-
$bundle_items
|
89 |
$fields_to_sync = array(
|
90 |
'optional',
|
91 |
'stock_status',
|
@@ -102,20 +105,20 @@ class WCML_Product_Bundles{
|
|
102 |
'order_price_visibility'
|
103 |
);
|
104 |
|
105 |
-
$target_lang
|
106 |
$translated_item_ids = array();
|
107 |
-
foreach( $bundle_items as $item_id => $bundle_item ){
|
108 |
|
109 |
-
$item_meta
|
110 |
$translated_product_id = apply_filters( 'translate_object_id', $item_meta['product_id'], get_post_type( $item_meta['product_id'] ), false, $target_lang );
|
111 |
|
112 |
-
if( $translated_product_id ){
|
113 |
-
$translated_item_id
|
114 |
$translated_item_ids[] = $translated_item_id;
|
115 |
|
116 |
$translated_item = $this->product_bundles_items->get_item_data_object( $translated_item_id );
|
117 |
-
foreach( $fields_to_sync as $key ){
|
118 |
-
$this->product_bundles_items->update_item_meta( $translated_item, $key, $item_meta[$key] );
|
119 |
}
|
120 |
$this->product_bundles_items->save_item_meta( $translated_item );
|
121 |
|
@@ -134,11 +137,11 @@ class WCML_Product_Bundles{
|
|
134 |
|
135 |
}
|
136 |
|
137 |
-
public function sync_product_bundle_meta_with_translations( $bundle_id ){
|
138 |
|
139 |
if ( WooCommerce_Functions_Wrapper::get_product_type( $bundle_id ) === 'bundle' ) {
|
140 |
|
141 |
-
$trid
|
142 |
$translations = $this->sitepress->get_element_translations( $trid, 'post_product' );
|
143 |
|
144 |
foreach ( $translations as $language => $translation ) {
|
@@ -159,14 +162,16 @@ class WCML_Product_Bundles{
|
|
159 |
|
160 |
}
|
161 |
|
162 |
-
private function get_product_id_for_item_id( $item_id ){
|
163 |
global $wpdb;
|
|
|
164 |
return $wpdb->get_var( $wpdb->prepare(
|
165 |
-
"SELECT product_id FROM {$wpdb->prefix}woocommerce_bundled_items WHERE bundled_item_id=%d", $item_id) );
|
166 |
}
|
167 |
|
168 |
-
private function get_item_id_for_product_id( $product_id, $bundle_id ){
|
169 |
global $wpdb;
|
|
|
170 |
return $wpdb->get_var( $wpdb->prepare(
|
171 |
"SELECT bundled_item_id FROM {$wpdb->prefix}woocommerce_bundled_items WHERE product_id=%d AND bundle_id=%d",
|
172 |
$product_id, $bundle_id
|
@@ -174,11 +179,11 @@ class WCML_Product_Bundles{
|
|
174 |
}
|
175 |
|
176 |
// Add Bundles Box to WCML Translation GUI
|
177 |
-
public function custom_box_html( $obj, $bundle_id, $data ){
|
178 |
|
179 |
$bundle_items = $this->product_bundles_items->get_items( $bundle_id );
|
180 |
|
181 |
-
if( empty( $bundle_items ) ){
|
182 |
return false;
|
183 |
}
|
184 |
|
@@ -186,16 +191,16 @@ class WCML_Product_Bundles{
|
|
186 |
|
187 |
end( $bundle_items );
|
188 |
$last_item_id = key( $bundle_items );
|
189 |
-
$divider
|
190 |
-
$flag
|
191 |
|
192 |
foreach ( $bundle_items as $item_id => $bundle_item ) {
|
193 |
|
194 |
$translated_product = apply_filters( 'translate_object_id', $bundle_item->product_id, get_post_type( $bundle_item->product_id ), false, $obj->get_target_language() );
|
195 |
-
if( !is_null($translated_product)) {
|
196 |
|
197 |
$add_group = false;
|
198 |
-
if( $item_id == $last_item_id ){
|
199 |
$divider = false;
|
200 |
}
|
201 |
|
@@ -203,7 +208,7 @@ class WCML_Product_Bundles{
|
|
203 |
|
204 |
$group = new WPML_Editor_UI_Field_Group( get_the_title( $bundle_item->product_id ), $divider );
|
205 |
|
206 |
-
if( $bundle_item_data[
|
207 |
$bundle_field = new WPML_Editor_UI_Single_Line_Field(
|
208 |
'bundle_' . $bundle_item->product_id . '_title',
|
209 |
__( 'Name', 'woocommerce-multilingual' ),
|
@@ -214,9 +219,9 @@ class WCML_Product_Bundles{
|
|
214 |
$add_group = true;
|
215 |
}
|
216 |
|
217 |
-
if( $bundle_item_data[
|
218 |
$bundle_field = new WPML_Editor_UI_Single_Line_Field(
|
219 |
-
'bundle_'. $bundle_item->product_id . '_desc'
|
220 |
__( 'Description', 'woocommerce-multilingual' ),
|
221 |
$data,
|
222 |
false
|
@@ -225,7 +230,7 @@ class WCML_Product_Bundles{
|
|
225 |
$add_group = true;
|
226 |
}
|
227 |
|
228 |
-
if( $add_group ){
|
229 |
$bundles_section->add_field( $group );
|
230 |
$flag = true;
|
231 |
}
|
@@ -234,22 +239,22 @@ class WCML_Product_Bundles{
|
|
234 |
|
235 |
}
|
236 |
|
237 |
-
if( $flag ){
|
238 |
$obj->add_field( $bundles_section );
|
239 |
}
|
240 |
|
241 |
}
|
242 |
|
243 |
-
public function custom_box_html_data( $data, $bundle_id, $translation, $lang ){
|
244 |
|
245 |
$bundle_data = $this->get_product_bundle_data( $bundle_id );
|
246 |
|
247 |
-
if( $translation ) {
|
248 |
-
$translated_bundle_id
|
249 |
$translated_bundle_data = $this->get_product_bundle_data( $translated_bundle_id );
|
250 |
}
|
251 |
|
252 |
-
if( empty( $bundle_data ) || $bundle_data == false ){
|
253 |
return $data;
|
254 |
}
|
255 |
|
@@ -260,50 +265,51 @@ class WCML_Product_Bundles{
|
|
260 |
$product_id = $this->get_product_id_for_item_id( $item_id );
|
261 |
|
262 |
$translated_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $lang );
|
263 |
-
if( $translation ){
|
264 |
$translated_item_id = $this->get_item_id_for_product_id( $translated_product_id, $translated_bundle_id );
|
265 |
}
|
266 |
|
267 |
-
if( $bundle_data[ $item_id ][
|
268 |
-
$data[ 'bundle_'
|
269 |
-
if( $translation && isset( $translated_bundle_data[ $translated_item_id ][
|
270 |
-
$data[ 'bundle_'
|
271 |
-
}else{
|
272 |
-
$data[ 'bundle_'
|
273 |
}
|
274 |
}
|
275 |
|
276 |
-
if( $bundle_data[ $item_id ][
|
277 |
-
$data[ 'bundle_'
|
278 |
-
if( $translation && isset( $translated_bundle_data[ $translated_item_id ][
|
279 |
-
$data[ 'bundle_'
|
280 |
-
}else{
|
281 |
-
$data[ 'bundle_'
|
282 |
}
|
283 |
}
|
284 |
}
|
|
|
285 |
return $data;
|
286 |
}
|
287 |
|
288 |
-
public function append_bundle_data_translation_package( $package, $post ){
|
289 |
|
290 |
-
if( $post->post_type == 'product' ) {
|
291 |
|
292 |
$bundle_data = $this->get_product_bundle_data( $post->ID );
|
293 |
|
294 |
-
if( $bundle_data ){
|
295 |
|
296 |
$fields = array( 'title', 'description' );
|
297 |
|
298 |
-
foreach( $bundle_data as $item_id => $product_data ){
|
299 |
|
300 |
$product_id = $this->get_product_id_for_item_id( $item_id );
|
301 |
-
foreach( $fields as $field ) {
|
302 |
-
if ( $product_data[ 'override_' . $field ] == 'yes' && !empty( $product_data[ $field ] ) ) {
|
303 |
-
$package[
|
304 |
'translate' => 1,
|
305 |
-
'data'
|
306 |
-
'format'
|
307 |
);
|
308 |
}
|
309 |
}
|
@@ -316,25 +322,25 @@ class WCML_Product_Bundles{
|
|
316 |
}
|
317 |
|
318 |
// Update Bundled products title and description after saving the translation
|
319 |
-
public function bundle_update( $bundle_id, $translated_bundle_id, $data, $lang ){
|
320 |
global $wpdb;
|
321 |
|
322 |
-
$bundle_data
|
323 |
$translated_bundle_data = $this->get_product_bundle_data( $translated_bundle_id );
|
324 |
|
325 |
-
if( empty( $bundle_data ) ){
|
326 |
return;
|
327 |
}
|
328 |
|
329 |
$translate_bundled_item_ids = $wpdb->get_col( $wpdb->prepare(
|
330 |
-
"SELECT product_id FROM {$wpdb->prefix}woocommerce_bundled_items WHERE bundle_id = %d", $translated_bundle_id ));
|
331 |
|
332 |
foreach ( $bundle_data as $item_id => $bundle_item_data ) {
|
333 |
|
334 |
-
$product_id
|
335 |
$translated_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $lang );
|
336 |
|
337 |
-
if( $translated_product_id ) {
|
338 |
|
339 |
if ( ! in_array( $translated_product_id, $translate_bundled_item_ids ) ) {
|
340 |
|
@@ -373,241 +379,243 @@ class WCML_Product_Bundles{
|
|
373 |
$this->save_product_bundle_data( $translated_bundle_id, $translated_bundle_data );
|
374 |
$this->sync_product_bundle_meta( $bundle_id, $translated_bundle_id );
|
375 |
|
376 |
-
$this->sitepress->copy_custom_fields
|
377 |
|
378 |
return $translated_bundle_data;
|
379 |
}
|
380 |
|
381 |
// Sync product bundle data with translated values when the product is duplicated
|
382 |
-
|
383 |
global $wpdb;
|
384 |
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
|
390 |
-
|
391 |
|
392 |
-
|
393 |
-
|
394 |
|
395 |
-
|
396 |
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
SELECT menu_order FROM {$wpdb->prefix}woocommerce_bundled_items
|
401 |
WHERE bundle_id=%d AND product_id=%d
|
402 |
", $bundle_id, $product_id ) );
|
403 |
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
if ( $cart_item[
|
482 |
-
$
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
499 |
}
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
'shipped_individually' => $bundle_data[ $item_id ][ 'shipped_individually' ],
|
579 |
-
'priced_individually' => $bundle_data[ $item_id ][ 'priced_individually' ],
|
580 |
-
'single_product_price_visibility' => $bundle_data[ $item_id ][ 'single_product_price_visibility' ],
|
581 |
-
'cart_price_visibility' => $bundle_data[ $item_id ][ 'cart_price_visibility' ],
|
582 |
-
'order_price_visibility' => $bundle_data[ $item_id ][ 'order_price_visibility' ]
|
583 |
-
);
|
584 |
-
}
|
585 |
-
|
586 |
-
$translated_bundle_data[ $translated_item_id ][ $field ] = $value[ 'data' ];
|
587 |
-
}
|
588 |
-
|
589 |
-
}
|
590 |
-
|
591 |
-
$this->save_product_bundle_data( $translated_bundle_id, $translated_bundle_data );
|
592 |
-
}
|
593 |
-
|
594 |
-
private function add_product_to_bundle( $product_id, $bundle_id, $original_bundle_id, $original_product_id ){
|
595 |
-
global $wpdb;
|
596 |
-
$menu_order = $wpdb->get_var( $wpdb->prepare( "
|
597 |
SELECT menu_order FROM {$wpdb->prefix}woocommerce_bundled_items
|
598 |
WHERE bundle_id=%d AND product_id=%d
|
599 |
", $original_bundle_id, $original_product_id ) );
|
600 |
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
|
609 |
-
|
610 |
-
|
611 |
|
612 |
/**
|
613 |
* @param array $custom_fields
|
1 |
<?php
|
2 |
|
3 |
+
class WCML_Product_Bundles {
|
4 |
|
5 |
+
/**
|
6 |
+
* @var WPML_Element_Translation_Package
|
7 |
+
*/
|
8 |
+
public $tp;
|
9 |
|
10 |
+
/**
|
11 |
+
* @var SitePress
|
12 |
+
*/
|
13 |
+
private $sitepress;
|
14 |
|
15 |
+
/**
|
16 |
+
* @var woocommerce_wpml
|
17 |
+
*/
|
18 |
+
private $woocommerce_wpml;
|
19 |
|
20 |
/**
|
21 |
* @var WCML_WC_Product_Bundles_Items
|
22 |
*/
|
23 |
private $product_bundles_items;
|
24 |
|
25 |
+
/**
|
26 |
+
* WCML_Product_Bundles constructor.
|
27 |
+
*/
|
28 |
+
function __construct( &$sitepress, &$woocommerce_wpml, &$product_bundles_items ) {
|
29 |
|
30 |
+
$this->sitepress = $sitepress;
|
31 |
+
$this->woocommerce_wpml = $woocommerce_wpml;
|
32 |
+
$this->product_bundles_items = $product_bundles_items;
|
33 |
|
34 |
add_action( 'woocommerce_get_cart_item_from_session', array( $this, 'resync_bundle' ), 5, 3 );
|
35 |
add_filter( 'woocommerce_cart_loaded_from_session', array( $this, 'resync_bundle_clean' ), 10 );
|
36 |
|
37 |
+
if ( is_admin() ) {
|
38 |
+
$this->tp = new WPML_Element_Translation_Package();
|
39 |
|
40 |
+
add_filter( 'wpml_tm_translation_job_data', array(
|
41 |
+
$this,
|
42 |
+
'append_bundle_data_translation_package'
|
43 |
+
), 10, 2 );
|
44 |
+
add_action( 'wpml_translation_job_saved', array( $this, 'save_bundle_data_translation' ), 10, 3 );
|
45 |
|
46 |
+
add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
|
47 |
+
add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
|
48 |
|
49 |
+
add_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_bundled_ids' ), 10, 2 );
|
50 |
+
add_action( 'wcml_update_extra_fields', array( $this, 'bundle_update' ), 10, 4 );
|
51 |
|
52 |
+
add_action( 'wp_insert_post', array( $this, 'sync_product_bundle_meta_with_translations' ), 10 );
|
53 |
|
54 |
+
}
|
55 |
|
56 |
+
// product bundle using separate custom fields for prices
|
57 |
+
if ( wcml_is_multi_currency_on() ) {
|
58 |
+
add_filter( 'wcml_price_custom_fields_filtered', array( $this, 'get_price_custom_fields' ) );
|
59 |
+
}
|
60 |
|
61 |
+
}
|
62 |
|
63 |
+
private function get_product_bundle_data( $bundle_id ) {
|
64 |
$product_bundle_data = array();
|
65 |
|
66 |
$bundle_items = $this->product_bundles_items->get_items( $bundle_id );
|
67 |
+
foreach ( $bundle_items as $key => $bundle_item ) {
|
68 |
$product_bundle_data[ $bundle_item->item_id ] = $this->product_bundles_items->get_item_data( $bundle_item );
|
69 |
}
|
70 |
|
71 |
return $product_bundle_data;
|
72 |
}
|
73 |
|
74 |
+
private function save_product_bundle_data( $bundle_id, $product_bundle_data ) {
|
75 |
|
76 |
$bundle_items = $this->product_bundles_items->get_items( $bundle_id );
|
77 |
|
78 |
+
foreach ( $bundle_items as $item_id => $bundle_item ) {
|
79 |
$bundled_item_data = $this->product_bundles_items->get_item_data_object( $item_id );
|
80 |
|
81 |
+
foreach ( $product_bundle_data[ $item_id ] as $key => $value ) {
|
82 |
+
$this->product_bundles_items->update_item_meta( $bundled_item_data, $key, $value );
|
83 |
}
|
84 |
$this->product_bundles_items->save_item_meta( $bundled_item_data );
|
85 |
}
|
86 |
|
87 |
}
|
88 |
|
89 |
+
private function sync_product_bundle_meta( $bundle_id, $translated_bundle_id ) {
|
90 |
|
91 |
+
$bundle_items = $this->product_bundles_items->get_items( $bundle_id );
|
92 |
$fields_to_sync = array(
|
93 |
'optional',
|
94 |
'stock_status',
|
105 |
'order_price_visibility'
|
106 |
);
|
107 |
|
108 |
+
$target_lang = $this->sitepress->get_language_for_element( $translated_bundle_id, 'post_product' );
|
109 |
$translated_item_ids = array();
|
110 |
+
foreach ( $bundle_items as $item_id => $bundle_item ) {
|
111 |
|
112 |
+
$item_meta = $this->product_bundles_items->get_item_data( $bundle_item );
|
113 |
$translated_product_id = apply_filters( 'translate_object_id', $item_meta['product_id'], get_post_type( $item_meta['product_id'] ), false, $target_lang );
|
114 |
|
115 |
+
if ( $translated_product_id ) {
|
116 |
+
$translated_item_id = $this->get_item_id_for_product_id( $translated_product_id, $translated_bundle_id );
|
117 |
$translated_item_ids[] = $translated_item_id;
|
118 |
|
119 |
$translated_item = $this->product_bundles_items->get_item_data_object( $translated_item_id );
|
120 |
+
foreach ( $fields_to_sync as $key ) {
|
121 |
+
$this->product_bundles_items->update_item_meta( $translated_item, $key, $item_meta[ $key ] );
|
122 |
}
|
123 |
$this->product_bundles_items->save_item_meta( $translated_item );
|
124 |
|
137 |
|
138 |
}
|
139 |
|
140 |
+
public function sync_product_bundle_meta_with_translations( $bundle_id ) {
|
141 |
|
142 |
if ( WooCommerce_Functions_Wrapper::get_product_type( $bundle_id ) === 'bundle' ) {
|
143 |
|
144 |
+
$trid = $this->sitepress->get_element_trid( $bundle_id, 'post_product' );
|
145 |
$translations = $this->sitepress->get_element_translations( $trid, 'post_product' );
|
146 |
|
147 |
foreach ( $translations as $language => $translation ) {
|
162 |
|
163 |
}
|
164 |
|
165 |
+
private function get_product_id_for_item_id( $item_id ) {
|
166 |
global $wpdb;
|
167 |
+
|
168 |
return $wpdb->get_var( $wpdb->prepare(
|
169 |
+
"SELECT product_id FROM {$wpdb->prefix}woocommerce_bundled_items WHERE bundled_item_id=%d", $item_id ) );
|
170 |
}
|
171 |
|
172 |
+
private function get_item_id_for_product_id( $product_id, $bundle_id ) {
|
173 |
global $wpdb;
|
174 |
+
|
175 |
return $wpdb->get_var( $wpdb->prepare(
|
176 |
"SELECT bundled_item_id FROM {$wpdb->prefix}woocommerce_bundled_items WHERE product_id=%d AND bundle_id=%d",
|
177 |
$product_id, $bundle_id
|
179 |
}
|
180 |
|
181 |
// Add Bundles Box to WCML Translation GUI
|
182 |
+
public function custom_box_html( $obj, $bundle_id, $data ) {
|
183 |
|
184 |
$bundle_items = $this->product_bundles_items->get_items( $bundle_id );
|
185 |
|
186 |
+
if ( empty( $bundle_items ) ) {
|
187 |
return false;
|
188 |
}
|
189 |
|
191 |
|
192 |
end( $bundle_items );
|
193 |
$last_item_id = key( $bundle_items );
|
194 |
+
$divider = true;
|
195 |
+
$flag = false;
|
196 |
|
197 |
foreach ( $bundle_items as $item_id => $bundle_item ) {
|
198 |
|
199 |
$translated_product = apply_filters( 'translate_object_id', $bundle_item->product_id, get_post_type( $bundle_item->product_id ), false, $obj->get_target_language() );
|
200 |
+
if ( ! is_null( $translated_product ) ) {
|
201 |
|
202 |
$add_group = false;
|
203 |
+
if ( $item_id == $last_item_id ) {
|
204 |
$divider = false;
|
205 |
}
|
206 |
|
208 |
|
209 |
$group = new WPML_Editor_UI_Field_Group( get_the_title( $bundle_item->product_id ), $divider );
|
210 |
|
211 |
+
if ( $bundle_item_data['override_title'] == 'yes' ) {
|
212 |
$bundle_field = new WPML_Editor_UI_Single_Line_Field(
|
213 |
'bundle_' . $bundle_item->product_id . '_title',
|
214 |
__( 'Name', 'woocommerce-multilingual' ),
|
219 |
$add_group = true;
|
220 |
}
|
221 |
|
222 |
+
if ( $bundle_item_data['override_description'] == 'yes' ) {
|
223 |
$bundle_field = new WPML_Editor_UI_Single_Line_Field(
|
224 |
+
'bundle_' . $bundle_item->product_id . '_desc',
|
225 |
__( 'Description', 'woocommerce-multilingual' ),
|
226 |
$data,
|
227 |
false
|
230 |
$add_group = true;
|
231 |
}
|
232 |
|
233 |
+
if ( $add_group ) {
|
234 |
$bundles_section->add_field( $group );
|
235 |
$flag = true;
|
236 |
}
|
239 |
|
240 |
}
|
241 |
|
242 |
+
if ( $flag ) {
|
243 |
$obj->add_field( $bundles_section );
|
244 |
}
|
245 |
|
246 |
}
|
247 |
|
248 |
+
public function custom_box_html_data( $data, $bundle_id, $translation, $lang ) {
|
249 |
|
250 |
$bundle_data = $this->get_product_bundle_data( $bundle_id );
|
251 |
|
252 |
+
if ( $translation ) {
|
253 |
+
$translated_bundle_id = $translation->ID;
|
254 |
$translated_bundle_data = $this->get_product_bundle_data( $translated_bundle_id );
|
255 |
}
|
256 |
|
257 |
+
if ( empty( $bundle_data ) || $bundle_data == false ) {
|
258 |
return $data;
|
259 |
}
|
260 |
|
265 |
$product_id = $this->get_product_id_for_item_id( $item_id );
|
266 |
|
267 |
$translated_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $lang );
|
268 |
+
if ( $translation ) {
|
269 |
$translated_item_id = $this->get_item_id_for_product_id( $translated_product_id, $translated_bundle_id );
|
270 |
}
|
271 |
|
272 |
+
if ( $bundle_data[ $item_id ]['override_title'] == 'yes' ) {
|
273 |
+
$data[ 'bundle_' . $product_id . '_title' ] = array( 'original' => $bundle_data[ $item_id ]['title'] );
|
274 |
+
if ( $translation && isset( $translated_bundle_data[ $translated_item_id ]['override_title'] ) ) {
|
275 |
+
$data[ 'bundle_' . $product_id . '_title' ]['translation'] = $translated_bundle_data[ $translated_item_id ]['title'];
|
276 |
+
} else {
|
277 |
+
$data[ 'bundle_' . $product_id . '_title' ]['translation'] = '';
|
278 |
}
|
279 |
}
|
280 |
|
281 |
+
if ( $bundle_data[ $item_id ]['override_description'] == 'yes' ) {
|
282 |
+
$data[ 'bundle_' . $product_id . '_desc' ] = array( 'original' => $bundle_data[ $item_id ]['description'] );
|
283 |
+
if ( $translation && isset( $translated_bundle_data[ $translated_item_id ]['override_description'] ) ) {
|
284 |
+
$data[ 'bundle_' . $product_id . '_desc' ]['translation'] = $translated_bundle_data[ $translated_item_id ]['description'];
|
285 |
+
} else {
|
286 |
+
$data[ 'bundle_' . $product_id . '_desc' ]['translation'] = '';
|
287 |
}
|
288 |
}
|
289 |
}
|
290 |
+
|
291 |
return $data;
|
292 |
}
|
293 |
|
294 |
+
public function append_bundle_data_translation_package( $package, $post ) {
|
295 |
|
296 |
+
if ( $post->post_type == 'product' ) {
|
297 |
|
298 |
$bundle_data = $this->get_product_bundle_data( $post->ID );
|
299 |
|
300 |
+
if ( $bundle_data ) {
|
301 |
|
302 |
$fields = array( 'title', 'description' );
|
303 |
|
304 |
+
foreach ( $bundle_data as $item_id => $product_data ) {
|
305 |
|
306 |
$product_id = $this->get_product_id_for_item_id( $item_id );
|
307 |
+
foreach ( $fields as $field ) {
|
308 |
+
if ( $product_data[ 'override_' . $field ] == 'yes' && ! empty( $product_data[ $field ] ) ) {
|
309 |
+
$package['contents'][ 'product_bundles:' . $product_id . ':' . $field ] = array(
|
310 |
'translate' => 1,
|
311 |
+
'data' => $this->tp->encode_field_data( $product_data[ $field ], 'base64' ),
|
312 |
+
'format' => 'base64'
|
313 |
);
|
314 |
}
|
315 |
}
|
322 |
}
|
323 |
|
324 |
// Update Bundled products title and description after saving the translation
|
325 |
+
public function bundle_update( $bundle_id, $translated_bundle_id, $data, $lang ) {
|
326 |
global $wpdb;
|
327 |
|
328 |
+
$bundle_data = $this->get_product_bundle_data( $bundle_id );
|
329 |
$translated_bundle_data = $this->get_product_bundle_data( $translated_bundle_id );
|
330 |
|
331 |
+
if ( empty( $bundle_data ) ) {
|
332 |
return;
|
333 |
}
|
334 |
|
335 |
$translate_bundled_item_ids = $wpdb->get_col( $wpdb->prepare(
|
336 |
+
"SELECT product_id FROM {$wpdb->prefix}woocommerce_bundled_items WHERE bundle_id = %d", $translated_bundle_id ) );
|
337 |
|
338 |
foreach ( $bundle_data as $item_id => $bundle_item_data ) {
|
339 |
|
340 |
+
$product_id = $this->get_product_id_for_item_id( $item_id );
|
341 |
$translated_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $lang );
|
342 |
|
343 |
+
if ( $translated_product_id ) {
|
344 |
|
345 |
if ( ! in_array( $translated_product_id, $translate_bundled_item_ids ) ) {
|
346 |
|
379 |
$this->save_product_bundle_data( $translated_bundle_id, $translated_bundle_data );
|
380 |
$this->sync_product_bundle_meta( $bundle_id, $translated_bundle_id );
|
381 |
|
382 |
+
$this->sitepress->copy_custom_fields( $bundle_id, $translated_bundle_id );
|
383 |
|
384 |
return $translated_bundle_data;
|
385 |
}
|
386 |
|
387 |
// Sync product bundle data with translated values when the product is duplicated
|
388 |
+
public function sync_bundled_ids( $bundle_id, $translated_bundle_id ) {
|
389 |
global $wpdb;
|
390 |
|
391 |
+
$bundle_data = $this->get_product_bundle_data( $bundle_id );
|
392 |
+
if ( $bundle_data ) {
|
393 |
+
$lang = $this->sitepress->get_language_for_element( $translated_bundle_id, 'post_product' );
|
394 |
+
$translated_bundle_data = $this->get_product_bundle_data( $translated_bundle_id );
|
395 |
|
396 |
+
foreach ( $bundle_data as $item_id => $product_data ) {
|
397 |
|
398 |
+
$product_id = $this->get_product_id_for_item_id( $item_id );
|
399 |
+
$translated_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $lang );
|
400 |
|
401 |
+
if ( $translated_product_id ) {
|
402 |
|
403 |
+
$translated_item_id = $this->get_item_id_for_product_id( $translated_product_id, $translated_bundle_id );
|
404 |
+
if ( ! $translated_item_id ) {
|
405 |
+
$menu_order = $wpdb->get_var( $wpdb->prepare( "
|
406 |
SELECT menu_order FROM {$wpdb->prefix}woocommerce_bundled_items
|
407 |
WHERE bundle_id=%d AND product_id=%d
|
408 |
", $bundle_id, $product_id ) );
|
409 |
|
410 |
+
$wpdb->insert( $wpdb->prefix . 'woocommerce_bundled_items',
|
411 |
+
array(
|
412 |
+
'product_id' => $translated_product_id,
|
413 |
+
'bundle_id' => $translated_bundle_id,
|
414 |
+
'menu_order' => $menu_order,
|
415 |
+
)
|
416 |
+
);
|
417 |
+
$translated_item_id = $wpdb->insert_id;
|
418 |
+
}
|
419 |
+
|
420 |
+
$translated_bundle_data[ $translated_item_id ] = $product_data;
|
421 |
+
$translated_bundle_data[ $translated_item_id ]['product_id'] = $translated_product_id;
|
422 |
+
|
423 |
+
if ( isset( $bundle_data['title'] ) ) {
|
424 |
+
if ( $bundle_data['override_title'] != 'yes' ) {
|
425 |
+
$translated_bundle_data[ $translated_item_id ]['title'] = get_the_title( $translated_product_id );
|
426 |
+
}
|
427 |
+
}
|
428 |
+
|
429 |
+
if ( isset( $bundle_data['title'] ) ) {
|
430 |
+
if ( $bundle_data['override_description'] != 'yes' ) {
|
431 |
+
$translated_bundle_data[ $translated_item_id ]['description'] = get_the_title( $translated_product_id );
|
432 |
+
}
|
433 |
+
}
|
434 |
+
|
435 |
+
if ( isset( $bundle_data['filter_variations'] ) && $bundle_data['filter_variations'] == 'yes' ) {
|
436 |
+
$allowed_var = $bundle_data['allowed_variations'];
|
437 |
+
foreach ( $allowed_var as $key => $var_id ) {
|
438 |
+
$translated_var_id = apply_filters( 'translate_object_id', $var_id, get_post_type( $var_id ), true, $lang );
|
439 |
+
$translated_bundle_data[ $translated_item_id ]['allowed_variations'][ $key ] = $translated_var_id;
|
440 |
+
}
|
441 |
+
}
|
442 |
+
|
443 |
+
|
444 |
+
if ( isset( $bundle_data['bundle_defaults'] ) && ! empty( $bundle_data['bundle_defaults'] ) ) {
|
445 |
+
foreach ( $bundle_data['bundle_defaults'] as $tax => $term_slug ) {
|
446 |
+
|
447 |
+
$term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $tax, $term_slug );
|
448 |
+
if ( $term_id ) {
|
449 |
+
// Global Attribute
|
450 |
+
$tr_def_id = apply_filters( 'translate_object_id', $term_id, $tax, true, $lang );
|
451 |
+
$tr_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_def_id, $tax );
|
452 |
+
$translated_bundle_data[ $translated_item_id ]['bundle_defaults'][ $tax ] = $tr_term->slug;
|
453 |
+
} else {
|
454 |
+
// Custom Attribute
|
455 |
+
$args = array(
|
456 |
+
'post_type' => 'product_variation',
|
457 |
+
'meta_key' => 'attribute_' . $tax,
|
458 |
+
'meta_value' => $term_slug,
|
459 |
+
'meta_compare' => '='
|
460 |
+
);
|
461 |
+
$variationloop = new WP_Query( $args );
|
462 |
+
while ( $variationloop->have_posts() ) : $variationloop->the_post();
|
463 |
+
$tr_var_id = apply_filters( 'translate_object_id', get_the_ID(), 'product_variation', true, $lang );
|
464 |
+
$tr_meta = get_post_meta( $tr_var_id, 'attribute_' . $tax, true );
|
465 |
+
$translated_bundle_data[ $translated_item_id ]['bundle_defaults'][ $tax ] = $tr_meta;
|
466 |
+
endwhile;
|
467 |
+
}
|
468 |
+
}
|
469 |
+
}
|
470 |
+
|
471 |
+
}
|
472 |
+
|
473 |
+
|
474 |
+
}
|
475 |
+
|
476 |
+
$this->save_product_bundle_data( $translated_bundle_id, $translated_bundle_data );
|
477 |
+
|
478 |
+
return $translated_bundle_data;
|
479 |
+
}
|
480 |
+
|
481 |
+
}
|
482 |
+
|
483 |
+
public function resync_bundle( $cart_item, $session_values, $cart_item_key ) {
|
484 |
+
|
485 |
+
if ( isset( $cart_item['bundled_items'] ) && $cart_item['data']->product_type === 'bundle' ) {
|
486 |
+
$current_bundle_id = apply_filters( 'translate_object_id', $cart_item['product_id'], 'product', true );
|
487 |
+
if ( $cart_item['product_id'] != $current_bundle_id ) {
|
488 |
+
if ( isset( $cart_item['data']->bundle_data ) && is_array( $cart_item['data']->bundle_data ) ) {
|
489 |
+
$old_bundled_item_ids = array_keys( $cart_item['data']->bundle_data );
|
490 |
+
$cart_item['data'] = wc_get_product( $current_bundle_id );
|
491 |
+
if ( isset( $cart_item['data']->bundle_data ) && is_array( $cart_item['data']->bundle_data ) ) {
|
492 |
+
$new_bundled_item_ids = array_keys( $cart_item['data']->bundle_data );
|
493 |
+
$remapped_bundled_item_ids = array();
|
494 |
+
foreach ( $old_bundled_item_ids as $old_item_id_index => $old_item_id ) {
|
495 |
+
$remapped_bundled_item_ids[ $old_item_id ] = $new_bundled_item_ids[ $old_item_id_index ];
|
496 |
+
}
|
497 |
+
$cart_item['remapped_bundled_item_ids'] = $remapped_bundled_item_ids;
|
498 |
+
if ( isset( $cart_item['stamp'] ) ) {
|
499 |
+
$new_stamp = array();
|
500 |
+
foreach ( $cart_item['stamp'] as $bundled_item_id => $stamp_data ) {
|
501 |
+
$new_stamp[ $remapped_bundled_item_ids[ $bundled_item_id ] ] = $stamp_data;
|
502 |
+
}
|
503 |
+
$cart_item['stamp'] = $new_stamp;
|
504 |
+
}
|
505 |
+
}
|
506 |
+
}
|
507 |
+
}
|
508 |
+
}
|
509 |
+
if ( isset( $cart_item['bundled_by'] ) && isset( WC()->cart->cart_contents[ $cart_item['bundled_by'] ] ) ) {
|
510 |
+
$bundle_cart_item = WC()->cart->cart_contents[ $cart_item['bundled_by'] ];
|
511 |
+
if (
|
512 |
+
isset( $bundle_cart_item['remapped_bundled_item_ids'] ) &&
|
513 |
+
isset( $cart_item['bundled_item_id'] ) &&
|
514 |
+
isset( $bundle_cart_item['remapped_bundled_item_ids'][ $cart_item['bundled_item_id'] ] )
|
515 |
+
) {
|
516 |
+
$old_id = $cart_item['bundled_item_id'];
|
517 |
+
$remapped_bundled_item_ids = $bundle_cart_item['remapped_bundled_item_ids'];
|
518 |
+
$cart_item['bundled_item_id'] = $remapped_bundled_item_ids[ $cart_item['bundled_item_id'] ];
|
519 |
+
if ( isset( $cart_item['stamp'] ) ) {
|
520 |
+
$new_stamp = array();
|
521 |
+
foreach ( $cart_item['stamp'] as $bundled_item_id => $stamp_data ) {
|
522 |
+
$new_stamp[ $remapped_bundled_item_ids[ $bundled_item_id ] ] = $stamp_data;
|
523 |
+
}
|
524 |
+
$cart_item['stamp'] = $new_stamp;
|
525 |
+
}
|
526 |
}
|
527 |
+
}
|
528 |
+
|
529 |
+
return $cart_item;
|
530 |
+
}
|
531 |
+
|
532 |
+
public function resync_bundle_clean( $cart ) {
|
533 |
+
foreach ( $cart->cart_contents as $cart_item_key => $cart_item ) {
|
534 |
+
if ( isset( $cart_item['bundled_items'] ) && WooCommerce_Functions_Wrapper::get_product_type( $cart_item['product_id'] ) === 'bundle' ) {
|
535 |
+
if ( isset( $cart_item['remapped_bundled_item_ids'] ) ) {
|
536 |
+
unset( WC()->cart->cart_contents[ $cart_item_key ]['remapped_bundled_item_ids'] );
|
537 |
+
}
|
538 |
+
}
|
539 |
+
}
|
540 |
+
}
|
541 |
+
|
542 |
+
public function save_bundle_data_translation( $translated_bundle_id, $data, $job ) {
|
543 |
+
|
544 |
+
remove_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_bundled_ids' ), 10, 2 );
|
545 |
+
|
546 |
+
$translated_bundle_data = $this->get_product_bundle_data( $translated_bundle_id );
|
547 |
+
|
548 |
+
$bundle_id =& $job->original_doc_id;
|
549 |
+
|
550 |
+
$bundle_data = $this->get_product_bundle_data( $bundle_id );
|
551 |
+
|
552 |
+
foreach ( $data as $value ) {
|
553 |
+
|
554 |
+
if ( preg_match( '/product_bundles:([0-9]+):(.+)/', $value['field_type'], $matches ) ) {
|
555 |
+
|
556 |
+
$product_id = $matches[1];
|
557 |
+
$field = $matches[2];
|
558 |
+
|
559 |
+
$translated_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $job->language_code );
|
560 |
+
$translated_item_id = $this->get_item_id_for_product_id( $translated_product_id, $translated_bundle_id );
|
561 |
+
if ( empty( $translated_item_id ) ) {
|
562 |
+
$translated_item_id = $this->add_product_to_bundle( $translated_product_id, $translated_bundle_id, $bundle_id, $product_id );
|
563 |
+
}
|
564 |
+
|
565 |
+
$item_id = $this->get_item_id_for_product_id( $product_id, $bundle_id );
|
566 |
+
|
567 |
+
if ( ! isset( $translated_bundle_data[ $translated_item_id ] ) ) {
|
568 |
+
$translated_bundle_data[ $translated_item_id ] = array(
|
569 |
+
'product_id' => $translated_product_id,
|
570 |
+
'hide_thumbnail' => $bundle_data[ $item_id ]['hide_thumbnail'],
|
571 |
+
'override_title' => $bundle_data[ $item_id ]['override_title'],
|
572 |
+
'product_title' => '',
|
573 |
+
'override_description' => $bundle_data[ $item_id ]['override_description'],
|
574 |
+
'product_description' => '',
|
575 |
+
'optional' => $bundle_data[ $item_id ]['optional'],
|
576 |
+
'bundle_quantity' => $bundle_data[ $item_id ]['bundle_quantity'],
|
577 |
+
'bundle_quantity_max' => $bundle_data[ $item_id ]['bundle_quantity_max'],
|
578 |
+
'bundle_discount' => $bundle_data[ $item_id ]['bundle_discount'],
|
579 |
+
'single_product_visibility' => $bundle_data[ $item_id ]['single_product_visibility'],
|
580 |
+
'cart_visibility' => $bundle_data[ $item_id ]['cart_visibility'],
|
581 |
+
'order_visibility' => $bundle_data[ $item_id ]['order_visibility'],
|
582 |
+
'stock_status' => $bundle_data[ $item_id ]['stock_status'],
|
583 |
+
'max_stock' => $bundle_data[ $item_id ]['max_stock'],
|
584 |
+
'quantity_min' => $bundle_data[ $item_id ]['quantity_min'],
|
585 |
+
'quantity_max' => $bundle_data[ $item_id ]['quantity_max'],
|
586 |
+
'shipped_individually' => $bundle_data[ $item_id ]['shipped_individually'],
|
587 |
+
'priced_individually' => $bundle_data[ $item_id ]['priced_individually'],
|
588 |
+
'single_product_price_visibility' => $bundle_data[ $item_id ]['single_product_price_visibility'],
|
589 |
+
'cart_price_visibility' => $bundle_data[ $item_id ]['cart_price_visibility'],
|
590 |
+
'order_price_visibility' => $bundle_data[ $item_id ]['order_price_visibility']
|
591 |
+
);
|
592 |
+
}
|
593 |
+
|
594 |
+
$translated_bundle_data[ $translated_item_id ][ $field ] = $value['data'];
|
595 |
+
}
|
596 |
+
|
597 |
+
}
|
598 |
+
|
599 |
+
$this->save_product_bundle_data( $translated_bundle_id, $translated_bundle_data );
|
600 |
+
}
|
601 |
+
|
602 |
+
private function add_product_to_bundle( $product_id, $bundle_id, $original_bundle_id, $original_product_id ) {
|
603 |
+
global $wpdb;
|
604 |
+
$menu_order = $wpdb->get_var( $wpdb->prepare( "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
605 |
SELECT menu_order FROM {$wpdb->prefix}woocommerce_bundled_items
|
606 |
WHERE bundle_id=%d AND product_id=%d
|
607 |
", $original_bundle_id, $original_product_id ) );
|
608 |
|
609 |
+
$wpdb->insert( $wpdb->prefix . 'woocommerce_bundled_items',
|
610 |
+
array(
|
611 |
+
'product_id' => $product_id,
|
612 |
+
'bundle_id' => $bundle_id,
|
613 |
+
'menu_order' => $menu_order,
|
614 |
+
)
|
615 |
+
);
|
616 |
|
617 |
+
return $wpdb->insert_id;
|
618 |
+
}
|
619 |
|
620 |
/**
|
621 |
* @param array $custom_fields
|
inc/class-wcml-emails.php
CHANGED
@@ -248,7 +248,7 @@ class WCML_Emails{
|
|
248 |
|
249 |
function filter_payment_method_string( $title, $object_id, $meta_key, $single ){
|
250 |
|
251 |
-
if( '_payment_method_title' === $meta_key ){
|
252 |
|
253 |
remove_filter( 'get_post_metadata', array( $this, 'filter_payment_method_string' ), 10, 4 );
|
254 |
$payment_gateway = wc_get_payment_gateway_by_order( $object_id );
|
248 |
|
249 |
function filter_payment_method_string( $title, $object_id, $meta_key, $single ){
|
250 |
|
251 |
+
if( $object_id && 'shop_order' === get_post_type( $object_id ) && '_payment_method_title' === $meta_key ){
|
252 |
|
253 |
remove_filter( 'get_post_metadata', array( $this, 'filter_payment_method_string' ), 10, 4 );
|
254 |
$payment_gateway = wc_get_payment_gateway_by_order( $object_id );
|
inc/class-wcml-url-translation.php
CHANGED
@@ -527,9 +527,8 @@ class WCML_Url_Translation {
|
|
527 |
if ( ( $taxonomy == 'product_cat' || $taxonomy == 'product_tag' || ( ! empty( $wc_taxonomies_wc_format ) && in_array( $taxonomy, $wc_taxonomies_wc_format ) ) ) && ! $no_recursion_flag ) {
|
528 |
|
529 |
$cache_key = 'termlink#' . $taxonomy . '#' . $term->term_id;
|
530 |
-
if (
|
531 |
$termlink = $link;
|
532 |
-
|
533 |
} else {
|
534 |
|
535 |
$no_recursion_flag = false;
|
@@ -542,7 +541,7 @@ class WCML_Url_Translation {
|
|
542 |
|
543 |
if ( $term_language ) {
|
544 |
|
545 |
-
$slug_details = $this->get_translated_tax_slug( $taxonomy, $term_language
|
546 |
|
547 |
$base = $slug_details['slug'];
|
548 |
$base_translated = $slug_details['translated_slug'];
|
@@ -597,7 +596,7 @@ class WCML_Url_Translation {
|
|
597 |
return $termlink;
|
598 |
}
|
599 |
|
600 |
-
function get_translated_tax_slug( $taxonomy, $language = false
|
601 |
global $sitepress, $woocommerce_wpml;
|
602 |
|
603 |
switch ( $taxonomy ) {
|
@@ -607,9 +606,6 @@ class WCML_Url_Translation {
|
|
607 |
$slug = $gettext_slug = trim( $this->wc_permalinks['tag_base'], '/' );
|
608 |
} else {
|
609 |
$slug = 'product-tag';
|
610 |
-
if ( $return_gettext_slug ) {
|
611 |
-
$gettext_slug = $this->default_product_tag_gettext_base;
|
612 |
-
}
|
613 |
}
|
614 |
|
615 |
$string_language = $woocommerce_wpml->strings->get_string_language( $slug, $this->url_strings_context(), $this->url_string_name( $taxonomy ) );
|
@@ -622,9 +618,6 @@ class WCML_Url_Translation {
|
|
622 |
$slug = $gettext_slug = trim( $this->wc_permalinks['category_base'], '/' );
|
623 |
} else {
|
624 |
$slug = 'product-category';
|
625 |
-
if ( $return_gettext_slug ) {
|
626 |
-
$gettext_slug = $this->default_product_category_gettext_base;
|
627 |
-
}
|
628 |
}
|
629 |
|
630 |
$string_language = $woocommerce_wpml->strings->get_string_language( $slug, $this->url_strings_context(), $this->url_string_name( $taxonomy ) );
|
@@ -632,7 +625,7 @@ class WCML_Url_Translation {
|
|
632 |
break;
|
633 |
|
634 |
default:
|
635 |
-
$slug =
|
636 |
|
637 |
$string_language = $woocommerce_wpml->strings->get_string_language( $slug, $this->url_strings_context(), $this->url_string_name( 'attribute' ) );
|
638 |
|
@@ -650,14 +643,14 @@ class WCML_Url_Translation {
|
|
650 |
$slug_translation = apply_filters( 'wpml_translate_single_string', $slug, $this->url_strings_context(), $this->url_string_name( $taxonomy ), $language, false );
|
651 |
|
652 |
return array(
|
653 |
-
'slug' => $
|
654 |
'translated_slug' => $slug_translation
|
655 |
);
|
656 |
}
|
657 |
|
658 |
return array(
|
659 |
-
'slug' => $
|
660 |
-
'translated_slug' => $
|
661 |
);
|
662 |
|
663 |
}
|
527 |
if ( ( $taxonomy == 'product_cat' || $taxonomy == 'product_tag' || ( ! empty( $wc_taxonomies_wc_format ) && in_array( $taxonomy, $wc_taxonomies_wc_format ) ) ) && ! $no_recursion_flag ) {
|
528 |
|
529 |
$cache_key = 'termlink#' . $taxonomy . '#' . $term->term_id;
|
530 |
+
if ( $link = wp_cache_get( $cache_key, 'terms' ) ) {
|
531 |
$termlink = $link;
|
|
|
532 |
} else {
|
533 |
|
534 |
$no_recursion_flag = false;
|
541 |
|
542 |
if ( $term_language ) {
|
543 |
|
544 |
+
$slug_details = $this->get_translated_tax_slug( $taxonomy, $term_language );
|
545 |
|
546 |
$base = $slug_details['slug'];
|
547 |
$base_translated = $slug_details['translated_slug'];
|
596 |
return $termlink;
|
597 |
}
|
598 |
|
599 |
+
function get_translated_tax_slug( $taxonomy, $language = false ) {
|
600 |
global $sitepress, $woocommerce_wpml;
|
601 |
|
602 |
switch ( $taxonomy ) {
|
606 |
$slug = $gettext_slug = trim( $this->wc_permalinks['tag_base'], '/' );
|
607 |
} else {
|
608 |
$slug = 'product-tag';
|
|
|
|
|
|
|
609 |
}
|
610 |
|
611 |
$string_language = $woocommerce_wpml->strings->get_string_language( $slug, $this->url_strings_context(), $this->url_string_name( $taxonomy ) );
|
618 |
$slug = $gettext_slug = trim( $this->wc_permalinks['category_base'], '/' );
|
619 |
} else {
|
620 |
$slug = 'product-category';
|
|
|
|
|
|
|
621 |
}
|
622 |
|
623 |
$string_language = $woocommerce_wpml->strings->get_string_language( $slug, $this->url_strings_context(), $this->url_string_name( $taxonomy ) );
|
625 |
break;
|
626 |
|
627 |
default:
|
628 |
+
$slug = trim( $this->wc_permalinks['attribute_base'], '/' );
|
629 |
|
630 |
$string_language = $woocommerce_wpml->strings->get_string_language( $slug, $this->url_strings_context(), $this->url_string_name( 'attribute' ) );
|
631 |
|
643 |
$slug_translation = apply_filters( 'wpml_translate_single_string', $slug, $this->url_strings_context(), $this->url_string_name( $taxonomy ), $language, false );
|
644 |
|
645 |
return array(
|
646 |
+
'slug' => $slug,
|
647 |
'translated_slug' => $slug_translation
|
648 |
);
|
649 |
}
|
650 |
|
651 |
return array(
|
652 |
+
'slug' => $slug,
|
653 |
+
'translated_slug' => $slug
|
654 |
);
|
655 |
|
656 |
}
|
inc/class-woocommerce-wpml.php
CHANGED
@@ -156,6 +156,8 @@ class woocommerce_wpml {
|
|
156 |
|| ( isset( $_POST[ 'action' ] ) && in_array( $_POST[ 'action' ], $actions_that_need_mc ) )
|
157 |
){
|
158 |
$this->multi_currency = new WCML_Multi_Currency;
|
|
|
|
|
159 |
}else{
|
160 |
add_shortcode('currency_switcher', '__return_empty_string');
|
161 |
}
|
156 |
|| ( isset( $_POST[ 'action' ] ) && in_array( $_POST[ 'action' ], $actions_that_need_mc ) )
|
157 |
){
|
158 |
$this->multi_currency = new WCML_Multi_Currency;
|
159 |
+
$wcml_price_filters = new WCML_Price_Filter( $this );
|
160 |
+
$wcml_price_filters->add_hooks();
|
161 |
}else{
|
162 |
add_shortcode('currency_switcher', '__return_empty_string');
|
163 |
}
|
inc/currencies/class-wcml-price-filter.php
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WCML_Price_Filter {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @var woocommerce_wpml;
|
7 |
+
*/
|
8 |
+
private $woocommerce_wpml;
|
9 |
+
|
10 |
+
public function __construct( woocommerce_wpml &$woocommerce_wpml ) {
|
11 |
+
$this->woocommerce_wpml = $woocommerce_wpml;
|
12 |
+
}
|
13 |
+
|
14 |
+
public function add_hooks() {
|
15 |
+
add_action( 'wp_footer', array( $this, 'override_currency_symbol' ), 100 );
|
16 |
+
|
17 |
+
if ( ! is_admin() ) {
|
18 |
+
add_filter( 'woocommerce_product_query_meta_query', array( $this, 'unconvert_price_filter_limits' ) );
|
19 |
+
}
|
20 |
+
|
21 |
+
}
|
22 |
+
|
23 |
+
public function override_currency_symbol() {
|
24 |
+
?>
|
25 |
+
<script type="text/javascript">
|
26 |
+
/* <![CDATA[ */
|
27 |
+
woocommerce_price_slider_params.currency_format_symbol = wcml_mc_settings.current_currency.symbol;
|
28 |
+
/* ]]> */
|
29 |
+
</script>
|
30 |
+
<?php
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @param array $meta_query
|
35 |
+
*
|
36 |
+
* @return array
|
37 |
+
*/
|
38 |
+
public function unconvert_price_filter_limits( $meta_query ) {
|
39 |
+
|
40 |
+
$multi_currency = $this->woocommerce_wpml->multi_currency;
|
41 |
+
|
42 |
+
if ( $multi_currency->get_client_currency() !== get_option( 'woocommerce_currency' ) ) {
|
43 |
+
if ( isset( $meta_query['price_filter'] ) && isset($meta_query['price_filter']['key']) && $meta_query['price_filter']['key'] === '_price' ) {
|
44 |
+
$meta_query['price_filter']['value'][0] = $multi_currency->prices->unconvert_price_amount( $meta_query['price_filter']['value'][0] );
|
45 |
+
$meta_query['price_filter']['value'][1] = $multi_currency->prices->unconvert_price_amount( $meta_query['price_filter']['value'][1] );
|
46 |
+
}
|
47 |
+
}
|
48 |
+
|
49 |
+
return $meta_query;
|
50 |
+
}
|
51 |
+
|
52 |
+
}
|
inc/currencies/currency-switcher/class-wcml-currency-switcher-templates.php
CHANGED
@@ -79,7 +79,7 @@ class WCML_Currency_Switcher_Templates {
|
|
79 |
}
|
80 |
}
|
81 |
}
|
82 |
-
}
|
83 |
//set default template to active
|
84 |
$templates['wcml-dropdown'] = $this->templates['wcml-dropdown'];
|
85 |
}
|
@@ -144,13 +144,6 @@ class WCML_Currency_Switcher_Templates {
|
|
144 |
$templates = array();
|
145 |
$dirs_to_scan = array();
|
146 |
|
147 |
-
/**
|
148 |
-
* Filter the directories to scan
|
149 |
-
*
|
150 |
-
* @param array $dirs_to_scan
|
151 |
-
*/
|
152 |
-
$dirs_to_scan = apply_filters( 'wcml_cs_directories_to_scan', $dirs_to_scan );
|
153 |
-
|
154 |
$sub_dir = $this->ds . 'templates' . $this->ds . 'currency-switchers';
|
155 |
|
156 |
$wcml_core_path = WCML_PLUGIN_PATH . $sub_dir;
|
@@ -160,6 +153,13 @@ class WCML_Currency_Switcher_Templates {
|
|
160 |
|
161 |
array_unshift( $dirs_to_scan, $wcml_core_path, $theme_path, $child_theme_path, $uploads_path );
|
162 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
$templates_paths = $this->scan_template_paths( $dirs_to_scan );
|
164 |
|
165 |
foreach ( $templates_paths as $template_path ) {
|
79 |
}
|
80 |
}
|
81 |
}
|
82 |
+
}else{
|
83 |
//set default template to active
|
84 |
$templates['wcml-dropdown'] = $this->templates['wcml-dropdown'];
|
85 |
}
|
144 |
$templates = array();
|
145 |
$dirs_to_scan = array();
|
146 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
$sub_dir = $this->ds . 'templates' . $this->ds . 'currency-switchers';
|
148 |
|
149 |
$wcml_core_path = WCML_PLUGIN_PATH . $sub_dir;
|
153 |
|
154 |
array_unshift( $dirs_to_scan, $wcml_core_path, $theme_path, $child_theme_path, $uploads_path );
|
155 |
|
156 |
+
/**
|
157 |
+
* Filter the directories to scan
|
158 |
+
*
|
159 |
+
* @param array $dirs_to_scan
|
160 |
+
*/
|
161 |
+
$dirs_to_scan = apply_filters( 'wcml_cs_directories_to_scan', $dirs_to_scan );
|
162 |
+
|
163 |
$templates_paths = $this->scan_template_paths( $dirs_to_scan );
|
164 |
|
165 |
foreach ( $templates_paths as $template_path ) {
|
inc/translation-editor/class-wcml-editor-ui-product-job.php
CHANGED
@@ -238,6 +238,21 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
|
|
238 |
}
|
239 |
}
|
240 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
241 |
$taxonomies = get_object_taxonomies( 'product', 'objects' );
|
242 |
foreach( $taxonomies as $taxonomy => $taxonomy_obj ){
|
243 |
if( $taxonomy != 'product_type' && is_taxonomy_translated( $taxonomy ) ){
|
@@ -251,7 +266,7 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
|
|
251 |
){
|
252 |
continue;
|
253 |
}
|
254 |
-
$term_field = new WPML_Editor_UI_Single_Line_Field( 't_'. $term->
|
255 |
$tax_section->add_field( $term_field );
|
256 |
}
|
257 |
if( isset( $term_field ) ){
|
@@ -261,15 +276,6 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
|
|
261 |
}
|
262 |
}
|
263 |
|
264 |
-
if( $this->product_type === 'external' ){
|
265 |
-
$external_product_section = new WPML_Editor_UI_Field_Section( __( 'External Product', 'woocommerce-multilingual' ) );
|
266 |
-
$external_product_section->add_field( new WPML_Editor_UI_Single_Line_Field( '_product_url', __( 'Product url', 'woocommerce-multilingual' ), $this->data, true ) );
|
267 |
-
$external_product_section->add_field( new WPML_Editor_UI_Single_Line_Field( '_button_text', __( 'Button text', 'woocommerce-multilingual' ), $this->data, true ) );
|
268 |
-
$this->add_field( $external_product_section );
|
269 |
-
}
|
270 |
-
|
271 |
-
do_action( 'wcml_gui_additional_box_html', $this, $this->product_id, $this->data );
|
272 |
-
|
273 |
}
|
274 |
|
275 |
public function add_custom_fields_ui_section( $custom_fields_section, $custom_fields, $variation_id = false ){
|
@@ -374,26 +380,7 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
|
|
374 |
}
|
375 |
}
|
376 |
|
377 |
-
$
|
378 |
-
foreach( $taxonomies as $taxonomy => $taxonomy_obj ){
|
379 |
-
if( $taxonomy != 'product_type' && is_taxonomy_translated( $taxonomy ) ){
|
380 |
-
$product_terms = wp_get_post_terms( $this->product_id, $taxonomy );
|
381 |
-
if( $product_terms ){
|
382 |
-
foreach( $product_terms as $term ){
|
383 |
-
$translated_term = $this->woocommerce_wpml->terms->wcml_get_translated_term( $term->term_id, $taxonomy, $this->get_target_language() );
|
384 |
-
if(
|
385 |
-
$this->sitepress->get_setting( 'tm_block_retranslating_terms' ) &&
|
386 |
-
$translated_term->term_id != $term->term_id
|
387 |
-
){
|
388 |
-
continue;
|
389 |
-
}
|
390 |
-
|
391 |
-
$element_data[ 't_'.$term->term_id ] = array( 'original' => $term->name );
|
392 |
-
$element_data[ 't_'.$term->term_id ][ 'translation' ] = $translated_term->term_id != $term->term_id ? $translated_term->name : '';
|
393 |
-
}
|
394 |
-
}
|
395 |
-
}
|
396 |
-
}
|
397 |
|
398 |
$element_data = $this->add_custom_field_to_element_data( $element_data, $this->product_id, isset( $translation->ID ) ? $translation->ID : false, false );
|
399 |
|
@@ -449,6 +436,33 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
|
|
449 |
return $element_data;
|
450 |
}
|
451 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
452 |
public function add_custom_field_to_element_data( $element_data, $element_id, $translation_id, $is_variation = false ){
|
453 |
$custom_fields = $this->get_product_custom_fields_to_translate( $element_id );
|
454 |
if( $custom_fields ){
|
238 |
}
|
239 |
}
|
240 |
|
241 |
+
$this->add_taxonomies_ui_section();
|
242 |
+
|
243 |
+
if( $this->product_type === 'external' ){
|
244 |
+
$external_product_section = new WPML_Editor_UI_Field_Section( __( 'External Product', 'woocommerce-multilingual' ) );
|
245 |
+
$external_product_section->add_field( new WPML_Editor_UI_Single_Line_Field( '_product_url', __( 'Product url', 'woocommerce-multilingual' ), $this->data, true ) );
|
246 |
+
$external_product_section->add_field( new WPML_Editor_UI_Single_Line_Field( '_button_text', __( 'Button text', 'woocommerce-multilingual' ), $this->data, true ) );
|
247 |
+
$this->add_field( $external_product_section );
|
248 |
+
}
|
249 |
+
|
250 |
+
do_action( 'wcml_gui_additional_box_html', $this, $this->product_id, $this->data );
|
251 |
+
|
252 |
+
}
|
253 |
+
|
254 |
+
public function add_taxonomies_ui_section(){
|
255 |
+
|
256 |
$taxonomies = get_object_taxonomies( 'product', 'objects' );
|
257 |
foreach( $taxonomies as $taxonomy => $taxonomy_obj ){
|
258 |
if( $taxonomy != 'product_type' && is_taxonomy_translated( $taxonomy ) ){
|
266 |
){
|
267 |
continue;
|
268 |
}
|
269 |
+
$term_field = new WPML_Editor_UI_Single_Line_Field( 't_'. $term->term_taxonomy_id, '', $this->data, false );
|
270 |
$tax_section->add_field( $term_field );
|
271 |
}
|
272 |
if( isset( $term_field ) ){
|
276 |
}
|
277 |
}
|
278 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
279 |
}
|
280 |
|
281 |
public function add_custom_fields_ui_section( $custom_fields_section, $custom_fields, $variation_id = false ){
|
380 |
}
|
381 |
}
|
382 |
|
383 |
+
$element_data = $this->add_taxonomies_to_element_data( $element_data );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
384 |
|
385 |
$element_data = $this->add_custom_field_to_element_data( $element_data, $this->product_id, isset( $translation->ID ) ? $translation->ID : false, false );
|
386 |
|
436 |
return $element_data;
|
437 |
}
|
438 |
|
439 |
+
public function add_taxonomies_to_element_data( $element_data ){
|
440 |
+
|
441 |
+
$taxonomies = get_object_taxonomies( 'product', 'objects' );
|
442 |
+
|
443 |
+
foreach( $taxonomies as $taxonomy => $taxonomy_obj ){
|
444 |
+
if( $taxonomy != 'product_type' && is_taxonomy_translated( $taxonomy ) ){
|
445 |
+
$product_terms = wp_get_post_terms( $this->product_id, $taxonomy );
|
446 |
+
if( !is_wp_error( $product_terms ) ){
|
447 |
+
foreach( $product_terms as $term ){
|
448 |
+
$translated_term = $this->woocommerce_wpml->terms->wcml_get_translated_term( $term->term_id, $taxonomy, $this->get_target_language() );
|
449 |
+
if(
|
450 |
+
$this->sitepress->get_setting( 'tm_block_retranslating_terms' ) &&
|
451 |
+
$translated_term->term_taxonomy_id != $term->term_taxonomy_id
|
452 |
+
){
|
453 |
+
continue;
|
454 |
+
}
|
455 |
+
|
456 |
+
$element_data[ 't_'.$term->term_taxonomy_id ] = array( 'original' => $term->name );
|
457 |
+
$element_data[ 't_'.$term->term_taxonomy_id ][ 'translation' ] = $translated_term->term_taxonomy_id != $term->term_taxonomy_id ? $translated_term->name : '';
|
458 |
+
}
|
459 |
+
}
|
460 |
+
}
|
461 |
+
}
|
462 |
+
|
463 |
+
return $element_data;
|
464 |
+
}
|
465 |
+
|
466 |
public function add_custom_field_to_element_data( $element_data, $element_id, $translation_id, $is_variation = false ){
|
467 |
$custom_fields = $this->get_product_custom_fields_to_translate( $element_id );
|
468 |
if( $custom_fields ){
|
inc/translation-editor/class-wcml-wc-admin-duplicate-product.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class WCML_WC_Admin_Duplicate_Product
|
4 |
|
5 |
/**
|
6 |
* @var woocommerce_wpml
|
@@ -68,6 +68,7 @@ class WCML_WC_Admin_Duplicate_Product extends WC_Admin_Duplicate_Product{
|
|
68 |
$translations = $this->sitepress->get_element_translations( $trid, 'post_' . $post->post_type );
|
69 |
$duplicated_products[ 'translations' ] = array();
|
70 |
if( $translations ){
|
|
|
71 |
foreach( $translations as $translation ){
|
72 |
if( !$translation->original && $translation->element_id != $product_id ){
|
73 |
$post_to_duplicate = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT * FROM {$this->wpdb->posts} WHERE ID=%d", $translation->element_id ) );
|
@@ -105,11 +106,12 @@ class WCML_WC_Admin_Duplicate_Product extends WC_Admin_Duplicate_Product{
|
|
105 |
public function wc_duplicate_product( $post_to_duplicate ){
|
106 |
|
107 |
$product = wc_get_product( $post_to_duplicate->ID );
|
108 |
-
|
|
|
109 |
if( WooCommerce_Functions_Wrapper::is_deprecated() ){
|
110 |
-
$new_orig_id = $
|
111 |
}else{
|
112 |
-
$duplicate = $
|
113 |
$new_orig_id = $duplicate->get_id();
|
114 |
}
|
115 |
|
1 |
<?php
|
2 |
|
3 |
+
class WCML_WC_Admin_Duplicate_Product{
|
4 |
|
5 |
/**
|
6 |
* @var woocommerce_wpml
|
68 |
$translations = $this->sitepress->get_element_translations( $trid, 'post_' . $post->post_type );
|
69 |
$duplicated_products[ 'translations' ] = array();
|
70 |
if( $translations ){
|
71 |
+
|
72 |
foreach( $translations as $translation ){
|
73 |
if( !$translation->original && $translation->element_id != $product_id ){
|
74 |
$post_to_duplicate = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT * FROM {$this->wpdb->posts} WHERE ID=%d", $translation->element_id ) );
|
106 |
public function wc_duplicate_product( $post_to_duplicate ){
|
107 |
|
108 |
$product = wc_get_product( $post_to_duplicate->ID );
|
109 |
+
$wc_duplicate_product_instance = new WC_Admin_Duplicate_Product();;
|
110 |
+
|
111 |
if( WooCommerce_Functions_Wrapper::is_deprecated() ){
|
112 |
+
$new_orig_id = $wc_duplicate_product_instance->duplicate_product( $product );
|
113 |
}else{
|
114 |
+
$duplicate = $wc_duplicate_product_instance->product_duplicate( $product );
|
115 |
$new_orig_id = $duplicate->get_id();
|
116 |
}
|
117 |
|
readme.txt
CHANGED
@@ -4,8 +4,8 @@ Donate link: http://wpml.org/documentation/related-projects/woocommerce-multilin
|
|
4 |
Tags: CMS, woocommerce, commerce, ecommerce, e-commerce, products, WPML, multilingual, e-shop, shop
|
5 |
License: GPLv2
|
6 |
Requires at least: 3.9
|
7 |
-
Tested up to: 4.
|
8 |
-
Stable tag: 4.1.
|
9 |
|
10 |
Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
|
11 |
|
@@ -142,6 +142,17 @@ WooCommerce Multilingual is compatible with all major WooCommerce extensions. We
|
|
142 |
|
143 |
== Changelog ==
|
144 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
= 4.1.3 =
|
146 |
* Improvements for the REST API support (compliant with WooCommerce REST API v2)
|
147 |
* Bug fix: Order confirmation emails were not translated correctly when using WooCommerce 3.0
|
@@ -172,17 +183,19 @@ WooCommerce Multilingual is compatible with all major WooCommerce extensions. We
|
|
172 |
* Fixed compatibility issues with Aelia Currency Switcher and Aelia Foundation
|
173 |
* Fixed a compatibility issue with Visual Composer: shortcodes were not parsed in the translation editor
|
174 |
|
175 |
-
|
176 |
= 4.1.2 =
|
|
|
177 |
* Fixed the currency switcher not being displayed correctly when using the Storefront theme
|
178 |
-
* Fixed
|
179 |
-
* Fixed the currency switcher css being loaded when no currency switcher was displayed
|
180 |
* Fixed a bug causing an error when upgrading WooCommerce Multilingual to version 4.1 with WooCommerce inactive.
|
|
|
181 |
|
182 |
= 4.1.1 =
|
183 |
-
* Fixed
|
184 |
-
* Fixed
|
185 |
-
* Fixed
|
|
|
|
|
186 |
|
187 |
= 4.1.0 =
|
188 |
* Enhanced language switchers
|
4 |
Tags: CMS, woocommerce, commerce, ecommerce, e-commerce, products, WPML, multilingual, e-shop, shop
|
5 |
License: GPLv2
|
6 |
Requires at least: 3.9
|
7 |
+
Tested up to: 4.8.0
|
8 |
+
Stable tag: 4.1.4
|
9 |
|
10 |
Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
|
11 |
|
142 |
|
143 |
== Changelog ==
|
144 |
|
145 |
+
= 4.1.4 =
|
146 |
+
* Fix: A PHP warning was shown on a product bundle page on the front end (when using WooCommerce Product Bundles)
|
147 |
+
* Fix: Added possibility to filter available Currency Switcher templates paths via "wcml_cs_directories_to_scan" filter
|
148 |
+
* Fix: The "Copy to a new draft" link was showing two times on the product edit page
|
149 |
+
* Fix: For taxonomies having the term_id distinct from term_taxonomy_id, the translations could have been accidentally overwritten
|
150 |
+
* Fix: In some conditions, a fatal error could come up when editing a product
|
151 |
+
* Fix: In some circustances, disabling currency switcher on product page produced a fatal error
|
152 |
+
* Fix: Custom attributes in the translations were reset after editing the original product
|
153 |
+
* Fix: Sometimes, the translated product category pages were returning a 404 error
|
154 |
+
* Fix: It was not possible to filter products by price on the shop page using the WooCommerce Price Filter widget
|
155 |
+
|
156 |
= 4.1.3 =
|
157 |
* Improvements for the REST API support (compliant with WooCommerce REST API v2)
|
158 |
* Bug fix: Order confirmation emails were not translated correctly when using WooCommerce 3.0
|
183 |
* Fixed compatibility issues with Aelia Currency Switcher and Aelia Foundation
|
184 |
* Fixed a compatibility issue with Visual Composer: shortcodes were not parsed in the translation editor
|
185 |
|
|
|
186 |
= 4.1.2 =
|
187 |
+
* Fixed `Fatal error: Call to undefined method WPML_WP_API::defined`
|
188 |
* Fixed the currency switcher not being displayed correctly when using the Storefront theme
|
189 |
+
* Fixed `Fatal error: Call to undefined function wc_format_decimal()`
|
|
|
190 |
* Fixed a bug causing an error when upgrading WooCommerce Multilingual to version 4.1 with WooCommerce inactive.
|
191 |
+
* Fixed the currency switcher css being loaded when no currency switcher was displayed
|
192 |
|
193 |
= 4.1.1 =
|
194 |
+
* Fixed a pre PHP 5.4 compatibility issue
|
195 |
+
* Fixed `Notice: Undefined index: switcher_id`
|
196 |
+
* Fixed `Fatal error: Class ‘WPML_File’ not found` when using an old version of WPML
|
197 |
+
* Fixed "Invalid or duplicated SKU" error when saving or updating a product with SKU
|
198 |
+
* Fixed `Fatal error: Call to undefined function WC()` when disabling WooCommerce while WCML is running
|
199 |
|
200 |
= 4.1.0 =
|
201 |
* Enhanced language switchers
|
vendor/autoload.php
CHANGED
@@ -4,4 +4,4 @@
|
|
4 |
|
5 |
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
|
7 |
-
return
|
4 |
|
5 |
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
|
7 |
+
return ComposerAutoloaderInit3d46cc8388475e6b99b9a4c2356d4330::getLoader();
|
vendor/autoload_52.php
CHANGED
@@ -4,4 +4,4 @@
|
|
4 |
|
5 |
require_once dirname(__FILE__) . '/composer'.'/autoload_real_52.php';
|
6 |
|
7 |
-
return
|
4 |
|
5 |
require_once dirname(__FILE__) . '/composer'.'/autoload_real_52.php';
|
6 |
|
7 |
+
return ComposerAutoloaderInit226a7f3fe2d604eac20e142d7118628a::getLoader();
|
vendor/composer/autoload_classmap.php
CHANGED
@@ -356,6 +356,7 @@ return array(
|
|
356 |
'WCML_Plugins_Wrap' => $baseDir . '/inc/template-classes/class-wcml-plugins-wrap.php',
|
357 |
'WCML_Pointer_UI' => $baseDir . '/inc/template-classes/class-wcml-pointer-ui.php',
|
358 |
'WCML_Pointers' => $baseDir . '/inc/admin-menus/class-wcml-pointers.php',
|
|
|
359 |
'WCML_Product_Addons' => $baseDir . '/compatibility/class-wcml-product-addons.php',
|
360 |
'WCML_Product_Bundles' => $baseDir . '/compatibility/class-wcml-product-bundles.php',
|
361 |
'WCML_Product_Bundles_Legacy' => $baseDir . '/compatibility/class-wcml-product-bundles-legacy.php',
|
356 |
'WCML_Plugins_Wrap' => $baseDir . '/inc/template-classes/class-wcml-plugins-wrap.php',
|
357 |
'WCML_Pointer_UI' => $baseDir . '/inc/template-classes/class-wcml-pointer-ui.php',
|
358 |
'WCML_Pointers' => $baseDir . '/inc/admin-menus/class-wcml-pointers.php',
|
359 |
+
'WCML_Price_Filter' => $baseDir . '/inc/currencies/class-wcml-price-filter.php',
|
360 |
'WCML_Product_Addons' => $baseDir . '/compatibility/class-wcml-product-addons.php',
|
361 |
'WCML_Product_Bundles' => $baseDir . '/compatibility/class-wcml-product-bundles.php',
|
362 |
'WCML_Product_Bundles_Legacy' => $baseDir . '/compatibility/class-wcml-product-bundles-legacy.php',
|
vendor/composer/autoload_real.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
-
class
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
@@ -19,15 +19,15 @@ class ComposerAutoloaderInitb9ffed287a5b4e2fcc802a91254f114a
|
|
19 |
return self::$loader;
|
20 |
}
|
21 |
|
22 |
-
spl_autoload_register(array('
|
23 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
24 |
-
spl_autoload_unregister(array('
|
25 |
|
26 |
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
27 |
if ($useStaticLoader) {
|
28 |
require_once __DIR__ . '/autoload_static.php';
|
29 |
|
30 |
-
call_user_func(\Composer\Autoload\
|
31 |
} else {
|
32 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
33 |
foreach ($map as $namespace => $path) {
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
+
class ComposerAutoloaderInit3d46cc8388475e6b99b9a4c2356d4330
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
19 |
return self::$loader;
|
20 |
}
|
21 |
|
22 |
+
spl_autoload_register(array('ComposerAutoloaderInit3d46cc8388475e6b99b9a4c2356d4330', 'loadClassLoader'), true, true);
|
23 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
24 |
+
spl_autoload_unregister(array('ComposerAutoloaderInit3d46cc8388475e6b99b9a4c2356d4330', 'loadClassLoader'));
|
25 |
|
26 |
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
27 |
if ($useStaticLoader) {
|
28 |
require_once __DIR__ . '/autoload_static.php';
|
29 |
|
30 |
+
call_user_func(\Composer\Autoload\ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330::getInitializer($loader));
|
31 |
} else {
|
32 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
33 |
foreach ($map as $namespace => $path) {
|
vendor/composer/autoload_real_52.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
// autoload_real_52.php generated by xrstf/composer-php52
|
4 |
|
5 |
-
class
|
6 |
private static $loader;
|
7 |
|
8 |
public static function loadClassLoader($class) {
|
@@ -19,9 +19,9 @@ class ComposerAutoloaderInit38be79df74f6b23b0833390c6a01eb02 {
|
|
19 |
return self::$loader;
|
20 |
}
|
21 |
|
22 |
-
spl_autoload_register(array('
|
23 |
self::$loader = $loader = new xrstf_Composer52_ClassLoader();
|
24 |
-
spl_autoload_unregister(array('
|
25 |
|
26 |
$vendorDir = dirname(dirname(__FILE__));
|
27 |
$baseDir = dirname($vendorDir);
|
2 |
|
3 |
// autoload_real_52.php generated by xrstf/composer-php52
|
4 |
|
5 |
+
class ComposerAutoloaderInit226a7f3fe2d604eac20e142d7118628a {
|
6 |
private static $loader;
|
7 |
|
8 |
public static function loadClassLoader($class) {
|
19 |
return self::$loader;
|
20 |
}
|
21 |
|
22 |
+
spl_autoload_register(array('ComposerAutoloaderInit226a7f3fe2d604eac20e142d7118628a', 'loadClassLoader'), true /*, true */);
|
23 |
self::$loader = $loader = new xrstf_Composer52_ClassLoader();
|
24 |
+
spl_autoload_unregister(array('ComposerAutoloaderInit226a7f3fe2d604eac20e142d7118628a', 'loadClassLoader'));
|
25 |
|
26 |
$vendorDir = dirname(dirname(__FILE__));
|
27 |
$baseDir = dirname($vendorDir);
|
vendor/composer/autoload_static.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
|
5 |
namespace Composer\Autoload;
|
6 |
|
7 |
-
class
|
8 |
{
|
9 |
public static $prefixLengthsPsr4 = array (
|
10 |
'C' =>
|
@@ -388,6 +388,7 @@ class ComposerStaticInitb9ffed287a5b4e2fcc802a91254f114a
|
|
388 |
'WCML_Plugins_Wrap' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-plugins-wrap.php',
|
389 |
'WCML_Pointer_UI' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-pointer-ui.php',
|
390 |
'WCML_Pointers' => __DIR__ . '/../..' . '/inc/admin-menus/class-wcml-pointers.php',
|
|
|
391 |
'WCML_Product_Addons' => __DIR__ . '/../..' . '/compatibility/class-wcml-product-addons.php',
|
392 |
'WCML_Product_Bundles' => __DIR__ . '/../..' . '/compatibility/class-wcml-product-bundles.php',
|
393 |
'WCML_Product_Bundles_Legacy' => __DIR__ . '/../..' . '/compatibility/class-wcml-product-bundles-legacy.php',
|
@@ -462,10 +463,10 @@ class ComposerStaticInitb9ffed287a5b4e2fcc802a91254f114a
|
|
462 |
public static function getInitializer(ClassLoader $loader)
|
463 |
{
|
464 |
return \Closure::bind(function () use ($loader) {
|
465 |
-
$loader->prefixLengthsPsr4 =
|
466 |
-
$loader->prefixDirsPsr4 =
|
467 |
-
$loader->prefixesPsr0 =
|
468 |
-
$loader->classMap =
|
469 |
|
470 |
}, null, ClassLoader::class);
|
471 |
}
|
4 |
|
5 |
namespace Composer\Autoload;
|
6 |
|
7 |
+
class ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330
|
8 |
{
|
9 |
public static $prefixLengthsPsr4 = array (
|
10 |
'C' =>
|
388 |
'WCML_Plugins_Wrap' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-plugins-wrap.php',
|
389 |
'WCML_Pointer_UI' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-pointer-ui.php',
|
390 |
'WCML_Pointers' => __DIR__ . '/../..' . '/inc/admin-menus/class-wcml-pointers.php',
|
391 |
+
'WCML_Price_Filter' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-price-filter.php',
|
392 |
'WCML_Product_Addons' => __DIR__ . '/../..' . '/compatibility/class-wcml-product-addons.php',
|
393 |
'WCML_Product_Bundles' => __DIR__ . '/../..' . '/compatibility/class-wcml-product-bundles.php',
|
394 |
'WCML_Product_Bundles_Legacy' => __DIR__ . '/../..' . '/compatibility/class-wcml-product-bundles-legacy.php',
|
463 |
public static function getInitializer(ClassLoader $loader)
|
464 |
{
|
465 |
return \Closure::bind(function () use ($loader) {
|
466 |
+
$loader->prefixLengthsPsr4 = ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330::$prefixLengthsPsr4;
|
467 |
+
$loader->prefixDirsPsr4 = ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330::$prefixDirsPsr4;
|
468 |
+
$loader->prefixesPsr0 = ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330::$prefixesPsr0;
|
469 |
+
$loader->classMap = ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330::$classMap;
|
470 |
|
471 |
}, null, ClassLoader::class);
|
472 |
}
|
vendor/otgs/installer/includes/class-installer-dependencies.php
CHANGED
@@ -42,7 +42,7 @@ class Installer_Dependencies{
|
|
42 |
|
43 |
$installer_settings = WP_Installer()->settings;
|
44 |
|
45 |
-
if ( is_array( $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'] ) ) {
|
46 |
$a_plugin = current( $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'] );
|
47 |
$url = WP_Installer()->append_site_key_to_download_url( $a_plugin['url'], 'xxxxxx', $repository_id );
|
48 |
$tmpfname = wp_tempnam( $url );
|
42 |
|
43 |
$installer_settings = WP_Installer()->settings;
|
44 |
|
45 |
+
if ( isset($installer_settings['repositories'][$repository_id]['data']) && is_array( $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'] ) ) {
|
46 |
$a_plugin = current( $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'] );
|
47 |
$url = WP_Installer()->append_site_key_to_download_url( $a_plugin['url'], 'xxxxxx', $repository_id );
|
48 |
$tmpfname = wp_tempnam( $url );
|
vendor/otgs/installer/includes/installer.class.php
CHANGED
@@ -471,11 +471,14 @@ final class WP_Installer{
|
|
471 |
$this->settings = unserialize($_settings);
|
472 |
}
|
473 |
|
474 |
-
|
475 |
-
|
476 |
-
|
|
|
|
|
|
|
477 |
|
478 |
-
if (is_multisite()
|
479 |
$network_settings = maybe_unserialize(get_site_option('wp_installer_network'));
|
480 |
if ($network_settings) {
|
481 |
foreach ($this->settings['repositories'] as $rep_id => $repository) {
|
@@ -559,20 +562,16 @@ final class WP_Installer{
|
|
559 |
private function _pre_1_6_backwards_compatibility($settings){
|
560 |
|
561 |
if( version_compare($this->version(), '1.8', '<') && !empty($settings['repositories']) ){
|
562 |
-
|
563 |
foreach ($settings['repositories'] as $repository_id => $repository) {
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
}
|
570 |
}
|
571 |
-
|
572 |
}
|
573 |
|
574 |
return $settings;
|
575 |
-
|
576 |
}
|
577 |
|
578 |
//backward compatibility - support old products list format (downloads under products instead of global downloads list)
|
@@ -581,61 +580,41 @@ final class WP_Installer{
|
|
581 |
if( version_compare($this->version(), '1.8', '<') && !empty($settings['repositories']) && empty($this->_old_products_format_backwards_compatibility) ) {
|
582 |
|
583 |
foreach ($settings['repositories'] as $repository_id => $repository) {
|
584 |
-
|
585 |
$populate_downloads = false;
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
foreach ($product['downloads'] as $download_id => $download) {
|
615 |
-
|
616 |
-
if (!isset($settings['repositories'][$repository_id]['data']['downloads']['plugins'][$download['slug']])) {
|
617 |
-
$settings['repositories'][$repository_id]['data']['downloads']['plugins'][$download['slug']] = $download;
|
618 |
-
}
|
619 |
-
|
620 |
-
$settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['plugins'][] = $download['slug'];
|
621 |
-
}
|
622 |
-
|
623 |
-
unset($settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['downloads']);
|
624 |
-
|
625 |
-
}
|
626 |
-
|
627 |
-
}
|
628 |
-
|
629 |
-
}
|
630 |
-
|
631 |
}
|
632 |
|
633 |
$this->_old_products_format_backwards_compatibility = true;
|
634 |
-
|
635 |
}
|
636 |
|
637 |
return $settings;
|
638 |
-
|
639 |
}
|
640 |
|
641 |
public function get_installer_site_url( $repository_id = false ){
|
471 |
$this->settings = unserialize($_settings);
|
472 |
}
|
473 |
|
474 |
+
// Initialize
|
475 |
+
if( empty( $this->settings ) ){
|
476 |
+
$this->settings = array(
|
477 |
+
'repositories' => array()
|
478 |
+
);
|
479 |
+
}
|
480 |
|
481 |
+
if ( is_multisite() ) {
|
482 |
$network_settings = maybe_unserialize(get_site_option('wp_installer_network'));
|
483 |
if ($network_settings) {
|
484 |
foreach ($this->settings['repositories'] as $rep_id => $repository) {
|
562 |
private function _pre_1_6_backwards_compatibility($settings){
|
563 |
|
564 |
if( version_compare($this->version(), '1.8', '<') && !empty($settings['repositories']) ){
|
|
|
565 |
foreach ($settings['repositories'] as $repository_id => $repository) {
|
566 |
+
if( isset( $repository['data'] ) ) {
|
567 |
+
foreach ( $repository['data']['downloads']['plugins'] as $slug => $download ) {
|
568 |
+
$settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $slug ]['slug'] = $download['basename'];
|
569 |
+
}
|
|
|
570 |
}
|
571 |
}
|
|
|
572 |
}
|
573 |
|
574 |
return $settings;
|
|
|
575 |
}
|
576 |
|
577 |
//backward compatibility - support old products list format (downloads under products instead of global downloads list)
|
580 |
if( version_compare($this->version(), '1.8', '<') && !empty($settings['repositories']) && empty($this->_old_products_format_backwards_compatibility) ) {
|
581 |
|
582 |
foreach ($settings['repositories'] as $repository_id => $repository) {
|
|
|
583 |
$populate_downloads = false;
|
584 |
+
if( isset( $repository['data'] ) ) {
|
585 |
+
|
586 |
+
foreach ( $repository['data']['packages'] as $package_id => $package ) {
|
587 |
+
foreach ( $package['products'] as $product_id => $product ) {
|
588 |
+
if ( ! isset( $product['plugins'] ) ) {
|
589 |
+
$populate_downloads = true;
|
590 |
+
foreach ( $product['downloads'] as $download_id => $download ) {
|
591 |
+
$settings['repositories'][ $repository_id ]['data']['packages'][ $package_id ]['products'][ $product_id ]['plugins'][] = $download['slug'];
|
592 |
+
}
|
593 |
+
}
|
594 |
+
}
|
595 |
+
}
|
596 |
+
|
597 |
+
if ( $populate_downloads ) {
|
598 |
+
// Add downloads branch
|
599 |
+
foreach ( $repository['data']['packages'] as $package_id => $package ) {
|
600 |
+
foreach ( $package['products'] as $product_id => $product ) {
|
601 |
+
foreach ( $product['downloads'] as $download_id => $download ) {
|
602 |
+
if ( ! isset( $settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $download['slug'] ] ) ) {
|
603 |
+
$settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $download['slug'] ] = $download;
|
604 |
+
}
|
605 |
+
$settings['repositories'][ $repository_id ]['data']['packages'][ $package_id ]['products'][ $product_id ]['plugins'][] = $download['slug'];
|
606 |
+
}
|
607 |
+
unset( $settings['repositories'][ $repository_id ]['data']['packages'][ $package_id ]['products'][ $product_id ]['downloads'] );
|
608 |
+
}
|
609 |
+
}
|
610 |
+
}
|
611 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
612 |
}
|
613 |
|
614 |
$this->_old_products_format_backwards_compatibility = true;
|
|
|
615 |
}
|
616 |
|
617 |
return $settings;
|
|
|
618 |
}
|
619 |
|
620 |
public function get_installer_site_url( $repository_id = false ){
|
vendor/otgs/installer/installer.php
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<?php
|
2 |
-
define('WP_INSTALLER_VERSION', '1.7.
|
3 |
|
4 |
include_once dirname(__FILE__) . '/includes/installer.class.php';
|
5 |
|
1 |
<?php
|
2 |
+
define('WP_INSTALLER_VERSION', '1.7.17');
|
3 |
|
4 |
include_once dirname(__FILE__) . '/includes/installer.class.php';
|
5 |
|
vendor/otgs/installer/loader.php
CHANGED
@@ -19,7 +19,7 @@ $wp_installer_instance = dirname(__FILE__) . '/installer.php';
|
|
19 |
global $wp_installer_instances;
|
20 |
$wp_installer_instances[$wp_installer_instance] = array(
|
21 |
'bootfile' => $wp_installer_instance,
|
22 |
-
'version' => '1.7.
|
23 |
);
|
24 |
|
25 |
|
19 |
global $wp_installer_instances;
|
20 |
$wp_installer_instances[$wp_installer_instance] = array(
|
21 |
'bootfile' => $wp_installer_instance,
|
22 |
+
'version' => '1.7.17'
|
23 |
);
|
24 |
|
25 |
|
vendor/twig/twig/CHANGELOG
CHANGED
@@ -1,7 +1,16 @@
|
|
1 |
-
* 1.
|
2 |
|
3 |
* n/a
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* 1.32.0 (2017-02-26)
|
6 |
|
7 |
* fixed deprecation notice in Twig_Util_DeprecationCollector
|
1 |
+
* 1.33.1 (2017-XX-XX)
|
2 |
|
3 |
* n/a
|
4 |
|
5 |
+
* 1.33.0 (2017-03-22)
|
6 |
+
|
7 |
+
* fixed a race condition handling when writing cache files
|
8 |
+
* "length" filter now returns string length when applied to an object that does
|
9 |
+
not implement \Countable but provides __toString()
|
10 |
+
* "empty" test will now consider the return value of the __toString() method for
|
11 |
+
objects implement __toString() but not \Countable
|
12 |
+
* fixed JS escaping for unicode characters with higher code points
|
13 |
+
|
14 |
* 1.32.0 (2017-02-26)
|
15 |
|
16 |
* fixed deprecation notice in Twig_Util_DeprecationCollector
|
vendor/twig/twig/ext/twig/php_twig.h
CHANGED
@@ -15,7 +15,7 @@
|
|
15 |
#ifndef PHP_TWIG_H
|
16 |
#define PHP_TWIG_H
|
17 |
|
18 |
-
#define PHP_TWIG_VERSION "1.
|
19 |
|
20 |
#include "php.h"
|
21 |
|
15 |
#ifndef PHP_TWIG_H
|
16 |
#define PHP_TWIG_H
|
17 |
|
18 |
+
#define PHP_TWIG_VERSION "1.33.1-DEV"
|
19 |
|
20 |
#include "php.h"
|
21 |
|
vendor/twig/twig/lib/Twig/Cache/Filesystem.php
CHANGED
@@ -49,8 +49,13 @@ class Twig_Cache_Filesystem implements Twig_CacheInterface
|
|
49 |
{
|
50 |
$dir = dirname($key);
|
51 |
if (!is_dir($dir)) {
|
52 |
-
if (false === @mkdir($dir, 0777, true)
|
53 |
-
|
|
|
|
|
|
|
|
|
|
|
54 |
}
|
55 |
} elseif (!is_writable($dir)) {
|
56 |
throw new RuntimeException(sprintf('Unable to write in the cache directory (%s).', $dir));
|
49 |
{
|
50 |
$dir = dirname($key);
|
51 |
if (!is_dir($dir)) {
|
52 |
+
if (false === @mkdir($dir, 0777, true)) {
|
53 |
+
if (PHP_VERSION_ID >= 50300) {
|
54 |
+
clearstatcache(true, $dir);
|
55 |
+
}
|
56 |
+
if (!is_dir($dir)) {
|
57 |
+
throw new RuntimeException(sprintf('Unable to create the cache directory (%s).', $dir));
|
58 |
+
}
|
59 |
}
|
60 |
} elseif (!is_writable($dir)) {
|
61 |
throw new RuntimeException(sprintf('Unable to write in the cache directory (%s).', $dir));
|
vendor/twig/twig/lib/Twig/Environment.php
CHANGED
@@ -16,10 +16,10 @@
|
|
16 |
*/
|
17 |
class Twig_Environment
|
18 |
{
|
19 |
-
const VERSION = '1.
|
20 |
-
const VERSION_ID =
|
21 |
const MAJOR_VERSION = 1;
|
22 |
-
const MINOR_VERSION =
|
23 |
const RELEASE_VERSION = 1;
|
24 |
const EXTRA_VERSION = 'DEV';
|
25 |
|
16 |
*/
|
17 |
class Twig_Environment
|
18 |
{
|
19 |
+
const VERSION = '1.33.1';
|
20 |
+
const VERSION_ID = 13301;
|
21 |
const MAJOR_VERSION = 1;
|
22 |
+
const MINOR_VERSION = 33;
|
23 |
const RELEASE_VERSION = 1;
|
24 |
const EXTRA_VERSION = 'DEV';
|
25 |
|
vendor/twig/twig/lib/Twig/Extension/Core.php
CHANGED
@@ -1168,8 +1168,13 @@ function _twig_escape_js_callback($matches)
|
|
1168 |
|
1169 |
// \uHHHH
|
1170 |
$char = twig_convert_encoding($char, 'UTF-16BE', 'UTF-8');
|
|
|
1171 |
|
1172 |
-
|
|
|
|
|
|
|
|
|
1173 |
}
|
1174 |
|
1175 |
function _twig_escape_css_callback($matches)
|
@@ -1259,7 +1264,15 @@ if (function_exists('mb_get_info')) {
|
|
1259 |
*/
|
1260 |
function twig_length_filter(Twig_Environment $env, $thing)
|
1261 |
{
|
1262 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1263 |
}
|
1264 |
|
1265 |
/**
|
@@ -1342,7 +1355,15 @@ else {
|
|
1342 |
*/
|
1343 |
function twig_length_filter(Twig_Environment $env, $thing)
|
1344 |
{
|
1345 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1346 |
}
|
1347 |
|
1348 |
/**
|
@@ -1404,6 +1425,10 @@ function twig_test_empty($value)
|
|
1404 |
return 0 == count($value);
|
1405 |
}
|
1406 |
|
|
|
|
|
|
|
|
|
1407 |
return '' === $value || false === $value || null === $value || array() === $value;
|
1408 |
}
|
1409 |
|
1168 |
|
1169 |
// \uHHHH
|
1170 |
$char = twig_convert_encoding($char, 'UTF-16BE', 'UTF-8');
|
1171 |
+
$char = strtoupper(bin2hex($char));
|
1172 |
|
1173 |
+
if (4 >= strlen($char)) {
|
1174 |
+
return sprintf('\u%04s', $char);
|
1175 |
+
}
|
1176 |
+
|
1177 |
+
return sprintf('\u%04s\u%04s', substr($char, 0, -4), substr($char, -4));
|
1178 |
}
|
1179 |
|
1180 |
function _twig_escape_css_callback($matches)
|
1264 |
*/
|
1265 |
function twig_length_filter(Twig_Environment $env, $thing)
|
1266 |
{
|
1267 |
+
if (is_scalar($thing)) {
|
1268 |
+
return mb_strlen($thing, $env->getCharset());
|
1269 |
+
}
|
1270 |
+
|
1271 |
+
if (is_object($thing) && method_exists($thing, '__toString') && !$thing instanceof \Countable) {
|
1272 |
+
return mb_strlen((string) $thing, $env->getCharset());
|
1273 |
+
}
|
1274 |
+
|
1275 |
+
return count($thing);
|
1276 |
}
|
1277 |
|
1278 |
/**
|
1355 |
*/
|
1356 |
function twig_length_filter(Twig_Environment $env, $thing)
|
1357 |
{
|
1358 |
+
if (is_scalar($thing)) {
|
1359 |
+
return strlen($thing);
|
1360 |
+
}
|
1361 |
+
|
1362 |
+
if (is_object($thing) && method_exists($thing, '__toString') && !$thing instanceof \Countable) {
|
1363 |
+
return strlen((string) $thing);
|
1364 |
+
}
|
1365 |
+
|
1366 |
+
return count($thing);
|
1367 |
}
|
1368 |
|
1369 |
/**
|
1425 |
return 0 == count($value);
|
1426 |
}
|
1427 |
|
1428 |
+
if (is_object($value) && method_exists($value, '__toString')) {
|
1429 |
+
return '' === (string) $value;
|
1430 |
+
}
|
1431 |
+
|
1432 |
return '' === $value || false === $value || null === $value || array() === $value;
|
1433 |
}
|
1434 |
|
vendor/twig/twig/lib/Twig/Loader/Array.php
CHANGED
@@ -80,7 +80,7 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
|
|
80 |
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
|
81 |
}
|
82 |
|
83 |
-
return $this->templates[$name];
|
84 |
}
|
85 |
|
86 |
public function isFresh($name, $time)
|
80 |
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
|
81 |
}
|
82 |
|
83 |
+
return $name.':'.$this->templates[$name];
|
84 |
}
|
85 |
|
86 |
public function isFresh($name, $time)
|
vendor/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php
CHANGED
@@ -22,7 +22,7 @@ class Twig_Profiler_Dumper_Blackfire
|
|
22 |
$this->dumpProfile('main()', $profile, $data);
|
23 |
$this->dumpChildren('main()', $profile, $data);
|
24 |
|
25 |
-
$start = microtime(true);
|
26 |
$str = <<<EOF
|
27 |
file-format: BlackfireProbe
|
28 |
cost-dimensions: wt mu pmu
|
22 |
$this->dumpProfile('main()', $profile, $data);
|
23 |
$this->dumpChildren('main()', $profile, $data);
|
24 |
|
25 |
+
$start = sprintf('%f', microtime(true));
|
26 |
$str = <<<EOF
|
27 |
file-format: BlackfireProbe
|
28 |
cost-dimensions: wt mu pmu
|
vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php
CHANGED
@@ -121,6 +121,10 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
|
|
121 |
|
122 |
protected function doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs)
|
123 |
{
|
|
|
|
|
|
|
|
|
124 |
if ($condition) {
|
125 |
eval('$ret = '.$condition.';');
|
126 |
if (!$ret) {
|
121 |
|
122 |
protected function doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs)
|
123 |
{
|
124 |
+
if (!$outputs) {
|
125 |
+
$this->markTestSkipped('no legacy tests to run');
|
126 |
+
}
|
127 |
+
|
128 |
if ($condition) {
|
129 |
eval('$ret = '.$condition.';');
|
130 |
if (!$ret) {
|
wpml-config.xml
CHANGED
@@ -61,6 +61,7 @@
|
|
61 |
<custom-field action="translate">_variation_description</custom-field>
|
62 |
<custom-field action="ignore">wcml_sync_hash</custom-field>
|
63 |
<custom-field action="ignore">wpml_language</custom-field>
|
|
|
64 |
</custom-fields>
|
65 |
<custom-types>
|
66 |
<custom-type translate="1">product</custom-type>
|
61 |
<custom-field action="translate">_variation_description</custom-field>
|
62 |
<custom-field action="ignore">wcml_sync_hash</custom-field>
|
63 |
<custom-field action="ignore">wpml_language</custom-field>
|
64 |
+
<custom-field action="ignore">_product_attributes</custom-field>
|
65 |
</custom-fields>
|
66 |
<custom-types>
|
67 |
<custom-type translate="1">product</custom-type>
|
wpml-woocommerce.php
CHANGED
@@ -6,12 +6,14 @@
|
|
6 |
Author: OnTheGoSystems
|
7 |
Author URI: http://www.onthegosystems.com/
|
8 |
Text Domain: woocommerce-multilingual
|
9 |
-
Version: 4.1.
|
10 |
*/
|
11 |
|
12 |
-
if( defined( 'WCML_VERSION' ) )
|
|
|
|
|
13 |
|
14 |
-
define( 'WCML_VERSION', '4.1.
|
15 |
define( 'WCML_PLUGIN_PATH', dirname( __FILE__ ) );
|
16 |
define( 'WCML_PLUGIN_FOLDER', basename( WCML_PLUGIN_PATH ) );
|
17 |
define( 'WCML_LOCALE_PATH', WCML_PLUGIN_PATH . '/locale' );
|
@@ -26,18 +28,18 @@ include WCML_PLUGIN_PATH . '/inc/wcml-core-functions.php';
|
|
26 |
include WCML_PLUGIN_PATH . '/inc/wcml-switch-lang-request.php';
|
27 |
include WCML_PLUGIN_PATH . '/inc/wcml-cart-switch-lang-functions.php';
|
28 |
|
29 |
-
if( defined( 'ICL_SITEPRESS_VERSION' ) && !ICL_PLUGIN_INACTIVE && class_exists( 'SitePress' ) ){
|
30 |
-
|
31 |
-
|
32 |
|
33 |
-
|
34 |
-
|
35 |
}
|
36 |
|
37 |
if ( version_compare( PHP_VERSION, '5.3.0' ) >= 0 ) {
|
38 |
-
|
39 |
} else {
|
40 |
-
|
41 |
}
|
42 |
|
43 |
// Load WooCommerce Multilingual when WPML is active
|
@@ -49,10 +51,10 @@ if( WCML_REST_API_Support::is_rest_api_request() ){
|
|
49 |
|
50 |
|
51 |
// Load WooCommerce Multilingual when WPML is NOT active
|
52 |
-
add_action('plugins_loaded', 'load_wcml_without_wpml', 10000);
|
53 |
-
function load_wcml_without_wpml(){
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
}
|
6 |
Author: OnTheGoSystems
|
7 |
Author URI: http://www.onthegosystems.com/
|
8 |
Text Domain: woocommerce-multilingual
|
9 |
+
Version: 4.1.4
|
10 |
*/
|
11 |
|
12 |
+
if ( defined( 'WCML_VERSION' ) ) {
|
13 |
+
return;
|
14 |
+
}
|
15 |
|
16 |
+
define( 'WCML_VERSION', '4.1.4' );
|
17 |
define( 'WCML_PLUGIN_PATH', dirname( __FILE__ ) );
|
18 |
define( 'WCML_PLUGIN_FOLDER', basename( WCML_PLUGIN_PATH ) );
|
19 |
define( 'WCML_LOCALE_PATH', WCML_PLUGIN_PATH . '/locale' );
|
28 |
include WCML_PLUGIN_PATH . '/inc/wcml-switch-lang-request.php';
|
29 |
include WCML_PLUGIN_PATH . '/inc/wcml-cart-switch-lang-functions.php';
|
30 |
|
31 |
+
if ( defined( 'ICL_SITEPRESS_VERSION' ) && ! ICL_PLUGIN_INACTIVE && class_exists( 'SitePress' ) ) {
|
32 |
+
//detecting language switching
|
33 |
+
$wcml_switch_lang_request = new WCML_Switch_Lang_Request( new WPML_Cookie(), new WPML_WP_API() );
|
34 |
|
35 |
+
//cart related language switching functions
|
36 |
+
$wcml_cart_switch_lang_functions = new WCML_Cart_Switch_Lang_Functions();
|
37 |
}
|
38 |
|
39 |
if ( version_compare( PHP_VERSION, '5.3.0' ) >= 0 ) {
|
40 |
+
require WCML_PLUGIN_PATH . '/vendor/autoload.php';
|
41 |
} else {
|
42 |
+
require WCML_PLUGIN_PATH . '/vendor/autoload_52.php';
|
43 |
}
|
44 |
|
45 |
// Load WooCommerce Multilingual when WPML is active
|
51 |
|
52 |
|
53 |
// Load WooCommerce Multilingual when WPML is NOT active
|
54 |
+
add_action( 'plugins_loaded', 'load_wcml_without_wpml', 10000 );
|
55 |
+
function load_wcml_without_wpml() {
|
56 |
+
if ( ! did_action( 'wpml_loaded' ) ) {
|
57 |
+
global $woocommerce_wpml;
|
58 |
+
$woocommerce_wpml = new woocommerce_wpml();
|
59 |
+
}
|
60 |
+
}
|