WooCommerce Multilingual – run WooCommerce with WPML - Version 1.1

Version Description

  • Added multi-currency feature
  • Fixed synchronization of attributes and variations
  • Fixed translation of attributes
  • Fixed JS error in the checkout page
  • Fixed enable guest checkout (no account required) issue
  • Fixed Up-sells/Cross-sells search (showed all translated products)
  • Fixed 'Show post translation link' repeating issue
Download this release

Release Info

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

Code changes from version 1.0 to 1.1

assets/css/management.css ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #add_currency label {
2
+ width: 170px;
3
+ float: left;
4
+ }
5
+
6
+ .manage_table_th_width {
7
+ width: 250px;
8
+ }
9
+
10
+ .lang_selector_width {
11
+ width: 195px;
12
+ }
13
+
14
+ .flag_img {
15
+ margin-right: 5px;
16
+ }
17
+
18
+ #add_currency label.error {
19
+ width: 230px;
20
+ display: block;
21
+ background: #ffd2d2;
22
+ padding: 0 10px;
23
+ margin-top: 2px;
24
+ margin-right: 43.5%;
25
+ float: right;
26
+ }
27
+
28
+ .general_options_table {
29
+ margin: 0 0 15px 0;
30
+ }
assets/images/delete.png ADDED
Binary file
assets/images/edit.png ADDED
Binary file
assets/js/jquery.validate.min.js ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * jQuery Validation Plugin 1.8.1
3
+ *
4
+ * http://bassistance.de/jquery-plugins/jquery-plugin-validation/
5
+ * http://docs.jquery.com/Plugins/Validation
6
+ *
7
+ * Copyright (c) 2006 - 2011 Jörn Zaefferer
8
+ *
9
+ * Dual licensed under the MIT and GPL licenses:
10
+ * http://www.opensource.org/licenses/mit-license.php
11
+ * http://www.gnu.org/licenses/gpl.html
12
+ */
13
+ (function(c){c.extend(c.fn,{validate:function(a){if(this.length){var b=c.data(this[0],"validator");if(b)return b;b=new c.validator(a,this[0]);c.data(this[0],"validator",b);if(b.settings.onsubmit){this.find("input, button").filter(".cancel").click(function(){b.cancelSubmit=true});b.settings.submitHandler&&this.find("input, button").filter(":submit").click(function(){b.submitButton=this});this.submit(function(d){function e(){if(b.settings.submitHandler){if(b.submitButton)var f=c("<input type='hidden'/>").attr("name",
14
+ b.submitButton.name).val(b.submitButton.value).appendTo(b.currentForm);b.settings.submitHandler.call(b,b.currentForm);b.submitButton&&f.remove();return false}return true}b.settings.debug&&d.preventDefault();if(b.cancelSubmit){b.cancelSubmit=false;return e()}if(b.form()){if(b.pendingRequest){b.formSubmitted=true;return false}return e()}else{b.focusInvalid();return false}})}return b}else a&&a.debug&&window.console&&console.warn("nothing selected, can't validate, returning nothing")},valid:function(){if(c(this[0]).is("form"))return this.validate().form();
15
+ else{var a=true,b=c(this[0].form).validate();this.each(function(){a&=b.element(this)});return a}},removeAttrs:function(a){var b={},d=this;c.each(a.split(/\s/),function(e,f){b[f]=d.attr(f);d.removeAttr(f)});return b},rules:function(a,b){var d=this[0];if(a){var e=c.data(d.form,"validator").settings,f=e.rules,g=c.validator.staticRules(d);switch(a){case "add":c.extend(g,c.validator.normalizeRule(b));f[d.name]=g;if(b.messages)e.messages[d.name]=c.extend(e.messages[d.name],b.messages);break;case "remove":if(!b){delete f[d.name];
16
+ return g}var h={};c.each(b.split(/\s/),function(j,i){h[i]=g[i];delete g[i]});return h}}d=c.validator.normalizeRules(c.extend({},c.validator.metadataRules(d),c.validator.classRules(d),c.validator.attributeRules(d),c.validator.staticRules(d)),d);if(d.required){e=d.required;delete d.required;d=c.extend({required:e},d)}return d}});c.extend(c.expr[":"],{blank:function(a){return!c.trim(""+a.value)},filled:function(a){return!!c.trim(""+a.value)},unchecked:function(a){return!a.checked}});c.validator=function(a,
17
+ b){this.settings=c.extend(true,{},c.validator.defaults,a);this.currentForm=b;this.init()};c.validator.format=function(a,b){if(arguments.length==1)return function(){var d=c.makeArray(arguments);d.unshift(a);return c.validator.format.apply(this,d)};if(arguments.length>2&&b.constructor!=Array)b=c.makeArray(arguments).slice(1);if(b.constructor!=Array)b=[b];c.each(b,function(d,e){a=a.replace(RegExp("\\{"+d+"\\}","g"),e)});return a};c.extend(c.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",
18
+ validClass:"valid",errorElement:"label",focusInvalid:true,errorContainer:c([]),errorLabelContainer:c([]),onsubmit:true,ignore:[],ignoreTitle:false,onfocusin:function(a){this.lastActive=a;if(this.settings.focusCleanup&&!this.blockFocusCleanup){this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass);this.addWrapper(this.errorsFor(a)).hide()}},onfocusout:function(a){if(!this.checkable(a)&&(a.name in this.submitted||!this.optional(a)))this.element(a)},
19
+ onkeyup:function(a){if(a.name in this.submitted||a==this.lastElement)this.element(a)},onclick:function(a){if(a.name in this.submitted)this.element(a);else a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(a,b,d){a.type==="radio"?this.findByName(a.name).addClass(b).removeClass(d):c(a).addClass(b).removeClass(d)},unhighlight:function(a,b,d){a.type==="radio"?this.findByName(a.name).removeClass(b).addClass(d):c(a).removeClass(b).addClass(d)}},setDefaults:function(a){c.extend(c.validator.defaults,
20
+ a)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",accept:"Please enter a value with a valid extension.",maxlength:c.validator.format("Please enter no more than {0} characters."),
21
+ minlength:c.validator.format("Please enter at least {0} characters."),rangelength:c.validator.format("Please enter a value between {0} and {1} characters long."),range:c.validator.format("Please enter a value between {0} and {1}."),max:c.validator.format("Please enter a value less than or equal to {0}."),min:c.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:false,prototype:{init:function(){function a(e){var f=c.data(this[0].form,"validator");e="on"+e.type.replace(/^validate/,
22
+ "");f.settings[e]&&f.settings[e].call(f,this[0])}this.labelContainer=c(this.settings.errorLabelContainer);this.errorContext=this.labelContainer.length&&this.labelContainer||c(this.currentForm);this.containers=c(this.settings.errorContainer).add(this.settings.errorLabelContainer);this.submitted={};this.valueCache={};this.pendingRequest=0;this.pending={};this.invalid={};this.reset();var b=this.groups={};c.each(this.settings.groups,function(e,f){c.each(f.split(/\s/),function(g,h){b[h]=e})});var d=this.settings.rules;
23
+ c.each(d,function(e,f){d[e]=c.validator.normalizeRule(f)});c(this.currentForm).validateDelegate(":text, :password, :file, select, textarea","focusin focusout keyup",a).validateDelegate(":radio, :checkbox, select, option","click",a);this.settings.invalidHandler&&c(this.currentForm).bind("invalid-form.validate",this.settings.invalidHandler)},form:function(){this.checkForm();c.extend(this.submitted,this.errorMap);this.invalid=c.extend({},this.errorMap);this.valid()||c(this.currentForm).triggerHandler("invalid-form",
24
+ [this]);this.showErrors();return this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(a){this.lastElement=a=this.clean(a);this.prepareElement(a);this.currentElements=c(a);var b=this.check(a);if(b)delete this.invalid[a.name];else this.invalid[a.name]=true;if(!this.numberOfInvalids())this.toHide=this.toHide.add(this.containers);this.showErrors();return b},showErrors:function(a){if(a){c.extend(this.errorMap,
25
+ a);this.errorList=[];for(var b in a)this.errorList.push({message:a[b],element:this.findByName(b)[0]});this.successList=c.grep(this.successList,function(d){return!(d.name in a)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){c.fn.resetForm&&c(this.currentForm).resetForm();this.submitted={};this.prepareForm();this.hideErrors();this.elements().removeClass(this.settings.errorClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)},
26
+ objectLength:function(a){var b=0,d;for(d in a)b++;return b},hideErrors:function(){this.addWrapper(this.toHide).hide()},valid:function(){return this.size()==0},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{c(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(a){}},findLastActive:function(){var a=this.lastActive;return a&&c.grep(this.errorList,function(b){return b.element.name==
27
+ a.name}).length==1&&a},elements:function(){var a=this,b={};return c(this.currentForm).find("input, select, textarea").not(":submit, :reset, :image, [disabled]").not(this.settings.ignore).filter(function(){!this.name&&a.settings.debug&&window.console&&console.error("%o has no name assigned",this);if(this.name in b||!a.objectLength(c(this).rules()))return false;return b[this.name]=true})},clean:function(a){return c(a)[0]},errors:function(){return c(this.settings.errorElement+"."+this.settings.errorClass,
28
+ this.errorContext)},reset:function(){this.successList=[];this.errorList=[];this.errorMap={};this.toShow=c([]);this.toHide=c([]);this.currentElements=c([])},prepareForm:function(){this.reset();this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset();this.toHide=this.errorsFor(a)},check:function(a){a=this.clean(a);if(this.checkable(a))a=this.findByName(a.name).not(this.settings.ignore)[0];var b=c(a).rules(),d=false,e;for(e in b){var f={method:e,parameters:b[e]};try{var g=
29
+ c.validator.methods[e].call(this,a.value.replace(/\r/g,""),a,f.parameters);if(g=="dependency-mismatch")d=true;else{d=false;if(g=="pending"){this.toHide=this.toHide.not(this.errorsFor(a));return}if(!g){this.formatAndAdd(a,f);return false}}}catch(h){this.settings.debug&&window.console&&console.log("exception occured when checking element "+a.id+", check the '"+f.method+"' method",h);throw h;}}if(!d){this.objectLength(b)&&this.successList.push(a);return true}},customMetaMessage:function(a,b){if(c.metadata){var d=
30
+ this.settings.meta?c(a).metadata()[this.settings.meta]:c(a).metadata();return d&&d.messages&&d.messages[b]}},customMessage:function(a,b){var d=this.settings.messages[a];return d&&(d.constructor==String?d:d[b])},findDefined:function(){for(var a=0;a<arguments.length;a++)if(arguments[a]!==undefined)return arguments[a]},defaultMessage:function(a,b){return this.findDefined(this.customMessage(a.name,b),this.customMetaMessage(a,b),!this.settings.ignoreTitle&&a.title||undefined,c.validator.messages[b],"<strong>Warning: No message defined for "+
31
+ a.name+"</strong>")},formatAndAdd:function(a,b){var d=this.defaultMessage(a,b.method),e=/\$?\{(\d+)\}/g;if(typeof d=="function")d=d.call(this,b.parameters,a);else if(e.test(d))d=jQuery.format(d.replace(e,"{$1}"),b.parameters);this.errorList.push({message:d,element:a});this.errorMap[a.name]=d;this.submitted[a.name]=d},addWrapper:function(a){if(this.settings.wrapper)a=a.add(a.parent(this.settings.wrapper));return a},defaultShowErrors:function(){for(var a=0;this.errorList[a];a++){var b=this.errorList[a];
32
+ this.settings.highlight&&this.settings.highlight.call(this,b.element,this.settings.errorClass,this.settings.validClass);this.showLabel(b.element,b.message)}if(this.errorList.length)this.toShow=this.toShow.add(this.containers);if(this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight){a=0;for(b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass)}this.toHide=this.toHide.not(this.toShow);
33
+ this.hideErrors();this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return c(this.errorList).map(function(){return this.element})},showLabel:function(a,b){var d=this.errorsFor(a);if(d.length){d.removeClass().addClass(this.settings.errorClass);d.attr("generated")&&d.html(b)}else{d=c("<"+this.settings.errorElement+"/>").attr({"for":this.idOrName(a),generated:true}).addClass(this.settings.errorClass).html(b||
34
+ "");if(this.settings.wrapper)d=d.hide().show().wrap("<"+this.settings.wrapper+"/>").parent();this.labelContainer.append(d).length||(this.settings.errorPlacement?this.settings.errorPlacement(d,c(a)):d.insertAfter(a))}if(!b&&this.settings.success){d.text("");typeof this.settings.success=="string"?d.addClass(this.settings.success):this.settings.success(d)}this.toShow=this.toShow.add(d)},errorsFor:function(a){var b=this.idOrName(a);return this.errors().filter(function(){return c(this).attr("for")==b})},
35
+ idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(a){var b=this.currentForm;return c(document.getElementsByName(a)).map(function(d,e){return e.form==b&&e.name==a&&e||null})},getLength:function(a,b){switch(b.nodeName.toLowerCase()){case "select":return c("option:selected",b).length;case "input":if(this.checkable(b))return this.findByName(b.name).filter(":checked").length}return a.length},
36
+ depend:function(a,b){return this.dependTypes[typeof a]?this.dependTypes[typeof a](a,b):true},dependTypes:{"boolean":function(a){return a},string:function(a,b){return!!c(a,b.form).length},"function":function(a,b){return a(b)}},optional:function(a){return!c.validator.methods.required.call(this,c.trim(a.value),a)&&"dependency-mismatch"},startRequest:function(a){if(!this.pending[a.name]){this.pendingRequest++;this.pending[a.name]=true}},stopRequest:function(a,b){this.pendingRequest--;if(this.pendingRequest<
37
+ 0)this.pendingRequest=0;delete this.pending[a.name];if(b&&this.pendingRequest==0&&this.formSubmitted&&this.form()){c(this.currentForm).submit();this.formSubmitted=false}else if(!b&&this.pendingRequest==0&&this.formSubmitted){c(this.currentForm).triggerHandler("invalid-form",[this]);this.formSubmitted=false}},previousValue:function(a){return c.data(a,"previousValue")||c.data(a,"previousValue",{old:null,valid:true,message:this.defaultMessage(a,"remote")})}},classRuleSettings:{required:{required:true},
38
+ email:{email:true},url:{url:true},date:{date:true},dateISO:{dateISO:true},dateDE:{dateDE:true},number:{number:true},numberDE:{numberDE:true},digits:{digits:true},creditcard:{creditcard:true}},addClassRules:function(a,b){a.constructor==String?this.classRuleSettings[a]=b:c.extend(this.classRuleSettings,a)},classRules:function(a){var b={};(a=c(a).attr("class"))&&c.each(a.split(" "),function(){this in c.validator.classRuleSettings&&c.extend(b,c.validator.classRuleSettings[this])});return b},attributeRules:function(a){var b=
39
+ {};a=c(a);for(var d in c.validator.methods){var e=a.attr(d);if(e)b[d]=e}b.maxlength&&/-1|2147483647|524288/.test(b.maxlength)&&delete b.maxlength;return b},metadataRules:function(a){if(!c.metadata)return{};var b=c.data(a.form,"validator").settings.meta;return b?c(a).metadata()[b]:c(a).metadata()},staticRules:function(a){var b={},d=c.data(a.form,"validator");if(d.settings.rules)b=c.validator.normalizeRule(d.settings.rules[a.name])||{};return b},normalizeRules:function(a,b){c.each(a,function(d,e){if(e===
40
+ false)delete a[d];else if(e.param||e.depends){var f=true;switch(typeof e.depends){case "string":f=!!c(e.depends,b.form).length;break;case "function":f=e.depends.call(b,b)}if(f)a[d]=e.param!==undefined?e.param:true;else delete a[d]}});c.each(a,function(d,e){a[d]=c.isFunction(e)?e(b):e});c.each(["minlength","maxlength","min","max"],function(){if(a[this])a[this]=Number(a[this])});c.each(["rangelength","range"],function(){if(a[this])a[this]=[Number(a[this][0]),Number(a[this][1])]});if(c.validator.autoCreateRanges){if(a.min&&
41
+ a.max){a.range=[a.min,a.max];delete a.min;delete a.max}if(a.minlength&&a.maxlength){a.rangelength=[a.minlength,a.maxlength];delete a.minlength;delete a.maxlength}}a.messages&&delete a.messages;return a},normalizeRule:function(a){if(typeof a=="string"){var b={};c.each(a.split(/\s/),function(){b[this]=true});a=b}return a},addMethod:function(a,b,d){c.validator.methods[a]=b;c.validator.messages[a]=d!=undefined?d:c.validator.messages[a];b.length<3&&c.validator.addClassRules(a,c.validator.normalizeRule(a))},
42
+ methods:{required:function(a,b,d){if(!this.depend(d,b))return"dependency-mismatch";switch(b.nodeName.toLowerCase()){case "select":return(a=c(b).val())&&a.length>0;case "input":if(this.checkable(b))return this.getLength(a,b)>0;default:return c.trim(a).length>0}},remote:function(a,b,d){if(this.optional(b))return"dependency-mismatch";var e=this.previousValue(b);this.settings.messages[b.name]||(this.settings.messages[b.name]={});e.originalMessage=this.settings.messages[b.name].remote;this.settings.messages[b.name].remote=
43
+ e.message;d=typeof d=="string"&&{url:d}||d;if(this.pending[b.name])return"pending";if(e.old===a)return e.valid;e.old=a;var f=this;this.startRequest(b);var g={};g[b.name]=a;c.ajax(c.extend(true,{url:d,mode:"abort",port:"validate"+b.name,dataType:"json",data:g,success:function(h){f.settings.messages[b.name].remote=e.originalMessage;var j=h===true;if(j){var i=f.formSubmitted;f.prepareElement(b);f.formSubmitted=i;f.successList.push(b);f.showErrors()}else{i={};h=h||f.defaultMessage(b,"remote");i[b.name]=
44
+ e.message=c.isFunction(h)?h(a):h;f.showErrors(i)}e.valid=j;f.stopRequest(b,j)}},d));return"pending"},minlength:function(a,b,d){return this.optional(b)||this.getLength(c.trim(a),b)>=d},maxlength:function(a,b,d){return this.optional(b)||this.getLength(c.trim(a),b)<=d},rangelength:function(a,b,d){a=this.getLength(c.trim(a),b);return this.optional(b)||a>=d[0]&&a<=d[1]},min:function(a,b,d){return this.optional(b)||a>=d},max:function(a,b,d){return this.optional(b)||a<=d},range:function(a,b,d){return this.optional(b)||
45
+ a>=d[0]&&a<=d[1]},email:function(a,b){return this.optional(b)||/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(a)},
46
+ url:function(a,b){return this.optional(b)||/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},
47
+ date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a))},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},creditcard:function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9-]+/.test(a))return false;var d=0,e=0,f=false;a=a.replace(/\D/g,"");for(var g=a.length-1;g>=
48
+ 0;g--){e=a.charAt(g);e=parseInt(e,10);if(f)if((e*=2)>9)e-=9;d+=e;f=!f}return d%10==0},accept:function(a,b,d){d=typeof d=="string"?d.replace(/,/g,"|"):"png|jpe?g|gif";return this.optional(b)||a.match(RegExp(".("+d+")$","i"))},equalTo:function(a,b,d){d=c(d).unbind(".validate-equalTo").bind("blur.validate-equalTo",function(){c(b).valid()});return a==d.val()}}});c.format=c.validator.format})(jQuery);
49
+ (function(c){var a={};if(c.ajaxPrefilter)c.ajaxPrefilter(function(d,e,f){e=d.port;if(d.mode=="abort"){a[e]&&a[e].abort();a[e]=f}});else{var b=c.ajax;c.ajax=function(d){var e=("port"in d?d:c.ajaxSettings).port;if(("mode"in d?d:c.ajaxSettings).mode=="abort"){a[e]&&a[e].abort();return a[e]=b.apply(this,arguments)}return b.apply(this,arguments)}}})(jQuery);
50
+ (function(c){!jQuery.event.special.focusin&&!jQuery.event.special.focusout&&document.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(e){e=c.event.fix(e);e.type=b;return c.event.handle.call(this,e)}c.event.special[b]={setup:function(){this.addEventListener(a,d,true)},teardown:function(){this.removeEventListener(a,d,true)},handler:function(e){arguments[0]=c.event.fix(e);arguments[0].type=b;return c.event.handle.apply(this,arguments)}}});c.extend(c.fn,{validateDelegate:function(a,
51
+ b,d){return this.bind(b,function(e){var f=c(e.target);if(f.is(a))return d.apply(f,arguments)})}})})(jQuery);
menu/management.php ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wrap">
2
+ <div id="icon-wpml" class="icon32"><br /></div>
3
+ <h2>WooCommerce Multilingual</h2>
4
+
5
+ <table class="widefat general_options_table">
6
+ <thead>
7
+ <tr>
8
+ <th><?php echo __('General options', 'wpml-wcml') ?></th>
9
+ </tr>
10
+ </thead>
11
+ <tbody>
12
+ <tr>
13
+ <td>
14
+ <p>
15
+ <form method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>" id="general_options">
16
+ <ul id="general_options">
17
+
18
+ <li><label for="multi_currency">Enable multi-currency: </label>
19
+ <input type="checkbox" name="multi_currency" id="multi_currency" value="yes" <?php if(get_option('icl_enable_multi_currency') == 'yes'){ echo 'checked'; } ?> /></li>
20
+
21
+ <input type='submit' name="general_options" value='<?php echo __('Save', 'wpml-wcml'); ?>' class='button-secondary' />
22
+ <?php wp_nonce_field('general_options', 'general_options_nonce'); ?>
23
+ </ul>
24
+ </form>
25
+ </p>
26
+ </td>
27
+ </tr>
28
+ </tbody>
29
+ </table>
30
+
31
+ <?php if(get_option('icl_enable_multi_currency') == 'yes'){ ?>
32
+ <table class="widefat">
33
+ <thead>
34
+ <tr>
35
+ <th><?php echo __('Add currency', 'wpml-wcml') ?></th>
36
+ </tr>
37
+ </thead>
38
+ <tbody>
39
+ <tr>
40
+ <td>
41
+ <p>
42
+ <form method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>" id="add_currency_form">
43
+ <ul id="add_currency">
44
+ <li>
45
+ <?php
46
+ if(!isset($_GET['edit'])){
47
+ ?>
48
+ <label for="language">Language: </label>
49
+ <select name="language" id="language" class="lang_selector_width">
50
+ <?php
51
+ }
52
+
53
+ if(isset($_GET['edit']) && $_GET['edit'] == $_GET['edit']){
54
+ global $wpdb;
55
+
56
+ $update_id = $_GET['edit'];
57
+
58
+ $sql = "SELECT * FROM ". $wpdb->prefix ."icl_currencies WHERE id = '$update_id'";
59
+ $currency = $wpdb->get_results($sql, OBJECT);
60
+
61
+ $currency_id = $currency[0]->id;
62
+ $currency_code = $currency[0]->code;
63
+ $currency_exchange_rate = $currency[0]->value;
64
+ $currency_language_code = $currency[0]->language_code;
65
+ }
66
+
67
+ if(!isset($_GET['edit'])){
68
+ global $sitepress;
69
+
70
+ $languages = $sitepress->get_active_languages();
71
+ //$path_to_flags = ICL_PLUGIN_URL . '/res/flags/';
72
+ foreach($languages as $lang_code => $language){
73
+ /*if(isset($_GET['edit'])){
74
+ $selected = ($currency_language_code == $lang_code) ? $selected = 'selected' : $selected = null;
75
+
76
+ echo "<option value=\"". $language['code'] ."\" $selected>". $language['english_name'] ."</option>\r\n";
77
+ } else {
78
+ */
79
+ echo "<option value=\"". $language['code'] ."\">". $language['english_name'] ."</option>\r\n";
80
+ //}
81
+ }
82
+
83
+ ?>
84
+ </select>
85
+ <?php
86
+ }
87
+ ?>
88
+ </li>
89
+
90
+ <li><label for="currency_code">Currency code: </label>
91
+ <input type="text" name="currency_code" id="currency_code" maxlength="5" size="35" value="<?php if(isset($_GET['edit'])){ echo $currency_code; } ?>" /></li>
92
+
93
+ <li><label for="exchange_rate">Exchange rate: </label>
94
+ <input type="text" name="exchange_rate" id="exchange_rate" maxlength="10" size="35" value="<?php if(isset($_GET['edit'])){ echo $currency_exchange_rate; } ?>" /></li>
95
+
96
+ <?php if(isset($_GET['edit'])){ ?>
97
+ <input type="text" name="currency_id" id="currency_id" maxlength="5" size="10" value="<?php echo $currency_id; ?>" style="display: none;" /></li>
98
+ <?php } ?>
99
+ </ul>
100
+
101
+ <input type='submit' name="add_currency" value='<?php if(isset($_GET['edit'])){ echo __('Update', 'wpml-wcml'); } else { echo __('Add', 'wpml-wcml'); } ?>' class='button-secondary' />
102
+ <?php wp_nonce_field('add_currency', 'add_currency_nonce'); ?>
103
+ </form>
104
+ </p>
105
+ </td>
106
+ </tr>
107
+ </tbody>
108
+ </table>
109
+ <?php
110
+ global $wpdb;
111
+
112
+ $sql = "SELECT * FROM ". $wpdb->prefix ."icl_currencies";
113
+ $result = $wpdb->get_results($sql);
114
+
115
+ if($result){
116
+ ?>
117
+ <h3><?php echo __('Manage currencies', 'wpml-wcml'); ?></h3>
118
+ <table class="widefat">
119
+ <thead>
120
+ <tr>
121
+ <th class="manage_table_th_width"><?php echo __('Language', 'wpml-wcml'); ?></th>
122
+ <th class="manage_table_th_width"><?php echo __('Currency code', 'wpml-wcml'); ?></th>
123
+ <th class="manage_table_th_width"><?php echo __('Exchange rate', 'wpml-wcml'); ?></th>
124
+ <th class="manage_table_th_width"><?php echo __('Changed', 'wpml-wcml'); ?></th>
125
+ <th><!-- spacer --></th>
126
+ <th><!-- spacer --></th>
127
+ </tr>
128
+ </thead>
129
+ <tfoot>
130
+ <tr>
131
+ <th><?php echo __('Language', 'wpml-wcml'); ?></th>
132
+ <th><?php echo __('Currency code', 'wpml-wcml'); ?></th>
133
+ <th><?php echo __('Exchange rate', 'wpml-wcml'); ?></th>
134
+ <th><?php echo __('Changed', 'wpml-wcml'); ?></th>
135
+ <th><!-- spacer --></th>
136
+ <th><!-- spacer --></th>
137
+ </tr>
138
+ </tfoot>
139
+ <tbody>
140
+ <?php
141
+ global $sitepress;
142
+
143
+ $sql = "SELECT * FROM ". $wpdb->prefix ."icl_currencies ORDER BY `id` DESC";
144
+ $currencies = $wpdb->get_results($sql, OBJECT);
145
+
146
+ foreach($currencies as $key => $currency){
147
+ $language = $sitepress->get_language_details($currency->language_code);
148
+ echo "<tr>";
149
+
150
+ echo "<td><!--<img src=\"". ICL_PLUGIN_URL ."/res/flags/". $currency->language_code .".png\" width=\"18\" height=\"12\" class=\"flag_img\" />-->". $language['english_name'] ."</td>\r\n";
151
+ echo "<td>". $currency->code ."</td>\r\n";
152
+ echo "<td>". $currency->value ."</td>\r\n";
153
+ echo "<td>". $currency->changed ."</td>\r\n";
154
+
155
+ echo "<td><a href=\"". admin_url('admin.php?page=wpml-wcml&edit='. $currency->id) ."\" title=\"Edit\"><img src=\"". WCML_PLUGIN_URL ."/assets/images/edit.png\" width=\"16\" height=\"16\" alt=\"Edit\" /></a></td>\r\n";
156
+ echo "<td><a href=\"". admin_url('admin.php?page=wpml-wcml&delete='. $currency->id) ."\" title=\"Delete\"><img src=\"". WCML_PLUGIN_URL ."/assets/images/delete.png\" width=\"16\" height=\"16\" alt=\"Delete\" /></a></td>\r\n";
157
+
158
+ echo "</tr>";
159
+ }
160
+ ?>
161
+ </tbody>
162
+ </table>
163
+ <?php
164
+ }
165
+ ?>
166
+ </div>
167
+
168
+ <script type="text/javascript">
169
+ jQuery(document).ready(function($) {
170
+ $('#add_currency_form').validate({
171
+ rules: {
172
+ currency_code: {
173
+ required: true
174
+ },
175
+
176
+ exchange_rate: {
177
+ required: true,
178
+ number: true
179
+ }
180
+ },
181
+
182
+ messages: {
183
+ currency_code: "Please fill the currency code field.",
184
+ exchange_rate: "Please enter the correct exchange rate."
185
+ }
186
+ });
187
+ });
188
+ </script>
189
+ <?php
190
+ }
191
+ ?>
readme.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: AmirHelzer, dominykasgel
3
  Donate link: http://wp-types.com
4
  Tags: CMS, woocommerce, commerce, ecommerce, e-commerce, products, WPML, multilingual, e-shop, shop
5
  Requires at least: 3.0
6
- Tested up to: 3.3.1
7
- Stable tag: 1.0
8
- Version: 1.0
9
 
10
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
11
 
@@ -15,9 +15,11 @@ This 'glue' plugin makes it possible to run fully multilingual e-commerce sites
15
 
16
  = Features =
17
 
18
- * Makes languages persist through the checkout process
 
19
  * Sends emails to clients and admins in their selected language
20
- * Collapses all products to the default language for inventory tracking and shipping
 
21
 
22
  = Documentation =
23
 
@@ -42,12 +44,30 @@ You will need:
42
 
43
  No. This plugin is tailored for WooCommerce.
44
 
 
 
 
 
 
 
 
 
45
  == Screenshots ==
46
 
47
  1. Translation controls for products
 
48
 
49
  == Changelog ==
50
 
 
 
 
 
 
 
 
 
 
51
  = 1.0 =
52
  * Fixed 'Return to store' URL
53
  * Fixed language selector for the translated shop base pages
@@ -60,8 +80,11 @@ No. This plugin is tailored for WooCommerce.
60
 
61
  == Upgrade Notice ==
62
 
 
 
 
63
  = 1.0 =
64
  Recommended update! Fixed a few bugs;
65
 
66
  = 0.9 =
67
- * First release
3
  Donate link: http://wp-types.com
4
  Tags: CMS, woocommerce, commerce, ecommerce, e-commerce, products, WPML, multilingual, e-shop, shop
5
  Requires at least: 3.0
6
+ Tested up to: 3.3.2
7
+ Stable tag: 1.1
8
+ Version: 1.1
9
 
10
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
11
 
15
 
16
  = Features =
17
 
18
+ * Lets you translate products, variations and categories
19
+ * Keeps the same language through the checkout process
20
  * Sends emails to clients and admins in their selected language
21
+ * Allows inventory tracking without breaking products into languages
22
+ * Enables running a single WooCommerce store with multiple currencies
23
 
24
  = Documentation =
25
 
44
 
45
  No. This plugin is tailored for WooCommerce.
46
 
47
+ = What do I need to do in my theme? =
48
+
49
+ Make sure that your theme is not hard-coding any URL. Always use API calls to receive URLs to pages and you'll be fine.
50
+
51
+ = My checkout page displays in the same language =
52
+
53
+ In order for the checkout and store pages to appear translated, you need to create several WordPress pages and insert the WooCommerce shortcodes into them. You'll have to go over the [documentation](http://wpml.org/documentation/related-projects/woocommerce-multilingual/) and see that you performed all steps on the way.
54
+
55
  == Screenshots ==
56
 
57
  1. Translation controls for products
58
+ 2. Enabling multi-currency
59
 
60
  == Changelog ==
61
 
62
+ = 1.1 =
63
+ * Added multi-currency feature
64
+ * Fixed synchronization of attributes and variations
65
+ * Fixed translation of attributes
66
+ * Fixed JS error in the checkout page
67
+ * Fixed enable guest checkout (no account required) issue
68
+ * Fixed Up-sells/Cross-sells search (showed all translated products)
69
+ * Fixed 'Show post translation link' repeating issue
70
+
71
  = 1.0 =
72
  * Fixed 'Return to store' URL
73
  * Fixed language selector for the translated shop base pages
80
 
81
  == Upgrade Notice ==
82
 
83
+ = 1.1 =
84
+ Fixed a few bugs. Added multi-currency mode.
85
+
86
  = 1.0 =
87
  Recommended update! Fixed a few bugs;
88
 
89
  = 0.9 =
90
+ * First release
screenshot-2.png ADDED
Binary file
wpml-config.xml CHANGED
@@ -28,6 +28,35 @@
28
  <custom-field action="copy">weight</custom-field>
29
  <custom-field action="copy">width</custom-field>
30
  <custom-field action="copy">total_sales</custom-field>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  </custom-fields>
32
  <custom-types>
33
  <custom-type translate="1">product</custom-type>
28
  <custom-field action="copy">weight</custom-field>
29
  <custom-field action="copy">width</custom-field>
30
  <custom-field action="copy">total_sales</custom-field>
31
+ <custom-field action="copy">_default_attributes</custom-field>
32
+ <custom-field action="copy">_download_limit</custom-field>
33
+ <custom-field action="copy">_height</custom-field>
34
+ <custom-field action="copy">_featured</custom-field>
35
+ <custom-field action="copy">_length</custom-field>
36
+ <custom-field action="copy">_manage_stock</custom-field>
37
+ <custom-field action="copy">_max_variation_price</custom-field>
38
+ <custom-field action="copy">_max_variation_regular_price</custom-field>
39
+ <custom-field action="copy">_max_variation_sale_price</custom-field>
40
+ <custom-field action="copy">_min_variation_price</custom-field>
41
+ <custom-field action="copy">_min_variation_regular_price</custom-field>
42
+ <custom-field action="copy">_min_variation_sale_price</custom-field>
43
+ <custom-field action="copy">_price</custom-field>
44
+ <custom-field action="copy">_product_attributes</custom-field>
45
+ <custom-field action="copy">_regular_price</custom-field>
46
+ <custom-field action="copy">_sale_price</custom-field>
47
+ <custom-field action="copy">_sale_price_dates_from</custom-field>
48
+ <custom-field action="copy">_sale_price_dates_to</custom-field>
49
+ <custom-field action="copy">_sku</custom-field>
50
+ <custom-field action="copy">_stock</custom-field>
51
+ <custom-field action="copy">_stock_status</custom-field>
52
+ <custom-field action="copy">_tax_class</custom-field>
53
+ <custom-field action="copy">_tax_status</custom-field>
54
+ <custom-field action="copy">_virtual</custom-field>
55
+ <custom-field action="copy">_visibility</custom-field>
56
+ <custom-field action="copy">_weight</custom-field>
57
+ <custom-field action="copy">_width</custom-field>
58
+ <custom-field action="copy">_file_path</custom-field>
59
+ <custom-field action="copy">_thumbnail_id</custom-field>
60
  </custom-fields>
61
  <custom-types>
62
  <custom-type translate="1">product</custom-type>
wpml-woocommerce.php CHANGED
@@ -5,11 +5,17 @@
5
  Description: Allows running fully multilingual e-Commerce sites with WooCommerce and WPML. <a href="http://wpml.org/documentation/related-projects/woocommerce-multilingual/">Documentation</a>.
6
  Author: ICanLocalize
7
  Author URI: http://wpml.org/
8
- Version: 1.0
9
- */
10
- add_action('plugins_loaded', 'wpml_woocommerce_init', 2);
 
 
 
 
 
 
11
 
12
- function wpml_woocommerce_init(){
13
  if(!defined('ICL_SITEPRESS_VERSION') || ICL_PLUGIN_INACTIVE){
14
  if(!function_exists('is_multisite') || !is_multisite()) {
15
  add_action('admin_notices', 'wpml_no_wpml_warning');
@@ -23,12 +29,16 @@ function wpml_woocommerce_init(){
23
  return false;
24
  }
25
 
26
- // Filter WPML language switcher
 
 
 
 
27
  add_filter('icl_ls_languages', 'wpml_ls_filter');
28
 
29
- add_filter('woocommerce_get_checkout_url', 'wpml_get_checkout_url');
30
- add_filter('woocommerce_get_cart_page_id', 'wpml_get_cart_url');
31
- add_filter('woocommerce_get_remove_url', 'wpml_get_remove_url');
32
  add_filter('woocommerce_get_myaccount_page_id', 'wpml_get_myaccount_page_id');
33
  add_filter('woocommerce_get_edit_address_page_id', 'wpml_get_edit_address_page_id');
34
  add_filter('woocommerce_get_view_order_page_id', 'wpml_get_view_order_page_id');
@@ -39,17 +49,182 @@ function wpml_woocommerce_init(){
39
  add_filter('woocommerce_get_checkout_payment_url', 'wpml_get_checkout_payment_url');
40
  add_filter('woocommerce_get_cancel_order_url', 'wpml_get_cancel_order_url');
41
  add_filter('woocommerce_get_return_url', 'wpml_get_return_url');
 
 
42
  add_filter('woocommerce_in_cart_product_title', 'wpml_in_cart_product_title', 13, 2);
43
  add_filter('woocommerce_in_cart_product_id', 'wpml_in_cart_product_id', 11, 2);
44
- add_filter('woocommerce_params', 'wpml_params');
45
- add_filter('woocommerce_redirect', 'wpml_redirect');
46
- add_filter('wp_head', 'wpml_redirect_to_shop_base_page');
47
 
48
- add_action("updated_post_meta", 'wpml_updated_post_meta_hook', 10, 4);
 
 
 
 
 
 
 
 
 
 
 
49
  add_action('woocommerce_email_header', 'wpml_email_header', 0);
50
  add_action('woocommerce_email_footer', 'wpml_email_footer', 0);
51
  add_action('woocommerce_new_order', 'wpml_order_language');
 
 
 
 
 
 
52
  add_action('init', 'wpml_change_permalinks');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  }
54
 
55
  /**
@@ -82,6 +257,15 @@ function wpml_no_woocommerce(){
82
  <?php
83
  }
84
 
 
 
 
 
 
 
 
 
 
85
  /**
86
  * Filters WooCommerce product link in cart.
87
  *
@@ -114,6 +298,7 @@ function wpml_in_cart_product_id($product_id) {
114
  */
115
  function wpml_updated_post_meta_hook($meta_id, $object_id, $meta_key, $_meta_value) {
116
  global $sitepress;
 
117
  $update_meta_keys = array('stock', 'stock_status');
118
 
119
  if (in_array($meta_key, $update_meta_keys)) {
@@ -137,7 +322,7 @@ function wpml_updated_post_meta_hook($meta_id, $object_id, $meta_key, $_meta_val
137
  * @global type $post
138
  * @global type $sitepress
139
  */
140
- function wpml_redirect_to_shop_base_page(){
141
  global $post, $sitepress;
142
 
143
  $shop_page_id = get_option('woocommerce_shop_page_id');
@@ -179,21 +364,16 @@ function wpml_get_return_url($link){
179
  * @param type $link
180
  * @return type
181
  */
182
- function wpml_redirect($link){
183
  global $sitepress;
184
  return $sitepress->convert_url($link);
185
  }
186
 
187
  /**
188
  * Filters WooCommerce shop link.
189
- *
190
- * @param type $link
191
- * @return type
192
  */
193
- function wpml_shop_page_id($link){
194
- $link = icl_object_id(get_option('woocommerce_shop_page_id'), 'page', false);
195
-
196
- return $link;
197
  }
198
 
199
  /**
@@ -203,6 +383,13 @@ function wpml_get_thanks_page_id(){
203
  return icl_object_id(get_option('woocommerce_thanks_page_id'), 'page', true);
204
  }
205
 
 
 
 
 
 
 
 
206
  /**
207
  * Filters WooCommerce payment link for unpaid - pending orders.
208
  *
@@ -233,7 +420,14 @@ function wpml_get_edit_address_page_id(){
233
  * Filters WooCommerce view order link.
234
  */
235
  function wpml_get_view_order_page_id(){
236
- return icl_object_id(get_option('woocommerce_view_order_page_id'), 'page', true);
 
 
 
 
 
 
 
237
  }
238
 
239
  /**
@@ -245,13 +439,12 @@ function wpml_get_change_password_page_id(){
245
 
246
  /**
247
  * Filters WooCommerce pay page id
248
- * @return type
249
  */
250
  function wpml_pay_page_id(){
251
  $is_cart_page = icl_object_id(get_option('woocommerce_cart_page_id'), 'page', true);
252
 
253
  if(is_page($is_cart_page)){
254
- //return true;
255
  } else {
256
  return icl_object_id(get_option('woocommerce_pay_page_id'), 'page', true);
257
  }
@@ -259,48 +452,38 @@ function wpml_pay_page_id(){
259
 
260
  /**
261
  * Filters WooCommerce checkout link.
262
- *
263
- * @global type $sitepress
264
- * @param type $link
265
- * @return type
266
  */
267
- function wpml_get_checkout_url($link){
268
- global $sitepress;
269
-
270
  return get_permalink(icl_object_id(get_option('woocommerce_checkout_page_id'), 'page', true));
271
  }
272
 
273
  /**
274
  * Filters WooCommerce cart link.
275
- *
276
- * @return type
277
  */
278
- function wpml_get_cart_url($link) {
279
  return icl_object_id(get_option('woocommerce_cart_page_id'), 'page', true);
280
  }
281
 
282
  /**
283
  * Filters WooCommerce product remove link.
284
  *
285
- * @global type $sitepress
286
  * @param type $link
287
  * @return type
288
  */
289
  function wpml_get_remove_url($link){
290
- global $sitepress;
291
-
292
  return $link;
293
  }
294
 
295
  /**
296
- * Filters WooCommerce js params
297
  *
298
  * @global type $sitepress
299
  * @global type $post
300
  * @param type $value
301
  * @return type
302
  */
303
- function wpml_params($value){
304
  global $sitepress, $post;
305
 
306
  if(!isset($post->ID)){
@@ -324,7 +507,23 @@ function wpml_params($value){
324
  $value['is_cart'] = 1;
325
  } else if($translated_checkout_page_id == $post->ID || $checkout_page_id == $post->ID){
326
  $value['is_checkout'] = 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
  $_SESSION['wpml_globalcart_language'] = $sitepress->get_current_language();
 
328
  } else if($translated_pay_page_id == $post->ID){
329
  $value['is_pay_page'] = 1;
330
  }
@@ -355,12 +554,19 @@ function wpml_order_language($order_id) {
355
  * @return type
356
  */
357
  function wpml_email_header() {
358
- global $sitepress, $order_id, $email_heading;
 
 
359
 
360
- $order_lang = get_post_custom_values('wpml_language', $order_id);
361
- $order_lang = trim($order_lang[0]);
 
 
 
 
 
362
 
363
- $sitepress->switch_lang($order_lang, true);
364
  }
365
 
366
  /**
@@ -436,4 +642,211 @@ function wpml_change_permalinks(){
436
  }
437
  }
438
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
439
  ?>
5
  Description: Allows running fully multilingual e-Commerce sites with WooCommerce and WPML. <a href="http://wpml.org/documentation/related-projects/woocommerce-multilingual/">Documentation</a>.
6
  Author: ICanLocalize
7
  Author URI: http://wpml.org/
8
+ Version: 1.1
9
+ */
10
+
11
+ define('WCML_VERSION', '1.1');
12
+ define('WCML_PLUGIN_PATH', dirname(__FILE__));
13
+ define('WCML_PLUGIN_FOLDER', basename(WCML_PLUGIN_PATH));
14
+ define('WCML_PLUGIN_URL', plugins_url() . '/' . WCML_PLUGIN_FOLDER);
15
+
16
+ add_action('plugins_loaded', 'wpml_woocommerce_multilingual_init', 2);
17
 
18
+ function wpml_woocommerce_multilingual_init(){
19
  if(!defined('ICL_SITEPRESS_VERSION') || ICL_PLUGIN_INACTIVE){
20
  if(!function_exists('is_multisite') || !is_multisite()) {
21
  add_action('admin_notices', 'wpml_no_wpml_warning');
29
  return false;
30
  }
31
 
32
+ if(get_option('icl_is_wcml_installed') !== 'yes'){
33
+ add_action('init', 'wpml_install');
34
+ }
35
+
36
+ // Filters WPML language switcher
37
  add_filter('icl_ls_languages', 'wpml_ls_filter');
38
 
39
+ add_filter('woocommerce_get_checkout_url', 'wpml_get_checkout_page_id');
40
+ add_filter('woocommerce_get_checkout_page_id', 'wpml_checkout_page_id');
41
+ add_filter('woocommerce_get_cart_page_id', 'wpml_get_cart_page_id');
42
  add_filter('woocommerce_get_myaccount_page_id', 'wpml_get_myaccount_page_id');
43
  add_filter('woocommerce_get_edit_address_page_id', 'wpml_get_edit_address_page_id');
44
  add_filter('woocommerce_get_view_order_page_id', 'wpml_get_view_order_page_id');
49
  add_filter('woocommerce_get_checkout_payment_url', 'wpml_get_checkout_payment_url');
50
  add_filter('woocommerce_get_cancel_order_url', 'wpml_get_cancel_order_url');
51
  add_filter('woocommerce_get_return_url', 'wpml_get_return_url');
52
+ add_filter('woocommerce_get_remove_url', 'wpml_get_remove_url');
53
+
54
  add_filter('woocommerce_in_cart_product_title', 'wpml_in_cart_product_title', 13, 2);
55
  add_filter('woocommerce_in_cart_product_id', 'wpml_in_cart_product_id', 11, 2);
 
 
 
56
 
57
+ add_filter('woocommerce_params', 'wpml_ajax_params');
58
+ add_filter('woocommerce_redirect', 'wpml_do_redirect');
59
+ add_filter('woocommerce_attribute_label', 'wpml_translate_attributes', 14, 2);
60
+ add_filter('woocommerce_upsell_crosssell_search_products', 'wpml_woocommerce_upsell_crosssell_search_posts');
61
+ add_filter('icl_post_alternative_languages', 'wpml_post_alternative_languages');
62
+ add_filter('wp_head', 'wpml_redirect_to_the_base_page');
63
+
64
+ if(get_option('icl_enable_multi_currency') == 'yes'){
65
+ add_filter('raw_woocommerce_price', 'wpml_woocommerce_price');
66
+ add_filter('woocommerce_currency_symbol', 'wpml_woocommerce_currency_symbol', 2);
67
+ }
68
+
69
  add_action('woocommerce_email_header', 'wpml_email_header', 0);
70
  add_action('woocommerce_email_footer', 'wpml_email_footer', 0);
71
  add_action('woocommerce_new_order', 'wpml_order_language');
72
+ add_action('updated_post_meta', 'wpml_updated_post_meta_hook', 10, 4);
73
+
74
+ add_action('admin_head', 'wpml_synchronizate_variations', 15);
75
+ //add_action('save_post', 'wpml_synchronization_of_variations', 16);
76
+
77
+ add_action('admin_menu', 'wpml_menu');
78
  add_action('init', 'wpml_change_permalinks');
79
+ add_action('init', 'wpml_load_css_and_js');
80
+
81
+ if(isset($_POST['general_options']) && check_admin_referer('general_options', 'general_options_nonce')){
82
+ $enable_multi_currency = (isset($_POST['multi_currency'])) ? trim($_POST['multi_currency']) : null;
83
+
84
+ if($enable_multi_currency == 'yes'){
85
+ add_option('icl_enable_multi_currency', 'yes');
86
+ } else {
87
+ delete_option('icl_enable_multi_currency');
88
+ }
89
+ }
90
+
91
+ if(isset($_POST['add_currency']) && check_admin_referer('add_currency', 'add_currency_nonce')){
92
+ global $wpdb, $pagenow;
93
+
94
+ $language_code = (isset($_POST['language'])) ? trim($_POST['language']) : null;
95
+ $currency_code = (isset($_POST['currency_code'])) ? mb_convert_case(trim($_POST['currency_code']), MB_CASE_UPPER, "UTF-8") : null;
96
+ $exchange_rate = (isset($_POST['exchange_rate'])) ? trim($_POST['exchange_rate']) : null;
97
+ $currency_id = (isset($_POST['currency_id'])) ? trim($_POST['currency_id']) : null;
98
+ $date = date('Y-m-d H:i:s');
99
+
100
+ if($currency_code == ''){
101
+ wp_die(__('<strong>ERROR</strong>: please fill the currency code field.'));
102
+ }
103
+
104
+ if($exchange_rate == ''){
105
+ wp_die(__('<strong>ERROR</strong>: please fill the exchange rate field.'));
106
+ } else if(!is_numeric($exchange_rate)){
107
+ wp_die(__('<strong>ERROR</strong>: please enter the correct exchange rate.'));
108
+ }
109
+
110
+ $result = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*)
111
+ FROM ". $wpdb->prefix ."icl_currencies WHERE language_code = '$language_code'"));
112
+
113
+ if($result && !$currency_id){
114
+ add_action('admin_notices', 'wpml_currency_exists_error');
115
+ } else {
116
+ // Add
117
+ if(!$currency_id){
118
+ $wpdb->insert($wpdb->prefix .'icl_currencies', array(
119
+ 'language_code' => $language_code,
120
+ 'code' => $currency_code,
121
+ 'value' => (double) $exchange_rate,
122
+ 'changed' => $date
123
+ )
124
+ );
125
+
126
+ // Update
127
+ } else {
128
+ $wpdb->update(
129
+ $wpdb->prefix .'icl_currencies',
130
+ array(
131
+ 'code' => $currency_code,
132
+ 'value' => (double) $exchange_rate,
133
+ 'changed' => $date
134
+ ),
135
+ array( 'id' => $currency_id )
136
+ );
137
+
138
+ wp_safe_redirect(admin_url('admin.php?page=wpml-wcml'));
139
+ }
140
+ }
141
+ }
142
+
143
+ if($_GET['page'] == 'wpml-wcml' && isset($_GET['delete']) && $_GET['delete'] == $_GET['delete']){
144
+ global $wpdb;
145
+
146
+ $remove_id = $_GET['delete'];
147
+
148
+ $delete = $wpdb->query("DELETE FROM ". $wpdb->prefix ."icl_currencies WHERE id = '$remove_id'");
149
+
150
+ if(!$delete){
151
+ wp_die(__('<strong>ERROR</strong>: currency can not be deleted. Please try again.'));
152
+ }
153
+
154
+ wp_safe_redirect(admin_url('admin.php?page=wpml-wcml'));
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Filters the product price.
160
+ */
161
+ function wpml_woocommerce_price($price){
162
+ global $sitepress, $wpdb;
163
+
164
+ $sql = "SELECT (value) FROM ". $wpdb->prefix ."icl_currencies WHERE language_code = '". $sitepress->get_current_language() ."'";
165
+ $currency = $wpdb->get_results($sql, OBJECT);
166
+
167
+ if($currency){
168
+ $exchange_rate = $currency[0]->value;
169
+ $price = $price * $exchange_rate;
170
+
171
+ $price = apply_filters('woocommerce_multilingual_price', $price);
172
+ }
173
+
174
+ return $price;
175
+ }
176
+
177
+ /**
178
+ * Filters the currency symbol.
179
+ */
180
+ function wpml_woocommerce_currency_symbol($currency_symbol){
181
+ global $sitepress, $wpdb;
182
+
183
+ $sql = "SELECT (code) FROM ". $wpdb->prefix ."icl_currencies WHERE language_code = '". $sitepress->get_current_language() ."'";
184
+ $db_currency = $wpdb->get_results($sql, OBJECT);
185
+
186
+ if($db_currency){
187
+ $currency = $db_currency[0]->code;
188
+ $currencies = array('BRL', 'USD', 'EUR', 'JPY', 'TRY', 'NOK', 'ZAR', 'CZK', 'THB', 'GBP');
189
+
190
+ if(in_array($currency, $currencies)){
191
+ switch ($currency) :
192
+ case 'BRL' : $currency_symbol = 'R&#36;'; break;
193
+ case 'USD' : $currency_symbol = '&#36;'; break;
194
+ case 'EUR' : $currency_symbol = '&euro;'; break;
195
+ case 'JPY' : $currency_symbol = '&yen;'; break;
196
+ case 'TRY' : $currency_symbol = 'TL'; break;
197
+ case 'NOK' : $currency_symbol = 'kr'; break;
198
+ case 'ZAR' : $currency_symbol = 'R'; break;
199
+ case 'CZK' : $currency_symbol = '&#75;&#269;'; break;
200
+ case 'GBP' : $currency_symbol = '&pound;'; break;
201
+ endswitch;
202
+ } else {
203
+ $currency_symbol = $currency;
204
+ }
205
+ }
206
+
207
+ return $currency_symbol;
208
+ }
209
+
210
+ /**
211
+ * Install the plugin.
212
+ */
213
+ function wpml_install(){
214
+ global $wpdb;
215
+
216
+ add_option('icl_is_wcml_installed', 'yes');
217
+
218
+ $sql = "CREATE TABLE IF NOT EXISTS `". $wpdb->prefix ."icl_currencies` (
219
+ `id` int(11) NOT NULL AUTO_INCREMENT,
220
+ `language_code` varchar(7) COLLATE utf8_unicode_ci NOT NULL,
221
+ `code` varchar(7) COLLATE utf8_unicode_ci NOT NULL,
222
+ `value` varchar(7) COLLATE utf8_unicode_ci DEFAULT NULL,
223
+ `changed` datetime DEFAULT NULL,
224
+ PRIMARY KEY (`id`)
225
+ )";
226
+
227
+ $install = $wpdb->query($sql);
228
  }
229
 
230
  /**
257
  <?php
258
  }
259
 
260
+ /**
261
+ * Adds admin notice.
262
+ */
263
+ function wpml_currency_exists_error(){
264
+ ?>
265
+ <div class="message error"><p><?php echo __('Currency of the selected language already exists.', 'wpml-wcml'); ?></p></div>
266
+ <?php
267
+ }
268
+
269
  /**
270
  * Filters WooCommerce product link in cart.
271
  *
298
  */
299
  function wpml_updated_post_meta_hook($meta_id, $object_id, $meta_key, $_meta_value) {
300
  global $sitepress;
301
+
302
  $update_meta_keys = array('stock', 'stock_status');
303
 
304
  if (in_array($meta_key, $update_meta_keys)) {
322
  * @global type $post
323
  * @global type $sitepress
324
  */
325
+ function wpml_redirect_to_the_base_page(){
326
  global $post, $sitepress;
327
 
328
  $shop_page_id = get_option('woocommerce_shop_page_id');
364
  * @param type $link
365
  * @return type
366
  */
367
+ function wpml_do_redirect($link){
368
  global $sitepress;
369
  return $sitepress->convert_url($link);
370
  }
371
 
372
  /**
373
  * Filters WooCommerce shop link.
 
 
 
374
  */
375
+ function wpml_shop_page_id(){
376
+ return icl_object_id(get_option('woocommerce_shop_page_id'), 'page', false);
 
 
377
  }
378
 
379
  /**
383
  return icl_object_id(get_option('woocommerce_thanks_page_id'), 'page', true);
384
  }
385
 
386
+ /**
387
+ * Filters WooCommerce checkout page id.
388
+ */
389
+ function wpml_checkout_page_id(){
390
+ return icl_object_id(get_option('woocommerce_checkout_page_id'), 'page', true);
391
+ }
392
+
393
  /**
394
  * Filters WooCommerce payment link for unpaid - pending orders.
395
  *
420
  * Filters WooCommerce view order link.
421
  */
422
  function wpml_get_view_order_page_id(){
423
+ // avoid redirect to the my account page
424
+ if(get_option('woocommerce_view_order_page_id') !== get_option('woocommerce_checkout_page_id')){
425
+ $return = icl_object_id(get_option('woocommerce_view_order_page_id'), 'page', true);
426
+ } else {
427
+ $return = false;
428
+ }
429
+
430
+ return $return;
431
  }
432
 
433
  /**
439
 
440
  /**
441
  * Filters WooCommerce pay page id
 
442
  */
443
  function wpml_pay_page_id(){
444
  $is_cart_page = icl_object_id(get_option('woocommerce_cart_page_id'), 'page', true);
445
 
446
  if(is_page($is_cart_page)){
447
+ //return
448
  } else {
449
  return icl_object_id(get_option('woocommerce_pay_page_id'), 'page', true);
450
  }
452
 
453
  /**
454
  * Filters WooCommerce checkout link.
 
 
 
 
455
  */
456
+ function wpml_get_checkout_page_id(){
 
 
457
  return get_permalink(icl_object_id(get_option('woocommerce_checkout_page_id'), 'page', true));
458
  }
459
 
460
  /**
461
  * Filters WooCommerce cart link.
 
 
462
  */
463
+ function wpml_get_cart_page_id() {
464
  return icl_object_id(get_option('woocommerce_cart_page_id'), 'page', true);
465
  }
466
 
467
  /**
468
  * Filters WooCommerce product remove link.
469
  *
 
470
  * @param type $link
471
  * @return type
472
  */
473
  function wpml_get_remove_url($link){
474
+ // outputs raw
 
475
  return $link;
476
  }
477
 
478
  /**
479
+ * Filters WooCommerce AJAX params
480
  *
481
  * @global type $sitepress
482
  * @global type $post
483
  * @param type $value
484
  * @return type
485
  */
486
+ function wpml_ajax_params($value){
487
  global $sitepress, $post;
488
 
489
  if(!isset($post->ID)){
507
  $value['is_cart'] = 1;
508
  } else if($translated_checkout_page_id == $post->ID || $checkout_page_id == $post->ID){
509
  $value['is_checkout'] = 1;
510
+
511
+ // Recreates woocommerce.params.locale
512
+ $value['locale'] = '{"AT":{"postcode_before_city":true,"state":{"required":false}},"BE":{"postcode_before_city":true,"state":{"required":false}},
513
+ "CA":{"state":{"label":"Province"}},"CL":{"city":{"required":false},"state":{"label":"Municipalit\u00e9"}},"CN":{"state":{"label":"Province"}},
514
+ "CZ":{"state":{"required":false}},"DE":{"postcode_before_city":true,"state":{"required":false}},
515
+ "DK":{"postcode_before_city":true,"state":{"required":false}},"FI":{"postcode_before_city":true,"state":{"required":false}},
516
+ "FR":{"postcode_before_city":true,"state":{"required":false}},"HK":{"postcode":{"required":false},"city":{"label":"Ville \/ Quartier"},"state":{"label":"R\u00e9gion"}},
517
+ "HU":{"state":{"required":false}},
518
+ "IS":{"postcode_before_city":true,"state":{"required":false}},"IL":{"postcode_before_city":true,"state":{"required":false}},
519
+ "NL":{"postcode_before_city":true,"state":{"required":false}},"NZ":{"state":{"required":false}},"NO":{"postcode_before_city":true,"state":{"required":false}},
520
+ "PL":{"postcode_before_city":true,"state":{"required":false}},"RO":{"state":{"required":false}},"SG":{"state":{"required":false}},
521
+ "SK":{"postcode_before_city":true,"state":{"required":false}},"SI":{"postcode_before_city":true,"state":{"required":false}},
522
+ "ES":{"postcode_before_city":true,"state":{"label":"Province"}},"LK":{"state":{"required":false}},"SE":{"postcode_before_city":true,"state":{"required":false}},
523
+ "TR":{"postcode_before_city":true,"state":{"label":"Province"}},"US":{"postcode":{"label":"Code postal"},"state":{"label":"State"}},
524
+ "GB":{"postcode":{"label":"Code Postal"},"state":{"label":"Comt\u00e9"}},"default":{"postcode":{"label":"Code Postal \/ Zip"},"city":{"label":"Ville"},"state":{"label":"Etat\/Pays"}}}';
525
  $_SESSION['wpml_globalcart_language'] = $sitepress->get_current_language();
526
+
527
  } else if($translated_pay_page_id == $post->ID){
528
  $value['is_pay_page'] = 1;
529
  }
554
  * @return type
555
  */
556
  function wpml_email_header() {
557
+ global $sitepress, $order_id;
558
+
559
+ $lang = get_post_meta($order_id, 'wpml_language', TRUE);
560
 
561
+ if(empty($lang)){
562
+ if(isset($_SESSION['wpml_globalcart_language'])){
563
+ $lang = $_SESSION['wpml_globalcart_language'];
564
+ } else {
565
+ $lang = $sitepress->get_current_language();
566
+ }
567
+ }
568
 
569
+ $sitepress->switch_lang($lang, true);
570
  }
571
 
572
  /**
642
  }
643
  }
644
 
645
+ /**
646
+ * Creates WCML page.
647
+ */
648
+ function wpml_menu(){
649
+ $top_page = apply_filters('icl_menu_main_page', basename(ICL_PLUGIN_PATH) .'/menu/languages.php');
650
+
651
+ add_submenu_page($top_page, __('WooCommerce Multilingual','wpml-wcml'),
652
+ __('WooCommerce Multilingual', 'wpml-wcml'), 'manage_options', 'wpml-wcml', 'wpml_menu_content');
653
+ }
654
+
655
+ /**
656
+ * Creates WCML page content.
657
+ */
658
+ function wpml_menu_content(){
659
+ include WCML_PLUGIN_PATH . '/menu/management.php';
660
+ }
661
+
662
+ /**
663
+ * Adds additional CSS and JS.
664
+ */
665
+ function wpml_load_css_and_js() {
666
+ wp_enqueue_style('wpml-wcml', WCML_PLUGIN_URL . '/assets/css/management.css', array(), WCML_VERSION);
667
+
668
+ wp_enqueue_script(
669
+ 'jquery-validate',
670
+ plugin_dir_url(__FILE__) . '/assets/js/jquery.validate.min.js',
671
+ array('jquery'),
672
+ '1.8.1',
673
+ true
674
+ );
675
+ }
676
+
677
+ /**
678
+ * Avoids the post translation links on the product post type.
679
+ *
680
+ * @global type $post
681
+ * @return type
682
+ */
683
+ function wpml_post_alternative_languages($output){
684
+ global $post;
685
+
686
+ $post_type = get_post_type($post->ID);
687
+ $checkout_page_id = wpml_checkout_page_id();
688
+
689
+ if($post_type == 'product' || is_page($checkout_page_id)){
690
+ $output = '';
691
+ }
692
+
693
+ return $output;
694
+ }
695
+
696
+ /**
697
+ * Translates attributes names.
698
+ *
699
+ * @param type $name
700
+ * @return type
701
+ */
702
+ function wpml_translate_attributes($name){
703
+ icl_register_string('woocommerce', $name .'_attribute', $name);
704
+
705
+ return icl_t('woocommerce', $name .'_attribute', $name);
706
+ }
707
+
708
+ /**
709
+ * Takes off translated products from the Up-sells/Cross-sells tab.
710
+ *
711
+ * @global type $sitepress
712
+ * @global type $wpdb
713
+ * @return type
714
+ */
715
+ function wpml_woocommerce_upsell_crosssell_search_posts($posts){
716
+ global $sitepress, $wpdb;
717
+
718
+ foreach($posts as $key => $post){
719
+ $post_id = $posts[$key]->ID;
720
+ $post_data = $wpdb->get_row("SELECT * FROM ". $wpdb->prefix ."icl_translations WHERE element_id = '$post_id'", ARRAY_A);
721
+
722
+ if($post_data['language_code'] !== $sitepress->get_current_language()){
723
+ unset($posts[$key]);
724
+ }
725
+ }
726
+
727
+ return $posts;
728
+ }
729
+
730
+ /**
731
+ * Sync attributes and variations during product duplication.
732
+ * Sync: term relationship, post meta, post variations, post variations meta.
733
+ *
734
+ * @global type $wpdb
735
+ * @global type $pagenow
736
+ * @global type $post
737
+ * @return type
738
+ */
739
+ function wpml_synchronizate_variations() {
740
+ global $wpdb, $pagenow, $post;
741
+
742
+ $post_id = $post->ID;
743
+ $post_type = get_post_type($post->ID);
744
+
745
+ if($pagenow == 'post.php' || $pagenow == 'post-new.php' && $post_type == 'product'){
746
+ $duplicated_post_id = get_post_meta($post_id, '_icl_lang_duplicate_of', TRUE);
747
+ $is_data_already_synced = get_post_meta($post_id, 'wpml_variations_already_synced', TRUE);
748
+
749
+ // Only on duplication and run once
750
+ if(!empty($duplicated_post_id) && empty($is_data_already_synced)){
751
+
752
+ $get_variation_term_name = $wpdb->get_results("SELECT * FROM $wpdb->terms WHERE name = 'variable'");
753
+ $get_variation_term_id = $get_variation_term_name[0]->term_id;
754
+
755
+ $is_post_has_variations = $wpdb->get_results("SELECT * FROM $wpdb->term_relationships WHERE object_id = '$duplicated_post_id' AND term_taxonomy_id = '$get_variation_term_id'");
756
+ if(!empty($is_post_has_variations)) $is_post_has_variations = TRUE;
757
+
758
+ // synchronize term data, postmeta and post variations
759
+ if($is_post_has_variations){
760
+ $get_all_term_data = $wpdb->get_results("SELECT * FROM $wpdb->term_relationships WHERE object_id = '$duplicated_post_id'");
761
+
762
+ // synchronize term data
763
+ foreach($get_all_term_data as $k => $term_relationship){
764
+
765
+ $wpdb->insert(
766
+ $wpdb->term_relationships,
767
+ array(
768
+ 'object_id' => $post_id,
769
+ 'term_taxonomy_id' => $term_relationship->term_taxonomy_id,
770
+ 'term_order' => $term_relationship->term_order
771
+ ));
772
+
773
+ }
774
+
775
+ // synchronize post meta
776
+ $get_all_post_meta = $wpdb->get_results("SELECT * FROM $wpdb->postmeta WHERE post_id = '$duplicated_post_id'");
777
+
778
+ foreach($get_all_post_meta as $k => $post_meta){
779
+ $meta_key = $post_meta->meta_key;
780
+ $meta_value = $post_meta->meta_value;
781
+
782
+ update_post_meta($post_id, $meta_key, $meta_value);
783
+ }
784
+
785
+ // synchronize post variations
786
+ $get_all_post_variations = $wpdb->get_results("SELECT * FROM $wpdb->posts
787
+ WHERE post_status = 'publish' AND post_type = 'product_variation' AND post_parent = '$duplicated_post_id'");
788
+
789
+ foreach($get_all_post_variations as $k => $post_data){
790
+ $guid = $post_data->guid;
791
+ $replaced_guid = str_replace($duplicated_post_id, $post_id, $guid);
792
+
793
+ $wpdb->insert(
794
+ $wpdb->posts,
795
+ array(
796
+ 'post_author' => $post_data->post_author,
797
+ 'post_date_gmt' => $post_data->post_date_gmt,
798
+ 'post_content' => $post_data->post_content,
799
+ 'post_title' => $post_data->post_title,
800
+ 'post_excerpt' => $post_data->post_excerpt,
801
+ 'post_status' => $post_data->post_status,
802
+ 'comment_status' => $post_data->comment_status,
803
+ 'ping_status' => $post_data->ping_status,
804
+ 'post_password' => $post_data->post_password,
805
+ 'post_name' => $post_data->post_name,
806
+ 'to_ping' => $post_data->to_ping,
807
+ 'pinged' => $post_data->pinged,
808
+ 'post_modified' => $post_data->post_modified,
809
+ 'post_modified_gmt' => $post_data->post_modified_gmt,
810
+ 'post_content_filtered' => $post_data->post_content_filtered,
811
+ 'post_parent' => $post_id, // current post id
812
+ 'guid' => $replaced_guid,
813
+ 'menu_order' => $post_data->menu_order,
814
+ 'post_type' => $post_data->post_type,
815
+ 'post_mime_type' => $post_data->post_mime_type,
816
+ 'comment_count' => $post_data->comment_count
817
+ ));
818
+
819
+ }
820
+
821
+ foreach($get_all_post_variations as $k => $post_data){
822
+ $duplicated_post_variation_ids[] = $post_data->ID;
823
+ }
824
+
825
+ $get_current_post_variations = $wpdb->get_results("SELECT * FROM $wpdb->posts
826
+ WHERE post_status = 'publish' AND post_type = 'product_variation' AND post_parent = '$post_id'");
827
+
828
+ foreach($get_current_post_variations as $k => $post_data){
829
+ $current_post_variation_ids[] = $post_data->ID;
830
+ }
831
+
832
+ // synchronize post variations post meta
833
+ foreach($duplicated_post_variation_ids as $dp_key => $duplicated_post_variation_id){
834
+ $get_all_post_meta = $wpdb->get_results("SELECT * FROM $wpdb->postmeta WHERE post_id = '$duplicated_post_variation_id'");
835
+
836
+ foreach($get_all_post_meta as $k => $post_meta){
837
+ $meta_key = $post_meta->meta_key;
838
+ $meta_value = $post_meta->meta_value;
839
+
840
+ // update current post variations meta
841
+ update_post_meta($current_post_variation_ids[$dp_key], $meta_key, $meta_value);
842
+ }
843
+ }
844
+
845
+ // add a record that data is already synced
846
+ update_post_meta($post_id, 'wpml_variations_already_synced', '1');
847
+ }
848
+ }
849
+ }
850
+ }
851
+
852
  ?>