Version Description
- ..
-
*
Download this release
Release Info
Developer | Persianscript |
Plugin | Persian Woocommerce |
Version | 5.8.0 |
Comparing to | |
See all releases |
Code changes from version 5.2.2 to 5.8.0
- assets/js/jquery.min.js +0 -2
- include/class-address.php +314 -312
- include/class-core.php +150 -298
- include/class-currencies.php +27 -29
- include/class-gateways.php +690 -677
- include/class-notice.php +321 -0
- include/class-tools.php +428 -399
- include/class-translate.php +220 -221
- include/class-widget.php +59 -61
- include/gateways/class-payir.php +63 -51
- include/tools/class-checkout.php +7 -26
- include/tools/class-date.php +11 -9
- include/tools/class-datepicker.php +76 -73
- include/tools/class-general.php +124 -0
- include/tools/class-price.php +43 -17
- include/tools/general.php +0 -111
- include/view/html-admin-page-plugins.php +108 -108
- include/view/html-admin-page-themes.php +109 -109
- readme.txt +48 -10
- woocommerce-persian.php +9 -10
assets/js/jquery.min.js
DELETED
@@ -1,2 +0,0 @@
|
|
1 |
-
/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */
|
2 |
-
!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}k.fn=k.prototype={jquery:f,constructor:k,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=k.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return k.each(this,e)},map:function(n){return this.pushStack(k.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},k.extend=k.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(k.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||k.isPlainObject(n)?n:{},i=!1,a[t]=k.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},k.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=v.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t){b(e,{nonce:t&&t.nonce})},each:function(e,t){var n,r=0;if(d(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?"":(e+"").replace(p,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(d(Object(e))?k.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(d(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g.apply([],a)},guid:1,support:y}),"function"==typeof Symbol&&(k.fn[Symbol.iterator]=t[Symbol.iterator]),k.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var h=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,v,s,c,y,k="sizzle"+1*new Date,m=n.document,S=0,r=0,p=ue(),x=ue(),N=ue(),A=ue(),D=function(e,t){return e===t&&(l=!0),0},j={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",I="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",$=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",F=new RegExp(M+"+","g"),B=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="<a id='"+k+"'></a><select id='"+k+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0<se(t,C,null,[e]).length},se.contains=function(e,t){return(e.ownerDocument||e)!==C&&T(e),y(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!==C&&T(e);var n=b.attrHandle[t.toLowerCase()],r=n&&j.call(b.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:d.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},se.escape=function(e){return(e+"").replace(re,ie)},se.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},se.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!d.detectDuplicates,u=!d.sortStable&&e.slice(0),e.sort(D),l){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return u=null,e},o=se.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=o(t);return n},(b=se.selectors={cacheLength:50,createPseudo:le,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace(F," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(h,e,t,g,v){var y="nth"!==h.slice(0,3),m="last"!==h.slice(-4),x="of-type"===e;return 1===g&&0===v?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=y!==m?"nextSibling":"previousSibling",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),p=!n&&!x,d=!1;if(c){if(y){while(l){a=e;while(a=a[l])if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&p){d=(s=(r=(i=(o=(a=c)[k]||(a[k]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===S&&r[1])&&r[2],a=s&&c.childNodes[s];while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if(1===a.nodeType&&++d&&a===e){i[h]=[S,s,d];break}}else if(p&&(d=s=(r=(i=(o=(a=e)[k]||(a[k]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===S&&r[1]),!1===d)while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if((x?a.nodeName.toLowerCase()===f:1===a.nodeType)&&++d&&(p&&((i=(o=a[k]||(a[k]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[S,d]),a===e))break;return(d-=v)===g||d%g==0&&0<=d/g}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||se.error("unsupported pseudo: "+e);return a[k]?a(o):1<a.length?(t=[e,e,"",o],b.setFilters.hasOwnProperty(e.toLowerCase())?le(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=P(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:le(function(e){var r=[],i=[],s=f(e.replace(B,"$1"));return s[k]?le(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:le(function(t){return function(e){return 0<se(t,e).length}}),contains:le(function(t){return t=t.replace(te,ne),function(e){return-1<(e.textContent||o(e)).indexOf(t)}}),lang:le(function(n){return V.test(n||"")||se.error("unsupported lang: "+n),n=n.replace(te,ne).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===a},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ve(function(){return[0]}),last:ve(function(e,t){return[t-1]}),eq:ve(function(e,t,n){return[n<0?n+t:n]}),even:ve(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:ve(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:ve(function(e,t,n){for(var r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:ve(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=de(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=he(e);function me(){}function xe(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function be(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&"parentNode"===c,p=r++;return e.first?function(e,t,n){while(e=e[u])if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[S,p];if(n){while(e=e[u])if((1===e.nodeType||f)&&s(e,t,n))return!0}else while(e=e[u])if(1===e.nodeType||f)if(i=(o=e[k]||(e[k]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===S&&r[1]===p)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function we(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Te(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Ce(d,h,g,v,y,e){return v&&!v[k]&&(v=Ce(v)),y&&!y[k]&&(y=Ce(y,e)),le(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)se(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!d||!e&&h?c:Te(c,s,d,n,r),p=g?y||(e?d:l||v)?[]:t:f;if(g&&g(f,p,n,r),v){i=Te(p,u),v(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(p[u[o]]=!(f[u[o]]=a))}if(e){if(y||d){if(y){i=[],o=p.length;while(o--)(a=p[o])&&i.push(f[o]=a);y(null,p=[],i,r)}o=p.length;while(o--)(a=p[o])&&-1<(i=y?P(e,a):s[o])&&(e[i]=!(t[i]=a))}}else p=Te(p===t?p.splice(l,p.length):p),y?y(null,t,p,r):H.apply(t,p)})}function Ee(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[" "],s=o?1:0,u=be(function(e){return e===i},a,!0),l=be(function(e){return-1<P(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!==w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[be(we(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[k]){for(n=++s;n<r;n++)if(b.relative[e[n].type])break;return Ce(1<s&&we(c),1<s&&xe(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace(B,"$1"),t,s<n&&Ee(e.slice(s,n)),n<r&&Ee(e=e.slice(n)),n<r&&xe(e))}c.push(t)}return we(c)}return me.prototype=b.filters=b.pseudos,b.setFilters=new me,h=se.tokenize=function(e,t){var n,r,i,o,a,s,u,l=x[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=_.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=z.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace(B," ")}),a=a.slice(n.length)),b.filter)!(r=G[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?se.error(e):x(e,s).slice(0)},f=se.compile=function(e,t){var n,v,y,m,x,r,i=[],o=[],a=N[e+" "];if(!a){t||(t=h(e)),n=t.length;while(n--)(a=Ee(t[n]))[k]?i.push(a):o.push(a);(a=N(e,(v=o,m=0<(y=i).length,x=0<v.length,r=function(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG("*",i),h=S+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t===C||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument===C||(T(o),n=!E);while(s=v[a++])if(s(o,t||C,n)){r.push(o);break}i&&(S=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=y[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=q.call(r));f=Te(f)}H.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&se.uniqueSort(r)}return i&&(S=h,w=p),c},m?le(r):r))).selector=e}return a},g=se.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&E&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(te,ne),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=G.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((u=b.find[s])&&(r=u(a.matches[0].replace(te,ne),ee.test(o[0].type)&&ye(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&xe(o)))return H.apply(n,r),n;break}}}return(l||f(e,c))(r,t,!E,n,!t||ee.test(e)&&ye(t.parentNode)||t),n},d.sortStable=k.split("").sort(D).join("")===k,d.detectDuplicates=!!l,T(),d.sortDetached=ce(function(e){return 1&e.compareDocumentPosition(C.createElement("fieldset"))}),ce(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||fe("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),d.attributes&&ce(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||fe("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ce(function(e){return null==e.getAttribute("disabled")})||fe(R,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),se}(C);k.find=h,k.expr=h.selectors,k.expr[":"]=k.expr.pseudos,k.uniqueSort=k.unique=h.uniqueSort,k.text=h.getText,k.isXMLDoc=h.isXML,k.contains=h.contains,k.escapeSelector=h.escape;var T=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&k(e).is(n))break;r.push(e)}return r},S=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},N=k.expr.match.needsContext;function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var D=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1<i.call(n,e)!==r}):k.filter(n,e,r)}k.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?k.find.matchesSelector(r,e)?[r]:[]:k.find.matches(e,k.grep(t,function(e){return 1===e.nodeType}))},k.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(k(e).filter(function(){for(t=0;t<r;t++)if(k.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)k.find(e,i[t],n);return 1<r?k.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&N.test(e)?k(e):e||[],!1).length}});var q,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(k.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&k(e);if(!N.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&k.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?k.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?i.call(k(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(k.uniqueSort(k.merge(this.get(),k(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),k.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return T(e,"parentNode")},parentsUntil:function(e,t,n){return T(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return T(e,"nextSibling")},prevAll:function(e){return T(e,"previousSibling")},nextUntil:function(e,t,n){return T(e,"nextSibling",n)},prevUntil:function(e,t,n){return T(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return"undefined"!=typeof e.contentDocument?e.contentDocument:(A(e,"template")&&(e=e.content||e),k.merge([],e.childNodes))}},function(r,i){k.fn[r]=function(e,t){var n=k.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=k.filter(t,n)),1<this.length&&(O[r]||k.uniqueSort(n),H.test(r)&&n.reverse()),this.pushStack(n)}});var R=/[^\x20\t\r\n\f]+/g;function M(e){return e}function I(e){throw e}function W(e,t,n,r){var i;try{e&&m(i=e.promise)?i.call(e).done(t).fail(n):e&&m(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}k.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},k.each(e.match(R)||[],function(e,t){n[t]=!0}),n):k.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:"")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){k.each(e,function(e,t){m(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&"string"!==w(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return k.each(arguments,function(e,t){var n;while(-1<(n=k.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<k.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t="",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=""),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},k.extend({Deferred:function(e){var o=[["notify","progress",k.Callbacks("memory"),k.Callbacks("memory"),2],["resolve","done",k.Callbacks("once memory"),k.Callbacks("once memory"),0,"resolved"],["reject","fail",k.Callbacks("once memory"),k.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},"catch":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return k.Deferred(function(r){k.each(o,function(e,t){var n=m(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&m(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,m(t)?s?t.call(e,l(u,o,M,s),l(u,o,I,s)):(u++,t.call(e,l(u,o,M,s),l(u,o,I,s),l(u,o,M,o.notifyWith))):(a!==M&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){k.Deferred.exceptionHook&&k.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==I&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(k.Deferred.getStackHook&&(t.stackTrace=k.Deferred.getStackHook()),C.setTimeout(t))}}return k.Deferred(function(e){o[0][3].add(l(0,e,m(r)?r:M,e.notifyWith)),o[1][3].add(l(0,e,m(t)?t:M)),o[2][3].add(l(0,e,m(n)?n:I))}).promise()},promise:function(e){return null!=e?k.extend(e,a):a}},s={};return k.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=s.call(arguments),o=k.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?s.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(W(e,o.done(a(t)).resolve,o.reject,!n),"pending"===o.state()||m(i[t]&&i[t].then)))return o.then();while(t--)W(i[t],a(t),o.reject);return o.promise()}});var $=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;k.Deferred.exceptionHook=function(e,t){C.console&&C.console.warn&&e&&$.test(e.name)&&C.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},k.readyException=function(e){C.setTimeout(function(){throw e})};var F=k.Deferred();function B(){E.removeEventListener("DOMContentLoaded",B),C.removeEventListener("load",B),k.ready()}k.fn.ready=function(e){return F.then(e)["catch"](function(e){k.readyException(e)}),this},k.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--k.readyWait:k.isReady)||(k.isReady=!0)!==e&&0<--k.readyWait||F.resolveWith(E,[k])}}),k.ready.then=F.then,"complete"===E.readyState||"loading"!==E.readyState&&!E.documentElement.doScroll?C.setTimeout(k.ready):(E.addEventListener("DOMContentLoaded",B),C.addEventListener("load",B));var _=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===w(n))for(s in i=!0,n)_(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,m(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(k(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},z=/^-ms-/,U=/-([a-z])/g;function X(e,t){return t.toUpperCase()}function V(e){return e.replace(z,"ms-").replace(U,X)}var G=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function Y(){this.expando=k.expando+Y.uid++}Y.uid=1,Y.prototype={cache:function(e){var t=e[this.expando];return t||(t={},G(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[V(t)]=n;else for(r in t)i[V(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][V(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(V):(t=V(t))in r?[t]:t.match(R)||[]).length;while(n--)delete r[t[n]]}(void 0===t||k.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!k.isEmptyObject(t)}};var Q=new Y,J=new Y,K=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Z=/[A-Z]/g;function ee(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(Z,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:K.test(i)?JSON.parse(i):i)}catch(e){}J.set(e,t,n)}else n=void 0;return n}k.extend({hasData:function(e){return J.hasData(e)||Q.hasData(e)},data:function(e,t,n){return J.access(e,t,n)},removeData:function(e,t){J.remove(e,t)},_data:function(e,t,n){return Q.access(e,t,n)},_removeData:function(e,t){Q.remove(e,t)}}),k.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=J.get(o),1===o.nodeType&&!Q.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=V(r.slice(5)),ee(o,r,i[r]));Q.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof n?this.each(function(){J.set(this,n)}):_(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=J.get(o,n))?t:void 0!==(t=ee(o,n))?t:void 0;this.each(function(){J.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){J.remove(this,e)})}}),k.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Q.get(e,t),n&&(!r||Array.isArray(n)?r=Q.access(e,t,k.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=k.queue(e,t),r=n.length,i=n.shift(),o=k._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){k.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Q.get(e,n)||Q.access(e,n,{empty:k.Callbacks("once memory").add(function(){Q.remove(e,[t+"queue",n])})})}}),k.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?k.queue(this[0],t):void 0===n?this:this.each(function(){var e=k.queue(this,t,n);k._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&k.dequeue(this,t)})},dequeue:function(e){return this.each(function(){k.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=k.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=Q.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var te=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ne=new RegExp("^(?:([+-])=|)("+te+")([a-z%]*)$","i"),re=["Top","Right","Bottom","Left"],ie=E.documentElement,oe=function(e){return k.contains(e.ownerDocument,e)},ae={composed:!0};ie.getRootNode&&(oe=function(e){return k.contains(e.ownerDocument,e)||e.getRootNode(ae)===e.ownerDocument});var se=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&oe(e)&&"none"===k.css(e,"display")},ue=function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];for(o in i=n.apply(e,r||[]),t)e.style[o]=a[o];return i};function le(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return k.css(e,t,"")},u=s(),l=n&&n[3]||(k.cssNumber[t]?"":"px"),c=e.nodeType&&(k.cssNumber[t]||"px"!==l&&+u)&&ne.exec(k.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)k.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,k.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var ce={};function fe(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=Q.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&se(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ce[s])||(o=a.body.appendChild(a.createElement(s)),u=k.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),ce[s]=u)))):"none"!==n&&(l[c]="none",Q.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}k.fn.extend({show:function(){return fe(this,!0)},hide:function(){return fe(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){se(this)?k(this).show():k(this).hide()})}});var pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n<r;n++)Q.set(e[n],"globalEval",!t||Q.get(t[n],"globalEval"))}ge.optgroup=ge.option,ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td;var me,xe,be=/<|&#?\w+;/;function we(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===w(o))k.merge(p,o.nodeType?[o]:o);else if(be.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+k.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;k.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&-1<k.inArray(o,r))i&&i.push(o);else if(l=oe(o),a=ve(f.appendChild(o),"script"),l&&ye(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}me=E.createDocumentFragment().appendChild(E.createElement("div")),(xe=E.createElement("input")).setAttribute("type","radio"),xe.setAttribute("checked","checked"),xe.setAttribute("name","t"),me.appendChild(xe),y.checkClone=me.cloneNode(!0).cloneNode(!0).lastChild.checked,me.innerHTML="<textarea>x</textarea>",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t<arguments.length;t++)u[t]=arguments[t];if(s.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,s)){a=k.event.handlers.call(this,s,l),t=0;while((i=a[t++])&&!s.isPropagationStopped()){s.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!s.isImmediatePropagationStopped())s.rnamespace&&!1!==o.namespace&&!s.rnamespace.test(o.namespace)||(s.handleObj=o,s.data=o.data,void 0!==(r=((k.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,u))&&!1===(s.result=r)&&(s.preventDefault(),s.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,s),s.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<k(i,this).index(l):k.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(k.Event.prototype,t,{enumerable:!0,configurable:!0,get:m(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[k.expando]?e:new k.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&De(t,"click",ke),!1},trigger:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&De(t,"click"),!0},_default:function(e){var t=e.target;return pe.test(t.type)&&t.click&&A(t,"input")&&Q.get(t,"click")||A(t,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},k.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},k.Event=function(e,t){if(!(this instanceof k.Event))return new k.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?ke:Se,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&k.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[k.expando]=!0},k.Event.prototype={constructor:k.Event,isDefaultPrevented:Se,isPropagationStopped:Se,isImmediatePropagationStopped:Se,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=ke,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=ke,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=ke,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},k.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&Te.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&Ce.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},k.event.addProp),k.each({focus:"focusin",blur:"focusout"},function(e,t){k.event.special[e]={setup:function(){return De(this,e,Ne),!1},trigger:function(){return De(this,e),!0},delegateType:t}}),k.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){k.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||k.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),k.fn.extend({on:function(e,t,n,r){return Ae(this,e,t,n,r)},one:function(e,t,n,r){return Ae(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,k(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=Se),this.each(function(){k.event.remove(this,e,n,t)})}});var je=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/<script|<style|<link/i,Le=/checked\s*(?:[^=]|=\s*.checked.)/i,He=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n<r;n++)k.event.add(t,i,l[i][n]);J.hasData(e)&&(s=J.access(e),u=k.extend({},s),J.set(t,u))}}function Ie(n,r,i,o){r=g.apply([],r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=m(d);if(h||1<f&&"string"==typeof d&&!y.checkClone&&Le.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),Ie(t,r,i,o)});if(f&&(t=(e=we(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=k.map(ve(e,"script"),Pe)).length;c<f;c++)u=e,c!==p&&(u=k.clone(u,!0,!0),s&&k.merge(a,ve(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,k.map(a,Re),c=0;c<s;c++)u=a[c],he.test(u.type||"")&&!Q.access(u,"globalEval")&&k.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?k._evalUrl&&!u.noModule&&k._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")}):b(u.textContent.replace(He,""),u,l))}return n}function We(e,t,n){for(var r,i=t?k.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||k.cleanData(ve(r)),r.parentNode&&(n&&oe(r)&&ye(ve(r,"script")),r.parentNode.removeChild(r));return e}k.extend({htmlPrefilter:function(e){return e.replace(je,"<$1></$2>")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r<i;r++)s=o[r],u=a[r],void 0,"input"===(l=u.nodeName.toLowerCase())&&pe.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||ve(e),a=a||ve(c),r=0,i=o.length;r<i;r++)Me(o[r],a[r]);else Me(e,c);return 0<(a=ve(c,"script")).length&&ye(a,!f&&ve(e,"script")),c},cleanData:function(e){for(var t,n,r,i=k.event.special,o=0;void 0!==(n=e[o]);o++)if(G(n)){if(t=n[Q.expando]){if(t.events)for(r in t.events)i[r]?k.event.remove(n,r):k.removeEvent(n,r,t.handle);n[Q.expando]=void 0}n[J.expando]&&(n[J.expando]=void 0)}}}),k.fn.extend({detach:function(e){return We(this,e,!0)},remove:function(e){return We(this,e)},text:function(e){return _(this,function(e){return void 0===e?k.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Ie(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Oe(this,e).appendChild(e)})},prepend:function(){return Ie(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Oe(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Ie(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Ie(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(k.cleanData(ve(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return k.clone(this,e,t)})},html:function(e){return _(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!qe.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=k.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(k.cleanData(ve(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return Ie(this,arguments,function(e){var t=this.parentNode;k.inArray(this,n)<0&&(k.cleanData(ve(this)),t&&t.replaceChild(e,this))},n)}}),k.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){k.fn[e]=function(e){for(var t,n=[],r=k(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),k(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var $e=new RegExp("^("+te+")(?!px)[a-z%]+$","i"),Fe=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},Be=new RegExp(re.join("|"),"i");function _e(e,t,n){var r,i,o,a,s=e.style;return(n=n||Fe(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||oe(e)||(a=k.style(e,t)),!y.pixelBoxStyles()&&$e.test(a)&&Be.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function ze(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(u){s.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",u.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",ie.appendChild(s).appendChild(u);var e=C.getComputedStyle(u);n="1%"!==e.top,a=12===t(e.marginLeft),u.style.right="60%",o=36===t(e.right),r=36===t(e.width),u.style.position="absolute",i=12===t(u.offsetWidth/3),ie.removeChild(s),u=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s=E.createElement("div"),u=E.createElement("div");u.style&&(u.style.backgroundClip="content-box",u.cloneNode(!0).style.backgroundClip="",y.clearCloneStyle="content-box"===u.style.backgroundClip,k.extend(y,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),a},scrollboxSize:function(){return e(),i}}))}();var Ue=["Webkit","Moz","ms"],Xe=E.createElement("div").style,Ve={};function Ge(e){var t=k.cssProps[e]||Ve[e];return t||(e in Xe?e:Ve[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=Ue.length;while(n--)if((e=Ue[n]+t)in Xe)return e}(e)||e)}var Ye=/^(none|table(?!-c[ea]).+)/,Qe=/^--/,Je={position:"absolute",visibility:"hidden",display:"block"},Ke={letterSpacing:"0",fontWeight:"400"};function Ze(e,t,n){var r=ne.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function et(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=k.css(e,n+re[a],!0,i)),r?("content"===n&&(u-=k.css(e,"padding"+re[a],!0,i)),"margin"!==n&&(u-=k.css(e,"border"+re[a]+"Width",!0,i))):(u+=k.css(e,"padding"+re[a],!0,i),"padding"!==n?u+=k.css(e,"border"+re[a]+"Width",!0,i):s+=k.css(e,"border"+re[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function tt(e,t,n){var r=Fe(e),i=(!y.boxSizingReliable()||n)&&"border-box"===k.css(e,"boxSizing",!1,r),o=i,a=_e(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if($e.test(a)){if(!n)return a;a="auto"}return(!y.boxSizingReliable()&&i||"auto"===a||!parseFloat(a)&&"inline"===k.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===k.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+et(e,t,n||(i?"border":"content"),o,r,a)+"px"}function nt(e,t,n,r,i){return new nt.prototype.init(e,t,n,r,i)}k.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=_e(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=V(t),u=Qe.test(t),l=e.style;if(u||(t=Ge(s)),a=k.cssHooks[t]||k.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=ne.exec(n))&&i[1]&&(n=le(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(k.cssNumber[s]?"":"px")),y.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=V(t);return Qe.test(t)||(t=Ge(s)),(a=k.cssHooks[t]||k.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=_e(e,t,r)),"normal"===i&&t in Ke&&(i=Ke[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),k.each(["height","width"],function(e,u){k.cssHooks[u]={get:function(e,t,n){if(t)return!Ye.test(k.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?tt(e,u,n):ue(e,Je,function(){return tt(e,u,n)})},set:function(e,t,n){var r,i=Fe(e),o=!y.scrollboxSize()&&"absolute"===i.position,a=(o||n)&&"border-box"===k.css(e,"boxSizing",!1,i),s=n?et(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e["offset"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-et(e,u,"border",!1,i)-.5)),s&&(r=ne.exec(t))&&"px"!==(r[3]||"px")&&(e.style[u]=t,t=k.css(e,u)),Ze(0,t,s)}}}),k.cssHooks.marginLeft=ze(y.reliableMarginLeft,function(e,t){if(t)return(parseFloat(_e(e,"marginLeft"))||e.getBoundingClientRect().left-ue(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),k.each({margin:"",padding:"",border:"Width"},function(i,o){k.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+re[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(k.cssHooks[i+o].set=Ze)}),k.fn.extend({css:function(e,t){return _(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Fe(e),i=t.length;a<i;a++)o[t[a]]=k.css(e,t[a],!1,r);return o}return void 0!==n?k.style(e,t,n):k.css(e,t)},e,t,1<arguments.length)}}),((k.Tween=nt).prototype={constructor:nt,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||k.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(k.cssNumber[n]?"":"px")},cur:function(){var e=nt.propHooks[this.prop];return e&&e.get?e.get(this):nt.propHooks._default.get(this)},run:function(e){var t,n=nt.propHooks[this.prop];return this.options.duration?this.pos=t=k.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):nt.propHooks._default.set(this),this}}).init.prototype=nt.prototype,(nt.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=k.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){k.fx.step[e.prop]?k.fx.step[e.prop](e):1!==e.elem.nodeType||!k.cssHooks[e.prop]&&null==e.elem.style[Ge(e.prop)]?e.elem[e.prop]=e.now:k.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=nt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},k.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},k.fx=nt.prototype.init,k.fx.step={};var rt,it,ot,at,st=/^(?:toggle|show|hide)$/,ut=/queueHooks$/;function lt(){it&&(!1===E.hidden&&C.requestAnimationFrame?C.requestAnimationFrame(lt):C.setTimeout(lt,k.fx.interval),k.fx.tick())}function ct(){return C.setTimeout(function(){rt=void 0}),rt=Date.now()}function ft(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=re[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function pt(e,t,n){for(var r,i=(dt.tweeners[t]||[]).concat(dt.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function dt(o,e,t){var n,a,r=0,i=dt.prefilters.length,s=k.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=rt||ct(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:k.extend({},e),opts:k.extend(!0,{specialEasing:{},easing:k.easing._default},t),originalProperties:e,originalOptions:t,startTime:rt||ct(),duration:t.duration,tweens:[],createTween:function(e,t){var n=k.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=V(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=k.cssHooks[r])&&"expand"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=dt.prefilters[r].call(l,o,c,l.opts))return m(n.stop)&&(k._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return k.map(c,pt,l),m(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),k.fx.timer(k.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}k.Animation=k.extend(dt,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return le(n.elem,e,ne.exec(t),n),n}]},tweener:function(e,t){m(e)?(t=e,e=["*"]):e=e.match(R);for(var n,r=0,i=e.length;r<i;r++)n=e[r],dt.tweeners[n]=dt.tweeners[n]||[],dt.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&se(e),v=Q.get(e,"fxshow");for(r in n.queue||(null==(a=k._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,k.queue(e,"fx").length||a.empty.fire()})})),t)if(i=t[r],st.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||k.style(e,r)}if((u=!k.isEmptyObject(t))||!k.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=v&&v.display)&&(l=Q.get(e,"display")),"none"===(c=k.css(e,"display"))&&(l?c=l:(fe([e],!0),l=e.style.display||l,c=k.css(e,"display"),fe([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===k.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(v?"hidden"in v&&(g=v.hidden):v=Q.access(e,"fxshow",{display:l}),o&&(v.hidden=!g),g&&fe([e],!0),p.done(function(){for(r in g||fe([e]),Q.remove(e,"fxshow"),d)k.style(e,r,d[r])})),u=pt(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?dt.prefilters.unshift(e):dt.prefilters.push(e)}}),k.speed=function(e,t,n){var r=e&&"object"==typeof e?k.extend({},e):{complete:n||!n&&t||m(e)&&e,duration:e,easing:n&&t||t&&!m(t)&&t};return k.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in k.fx.speeds?r.duration=k.fx.speeds[r.duration]:r.duration=k.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){m(r.old)&&r.old.call(this),r.queue&&k.dequeue(this,r.queue)},r},k.fn.extend({fadeTo:function(e,t,n,r){return this.filter(se).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=k.isEmptyObject(t),o=k.speed(e,n,r),a=function(){var e=dt(this,k.extend({},t),o);(i||Q.get(this,"finish"))&&e.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(i,e,o){var a=function(e){var t=e.stop;delete e.stop,t(o)};return"string"!=typeof i&&(o=e,e=i,i=void 0),e&&!1!==i&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=k.timers,r=Q.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&ut.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||k.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=Q.get(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=k.timers,o=n?n.length:0;for(t.finish=!0,k.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),k.each(["toggle","show","hide"],function(e,r){var i=k.fn[r];k.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(ft(r,!0),e,t,n)}}),k.each({slideDown:ft("show"),slideUp:ft("hide"),slideToggle:ft("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){k.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),k.timers=[],k.fx.tick=function(){var e,t=0,n=k.timers;for(rt=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||k.fx.stop(),rt=void 0},k.fx.timer=function(e){k.timers.push(e),k.fx.start()},k.fx.interval=13,k.fx.start=function(){it||(it=!0,lt())},k.fx.stop=function(){it=null},k.fx.speeds={slow:600,fast:200,_default:400},k.fn.delay=function(r,e){return r=k.fx&&k.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=C.setTimeout(e,r);t.stop=function(){C.clearTimeout(n)}})},ot=E.createElement("input"),at=E.createElement("select").appendChild(E.createElement("option")),ot.type="checkbox",y.checkOn=""!==ot.value,y.optSelected=at.selected,(ot=E.createElement("input")).value="t",ot.type="radio",y.radioValue="t"===ot.value;var ht,gt=k.expr.attrHandle;k.fn.extend({attr:function(e,t){return _(this,k.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){k.removeAttr(this,e)})}}),k.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?k.prop(e,t,n):(1===o&&k.isXMLDoc(e)||(i=k.attrHooks[t.toLowerCase()]||(k.expr.match.bool.test(t)?ht:void 0)),void 0!==n?null===n?void k.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=k.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!y.radioValue&&"radio"===t&&A(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(R);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),ht={set:function(e,t,n){return!1===t?k.removeAttr(e,n):e.setAttribute(n,n),n}},k.each(k.expr.match.bool.source.match(/\w+/g),function(e,t){var a=gt[t]||k.find.attr;gt[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=gt[o],gt[o]=r,r=null!=a(e,t,n)?o:null,gt[o]=i),r}});var vt=/^(?:input|select|textarea|button)$/i,yt=/^(?:a|area)$/i;function mt(e){return(e.match(R)||[]).join(" ")}function xt(e){return e.getAttribute&&e.getAttribute("class")||""}function bt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(R)||[]}k.fn.extend({prop:function(e,t){return _(this,k.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[k.propFix[e]||e]})}}),k.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&k.isXMLDoc(e)||(t=k.propFix[t]||t,i=k.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=k.find.attr(e,"tabindex");return t?parseInt(t,10):vt.test(e.nodeName)||yt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),y.optSelected||(k.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),k.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){k.propFix[this.toLowerCase()]=this}),k.fn.extend({addClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){k(this).addClass(t.call(this,e,xt(this)))});if((e=bt(t)).length)while(n=this[u++])if(i=xt(n),r=1===n.nodeType&&" "+mt(i)+" "){a=0;while(o=e[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=mt(r))&&n.setAttribute("class",s)}return this},removeClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){k(this).removeClass(t.call(this,e,xt(this)))});if(!arguments.length)return this.attr("class","");if((e=bt(t)).length)while(n=this[u++])if(i=xt(n),r=1===n.nodeType&&" "+mt(i)+" "){a=0;while(o=e[a++])while(-1<r.indexOf(" "+o+" "))r=r.replace(" "+o+" "," ");i!==(s=mt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(i,t){var o=typeof i,a="string"===o||Array.isArray(i);return"boolean"==typeof t&&a?t?this.addClass(i):this.removeClass(i):m(i)?this.each(function(e){k(this).toggleClass(i.call(this,e,xt(this),t),t)}):this.each(function(){var e,t,n,r;if(a){t=0,n=k(this),r=bt(i);while(e=r[t++])n.hasClass(e)?n.removeClass(e):n.addClass(e)}else void 0!==i&&"boolean"!==o||((e=xt(this))&&Q.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||!1===i?"":Q.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&-1<(" "+mt(xt(n))+" ").indexOf(t))return!0;return!1}});var wt=/\r/g;k.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=m(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,k(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=k.map(t,function(e){return null==e?"":e+""})),(r=k.valHooks[this.type]||k.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=k.valHooks[t.type]||k.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(wt,""):null==e?"":e:void 0}}),k.extend({valHooks:{option:{get:function(e){var t=k.find.attr(e,"value");return null!=t?t:mt(k.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!A(n.parentNode,"optgroup"))){if(t=k(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=k.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<k.inArray(k.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),k.each(["radio","checkbox"],function(){k.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<k.inArray(k(e).val(),t)}},y.checkOn||(k.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),y.focusin="onfocusin"in C;var Tt=/^(?:focusinfocus|focusoutblur)$/,Ct=function(e){e.stopPropagation()};k.extend(k.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,p=[n||E],d=v.call(e,"type")?e.type:e,h=v.call(e,"namespace")?e.namespace.split("."):[];if(o=f=a=n=n||E,3!==n.nodeType&&8!==n.nodeType&&!Tt.test(d+k.event.triggered)&&(-1<d.indexOf(".")&&(d=(h=d.split(".")).shift(),h.sort()),u=d.indexOf(":")<0&&"on"+d,(e=e[k.expando]?e:new k.Event(d,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:k.makeArray(t,[e]),c=k.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!x(n)){for(s=c.delegateType||d,Tt.test(s+d)||(o=o.parentNode);o;o=o.parentNode)p.push(o),a=o;a===(n.ownerDocument||E)&&p.push(a.defaultView||a.parentWindow||C)}i=0;while((o=p[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||d,(l=(Q.get(o,"events")||{})[e.type]&&Q.get(o,"handle"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&G(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=d,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(p.pop(),t)||!G(n)||u&&m(n[d])&&!x(n)&&((a=n[u])&&(n[u]=null),k.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,Ct),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,Ct),k.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=k.extend(new k.Event,n,{type:e,isSimulated:!0});k.event.trigger(r,null,t)}}),k.fn.extend({trigger:function(e,t){return this.each(function(){k.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return k.event.trigger(e,t,n,!0)}}),y.focusin||k.each({focus:"focusin",blur:"focusout"},function(n,r){var i=function(e){k.event.simulate(r,e.target,k.event.fix(e))};k.event.special[r]={setup:function(){var e=this.ownerDocument||this,t=Q.access(e,r);t||e.addEventListener(n,i,!0),Q.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this,t=Q.access(e,r)-1;t?Q.access(e,r,t):(e.removeEventListener(n,i,!0),Q.remove(e,r))}}});var Et=C.location,kt=Date.now(),St=/\?/;k.parseXML=function(e){var t;if(!e||"string"!=typeof e)return null;try{t=(new C.DOMParser).parseFromString(e,"text/xml")}catch(e){t=void 0}return t&&!t.getElementsByTagName("parsererror").length||k.error("Invalid XML: "+e),t};var Nt=/\[\]$/,At=/\r?\n/g,Dt=/^(?:submit|button|image|reset|file)$/i,jt=/^(?:input|select|textarea|keygen)/i;function qt(n,e,r,i){var t;if(Array.isArray(e))k.each(e,function(e,t){r||Nt.test(n)?i(n,t):qt(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==w(e))i(n,e);else for(t in e)qt(n+"["+t+"]",e[t],r,i)}k.param=function(e,t){var n,r=[],i=function(e,t){var n=m(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!k.isPlainObject(e))k.each(e,function(){i(this.name,this.value)});else for(n in e)qt(n,e[n],t,i);return r.join("&")},k.fn.extend({serialize:function(){return k.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=k.prop(this,"elements");return e?k.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!k(this).is(":disabled")&&jt.test(this.nodeName)&&!Dt.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=k(this).val();return null==n?null:Array.isArray(n)?k.map(n,function(e){return{name:t.name,value:e.replace(At,"\r\n")}}):{name:t.name,value:n.replace(At,"\r\n")}}).get()}});var Lt=/%20/g,Ht=/#.*$/,Ot=/([?&])_=[^&]*/,Pt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Rt=/^(?:GET|HEAD)$/,Mt=/^\/\//,It={},Wt={},$t="*/".concat("*"),Ft=E.createElement("a");function Bt(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(R)||[];if(m(t))while(n=i[r++])"+"===n[0]?(n=n.slice(1)||"*",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function _t(t,i,o,a){var s={},u=t===Wt;function l(e){var r;return s[e]=!0,k.each(t[e]||[],function(e,t){var n=t(i,o,a);return"string"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s["*"]&&l("*")}function zt(e,t){var n,r,i=k.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&k.extend(!0,e,r),e}Ft.href=Et.href,k.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Et.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Et.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":$t,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":k.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?zt(zt(e,k.ajaxSettings),t):zt(k.ajaxSettings,e)},ajaxPrefilter:Bt(It),ajaxTransport:Bt(Wt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,v=k.ajaxSetup({},t),y=v.context||v,m=v.context&&(y.nodeType||y.jquery)?k(y):k.event,x=k.Deferred(),b=k.Callbacks("once memory"),w=v.statusCode||{},a={},s={},u="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n){n={};while(t=Pt.exec(p))n[t[1].toLowerCase()+" "]=(n[t[1].toLowerCase()+" "]||[]).concat(t[2])}t=n[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(v.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),v.url=((e||v.url||Et.href)+"").replace(Mt,Et.protocol+"//"),v.type=t.method||t.type||v.method||v.type,v.dataTypes=(v.dataType||"*").toLowerCase().match(R)||[""],null==v.crossDomain){r=E.createElement("a");try{r.href=v.url,r.href=r.href,v.crossDomain=Ft.protocol+"//"+Ft.host!=r.protocol+"//"+r.host}catch(e){v.crossDomain=!0}}if(v.data&&v.processData&&"string"!=typeof v.data&&(v.data=k.param(v.data,v.traditional)),_t(It,v,t,T),h)return T;for(i in(g=k.event&&v.global)&&0==k.active++&&k.event.trigger("ajaxStart"),v.type=v.type.toUpperCase(),v.hasContent=!Rt.test(v.type),f=v.url.replace(Ht,""),v.hasContent?v.data&&v.processData&&0===(v.contentType||"").indexOf("application/x-www-form-urlencoded")&&(v.data=v.data.replace(Lt,"+")):(o=v.url.slice(f.length),v.data&&(v.processData||"string"==typeof v.data)&&(f+=(St.test(f)?"&":"?")+v.data,delete v.data),!1===v.cache&&(f=f.replace(Ot,"$1"),o=(St.test(f)?"&":"?")+"_="+kt+++o),v.url=f+o),v.ifModified&&(k.lastModified[f]&&T.setRequestHeader("If-Modified-Since",k.lastModified[f]),k.etag[f]&&T.setRequestHeader("If-None-Match",k.etag[f])),(v.data&&v.hasContent&&!1!==v.contentType||t.contentType)&&T.setRequestHeader("Content-Type",v.contentType),T.setRequestHeader("Accept",v.dataTypes[0]&&v.accepts[v.dataTypes[0]]?v.accepts[v.dataTypes[0]]+("*"!==v.dataTypes[0]?", "+$t+"; q=0.01":""):v.accepts["*"]),v.headers)T.setRequestHeader(i,v.headers[i]);if(v.beforeSend&&(!1===v.beforeSend.call(y,T,v)||h))return T.abort();if(u="abort",b.add(v.complete),T.done(v.success),T.fail(v.error),c=_t(Wt,v,t,T)){if(T.readyState=1,g&&m.trigger("ajaxSend",[T,v]),h)return T;v.async&&0<v.timeout&&(d=C.setTimeout(function(){T.abort("timeout")},v.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,"No Transport");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&C.clearTimeout(d),c=void 0,p=r||"",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(v,T,n)),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(v,s,T,i),i?(v.ifModified&&((u=T.getResponseHeader("Last-Modified"))&&(k.lastModified[f]=u),(u=T.getResponseHeader("etag"))&&(k.etag[f]=u)),204===e||"HEAD"===v.type?l="nocontent":304===e?l="notmodified":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l="error",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+"",i?x.resolveWith(y,[o,l,T]):x.rejectWith(y,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?"ajaxSuccess":"ajaxError",[T,v,i?o:a]),b.fireWith(y,[T,l]),g&&(m.trigger("ajaxComplete",[T,v]),--k.active||k.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return k.get(e,t,n,"json")},getScript:function(e,t){return k.get(e,void 0,t,"script")}}),k.each(["get","post"],function(e,i){k[i]=function(e,t,n,r){return m(t)&&(r=r||n,n=t,t=void 0),k.ajax(k.extend({url:e,type:i,dataType:r,data:t,success:n},k.isPlainObject(e)&&e))}}),k._evalUrl=function(e,t){return k.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){k.globalEval(e,t)}})},k.fn.extend({wrapAll:function(e){var t;return this[0]&&(m(e)&&(e=e.call(this[0])),t=k(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return m(n)?this.each(function(e){k(this).wrapInner(n.call(this,e))}):this.each(function(){var e=k(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=m(t);return this.each(function(e){k(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){k(this).replaceWith(this.childNodes)}),this}}),k.expr.pseudos.hidden=function(e){return!k.expr.pseudos.visible(e)},k.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},k.ajaxSettings.xhr=function(){try{return new C.XMLHttpRequest}catch(e){}};var Ut={0:200,1223:204},Xt=k.ajaxSettings.xhr();y.cors=!!Xt&&"withCredentials"in Xt,y.ajax=Xt=!!Xt,k.ajaxTransport(function(i){var o,a;if(y.cors||Xt&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,"abort"===e?r.abort():"error"===e?"number"!=typeof r.status?t(0,"error"):t(r.status,r.statusText):t(Ut[r.status]||r.status,r.statusText,"text"!==(r.responseType||"text")||"string"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o("error"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&C.setTimeout(function(){o&&a()})},o=o("abort");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),k.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),k.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return k.globalEval(e),e}}}),k.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),k.ajaxTransport("script",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=k("<script>").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=mt(e.slice(s)),e=e.slice(0,s)),m(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&k.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?k("<div>").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}}),k.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),k.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}}),k.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),m(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||k.guid++,i},k.holdReady=function(e){e?k.readyWait++:k.ready(!0)},k.isArray=Array.isArray,k.parseJSON=JSON.parse,k.nodeName=A,k.isFunction=m,k.isWindow=x,k.camelCase=V,k.type=w,k.now=Date.now,k.isNumeric=function(e){var t=k.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},"function"==typeof define&&define.amd&&define("jquery",[],function(){return k});var Qt=C.jQuery,Jt=C.$;return k.noConflict=function(e){return C.$===k&&(C.$=Jt),e&&C.jQuery===k&&(C.jQuery=Qt),k},e||(C.jQuery=C.$=k),k});
|
|
|
|
include/class-address.php
CHANGED
@@ -1,402 +1,404 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
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 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
if ( PW()->get_options( '
|
66 |
-
|
67 |
-
if ( ( $class = array( 'first', 'last' ) ) && PW()->get_options( 'flip_state_city' ) == 'yes' ) {
|
68 |
-
$class = array_reverse( $class );
|
69 |
-
}
|
70 |
-
$this->class = array( 'state' => $class[0], 'city' => $class[1] );
|
71 |
-
|
72 |
-
add_filter( 'woocommerce_checkout_fields', array( $this, 'checkout_fields' ) );
|
73 |
-
add_filter( 'woocommerce_billing_fields', array( $this, 'billing_fields' ) );
|
74 |
-
add_filter( 'woocommerce_shipping_fields', array( $this, 'shipping_fields' ) );
|
75 |
-
|
76 |
-
add_filter( 'woocommerce_form_field_billing_iran_cities', array( $this, 'iran_cities_field' ), 11, 4 );
|
77 |
-
add_filter( 'woocommerce_form_field_shipping_iran_cities', array( $this, 'iran_cities_field' ), 11, 4 );
|
78 |
-
|
79 |
-
add_action( 'wp_enqueue_scripts', array( $this, 'external_js' ) );
|
80 |
-
add_action( 'wp_footer', array( $this, 'inline_js' ), 0 );
|
81 |
-
add_action( 'wp_footer', array( $this, 'force_inline_js' ), 999999 );
|
82 |
}
|
83 |
-
|
84 |
-
|
85 |
-
public function locales( $locales ) {
|
86 |
-
$locales[ $this->country ] = array(
|
87 |
-
'state' => array( 'label' => __( 'Province', 'woocommerce' ) ),
|
88 |
-
'postcode' => array( 'label' => __( 'Postcode', 'woocommerce' ) )
|
89 |
-
);
|
90 |
|
91 |
-
|
92 |
-
|
|
|
93 |
|
94 |
-
|
95 |
-
|
96 |
|
97 |
-
|
|
|
|
|
98 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
|
100 |
-
|
|
|
101 |
|
102 |
-
|
|
|
103 |
|
104 |
-
|
105 |
-
|
106 |
-
}
|
107 |
|
108 |
-
|
109 |
|
110 |
-
|
111 |
-
$states[ $this->country ] = array_intersect_key( $this->states, array_flip( $selections ) );
|
112 |
-
}
|
113 |
|
|
|
114 |
return $states;
|
115 |
}
|
116 |
|
117 |
-
|
118 |
-
public function checkout_fields( $fields ) {
|
119 |
|
120 |
-
|
|
|
|
|
121 |
|
122 |
-
|
123 |
-
|
124 |
-
foreach ( $types as $type ) {
|
125 |
|
126 |
-
|
127 |
-
|
128 |
-
}
|
129 |
|
130 |
-
|
131 |
-
$fields[ $type ][ $type . '_state' ] = $this->modify_state_field( $fields[ $type ][ $type . '_state' ], $type );
|
132 |
-
}
|
133 |
-
}
|
134 |
-
}
|
135 |
|
136 |
-
|
137 |
-
}
|
138 |
|
139 |
-
|
140 |
|
141 |
-
|
142 |
-
|
143 |
-
if ( ! empty( $fields[ $type . '_city' ] ) ) {
|
144 |
-
$fields[ $type . '_city' ] = $this->modify_city_field( $fields[ $type . '_city' ], $type );
|
145 |
}
|
146 |
-
|
147 |
-
|
|
|
148 |
}
|
149 |
}
|
150 |
-
|
151 |
-
return $fields;
|
152 |
}
|
153 |
|
154 |
-
|
|
|
155 |
|
156 |
-
|
157 |
-
$type = 'shipping';
|
158 |
-
if ( ! empty( $fields[ $type . '_city' ] ) ) {
|
159 |
-
$fields[ $type . '_city' ] = $this->modify_city_field( $fields[ $type . '_city' ], $type );
|
160 |
-
}
|
161 |
-
if ( ! empty( $fields[ $type . '_state' ] ) ) {
|
162 |
-
$fields[ $type . '_state' ] = $this->modify_state_field( $fields[ $type . '_state' ], $type );
|
163 |
-
}
|
164 |
-
}
|
165 |
|
166 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
167 |
}
|
168 |
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
174 |
}
|
175 |
-
|
|
|
|
|
|
|
176 |
|
177 |
-
|
|
|
|
|
|
|
|
|
178 |
}
|
|
|
179 |
|
180 |
-
|
181 |
-
|
182 |
-
if ( ! empty( $fields['class'] ) && $classes = $fields['class'] ) {
|
183 |
-
$classes = is_array( $classes ) ? implode( ',', $classes ) : $classes;
|
184 |
-
$classes = str_ireplace( 'form-row-wide', 'form-row-' . $this->class['city'], $classes );
|
185 |
-
}
|
186 |
-
$fields['class'] = apply_filters( $type . '_iran_city_class', explode( ',', $classes ), $fields, $type );
|
187 |
-
$fields['type'] = apply_filters( $type . '_iran_city_type', $type . '_iran_cities', $fields, $type );
|
188 |
-
$fields['options'] = apply_filters( $type . '_iran_city_options', array( '' => '' ), $fields, $type );
|
189 |
|
190 |
-
|
|
|
|
|
|
|
|
|
191 |
}
|
|
|
|
|
|
|
192 |
|
193 |
-
|
|
|
194 |
|
195 |
-
|
196 |
-
if ( ! empty( $value ) ) {
|
197 |
-
$this->selected_city[] = $value . '_vsh_' . $type[0];
|
198 |
-
}
|
199 |
|
200 |
-
|
|
|
|
|
|
|
201 |
|
202 |
-
|
203 |
-
if ( is_string( $args['label_class'] ) ) {
|
204 |
-
$args['label_class'] = array( $args['label_class'] );
|
205 |
-
}
|
206 |
|
207 |
-
|
208 |
-
|
209 |
-
|
|
|
210 |
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
|
|
|
|
|
|
220 |
}
|
|
|
221 |
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
}
|
226 |
}
|
|
|
227 |
|
228 |
-
|
229 |
|
230 |
-
|
231 |
-
|
232 |
|
233 |
-
|
234 |
|
235 |
-
|
236 |
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
|
241 |
-
|
242 |
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
|
247 |
-
|
248 |
-
|
249 |
|
250 |
-
|
251 |
|
252 |
-
|
253 |
|
254 |
-
|
255 |
-
|
256 |
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
|
262 |
-
|
263 |
-
|
264 |
-
}
|
265 |
}
|
|
|
266 |
|
267 |
-
|
268 |
-
|
269 |
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
|
278 |
-
|
279 |
-
}
|
280 |
}
|
|
|
281 |
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
$selected_value = $type . '_iran_cities_selected_value';
|
293 |
-
global ${$selected_value};
|
294 |
-
$value = ! empty( ${$selected_value} ) ? ${$selected_value} : '';
|
295 |
-
$placeholder = isset( $this->fields[ $type ][ $type . '_city' ]['placeholder'] ) ? $this->fields[ $type ][ $type . '_city' ]['placeholder'] : __( 'City', 'woocommerce' );
|
296 |
|
297 |
-
|
298 |
-
$countries = WC()->countries->$countries();
|
299 |
-
$iran_exist = isset( $countries[ strtoupper( $this->country ) ] ) || isset( $countries[ strtolower( $this->country ) ] ) || isset( $countries[ ucfirst( $this->country ) ] ) ? 'yes' : 'no';
|
300 |
-
$just_iran = count( $countries ) == 1 && $iran_exist == 'yes' ? 'yes' : 'no';
|
301 |
-
?>
|
302 |
|
303 |
-
|
304 |
-
|
|
|
|
|
305 |
|
306 |
-
|
|
|
|
|
|
|
|
|
307 |
|
308 |
-
|
|
|
309 |
|
310 |
-
|
311 |
-
<?php echo $type; ?>_cities[0] = new Array('خطا در دریافت شهرها', '0');
|
312 |
|
313 |
-
|
314 |
-
<?php echo $type; ?>_cities = Persian_Woo_iranCities('' + $('#<?php echo $type; ?>_state').val() + '');
|
315 |
-
else {
|
316 |
-
alert('تابع مربوط به شهرهای ایران یافت نمیشود. با مدیریت در میان بگذارید.');
|
317 |
-
}
|
318 |
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
|
|
|
|
|
|
341 |
}
|
342 |
-
|
343 |
}
|
344 |
-
|
345 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
346 |
|
347 |
-
|
348 |
-
|
349 |
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
|
367 |
-
|
368 |
-
|
369 |
$('#" . $type . "_state').select2();" );
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
$('#' + type + '_state').val('').trigger("change");
|
379 |
-
$('#' + type + '_city').val('').trigger("change");
|
380 |
-
}
|
381 |
-
}
|
382 |
-
else {
|
383 |
-
$('#' + type + '_city_field').find('*').not('label').remove();
|
384 |
-
$('#' + type + '_city_field').append(eval(type + '_city_input'));
|
385 |
$('#' + type + '_state').val('').trigger("change");
|
386 |
$('#' + type + '_city').val('').trigger("change");
|
387 |
}
|
|
|
|
|
|
|
|
|
|
|
388 |
}
|
|
|
389 |
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
}
|
399 |
}
|
400 |
}
|
401 |
-
|
|
|
402 |
PW()->address = new Persian_Woocommerce_Address();
|
1 |
+
<?php
|
2 |
+
|
3 |
+
defined( 'ABSPATH' ) || exit;
|
4 |
+
|
5 |
+
class Persian_Woocommerce_Address extends Persian_Woocommerce_Core {
|
6 |
+
|
7 |
+
//public
|
8 |
+
public $country, $states, $class;
|
9 |
+
|
10 |
+
//private
|
11 |
+
private $fields = [];
|
12 |
+
|
13 |
+
private $selected_city = [];
|
14 |
+
|
15 |
+
//private static
|
16 |
+
private static $action_priority = 0;
|
17 |
+
|
18 |
+
private static $iran_cities_page = false;
|
19 |
+
|
20 |
+
private static $inline_script_printed = false;
|
21 |
+
|
22 |
+
public function __construct() {
|
23 |
+
|
24 |
+
$this->country = 'IR';
|
25 |
+
$this->states = [
|
26 |
+
'ABZ' => 'البرز',
|
27 |
+
'ADL' => 'اردبیل',
|
28 |
+
'EAZ' => 'آذربایجان شرقی',
|
29 |
+
'WAZ' => 'آذربایجان غربی',
|
30 |
+
'BHR' => 'بوشهر',
|
31 |
+
'CHB' => 'چهارمحال و بختیاری',
|
32 |
+
'FRS' => 'فارس',
|
33 |
+
'GIL' => 'گیلان',
|
34 |
+
'GLS' => 'گلستان',
|
35 |
+
'HDN' => 'همدان',
|
36 |
+
'HRZ' => 'هرمزگان',
|
37 |
+
'ILM' => 'ایلام',
|
38 |
+
'ESF' => 'اصفهان',
|
39 |
+
'KRN' => 'کرمان',
|
40 |
+
'KRH' => 'کرمانشاه',
|
41 |
+
'NKH' => 'خراسان شمالی',
|
42 |
+
'RKH' => 'خراسان رضوی',
|
43 |
+
'SKH' => 'خراسان جنوبی',
|
44 |
+
'KHZ' => 'خوزستان',
|
45 |
+
'KBD' => 'کهگیلویه و بویراحمد',
|
46 |
+
'KRD' => 'کردستان',
|
47 |
+
'LRS' => 'لرستان',
|
48 |
+
'MKZ' => 'مرکزی',
|
49 |
+
'MZN' => 'مازندران',
|
50 |
+
'GZN' => 'قزوین',
|
51 |
+
'QHM' => 'قم',
|
52 |
+
'SMN' => 'سمنان',
|
53 |
+
'SBN' => 'سیستان و بلوچستان',
|
54 |
+
'THR' => 'تهران',
|
55 |
+
'YZD' => 'یزد',
|
56 |
+
'ZJN' => 'زنجان',
|
57 |
+
];
|
58 |
+
|
59 |
+
add_filter( 'woocommerce_get_country_locale', [ $this, 'locales' ] );
|
60 |
+
add_filter( 'woocommerce_localisation_address_formats', [ $this, 'address_formats' ] );
|
61 |
+
add_filter( 'woocommerce_states', [ $this, 'iran_states' ], 10, 1 );
|
62 |
+
|
63 |
+
if ( PW()->get_options( 'enable_iran_cities' ) == 'yes' ) {
|
64 |
+
|
65 |
+
if ( ( $class = [ 'first', 'last' ] ) && PW()->get_options( 'flip_state_city' ) == 'yes' ) {
|
66 |
+
$class = array_reverse( $class );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
}
|
68 |
+
$this->class = [ 'state' => $class[0], 'city' => $class[1] ];
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
|
70 |
+
add_filter( 'woocommerce_checkout_fields', [ $this, 'checkout_fields' ] );
|
71 |
+
add_filter( 'woocommerce_billing_fields', [ $this, 'billing_fields' ] );
|
72 |
+
add_filter( 'woocommerce_shipping_fields', [ $this, 'shipping_fields' ] );
|
73 |
|
74 |
+
add_filter( 'woocommerce_form_field_billing_iran_cities', [ $this, 'iran_cities_field' ], 11, 4 );
|
75 |
+
add_filter( 'woocommerce_form_field_shipping_iran_cities', [ $this, 'iran_cities_field' ], 11, 4 );
|
76 |
|
77 |
+
add_action( 'wp_enqueue_scripts', [ $this, 'external_js' ] );
|
78 |
+
add_action( 'wp_footer', [ $this, 'inline_js' ], 0 );
|
79 |
+
add_action( 'wp_footer', [ $this, 'force_inline_js' ], 999999 );
|
80 |
}
|
81 |
+
}
|
82 |
+
|
83 |
+
public function locales( $locales ) {
|
84 |
+
$locales[ $this->country ] = [
|
85 |
+
'state' => [ 'label' => __( 'Province', 'woocommerce' ) ],
|
86 |
+
'postcode' => [ 'label' => __( 'Postcode', 'woocommerce' ) ],
|
87 |
+
];
|
88 |
|
89 |
+
return $locales;
|
90 |
+
}
|
91 |
|
92 |
+
public function address_formats( $formats ) {
|
93 |
+
$formats[ $this->country ] = "{first_name} {last_name}\n{company}\n{country}\n{state}\n{city}\n{address_1}\n{address_2}\n{postcode}";
|
94 |
|
95 |
+
return $formats;
|
96 |
+
}
|
|
|
97 |
|
98 |
+
public function iran_states( $states ) {
|
99 |
|
100 |
+
$states[ $this->country ] = $this->states;
|
|
|
|
|
101 |
|
102 |
+
if ( PW()->get_options( 'allowed_states' ) == 'all' ) {
|
103 |
return $states;
|
104 |
}
|
105 |
|
106 |
+
$selections = PW()->get_options( 'specific_allowed_states' );
|
|
|
107 |
|
108 |
+
if ( is_array( $selections ) ) {
|
109 |
+
$states[ $this->country ] = array_intersect_key( $this->states, array_flip( $selections ) );
|
110 |
+
}
|
111 |
|
112 |
+
return $states;
|
113 |
+
}
|
|
|
114 |
|
115 |
+
//--------------------------------------------
|
116 |
+
public function checkout_fields( $fields ) {
|
|
|
117 |
|
118 |
+
$this->fields = $fields;
|
|
|
|
|
|
|
|
|
119 |
|
120 |
+
if ( is_checkout() ) {
|
|
|
121 |
|
122 |
+
$types = [ 'billing', 'shipping' ];
|
123 |
|
124 |
+
foreach ( $types as $type ) {
|
125 |
+
|
126 |
+
if ( ! empty( $fields[ $type ][ $type . '_city' ] ) ) {
|
127 |
+
$fields[ $type ][ $type . '_city' ] = $this->modify_city_field( $fields[ $type ][ $type . '_city' ], $type );
|
128 |
}
|
129 |
+
|
130 |
+
if ( ! empty( $fields[ $type ][ $type . '_state' ] ) ) {
|
131 |
+
$fields[ $type ][ $type . '_state' ] = $this->modify_state_field( $fields[ $type ][ $type . '_state' ], $type );
|
132 |
}
|
133 |
}
|
|
|
|
|
134 |
}
|
135 |
|
136 |
+
return $fields;
|
137 |
+
}
|
138 |
|
139 |
+
public function billing_fields( $fields ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
|
141 |
+
if ( is_wc_endpoint_url( 'edit-address' ) ) {
|
142 |
+
$type = 'billing';
|
143 |
+
if ( ! empty( $fields[ $type . '_city' ] ) ) {
|
144 |
+
$fields[ $type . '_city' ] = $this->modify_city_field( $fields[ $type . '_city' ], $type );
|
145 |
+
}
|
146 |
+
if ( ! empty( $fields[ $type . '_state' ] ) ) {
|
147 |
+
$fields[ $type . '_state' ] = $this->modify_state_field( $fields[ $type . '_state' ], $type );
|
148 |
+
}
|
149 |
}
|
150 |
|
151 |
+
return $fields;
|
152 |
+
}
|
153 |
+
|
154 |
+
public function shipping_fields( $fields ) {
|
155 |
+
|
156 |
+
if ( is_wc_endpoint_url( 'edit-address' ) ) {
|
157 |
+
$type = 'shipping';
|
158 |
+
if ( ! empty( $fields[ $type . '_city' ] ) ) {
|
159 |
+
$fields[ $type . '_city' ] = $this->modify_city_field( $fields[ $type . '_city' ], $type );
|
160 |
+
}
|
161 |
+
if ( ! empty( $fields[ $type . '_state' ] ) ) {
|
162 |
+
$fields[ $type . '_state' ] = $this->modify_state_field( $fields[ $type . '_state' ], $type );
|
163 |
}
|
164 |
+
}
|
165 |
+
|
166 |
+
return $fields;
|
167 |
+
}
|
168 |
|
169 |
+
public function modify_state_field( $fields, $type ) {
|
170 |
+
$classes = '';
|
171 |
+
if ( ! empty( $fields['class'] ) && $classes = $fields['class'] ) {
|
172 |
+
$classes = is_array( $classes ) ? implode( ',', $classes ) : $classes;
|
173 |
+
$classes = str_ireplace( 'form-row-wide', 'form-row-' . $this->class['state'], $classes );
|
174 |
}
|
175 |
+
$fields['class'] = apply_filters( $type . '_iran_state_class', explode( ',', $classes ), $fields, $type );
|
176 |
|
177 |
+
return $fields;
|
178 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
|
180 |
+
public function modify_city_field( $fields, $type ) {
|
181 |
+
$classes = '';
|
182 |
+
if ( ! empty( $fields['class'] ) && $classes = $fields['class'] ) {
|
183 |
+
$classes = is_array( $classes ) ? implode( ',', $classes ) : $classes;
|
184 |
+
$classes = str_ireplace( 'form-row-wide', 'form-row-' . $this->class['city'], $classes );
|
185 |
}
|
186 |
+
$fields['class'] = apply_filters( $type . '_iran_city_class', explode( ',', $classes ), $fields, $type );
|
187 |
+
$fields['type'] = apply_filters( $type . '_iran_city_type', $type . '_iran_cities', $fields, $type );
|
188 |
+
$fields['options'] = apply_filters( $type . '_iran_city_options', [ '' => '' ], $fields, $type );
|
189 |
|
190 |
+
return $fields;
|
191 |
+
}
|
192 |
|
193 |
+
public function iran_cities_field( $field, $key, $args, $value ) {
|
|
|
|
|
|
|
194 |
|
195 |
+
$type = explode( '_', $args['type'] );
|
196 |
+
if ( ! empty( $value ) ) {
|
197 |
+
$this->selected_city[] = $value . '_vsh_' . $type[0];
|
198 |
+
}
|
199 |
|
200 |
+
$required = $args['required'] ? ' <abbr class="required" title="' . esc_attr__( 'required', 'woocommerce' ) . '">*</abbr>' : '';
|
|
|
|
|
|
|
201 |
|
202 |
+
$args['label_class'] = [];
|
203 |
+
if ( is_string( $args['label_class'] ) ) {
|
204 |
+
$args['label_class'] = [ $args['label_class'] ];
|
205 |
+
}
|
206 |
|
207 |
+
if ( is_null( $value ) ) {
|
208 |
+
$value = ! empty( $args['default'] ) ? $args['default'] : '';
|
209 |
+
}
|
210 |
|
211 |
+
$selected_value = $args['type'] . '_selected_value';
|
212 |
+
global ${$selected_value};
|
213 |
+
${$selected_value} = $value;
|
214 |
+
|
215 |
+
$custom_attributes = [];
|
216 |
+
if ( ! empty( $args['custom_attributes'] ) && is_array( $args['custom_attributes'] ) ) {
|
217 |
+
foreach ( $args['custom_attributes'] as $attribute => $attribute_value ) {
|
218 |
+
$custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
|
219 |
}
|
220 |
+
}
|
221 |
|
222 |
+
if ( ! empty( $args['validate'] ) ) {
|
223 |
+
foreach ( $args['validate'] as $validate ) {
|
224 |
+
$args['class'][] = 'validate-' . $validate;
|
|
|
225 |
}
|
226 |
+
}
|
227 |
|
228 |
+
$args['placeholder'] = __( 'یک شهر انتخاب کنید', 'woocommerce' );
|
229 |
|
230 |
+
$label_id = $args['id'];
|
231 |
+
$field_container = '<p class="form-row %1$s" id="%2$s">%3$s</p>';
|
232 |
|
233 |
+
$field = '<select name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" class="state_select ' . esc_attr( implode( ' ', $args['input_class'] ) ) . '" ' . implode( ' ', $custom_attributes ) . ' placeholder="' . esc_attr( $args['placeholder'] ) . '"></select>';
|
234 |
|
235 |
+
$field_html = '';
|
236 |
|
237 |
+
if ( $args['label'] && 'checkbox' != $args['type'] ) {
|
238 |
+
$field_html .= '<label for="' . esc_attr( $label_id ) . '" class="' . esc_attr( implode( ' ', $args['label_class'] ) ) . '">' . $args['label'] . $required . '</label>';
|
239 |
+
}
|
240 |
|
241 |
+
$field_html .= $field;
|
242 |
|
243 |
+
if ( $args['description'] ) {
|
244 |
+
$field_html .= '<span class="description">' . esc_attr( $args['description'] ) . '</span>';
|
245 |
+
}
|
246 |
|
247 |
+
$container_class = 'form-row ' . esc_attr( implode( ' ', $args['class'] ) );
|
248 |
+
$container_id = esc_attr( $args['id'] ) . '_field';
|
249 |
|
250 |
+
$after = ! empty( $args['clear'] ) ? '<div class="clear"></div>' : '';
|
251 |
|
252 |
+
$iran_cities = sprintf( $field_container, $container_class, $container_id, $field_html ) . $after;
|
253 |
|
254 |
+
return apply_filters( 'iran_cities_field_select_input', $iran_cities, $field_container, $container_class, $container_id, $field_html, $field, $key, $args, $value, $after );
|
255 |
+
}
|
256 |
|
257 |
+
public function external_js() {
|
258 |
+
wp_dequeue_script( 'pw-iran-cities' );
|
259 |
+
wp_deregister_script( 'pw-iran-cities' );
|
260 |
+
wp_register_script( 'pw-iran-cities', apply_filters( 'persian_woo_iran_cities', PW()->plugin_url( 'assets/js/iran_cities.min.js' ) ), false, PW_VERSION, true );
|
261 |
|
262 |
+
if ( self::$iran_cities_page = ( is_checkout() || is_wc_endpoint_url( 'edit-address' ) ) ) {
|
263 |
+
wp_enqueue_script( 'pw-iran-cities' );
|
|
|
264 |
}
|
265 |
+
}
|
266 |
|
267 |
+
public function inline_js( $force_inline_js = false ) {
|
268 |
+
if ( ! $force_inline_js ) {
|
269 |
|
270 |
+
if ( self::$inline_script_printed == 'yes' || ! self::$iran_cities_page || self::$action_priority > 100 ) {
|
271 |
+
return;
|
272 |
+
}
|
273 |
|
274 |
+
if ( ! ( wp_script_is( 'jquery', 'done' ) && ! wp_script_is( 'wc-country-select', 'done' ) ) ) {
|
275 |
+
self::$action_priority += 5;
|
276 |
+
add_action( 'wp_footer', [ $this, 'inline_js' ], self::$action_priority );
|
277 |
|
278 |
+
return;
|
|
|
279 |
}
|
280 |
+
}
|
281 |
|
282 |
+
self::$inline_script_printed = 'yes';
|
283 |
+
$value_index = apply_filters( 'iran_cities_value_index', 0 );
|
284 |
+
$types = [ 'billing', 'shipping' ];
|
285 |
+
?>
|
286 |
+
<script type="text/javascript">
|
287 |
+
if (!window.jQuery) {
|
288 |
+
alert("کتابخانه جیکوئری قبل از کدهای مربوط به شهرهای ایران لود نشده است!");
|
289 |
+
}
|
290 |
+
jQuery(function ($) {
|
291 |
+
<?php foreach ($types as $type) :
|
|
|
|
|
|
|
|
|
292 |
|
293 |
+
$type = esc_attr( $type );
|
|
|
|
|
|
|
|
|
294 |
|
295 |
+
$selected_value = $type . '_iran_cities_selected_value';
|
296 |
+
global ${$selected_value};
|
297 |
+
$value = ! empty( ${$selected_value} ) ? ${$selected_value} : '';
|
298 |
+
$placeholder = isset( $this->fields[ $type ][ $type . '_city' ]['placeholder'] ) ? $this->fields[ $type ][ $type . '_city' ]['placeholder'] : __( 'City', 'woocommerce' );
|
299 |
|
300 |
+
$countries = 'get_' . str_replace( 'billing', 'allowed', $type ) . '_countries';
|
301 |
+
$countries = WC()->countries->$countries();
|
302 |
+
$iran_exist = isset( $countries[ strtoupper( $this->country ) ] ) || isset( $countries[ strtolower( $this->country ) ] ) || isset( $countries[ ucfirst( $this->country ) ] ) ? 'yes' : 'no';
|
303 |
+
$just_iran = count( $countries ) == 1 && $iran_exist == 'yes' ? 'yes' : 'no';
|
304 |
+
?>
|
305 |
|
306 |
+
var <?php echo esc_attr( $type ); ?>_iran_exist = '<?php echo esc_attr( $iran_exist ); ?>';
|
307 |
+
var <?php echo esc_attr( $type ); ?>_just_iran = '<?php echo esc_attr( $just_iran ); ?>';
|
308 |
|
309 |
+
$(document.body).on('change', '#<?php echo esc_attr( $type ); ?>_state', function () {
|
|
|
310 |
|
311 |
+
if (<?php echo esc_attr( $type ); ?>_iran_exist == 'yes' && (<?php echo esc_attr( $type ); ?>_just_iran || $('#<?php echo esc_attr( $type ); ?>_country').val() == '<?php echo $this->country ?>')) {
|
|
|
|
|
|
|
|
|
312 |
|
313 |
+
<?php echo esc_attr( $type ); ?>_cities = [];
|
314 |
+
<?php echo esc_attr( $type ); ?>_cities[0] = new Array('خطا در دریافت شهرها', '0');
|
315 |
+
|
316 |
+
if (typeof Persian_Woo_iranCities === "function")
|
317 |
+
<?php echo esc_attr( $type ); ?>_cities = Persian_Woo_iranCities('' + $('#<?php echo esc_attr( $type ); ?>_state').val() + '');
|
318 |
+
else {
|
319 |
+
alert('تابع مربوط به شهرهای ایران یافت نمیشود. با مدیریت در میان بگذارید.');
|
320 |
+
}
|
321 |
+
|
322 |
+
<?php echo esc_attr( $type ); ?>_cities.sort(function (a, b) {
|
323 |
+
if (a[0] == b[0])
|
324 |
+
return 0;
|
325 |
+
if (a[0] > b[0])
|
326 |
+
return 1;
|
327 |
+
else
|
328 |
+
return -1;
|
329 |
+
});
|
330 |
+
var options = '<option value="-1">انتخاب کنید</option>';
|
331 |
+
var j;
|
332 |
+
<?php echo esc_attr( $type ); ?>_selected = '';
|
333 |
+
for (j in <?php echo esc_attr( $type ); ?>_cities) {
|
334 |
+
selected = '';
|
335 |
+
if (<?php echo esc_attr( $type ); ?>_cities[j][<?php echo intval( $value_index ); ?>] == '<?php echo esc_attr( $value );?>') {
|
336 |
+
selected = "selected";
|
337 |
+
<?php echo esc_attr( $type ); ?>_selected = '<?php echo esc_attr( $value );?>';
|
338 |
}
|
339 |
+
options += "<option value='" + <?php echo esc_attr( $type ); ?>_cities[j][<?php echo intval( $value_index ); ?>] + "' " + selected + ">" + <?php echo esc_attr( $type ); ?>_cities[j][0] + "</option>";
|
340 |
}
|
341 |
+
$('#<?php echo esc_attr( $type ); ?>_city').empty();
|
342 |
+
if ($("#<?php echo esc_attr( $type ); ?>_city").is('select')) {
|
343 |
+
$('#<?php echo esc_attr( $type ); ?>_city').append(options);
|
344 |
+
}
|
345 |
+
$('#<?php echo esc_attr( $type ); ?>_city').val(<?php echo esc_attr( $type ); ?>_selected).trigger("change");
|
346 |
+
}
|
347 |
+
});
|
348 |
+
$('#<?php echo esc_attr( $type ); ?>_state').trigger('change');
|
349 |
|
350 |
+
var <?php echo esc_attr( $type ); ?>_city_select = $('#<?php echo esc_attr( $type ); ?>_city_field').html();
|
351 |
+
var <?php echo esc_attr( $type ); ?>_city_input = '<input id="<?php echo esc_attr( $type ); ?>_city" name="<?php echo esc_attr( $type ); ?>_city" type="text" class="input-text" value="<?php echo esc_attr( $value );?>" placeholder="<?php echo esc_attr( $placeholder );?>" />';
|
352 |
|
353 |
+
$(document.body).on('change', '#<?php echo esc_attr( $type ); ?>_country', function () {
|
354 |
+
var is_iran = $('#<?php echo esc_attr( $type ); ?>_country').val() == '<?php echo $this->country ?>' ? 'yes' : 'no';
|
355 |
+
set_iran_cities_field('<?php echo esc_attr( $type ); ?>', is_iran);
|
356 |
+
});
|
357 |
+
$('#<?php echo esc_attr( $type ); ?>_country').trigger('change');
|
358 |
|
359 |
+
if (!$('#<?php echo esc_attr( $type ); ?>_country').length) {
|
360 |
+
set_iran_cities_field('<?php echo esc_attr( $type ); ?>', <?php echo esc_attr( $type ); ?>_just_iran);
|
361 |
+
}
|
362 |
|
363 |
+
$(document.body).on('change', '#<?php echo esc_attr( $type ); ?>_city', function () {
|
364 |
+
if ($('#<?php echo esc_attr( $type ); ?>_city').val() == 'لطفا استان خود را انتخاب کنید') {
|
365 |
+
if ($().select2 && $('#<?php echo esc_attr( $type ); ?>_state').data('select2'))
|
366 |
+
$('#<?php echo esc_attr( $type ); ?>_state').select2('open');
|
367 |
+
}
|
368 |
+
});
|
369 |
|
370 |
+
<?php if ( is_checkout() ) {
|
371 |
+
wc_enqueue_js( "if ($().select2 && $('#" . $type . "_city').data('select2') && !$('#" . $type . "_state').data('select2'))
|
372 |
$('#" . $type . "_state').select2();" );
|
373 |
+
} ?>
|
374 |
+
|
375 |
+
<?php endforeach; ?>
|
376 |
+
function set_iran_cities_field(type, iran) {
|
377 |
+
if (iran == 'yes') {
|
378 |
+
if (!$('#' + type + '_city').is('select')) {
|
379 |
+
$('#' + type + '_city_field').empty();
|
380 |
+
$('#' + type + '_city_field').html(eval(type + '_city_select'));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
381 |
$('#' + type + '_state').val('').trigger("change");
|
382 |
$('#' + type + '_city').val('').trigger("change");
|
383 |
}
|
384 |
+
} else {
|
385 |
+
$('#' + type + '_city_field').find('*').not('label').remove();
|
386 |
+
$('#' + type + '_city_field').append(eval(type + '_city_input'));
|
387 |
+
$('#' + type + '_state').val('').trigger("change");
|
388 |
+
$('#' + type + '_city').val('').trigger("change");
|
389 |
}
|
390 |
+
}
|
391 |
|
392 |
+
});
|
393 |
+
</script>
|
394 |
+
<?php
|
395 |
+
}
|
396 |
|
397 |
+
public function force_inline_js() {
|
398 |
+
if ( self::$inline_script_printed != 'yes' && self::$iran_cities_page && wp_script_is( 'jquery', 'done' ) ) {
|
399 |
+
$this->inline_js( true );
|
|
|
400 |
}
|
401 |
}
|
402 |
+
}
|
403 |
+
|
404 |
PW()->address = new Persian_Woocommerce_Address();
|
include/class-core.php
CHANGED
@@ -1,355 +1,207 @@
|
|
1 |
-
<?php
|
2 |
-
exit;
|
3 |
-
}
|
4 |
-
|
5 |
-
if ( ! class_exists( 'Persian_Woocommerce_Core' ) ) :
|
6 |
|
7 |
-
|
8 |
|
9 |
-
|
10 |
|
11 |
-
|
12 |
-
public $tools, $widget, $translate, $currencies, $address, $gateways;
|
13 |
|
14 |
-
|
|
|
15 |
|
16 |
-
|
17 |
-
if ( is_null( self::$_instance ) ) {
|
18 |
-
self::$_instance = new self();
|
19 |
-
}
|
20 |
|
21 |
-
|
|
|
|
|
22 |
}
|
23 |
|
24 |
-
|
|
|
25 |
|
26 |
-
|
27 |
|
28 |
-
|
29 |
|
30 |
-
|
31 |
-
add_action( 'admin_menu', [ $this, 'admin_menus' ], 59 );
|
32 |
-
add_action( 'admin_head', [ $this, 'admin_head' ] );
|
33 |
-
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
|
34 |
-
add_action( 'admin_notices', [ $this, 'notices_render' ] );
|
35 |
-
add_action( 'wp_ajax_pw_notice_dismiss', [ $this, 'notices_dismiss' ] );
|
36 |
-
add_action( 'plugins_loaded', [ $this, 'plugins_loaded' ], 10 );
|
37 |
-
}
|
38 |
|
39 |
-
|
40 |
-
|
41 |
-
|
|
|
|
|
|
|
42 |
|
43 |
-
|
|
|
|
|
44 |
|
45 |
-
|
46 |
-
$this->translate,
|
47 |
-
'translate_page'
|
48 |
-
), $this->plugin_url( 'assets/images/logo.png' ), '55.6' );
|
49 |
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
|
60 |
-
|
|
|
|
|
|
|
61 |
|
62 |
-
|
63 |
-
$this,
|
64 |
-
'plugins_page'
|
65 |
-
) );
|
66 |
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
|
72 |
-
|
|
|
|
|
|
|
73 |
|
74 |
-
|
75 |
-
$this,
|
76 |
-
'plugins_page'
|
77 |
-
) );
|
78 |
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
}
|
89 |
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
});
|
96 |
-
</script>
|
97 |
-
<?php
|
98 |
-
}
|
99 |
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
|
|
|
|
|
|
|
|
|
|
104 |
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
|
110 |
-
|
111 |
-
|
112 |
-
|
|
|
113 |
|
114 |
-
|
115 |
-
|
|
|
116 |
|
117 |
-
|
118 |
-
|
119 |
-
}
|
120 |
|
121 |
-
|
|
|
|
|
|
|
|
|
122 |
`id` int(11) NOT NULL AUTO_INCREMENT,
|
123 |
`text1` text CHARACTER SET utf8 COLLATE utf8_persian_ci NOT NULL,
|
124 |
`text2` text CHARACTER SET utf8 COLLATE utf8_persian_ci,
|
125 |
PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;";
|
126 |
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
foreach ( $deprecated_tables as $deprecated_table ) {
|
137 |
-
$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}{$deprecated_table}" );
|
138 |
-
}
|
139 |
-
|
140 |
-
//delete deprecated Options-----------------------------
|
141 |
-
$deprecated_options = array(
|
142 |
-
'is_cities_installed',
|
143 |
-
'pw_delete_city_table_2_5',
|
144 |
-
'woocommerce_persian_feed',
|
145 |
-
'redirect_to_woo_persian_about_page',
|
146 |
-
'enable_woocommerce_notice_dismissed',
|
147 |
-
'Persian_Woocommerce_rename_old_table',
|
148 |
-
);
|
149 |
-
|
150 |
-
foreach ( $deprecated_options as $deprecated_option ) {
|
151 |
-
delete_option( $deprecated_option );
|
152 |
-
}
|
153 |
-
|
154 |
-
for ( $i = 0; $i < 10; $i ++ ) {
|
155 |
-
delete_option( 'persian_woo_notice_number_' . $i );
|
156 |
-
}
|
157 |
-
|
158 |
-
unlink( PW_DIR . '/.activated' );
|
159 |
-
|
160 |
-
if ( ! headers_sent() ) {
|
161 |
-
wp_redirect( admin_url( 'admin.php?page=persian-wc-about' ) );
|
162 |
-
die();
|
163 |
-
}
|
164 |
-
}
|
165 |
|
166 |
-
|
167 |
-
$
|
168 |
-
'persian-wc-about',
|
169 |
-
'persian-wc-plugins',
|
170 |
-
'wc-persian-plugins',
|
171 |
-
'persian-wc-themes',
|
172 |
-
'wc-persian-themes',
|
173 |
-
];
|
174 |
-
|
175 |
-
if ( ! empty( $_GET['page'] ) && in_array( $_GET['page'], $pages ) ) {
|
176 |
-
wp_register_style( 'pw-admin-fonts', $this->plugin_url( 'assets/css/admin.font.css' ) );
|
177 |
-
wp_enqueue_style( 'pw-admin-fonts' );
|
178 |
-
}
|
179 |
}
|
180 |
|
181 |
-
|
182 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
183 |
}
|
184 |
|
185 |
-
|
|
|
|
|
186 |
|
187 |
-
|
188 |
-
return $this->options;
|
189 |
-
}
|
190 |
|
191 |
-
|
|
|
|
|
|
|
|
|
192 |
|
193 |
-
|
194 |
-
|
195 |
-
|
|
|
|
|
|
|
|
|
|
|
196 |
|
197 |
-
|
198 |
-
return $this->options[ $option_name ];
|
199 |
-
} elseif ( isset( $default_options["PW_Options[$option_name]"] ) ) {
|
200 |
-
return $default_options["PW_Options[$option_name]"];
|
201 |
-
} else {
|
202 |
-
return $default;
|
203 |
-
}
|
204 |
-
}
|
205 |
|
206 |
-
|
207 |
-
$
|
208 |
-
|
209 |
-
$dismissed = (array) get_option( 'persian_woocommerce_dismissed_notices' );
|
210 |
-
|
211 |
-
foreach ( $notices as $id => $notice ) {
|
212 |
-
if ( count( $notice ) == 3 && ! $notice[2] ) {
|
213 |
-
continue;
|
214 |
-
}
|
215 |
-
if ( ! in_array( $id, $dismissed ) ) {
|
216 |
-
printf( '<div class="notice persian_woocommerce_notice notice-%2$s is-dismissible" id="persian_woocommerce_%1$s"><p>%3$s</p></div>', $id, $notice[0], $notice[1] );
|
217 |
-
break;
|
218 |
-
}
|
219 |
-
}
|
220 |
-
?>
|
221 |
-
<script type="text/javascript">
|
222 |
-
jQuery(document).ready(function ( $ ) {
|
223 |
-
$(document.body).on('click', '.notice-dismiss', function () {
|
224 |
-
var notice = $(this).closest('.persian_woocommerce_notice');
|
225 |
-
notice = notice.attr('id');
|
226 |
-
if( notice.indexOf('persian_woocommerce_') !== -1 ) {
|
227 |
-
notice = notice.replace('persian_woocommerce_', '');
|
228 |
-
$.ajax({
|
229 |
-
url: "<?php echo admin_url( 'admin-ajax.php' ) ?>",
|
230 |
-
type: "post",
|
231 |
-
data: {
|
232 |
-
notice: notice,
|
233 |
-
action: 'pw_notice_dismiss',
|
234 |
-
security: "<?php echo wp_create_nonce( 'pw_notice_dismiss' ); ?>"
|
235 |
-
},
|
236 |
-
success: function ( response ) {
|
237 |
-
}
|
238 |
-
});
|
239 |
-
}
|
240 |
-
return false;
|
241 |
-
});
|
242 |
-
});
|
243 |
-
</script>
|
244 |
-
<?php
|
245 |
}
|
|
|
246 |
|
247 |
-
|
|
|
|
|
248 |
|
249 |
-
|
250 |
|
251 |
-
|
252 |
-
|
253 |
-
$dismissed[] = $_POST['notice'];
|
254 |
-
update_option( 'persian_woocommerce_dismissed_notices', array_unique( $dismissed ) );
|
255 |
-
}
|
256 |
-
die();
|
257 |
}
|
258 |
|
259 |
-
|
260 |
-
global $pagenow;
|
261 |
-
|
262 |
-
$post_type = $_GET['post_type'] ?? null;
|
263 |
-
$page = $_GET['page'] ?? null;
|
264 |
-
$tab = $_GET['tab'] ?? null;
|
265 |
-
|
266 |
-
$notices['tapin-orders'] = [
|
267 |
-
'success',
|
268 |
-
'<b>با افزونه حمل و نقل ووکامرس فارسی یک دفتر پستی اختصاصی داشته باش و بدون مراجعه به پست همه سفارشاتتو ارسال کن.</b>
|
269 |
-
<ul>
|
270 |
-
<li>- تولید فاکتور پست همراه با بارکد پستی به صورت آنلاین</li>
|
271 |
-
<li>- جمع آوری مرسولات از محل شما توسط ماموران پست</li>
|
272 |
-
<li>- ارسال کد رهگیری پستی برای مشتریان به صورت پیامکی</li>
|
273 |
-
<li>- بروزرسانی خودکار آخرین وضعیت مرسوله در پنل ووکامرس</li>
|
274 |
-
</ul>
|
275 |
-
<a href="https://yun.ir/pwto" target="_blank">
|
276 |
-
<input type="button" class="button button-primary" value="اطلاعات بیشتر">
|
277 |
-
</a>
|
278 |
-
<a href="' . admin_url( 'plugin-install.php?tab=plugin-information&plugin=persian-woocommerce-shipping' ) . '" target="_blank">
|
279 |
-
<input type="button" class="button" value="نصب افزونه پیشخوان پست">
|
280 |
-
</a>',
|
281 |
-
$pagenow == 'edit.php' && $post_type == 'shop_order'
|
282 |
-
];
|
283 |
-
|
284 |
-
$notices['tapin-shipping'] = [
|
285 |
-
'success',
|
286 |
-
'<b>با افزونه حمل و نقل ووکامرس فارسی به رایگان هزینه پست سفارشی و پیشتاز رو بصورت دقیق و طبق آخرین تعرفه پست محاسبه کنید و سرویس پرداخت در محل رو در سراسر کشور فعال کنید.</b>
|
287 |
-
<ul>
|
288 |
-
<li>- محاسبه دقیق هزینه ارسال بر اساس وزن و شهر خریدار</li>
|
289 |
-
<li>- امکان تخفیف در هزینه ارسال بر اساس میزان خرید</li>
|
290 |
-
<li>- صدور آنلاین کد رهگیری پستی و تولید فاکتور</li>
|
291 |
-
<li>- ارسال کد رهگیری به خریدار به صورت پیامکی و در پنل کاربری</li>
|
292 |
-
</ul>
|
293 |
-
<a href="https://yun.ir/pwts" target="_blank">
|
294 |
-
<input type="button" class="button button-primary" value="اطلاعات بیشتر">
|
295 |
-
</a>
|
296 |
-
<a href="' . admin_url( 'plugin-install.php?tab=plugin-information&plugin=persian-woocommerce-shipping' ) . '" target="_blank">
|
297 |
-
<input type="button" class="button" value="نصب افزونه پیشخوان پست">
|
298 |
-
</a>',
|
299 |
-
$page == 'wc-settings' && $tab == 'shipping'
|
300 |
-
];
|
301 |
-
|
302 |
-
$notices['tapin-tools'] = [
|
303 |
-
'success',
|
304 |
-
'
|
305 |
-
<a href="https://yun.ir/pwtt" target="_blank">
|
306 |
-
<img src="' . $this->plugin_url( 'assets/images/tapin.jpg' ) . '" style="width: 100%">
|
307 |
-
</a>',
|
308 |
-
$page == 'persian-wc-tools'
|
309 |
-
];
|
310 |
-
|
311 |
-
$notices['tapin-dashboard'] = [
|
312 |
-
'success',
|
313 |
-
'<b>پیشخوان وردپرس خود را رایگان به شرکت ملی پست متصل کنید و یک دفتر پستی اختصاصی داشته باشید.</b>
|
314 |
-
<ul>
|
315 |
-
<li>- محاسبه دقیق هزینه های پستی در سبد خرید</li>
|
316 |
-
<li>- جمع آری سفارشات از محل شما توسط ماموران پست در سراسر کشور</li>
|
317 |
-
<li>- صدور فاکتور استاندارد پست همراه با بارکد پست</li>
|
318 |
-
<li>- ارسال کد رهگیری پست به مشتری به صورت پیامکی و پنل کاربری</li>
|
319 |
-
</ul>
|
320 |
-
<a href="https://yun.ir/pwtd" target="_blank">
|
321 |
-
<input type="button" class="button button-primary" value="اطلاعات بیشتر">
|
322 |
-
</a>
|
323 |
-
<a href="' . admin_url( 'plugin-install.php?tab=plugin-information&plugin=persian-woocommerce-shipping' ) . '" target="_blank">
|
324 |
-
<input type="button" class="button" value="نصب افزونه پیشخوان پست">
|
325 |
-
</a>',
|
326 |
-
true
|
327 |
-
];
|
328 |
-
|
329 |
-
$notices['persian-date'] = [
|
330 |
-
'info',
|
331 |
-
'<b>ووکامرس فارسی با طمع ووکامرس شمسی!</b>
|
332 |
-
<ul>
|
333 |
-
<li>- شمسی سازی محیط وردپرس بدون نیاز به افزونه جانبی</li>
|
334 |
-
<li>- شمسی سازی ووکامرس در محصولات، سفارشات، کوپن ها و گزارشات</li>
|
335 |
-
<li>- افزودن DatePicker شمسی در پنل ووکامرس</li>
|
336 |
-
<li>- برای فعالسازی شمسی ساز ووکامرس روی کلید زیر کلیک کنید:</li>
|
337 |
-
</ul>
|
338 |
-
<a href="' . admin_url( 'admin.php?page=persian-wc-tools' ) . '" target="_blank">
|
339 |
-
<input type="button" class="button button-primary" value="فعالسازی شمسی ساز وردپرس و ووکامرس">
|
340 |
-
</a>',
|
341 |
-
$this->get_options( 'enable_jalali_datepicker' ) !== 'yes',
|
342 |
-
];
|
343 |
-
|
344 |
-
$notices['pws'] = [
|
345 |
-
'info',
|
346 |
-
sprintf( 'بنظر میرسه هنوز حمل و نقل (پست پیشتاز، سفارشی، پیک موتوری و...) فروشگاه رو پیکربندی نکردید؟ <a href="%s" target="_blank">نصب افزونه حمل و نقل فارسی ووکامرس و پیکربندی.</a>', admin_url( 'plugin-install.php?tab=plugin-information&plugin=persian-woocommerce-shipping' ) ),
|
347 |
-
class_exists( 'WC_Shipping_Zones' ) && ! count( WC_Shipping_Zones::get_zones() ) && current_user_can( 'install_plugins' ),
|
348 |
-
];
|
349 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
350 |
}
|
351 |
}
|
352 |
-
|
|
|
353 |
|
354 |
if ( ! class_exists( 'Persian_Woocommerce_Plugin' ) ) {
|
355 |
class Persian_Woocommerce_Plugin extends Persian_Woocommerce_Core {
|
1 |
+
<?php
|
|
|
|
|
|
|
|
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || exit;
|
4 |
|
5 |
+
class Persian_Woocommerce_Core {
|
6 |
|
7 |
+
protected $options;
|
|
|
8 |
|
9 |
+
// sub classes
|
10 |
+
public $tools, $translate, $address, $gateways;
|
11 |
|
12 |
+
protected static $_instance = null;
|
|
|
|
|
|
|
13 |
|
14 |
+
public static function instance() {
|
15 |
+
if ( is_null( self::$_instance ) ) {
|
16 |
+
self::$_instance = new self();
|
17 |
}
|
18 |
|
19 |
+
return self::$_instance;
|
20 |
+
}
|
21 |
|
22 |
+
public function __construct() {
|
23 |
|
24 |
+
$this->activated_plugin();
|
25 |
|
26 |
+
$this->options = get_option( 'PW_Options' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
|
28 |
+
//add_filter( 'woocommerce_show_addons_page', '__return_false', 100 );
|
29 |
+
add_action( 'admin_menu', [ $this, 'admin_menus' ], 59 );
|
30 |
+
add_action( 'admin_head', [ $this, 'admin_head' ] );
|
31 |
+
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
|
32 |
+
add_action( 'plugins_loaded', [ $this, 'plugins_loaded' ], 10 );
|
33 |
+
}
|
34 |
|
35 |
+
public function plugins_loaded() {
|
36 |
+
require_once( 'class-gateways.php' );
|
37 |
+
}
|
38 |
|
39 |
+
public function admin_menus() {
|
|
|
|
|
|
|
40 |
|
41 |
+
add_menu_page( 'ووکامرس فارسی', 'ووکامرس فارسی', 'manage_options', 'persian-wc', [
|
42 |
+
$this->translate,
|
43 |
+
'translate_page',
|
44 |
+
], $this->plugin_url( 'assets/images/logo.png' ), '55.6' );
|
45 |
|
46 |
+
add_submenu_page( 'persian-wc', 'حلقه های ترجمه', 'حلقه های ترجمه', 'manage_options', 'persian-wc', [
|
47 |
+
$this->translate,
|
48 |
+
'translate_page',
|
49 |
+
] );
|
50 |
|
51 |
+
add_submenu_page( 'persian-wc', 'ابزار ها', 'ابزار ها', 'manage_options', 'persian-wc-tools', [
|
52 |
+
$this->tools,
|
53 |
+
'tools_page',
|
54 |
+
] );
|
55 |
|
56 |
+
do_action( "PW_Menu" );
|
|
|
|
|
|
|
57 |
|
58 |
+
add_submenu_page( 'persian-wc', 'افزونه ها', 'افزونه ها', 'manage_woocommerce', 'persian-wc-plugins', [
|
59 |
+
$this,
|
60 |
+
'plugins_page',
|
61 |
+
] );
|
62 |
|
63 |
+
add_submenu_page( 'persian-wc', 'پوسته ها', 'پوسته ها', 'manage_woocommerce', 'persian-wc-themes', [
|
64 |
+
$this,
|
65 |
+
'themes_page',
|
66 |
+
] );
|
67 |
|
68 |
+
add_submenu_page( 'persian-wc', 'پیشخوان پست تاپین', 'پیشخوان پست تاپین', 'manage_woocommerce', 'https://yun.ir/pwtm' );
|
|
|
|
|
|
|
69 |
|
70 |
+
add_submenu_page( 'woocommerce', 'افزونه های پارسی', 'افزونه های پارسی', 'manage_woocommerce', 'wc-persian-plugins', [
|
71 |
+
$this,
|
72 |
+
'plugins_page',
|
73 |
+
] );
|
74 |
|
75 |
+
add_submenu_page( 'woocommerce', 'پوسته های پارسی', 'پوسته های پارسی', 'manage_woocommerce', 'wc-persian-themes', [
|
76 |
+
$this,
|
77 |
+
'themes_page',
|
78 |
+
] );
|
|
|
79 |
|
80 |
+
add_submenu_page( 'persian-wc', 'درباره ما', 'درباره ما', 'manage_options', 'persian-wc-about', [
|
81 |
+
$this,
|
82 |
+
'about_page',
|
83 |
+
] );
|
84 |
+
}
|
|
|
|
|
|
|
|
|
85 |
|
86 |
+
public function admin_head() {
|
87 |
+
?>
|
88 |
+
<script type="text/javascript">
|
89 |
+
jQuery(document).ready(function ($) {
|
90 |
+
$("ul#adminmenu a[href$='https://yun.ir/pwtm']").attr('target', '_blank');
|
91 |
+
});
|
92 |
+
</script>
|
93 |
+
<?php
|
94 |
+
}
|
95 |
|
96 |
+
public function themes_page() {
|
97 |
+
wp_enqueue_style( 'woocommerce_admin_styles' );
|
98 |
+
include( 'view/html-admin-page-themes.php' );
|
99 |
+
}
|
100 |
|
101 |
+
public function plugins_page() {
|
102 |
+
wp_enqueue_style( 'woocommerce_admin_styles' );
|
103 |
+
include( 'view/html-admin-page-plugins.php' );
|
104 |
+
}
|
105 |
|
106 |
+
public function about_page() {
|
107 |
+
include( 'view/html-admin-page-about.php' );
|
108 |
+
}
|
109 |
|
110 |
+
public function activated_plugin() {
|
111 |
+
global $wpdb;
|
|
|
112 |
|
113 |
+
if ( ! file_exists( PW_DIR . '/.activated' ) ) {
|
114 |
+
return false;
|
115 |
+
}
|
116 |
+
|
117 |
+
$woocommerce_ir_sql = "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}woocommerce_ir` (
|
118 |
`id` int(11) NOT NULL AUTO_INCREMENT,
|
119 |
`text1` text CHARACTER SET utf8 COLLATE utf8_persian_ci NOT NULL,
|
120 |
`text2` text CHARACTER SET utf8 COLLATE utf8_persian_ci,
|
121 |
PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;";
|
122 |
|
123 |
+
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
124 |
+
dbDelta( $woocommerce_ir_sql );
|
125 |
+
|
126 |
+
//delete deprecated tables-----------------------------
|
127 |
+
$deprecated_tables = [
|
128 |
+
'woocommerce_ir_cities',
|
129 |
+
'Woo_Iran_Cities_By_HANNANStd',
|
130 |
+
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
|
132 |
+
foreach ( $deprecated_tables as $deprecated_table ) {
|
133 |
+
$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}{$deprecated_table}" );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
}
|
135 |
|
136 |
+
//delete deprecated Options-----------------------------
|
137 |
+
$deprecated_options = [
|
138 |
+
'is_cities_installed',
|
139 |
+
'pw_delete_city_table_2_5',
|
140 |
+
'woocommerce_persian_feed',
|
141 |
+
'redirect_to_woo_persian_about_page',
|
142 |
+
'enable_woocommerce_notice_dismissed',
|
143 |
+
'Persian_Woocommerce_rename_old_table',
|
144 |
+
];
|
145 |
+
|
146 |
+
foreach ( $deprecated_options as $deprecated_option ) {
|
147 |
+
delete_option( $deprecated_option );
|
148 |
}
|
149 |
|
150 |
+
for ( $i = 0; $i < 10; $i ++ ) {
|
151 |
+
delete_option( 'persian_woo_notice_number_' . $i );
|
152 |
+
}
|
153 |
|
154 |
+
unlink( PW_DIR . '/.activated' );
|
|
|
|
|
155 |
|
156 |
+
if ( ! headers_sent() ) {
|
157 |
+
wp_redirect( admin_url( 'admin.php?page=persian-wc-about' ) );
|
158 |
+
die();
|
159 |
+
}
|
160 |
+
}
|
161 |
|
162 |
+
public function enqueue_scripts() {
|
163 |
+
$pages = [
|
164 |
+
'persian-wc-about',
|
165 |
+
'persian-wc-plugins',
|
166 |
+
'wc-persian-plugins',
|
167 |
+
'persian-wc-themes',
|
168 |
+
'wc-persian-themes',
|
169 |
+
];
|
170 |
|
171 |
+
$sanitize_text_field = sanitize_text_field( $_GET['page'] ?? null );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
|
173 |
+
if ( in_array( $sanitize_text_field, $pages ) ) {
|
174 |
+
wp_register_style( 'pw-admin-fonts', $this->plugin_url( 'assets/css/admin.font.css' ) );
|
175 |
+
wp_enqueue_style( 'pw-admin-fonts' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
176 |
}
|
177 |
+
}
|
178 |
|
179 |
+
public function plugin_url( $path = null ) {
|
180 |
+
return untrailingslashit( plugins_url( is_null( $path ) ? '/' : $path, PW_FILE ) );
|
181 |
+
}
|
182 |
|
183 |
+
public function get_options( $option_name = null, $default = false ) {
|
184 |
|
185 |
+
if ( is_null( $option_name ) ) {
|
186 |
+
return $this->options;
|
|
|
|
|
|
|
|
|
187 |
}
|
188 |
|
189 |
+
$default_options = [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
190 |
|
191 |
+
if ( ! empty( $this->tools ) && method_exists( $this->tools, 'get_tools_default' ) ) {
|
192 |
+
$default_options = $this->tools->get_tools_default();
|
193 |
+
}
|
194 |
+
|
195 |
+
if ( isset( $this->options[ $option_name ] ) ) {
|
196 |
+
return $this->options[ $option_name ];
|
197 |
+
} elseif ( isset( $default_options["PW_Options[$option_name]"] ) ) {
|
198 |
+
return $default_options["PW_Options[$option_name]"];
|
199 |
+
} else {
|
200 |
+
return $default;
|
201 |
}
|
202 |
}
|
203 |
+
|
204 |
+
}
|
205 |
|
206 |
if ( ! class_exists( 'Persian_Woocommerce_Plugin' ) ) {
|
207 |
class Persian_Woocommerce_Plugin extends Persian_Woocommerce_Core {
|
include/class-currencies.php
CHANGED
@@ -1,43 +1,41 @@
|
|
1 |
-
<?php
|
2 |
-
exit;
|
3 |
-
}
|
4 |
-
|
5 |
-
if ( ! class_exists( 'Persian_Woocommerce_Currencies' ) ) :
|
6 |
|
7 |
-
|
8 |
|
9 |
-
|
10 |
|
11 |
-
|
12 |
|
13 |
-
|
14 |
-
'IRR' => __( 'ریال', 'woocommerce' ),
|
15 |
-
'IRHR' => __( 'هزار ریال', 'woocommerce' ),
|
16 |
-
'IRT' => __( 'تومان', 'woocommerce' ),
|
17 |
-
'IRHT' => __( 'هزار تومان', 'woocommerce' )
|
18 |
-
);
|
19 |
|
20 |
-
|
21 |
-
|
22 |
-
|
|
|
|
|
|
|
23 |
|
24 |
-
|
|
|
|
|
25 |
|
26 |
-
|
27 |
-
unset( $currencies[ $key ] );
|
28 |
-
}
|
29 |
|
30 |
-
|
|
|
31 |
}
|
32 |
|
33 |
-
|
|
|
34 |
|
35 |
-
|
36 |
-
return $this->currencies[ $currency ];
|
37 |
-
}
|
38 |
|
39 |
-
|
|
|
40 |
}
|
|
|
|
|
41 |
}
|
42 |
-
|
43 |
-
|
|
1 |
+
<?php
|
|
|
|
|
|
|
|
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || exit;
|
4 |
|
5 |
+
class Persian_Woocommerce_Currencies extends Persian_Woocommerce_Core {
|
6 |
|
7 |
+
public $currencies;
|
8 |
|
9 |
+
public function __construct() {
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
+
$this->currencies = [
|
12 |
+
'IRR' => __( 'ریال', 'woocommerce' ),
|
13 |
+
'IRHR' => __( 'هزار ریال', 'woocommerce' ),
|
14 |
+
'IRT' => __( 'تومان', 'woocommerce' ),
|
15 |
+
'IRHT' => __( 'هزار تومان', 'woocommerce' ),
|
16 |
+
];
|
17 |
|
18 |
+
add_filter( 'woocommerce_currencies', [ $this, 'currencies' ] );
|
19 |
+
add_filter( 'woocommerce_currency_symbol', [ $this, 'currencies_symbol' ], 10, 2 );
|
20 |
+
}
|
21 |
|
22 |
+
public function currencies( $currencies ): array {
|
|
|
|
|
23 |
|
24 |
+
foreach ( $this->currencies as $key => $value ) {
|
25 |
+
unset( $currencies[ $key ] );
|
26 |
}
|
27 |
|
28 |
+
return array_merge( $currencies, $this->currencies );
|
29 |
+
}
|
30 |
|
31 |
+
public function currencies_symbol( $currency_symbol, $currency ) {
|
|
|
|
|
32 |
|
33 |
+
if ( in_array( $currency, array_keys( $this->currencies ) ) ) {
|
34 |
+
return $this->currencies[ $currency ];
|
35 |
}
|
36 |
+
|
37 |
+
return $currency_symbol;
|
38 |
}
|
39 |
+
}
|
40 |
+
|
41 |
+
new Persian_Woocommerce_Currencies();
|
include/class-gateways.php
CHANGED
@@ -1,678 +1,691 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
if ( ! class_exists( 'Persian_Woocommerce_Gateways' ) && class_exists( 'WC_Payment_Gateway' ) ) :
|
6 |
-
|
7 |
-
abstract class Persian_Woocommerce_Gateways extends WC_Payment_Gateway {
|
8 |
-
|
9 |
-
protected $order_id = 0;
|
10 |
-
|
11 |
-
private $verification_params;
|
12 |
-
|
13 |
-
const PREFIX = 'Woocommerce_Ir_Gateway_';
|
14 |
-
|
15 |
-
public static function register( $gateway ) {
|
16 |
-
add_filter( 'woocommerce_payment_gateways', function ( $methods ) use ( $gateway ) {
|
17 |
-
|
18 |
-
$methods[] = self::PREFIX . $gateway;
|
19 |
-
|
20 |
-
return
|
21 |
-
} );
|
22 |
-
}
|
23 |
-
|
24 |
-
protected function init( $gateway ) {
|
25 |
-
|
26 |
-
$Gateway_Class = get_class( $gateway );
|
27 |
-
|
28 |
-
if ( stripos( $Gateway_Class, self::PREFIX ) === false ) {
|
29 |
-
return false;
|
30 |
-
}
|
31 |
-
|
32 |
-
$gateway_class = strtolower( $Gateway_Class );
|
33 |
-
$gateway->id = str_ireplace( self::PREFIX, '', $gateway_class );
|
34 |
-
|
35 |
-
if ( method_exists( $gateway, 'init_form_fields' ) ) {
|
36 |
-
$gateway->init_form_fields();
|
37 |
-
} else {
|
38 |
-
$this->init_form_fields();
|
39 |
-
}
|
40 |
-
|
41 |
-
if ( method_exists( $gateway, 'init_settings' ) ) {
|
42 |
-
$gateway->init_settings();
|
43 |
-
} else {
|
44 |
-
$this->init_settings();
|
45 |
-
}
|
46 |
-
|
47 |
-
$gateway->has_fields = false;
|
48 |
-
$gateway->title = $gateway->settings['title'] ?: $gateway->method_title;
|
49 |
-
$gateway->description = $gateway->settings['description'];
|
50 |
-
$gateway->method_description = $gateway->method_description ?: sprintf( 'تنظیمات درگاه پرداخت %s برای افزونه فروشگاه ساز ووکامرس', $gateway->method_title );
|
51 |
-
|
52 |
-
if ( empty( $gateway->icon ) && class_exists( 'ReflectionClass' ) ) {
|
53 |
-
try {
|
54 |
-
$file = ( new ReflectionClass( $Gateway_Class ) )->getFileName();
|
55 |
-
$gateway->icon = trailingslashit( WP_PLUGIN_URL ) . plugin_basename( dirname( $file ) ) . '/assets/images/logo.png';
|
56 |
-
} catch ( Exception $e ) {
|
57 |
-
}
|
58 |
-
}
|
59 |
-
|
60 |
-
add_action( 'woocommerce_update_options_payment_gateways_' . $gateway->id,
|
61 |
-
|
62 |
-
|
63 |
-
add_filter( 'woocommerce_settings_api_sanitized_fields_' . $gateway->id,
|
64 |
-
$gateway,
|
65 |
-
'unsanitie_fields'
|
66 |
-
|
67 |
-
|
68 |
-
add_action( 'woocommerce_receipt_' . $gateway->id,
|
69 |
-
|
70 |
-
|
71 |
-
add_action( 'woocommerce_api_' . $gateway_class,
|
72 |
-
|
73 |
-
}
|
74 |
-
|
75 |
-
public function unsanitie_fields( $fields ) {
|
76 |
-
|
77 |
-
$unsanitie_fields =
|
78 |
-
foreach ( (array) $fields as $key => $value ) {
|
79 |
-
if ( substr( $key, - 3 ) == '___' ) {
|
80 |
-
$unsanitie_fields[] = $key;
|
81 |
-
}
|
82 |
-
}
|
83 |
-
|
84 |
-
if ( ! empty( $unsanitie_fields ) ) {
|
85 |
-
foreach ( $_POST as $key => $value ) {
|
86 |
-
foreach ( $unsanitie_fields as $item ) {
|
87 |
-
if ( stripos( $key, $item ) !== false ) {
|
88 |
-
$fields[ $item ] = trim( $value );
|
89 |
-
}
|
90 |
-
}
|
91 |
-
}
|
92 |
-
}
|
93 |
-
|
94 |
-
return $fields;
|
95 |
-
}
|
96 |
-
|
97 |
-
public function init_form_fields() {
|
98 |
-
|
99 |
-
$main =
|
100 |
-
'enabled' =>
|
101 |
-
'title' => 'فعالسازی',
|
102 |
-
'type' => 'checkbox',
|
103 |
-
'label' => 'فعالسازی درگاه',
|
104 |
-
'description' => 'برای فعالسازی این درگاه پرداخت باید چک باکس را تیک بزنید',
|
105 |
-
'default' => 'yes',
|
106 |
-
'desc_tip' => true,
|
107 |
-
|
108 |
-
'title' =>
|
109 |
-
'title' => 'عنوان درگاه',
|
110 |
-
'type' => 'text',
|
111 |
-
'description' => 'عنوان این درگاه که در طی خرید به مشتری نمایش داده میشود',
|
112 |
-
'default' => $this->method_title,
|
113 |
-
'desc_tip' => true,
|
114 |
-
|
115 |
-
'description' =>
|
116 |
-
'title' => 'توضیحات درگاه',
|
117 |
-
'type' => 'text',
|
118 |
-
'desc_tip' => true,
|
119 |
-
'description' => 'توضیحاتی که در طی عملیات پرداخت برای این درگاه نمایش داده خواهد شد',
|
120 |
-
'default' => sprintf( 'پرداخت امن به وسیله کلیه کارت های عضو شتاب از طریق درگاه %s', $this->method_title )
|
121 |
-
|
122 |
-
'direct_redirect' =>
|
123 |
-
'title' => 'هدایت مستقیم به درگاه',
|
124 |
-
'type' => 'checkbox',
|
125 |
-
'label' => 'در صورتی که قصد دارید کاربر مستقیما به درگاه هدایت شود و در صفحه پیشفاکتور گزینه پرداحت را کلیک نکند، این گزینه را فعال نمایید.',
|
126 |
-
'description' => 'به صورت پیشفرض (غیرفعال بودن این گزینه) خریدار قبل از هدایت به درگاه ابتدا شماره سفارش و قیمت نهایی را مشاهده میکند و سپس با زدن دکمه تایید به درگاه هدایت میشود.',
|
127 |
-
'default' => 'no',
|
128 |
-
'desc_tip' => true,
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
$fields = $this->fields();
|
133 |
-
|
134 |
-
$shortcodes =
|
135 |
-
foreach ( $this->fields_shortcodes() as $shortcode => $title ) {
|
136 |
-
$shortcode = '{' . trim( $shortcode, '\{\}' ) . '}';
|
137 |
-
$shortcodes[] = "$shortcode:$title";
|
138 |
-
}
|
139 |
-
$shortcodes = '<br>' . implode( ' - ', $shortcodes );
|
140 |
-
|
141 |
-
unset( $fields['shortcodes'] );
|
142 |
-
|
143 |
-
$messages =
|
144 |
-
'completed_massage' =>
|
145 |
-
'title' => 'پیام پرداخت موفق',
|
146 |
-
'type' => 'textarea',
|
147 |
-
'description' => 'متن پیامی که میخواهید بعد از پرداخت موفق به کاربر نمایش دهید را وارد نمایید. همچنین می توانید از شورت کدهای زیر نیز استفاده نمایید.' . $shortcodes,
|
148 |
-
'default' => 'با تشکر از شما. سفارش شما با موفقیت پرداخت شد.',
|
149 |
-
|
150 |
-
'failed_massage' =>
|
151 |
-
'title' => 'پیام پرداخت ناموفق',
|
152 |
-
'type' => 'textarea',
|
153 |
-
'description' => 'متن پیامی که میخواهید بعد از پرداخت ناموفق به کاربر نمایش دهید را وارد نمایید. همچنین می توانید از شورت کد {fault} برای نمایش دلیل خطای رخ داده استفاده نمایید. این دلیل خطا از سایت درگاه ارسال میگردد.',
|
154 |
-
'default' => 'پرداخت شما ناموفق بوده است. لطفا مجددا تلاش نمایید یا در صورت بروز اشکال با مدیر سایت تماس بگیرید.',
|
155 |
-
|
156 |
-
'cancelled_massage' =>
|
157 |
-
'title' => 'پیام انصراف از پرداخت',
|
158 |
-
'type' => 'textarea',
|
159 |
-
'description' => 'متن پیامی که میخواهید بعد از انصراف کاربر از پرداخت نمایش دهید را وارد نمایید. این پیام بعد از بازگشت از بانک نمایش داده خواهد شد.',
|
160 |
-
'default' => 'پرداخت به دلیل انصراف شما ناتمام باقی ماند.',
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
$this->form_fields = array_merge( $main, $fields, $messages );
|
165 |
-
foreach ( array_merge( $main, $messages ) as $key => $value ) {
|
166 |
-
if ( isset( $fields[ $key ] ) ) {
|
167 |
-
$this->form_fields[ $key ] = $fields[ $key ];
|
168 |
-
}
|
169 |
-
}
|
170 |
-
$this->form_fields = array_filter( $this->form_fields );
|
171 |
-
}
|
172 |
-
|
173 |
-
public function process_payment( $order ) {
|
174 |
-
|
175 |
-
$order = $this->get_order( $order );
|
176 |
-
|
177 |
-
return
|
178 |
-
'result' => 'success',
|
179 |
-
'redirect' => $order->get_checkout_payment_url( true )
|
180 |
-
|
181 |
-
}
|
182 |
-
|
183 |
-
public function process_payment_request( $order_id ) {
|
184 |
-
|
185 |
-
$this->order_id = $order_id;
|
186 |
-
$this->session( 'set', 'order_id', $order_id );
|
187 |
-
$order = $this->get_order( $order_id );
|
188 |
-
$form = $this->option( 'direct_redirect' ) != '1';
|
189 |
-
|
190 |
-
if ( $form ) {
|
191 |
-
|
192 |
-
<input type="submit" name="pw-gateway-submit" class="pw-gateway-submit button alt" value="پرداخت"/>
|
193 |
-
<a class="pw-gateway-cancel button cancel" href="' . $this->get_checkout_url() . '">بازگشت</a>
|
194 |
-
</form><br/>';
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
$
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
$
|
222 |
-
|
223 |
-
if ( !
|
224 |
-
$
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
$
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
$
|
247 |
-
|
248 |
-
|
249 |
-
$
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
if (
|
273 |
-
$
|
274 |
-
}
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
if (
|
290 |
-
$
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
if (
|
309 |
-
|
310 |
-
}
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
$
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
$Mobile =
|
352 |
-
|
353 |
-
$Mobile =
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
}
|
394 |
-
|
395 |
-
$
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
$price
|
401 |
-
}
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
$price
|
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 |
-
|
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 |
-
if (
|
535 |
-
$
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
if (
|
543 |
-
|
544 |
-
}
|
545 |
-
$this->
|
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 |
-
|
579 |
-
|
580 |
-
|
581 |
-
return
|
582 |
-
}
|
583 |
-
|
584 |
-
protected function
|
585 |
-
|
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 |
-
if ( $wc_session && method_exists( WC()->session, '
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
}
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
}
|
654 |
-
|
655 |
-
|
656 |
-
}
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
678 |
include 'gateways/class-payir.php';
|
1 |
+
<?php
|
2 |
+
|
3 |
+
defined( 'ABSPATH' ) || exit;
|
4 |
+
|
5 |
+
if ( ! class_exists( 'Persian_Woocommerce_Gateways' ) && class_exists( 'WC_Payment_Gateway' ) ) :
|
6 |
+
|
7 |
+
abstract class Persian_Woocommerce_Gateways extends WC_Payment_Gateway {
|
8 |
+
|
9 |
+
protected $order_id = 0;
|
10 |
+
|
11 |
+
private $verification_params;
|
12 |
+
|
13 |
+
const PREFIX = 'Woocommerce_Ir_Gateway_';
|
14 |
+
|
15 |
+
public static function register( $gateway ) {
|
16 |
+
add_filter( 'woocommerce_payment_gateways', function ( $methods ) use ( $gateway ) {
|
17 |
+
|
18 |
+
$methods[] = self::PREFIX . $gateway;
|
19 |
+
|
20 |
+
return $methods;
|
21 |
+
} );
|
22 |
+
}
|
23 |
+
|
24 |
+
protected function init( $gateway ) {
|
25 |
+
|
26 |
+
$Gateway_Class = get_class( $gateway );
|
27 |
+
|
28 |
+
if ( stripos( $Gateway_Class, self::PREFIX ) === false ) {
|
29 |
+
return false;
|
30 |
+
}
|
31 |
+
|
32 |
+
$gateway_class = strtolower( $Gateway_Class );
|
33 |
+
$gateway->id = str_ireplace( self::PREFIX, '', $gateway_class );
|
34 |
+
|
35 |
+
if ( method_exists( $gateway, 'init_form_fields' ) ) {
|
36 |
+
$gateway->init_form_fields();
|
37 |
+
} else {
|
38 |
+
$this->init_form_fields();
|
39 |
+
}
|
40 |
+
|
41 |
+
if ( method_exists( $gateway, 'init_settings' ) ) {
|
42 |
+
$gateway->init_settings();
|
43 |
+
} else {
|
44 |
+
$this->init_settings();
|
45 |
+
}
|
46 |
+
|
47 |
+
$gateway->has_fields = false;
|
48 |
+
$gateway->title = $gateway->settings['title'] ?: $gateway->method_title;
|
49 |
+
$gateway->description = $gateway->settings['description'];
|
50 |
+
$gateway->method_description = $gateway->method_description ?: sprintf( 'تنظیمات درگاه پرداخت %s برای افزونه فروشگاه ساز ووکامرس', $gateway->method_title );
|
51 |
+
|
52 |
+
if ( empty( $gateway->icon ) && class_exists( 'ReflectionClass' ) ) {
|
53 |
+
try {
|
54 |
+
$file = ( new ReflectionClass( $Gateway_Class ) )->getFileName();
|
55 |
+
$gateway->icon = trailingslashit( WP_PLUGIN_URL ) . plugin_basename( dirname( $file ) ) . '/assets/images/logo.png';
|
56 |
+
} catch ( Exception $e ) {
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
add_action( 'woocommerce_update_options_payment_gateways_' . $gateway->id,
|
61 |
+
[ $gateway, 'process_admin_options' ] );
|
62 |
+
|
63 |
+
add_filter( 'woocommerce_settings_api_sanitized_fields_' . $gateway->id, [
|
64 |
+
$gateway,
|
65 |
+
'unsanitie_fields',
|
66 |
+
] );
|
67 |
+
|
68 |
+
add_action( 'woocommerce_receipt_' . $gateway->id,
|
69 |
+
[ $gateway, 'process_payment_request' ] );
|
70 |
+
|
71 |
+
add_action( 'woocommerce_api_' . $gateway_class,
|
72 |
+
[ $gateway, 'process_payment_verify' ] );
|
73 |
+
}
|
74 |
+
|
75 |
+
public function unsanitie_fields( $fields ) {
|
76 |
+
|
77 |
+
$unsanitie_fields = [];
|
78 |
+
foreach ( (array) $fields as $key => $value ) {
|
79 |
+
if ( substr( $key, - 3 ) == '___' ) {
|
80 |
+
$unsanitie_fields[] = $key;
|
81 |
+
}
|
82 |
+
}
|
83 |
+
|
84 |
+
if ( ! empty( $unsanitie_fields ) ) {
|
85 |
+
foreach ( $_POST as $key => $value ) {
|
86 |
+
foreach ( $unsanitie_fields as $item ) {
|
87 |
+
if ( stripos( $key, $item ) !== false ) {
|
88 |
+
$fields[ $item ] = trim( $value );
|
89 |
+
}
|
90 |
+
}
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
return $fields;
|
95 |
+
}
|
96 |
+
|
97 |
+
public function init_form_fields() {
|
98 |
+
|
99 |
+
$main = [
|
100 |
+
'enabled' => [
|
101 |
+
'title' => 'فعالسازی',
|
102 |
+
'type' => 'checkbox',
|
103 |
+
'label' => 'فعالسازی درگاه',
|
104 |
+
'description' => 'برای فعالسازی این درگاه پرداخت باید چک باکس را تیک بزنید',
|
105 |
+
'default' => 'yes',
|
106 |
+
'desc_tip' => true,
|
107 |
+
],
|
108 |
+
'title' => [
|
109 |
+
'title' => 'عنوان درگاه',
|
110 |
+
'type' => 'text',
|
111 |
+
'description' => 'عنوان این درگاه که در طی خرید به مشتری نمایش داده میشود',
|
112 |
+
'default' => $this->method_title,
|
113 |
+
'desc_tip' => true,
|
114 |
+
],
|
115 |
+
'description' => [
|
116 |
+
'title' => 'توضیحات درگاه',
|
117 |
+
'type' => 'text',
|
118 |
+
'desc_tip' => true,
|
119 |
+
'description' => 'توضیحاتی که در طی عملیات پرداخت برای این درگاه نمایش داده خواهد شد',
|
120 |
+
'default' => sprintf( 'پرداخت امن به وسیله کلیه کارت های عضو شتاب از طریق درگاه %s', $this->method_title ),
|
121 |
+
],
|
122 |
+
'direct_redirect' => [
|
123 |
+
'title' => 'هدایت مستقیم به درگاه',
|
124 |
+
'type' => 'checkbox',
|
125 |
+
'label' => 'در صورتی که قصد دارید کاربر مستقیما به درگاه هدایت شود و در صفحه پیشفاکتور گزینه پرداحت را کلیک نکند، این گزینه را فعال نمایید.',
|
126 |
+
'description' => 'به صورت پیشفرض (غیرفعال بودن این گزینه) خریدار قبل از هدایت به درگاه ابتدا شماره سفارش و قیمت نهایی را مشاهده میکند و سپس با زدن دکمه تایید به درگاه هدایت میشود.',
|
127 |
+
'default' => 'no',
|
128 |
+
'desc_tip' => true,
|
129 |
+
],
|
130 |
+
];
|
131 |
+
|
132 |
+
$fields = $this->fields();
|
133 |
+
|
134 |
+
$shortcodes = [];
|
135 |
+
foreach ( $this->fields_shortcodes() as $shortcode => $title ) {
|
136 |
+
$shortcode = '{' . trim( $shortcode, '\{\}' ) . '}';
|
137 |
+
$shortcodes[] = "$shortcode:$title";
|
138 |
+
}
|
139 |
+
$shortcodes = '<br>' . implode( ' - ', $shortcodes );
|
140 |
+
|
141 |
+
unset( $fields['shortcodes'] );
|
142 |
+
|
143 |
+
$messages = [
|
144 |
+
'completed_massage' => [
|
145 |
+
'title' => 'پیام پرداخت موفق',
|
146 |
+
'type' => 'textarea',
|
147 |
+
'description' => 'متن پیامی که میخواهید بعد از پرداخت موفق به کاربر نمایش دهید را وارد نمایید. همچنین می توانید از شورت کدهای زیر نیز استفاده نمایید.' . $shortcodes,
|
148 |
+
'default' => 'با تشکر از شما. سفارش شما با موفقیت پرداخت شد.',
|
149 |
+
],
|
150 |
+
'failed_massage' => [
|
151 |
+
'title' => 'پیام پرداخت ناموفق',
|
152 |
+
'type' => 'textarea',
|
153 |
+
'description' => 'متن پیامی که میخواهید بعد از پرداخت ناموفق به کاربر نمایش دهید را وارد نمایید. همچنین می توانید از شورت کد {fault} برای نمایش دلیل خطای رخ داده استفاده نمایید. این دلیل خطا از سایت درگاه ارسال میگردد.',
|
154 |
+
'default' => 'پرداخت شما ناموفق بوده است. لطفا مجددا تلاش نمایید یا در صورت بروز اشکال با مدیر سایت تماس بگیرید.',
|
155 |
+
],
|
156 |
+
'cancelled_massage' => [
|
157 |
+
'title' => 'پیام انصراف از پرداخت',
|
158 |
+
'type' => 'textarea',
|
159 |
+
'description' => 'متن پیامی که میخواهید بعد از انصراف کاربر از پرداخت نمایش دهید را وارد نمایید. این پیام بعد از بازگشت از بانک نمایش داده خواهد شد.',
|
160 |
+
'default' => 'پرداخت به دلیل انصراف شما ناتمام باقی ماند.',
|
161 |
+
],
|
162 |
+
];
|
163 |
+
|
164 |
+
$this->form_fields = array_merge( $main, $fields, $messages );
|
165 |
+
foreach ( array_merge( $main, $messages ) as $key => $value ) {
|
166 |
+
if ( isset( $fields[ $key ] ) ) {
|
167 |
+
$this->form_fields[ $key ] = $fields[ $key ];
|
168 |
+
}
|
169 |
+
}
|
170 |
+
$this->form_fields = array_filter( $this->form_fields );
|
171 |
+
}
|
172 |
+
|
173 |
+
public function process_payment( $order ) {
|
174 |
+
|
175 |
+
$order = $this->get_order( $order );
|
176 |
+
|
177 |
+
return [
|
178 |
+
'result' => 'success',
|
179 |
+
'redirect' => $order->get_checkout_payment_url( true ),
|
180 |
+
];
|
181 |
+
}
|
182 |
+
|
183 |
+
public function process_payment_request( $order_id ) {
|
184 |
+
|
185 |
+
$this->order_id = $order_id;
|
186 |
+
$this->session( 'set', 'order_id', $order_id );
|
187 |
+
$order = $this->get_order( $order_id );
|
188 |
+
$form = $this->option( 'direct_redirect' ) != '1';
|
189 |
+
|
190 |
+
if ( $form ) {
|
191 |
+
$globalpaymentform = '<form action="" method="POST" class="pw-gateway-checkout-form" id="pw-gateway-checkout-form-' . $this->id . '">
|
192 |
+
<input type="submit" name="pw-gateway-submit" class="pw-gateway-submit button alt" value="پرداخت"/>
|
193 |
+
<a class="pw-gateway-cancel button cancel" href="' . $this->get_checkout_url() . '">بازگشت</a>
|
194 |
+
</form><br/>';
|
195 |
+
|
196 |
+
echo wp_kses($globalpaymentform,array(
|
197 |
+
'form'=>array('action','method','class','id'),
|
198 |
+
'input'=>array('type','name','class','value'),
|
199 |
+
'a'=>array('class','href')
|
200 |
+
|
201 |
+
));
|
202 |
+
}
|
203 |
+
|
204 |
+
if ( ! $form || isset( $_POST['pw-gateway-submit'] ) ) {
|
205 |
+
$error = $this->request( $order );
|
206 |
+
$this->set_message( 'failed', $error, true, false );
|
207 |
+
$order->add_order_note( sprintf( 'در هنگام اتصال به درگاه %s خطای زیر رخ داده است.', $this->title ) . "<br>{$error}" );
|
208 |
+
}
|
209 |
+
}
|
210 |
+
|
211 |
+
public function process_payment_verify() {
|
212 |
+
|
213 |
+
$redirect = $this->get_checkout_url();
|
214 |
+
|
215 |
+
$order_id = ! empty( $_GET['wc_order'] ) ? intval( $_GET['wc_order'] ) : $this->session( 'get', 'order_id' );
|
216 |
+
|
217 |
+
if ( empty( $order_id ) ) {
|
218 |
+
$this->set_message( 'failed', 'شماره سفارش وجود ندارد.', true, $redirect );
|
219 |
+
}
|
220 |
+
|
221 |
+
$order = $this->get_order( $order_id );
|
222 |
+
|
223 |
+
if ( ! $this->needs_payment( $order ) ) {
|
224 |
+
$this->set_message( 'failed', 'وضعیت تراکنش قبلا مشخص شده است.', true, $redirect, true );
|
225 |
+
}
|
226 |
+
|
227 |
+
$this->order_id = $order_id;
|
228 |
+
|
229 |
+
$result = $this->verify( $order );
|
230 |
+
|
231 |
+
if ( ! is_array( $result ) ) {
|
232 |
+
$error = is_string( $result ) && strlen( $result ) > 5 ? $result : 'اطلاعات صحت سنجی تراکنش صحیح نیست.';
|
233 |
+
$this->set_message( 'failed', $error, true, $redirect, true );
|
234 |
+
}
|
235 |
+
|
236 |
+
$error = '';
|
237 |
+
$status = ! empty( $result['status'] ) ? $result['status'] : '';
|
238 |
+
$transaction_id = ! empty( $result['transaction_id'] ) ? $result['transaction_id'] : '';
|
239 |
+
|
240 |
+
if ( $status == 'completed' ) {
|
241 |
+
|
242 |
+
$redirect = $this->get_return_url( $order );
|
243 |
+
|
244 |
+
$order->payment_complete( $transaction_id );
|
245 |
+
$this->empty_cart();
|
246 |
+
$this->set_verification();
|
247 |
+
|
248 |
+
$shortcodes = $this->get_shortcodes_values();
|
249 |
+
$note = [ 'تراکنش موفق بود.' ];
|
250 |
+
foreach ( $this->fields_shortcodes() as $key => $value ) {
|
251 |
+
$key = trim( $key, '\{\}' );
|
252 |
+
$note[] = "$value : {$shortcodes[$key]}";
|
253 |
+
}
|
254 |
+
$order->add_order_note( implode( "<br>", $note ), 1 );
|
255 |
+
|
256 |
+
} elseif ( $status == 'cancelled' ) {
|
257 |
+
$order->add_order_note( 'تراکنش به بعلت انصراف کاربر ناتمام باقی ماند.', 1 );
|
258 |
+
} else {
|
259 |
+
$error = ! empty( $result['error'] ) ? $result['error'] : 'در حین پرداخت خطایی رخ داده است.';
|
260 |
+
$order->add_order_note( sprintf( 'در هنگام بازگشت از درگاه %s خطای زیر رخ داده است.', $this->title ) . "<br>{$error}", 1 );
|
261 |
+
}
|
262 |
+
|
263 |
+
$this->set_message( $status, $error, true, $redirect );
|
264 |
+
exit;
|
265 |
+
}
|
266 |
+
|
267 |
+
/*
|
268 |
+
* ---------------------------------------------------
|
269 |
+
* */
|
270 |
+
protected function order_id( $order ) {
|
271 |
+
|
272 |
+
if ( is_numeric( $order ) ) {
|
273 |
+
$order_id = $order;
|
274 |
+
} elseif ( method_exists( $order, 'get_id' ) ) {
|
275 |
+
$order_id = $order->get_id();
|
276 |
+
} elseif ( ! ( $order_id = absint( get_query_var( 'order-pay' ) ) ) ) {
|
277 |
+
$order_id = $order->id;
|
278 |
+
}
|
279 |
+
|
280 |
+
if ( ! empty( $order_id ) ) {
|
281 |
+
$this->order_id = $order_id;
|
282 |
+
}
|
283 |
+
|
284 |
+
return $order_id;
|
285 |
+
}
|
286 |
+
|
287 |
+
protected function get_order( $order = 0 ) {
|
288 |
+
|
289 |
+
if ( empty( $order ) ) {
|
290 |
+
$order = $this->order_id;
|
291 |
+
}
|
292 |
+
|
293 |
+
if ( empty( $order ) ) {
|
294 |
+
return (object) [];
|
295 |
+
}
|
296 |
+
|
297 |
+
if ( is_numeric( $order ) ) {
|
298 |
+
$this->order_id = $order;
|
299 |
+
|
300 |
+
$order = new WC_Order( $order );
|
301 |
+
}
|
302 |
+
|
303 |
+
return $order;
|
304 |
+
}
|
305 |
+
|
306 |
+
protected function get_order_props( $prop, $default = '' ) {
|
307 |
+
|
308 |
+
if ( empty( $this->order_id ) ) {
|
309 |
+
return '';
|
310 |
+
}
|
311 |
+
|
312 |
+
$order = $this->get_order();
|
313 |
+
|
314 |
+
$method = 'get_' . $prop;
|
315 |
+
|
316 |
+
if ( method_exists( $order, $method ) ) {
|
317 |
+
$prop = $order->$method();
|
318 |
+
} elseif ( ! empty( $order->{$prop} ) ) {
|
319 |
+
$prop = $order->{$prop};
|
320 |
+
} else {
|
321 |
+
$prop = '';
|
322 |
+
}
|
323 |
+
|
324 |
+
return ! empty( $prop ) ? $prop : $default;
|
325 |
+
}
|
326 |
+
|
327 |
+
protected function get_order_items( $product = false ) {
|
328 |
+
|
329 |
+
if ( empty( $this->order_id ) ) {
|
330 |
+
return [];
|
331 |
+
}
|
332 |
+
|
333 |
+
$order = $this->get_order();
|
334 |
+
$items = $order->get_items();
|
335 |
+
|
336 |
+
if ( $product ) {
|
337 |
+
$products = [];
|
338 |
+
foreach ( (array) $items as $item ) {
|
339 |
+
$products[] = $item['name'] . ' (' . $item['qty'] . ') ';
|
340 |
+
}
|
341 |
+
|
342 |
+
return implode( ' - ', $products );
|
343 |
+
}
|
344 |
+
|
345 |
+
return $items;
|
346 |
+
}
|
347 |
+
|
348 |
+
protected function get_order_mobile() {
|
349 |
+
|
350 |
+
$Mobile = $this->get_order_props( 'billing_phone' );
|
351 |
+
$Mobile = $this->get_order_props( 'billing_mobile', $Mobile );
|
352 |
+
|
353 |
+
$Mobile = str_ireplace( [ '۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹' ],
|
354 |
+
[ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ], $Mobile ); //farsi
|
355 |
+
|
356 |
+
$Mobile = str_ireplace( [ '٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩' ],
|
357 |
+
[ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ], $Mobile ); //arabi
|
358 |
+
|
359 |
+
$Mobile = preg_replace( '/\D/is', '', $Mobile );
|
360 |
+
$Mobile = ltrim( $Mobile, '0' );
|
361 |
+
$Mobile = substr( $Mobile, 0, 2 ) == '98' ? substr( $Mobile, 2 ) : $Mobile;
|
362 |
+
|
363 |
+
return '0' . $Mobile;
|
364 |
+
}
|
365 |
+
|
366 |
+
protected function get_currency() {
|
367 |
+
|
368 |
+
if ( empty( $this->order_id ) ) {
|
369 |
+
return '';
|
370 |
+
}
|
371 |
+
|
372 |
+
$order = $this->get_order();
|
373 |
+
|
374 |
+
$currency = method_exists( $order, 'get_currency' ) ? $order->get_currency() : $order->get_order_currency();
|
375 |
+
|
376 |
+
$irt = [ 'irt', 'toman', 'tomaan', 'iran toman', 'iranian toman', 'تومان', 'تومان ایران' ];
|
377 |
+
if ( in_array( strtolower( $currency ), $irt ) ) {
|
378 |
+
$currency = 'IRT';
|
379 |
+
}
|
380 |
+
|
381 |
+
$irr = [ 'irr', 'rial', 'iran rial', 'iranian rial', 'ریال', 'ریال ایران' ];
|
382 |
+
if ( in_array( strtolower( $currency ), $irr ) ) {
|
383 |
+
$currency = 'IRR';
|
384 |
+
}
|
385 |
+
|
386 |
+
return $currency;
|
387 |
+
}
|
388 |
+
|
389 |
+
protected function get_total( $to_currency = 'IRR' ) {
|
390 |
+
|
391 |
+
if ( empty( $this->order_id ) ) {
|
392 |
+
return 0;
|
393 |
+
}
|
394 |
+
|
395 |
+
$order = $this->get_order();
|
396 |
+
|
397 |
+
if ( method_exists( $order, 'get_total' ) ) {
|
398 |
+
$price = $order->get_total();
|
399 |
+
} else {
|
400 |
+
$price = intval( $order->order_total );
|
401 |
+
}
|
402 |
+
|
403 |
+
$currency = strtoupper( $this->get_currency() );
|
404 |
+
$to_currency = strtoupper( $to_currency );
|
405 |
+
|
406 |
+
if ( in_array( $currency, [ 'IRHR', 'IRHT' ] ) ) {
|
407 |
+
$currency = str_ireplace( 'H', '', $currency );
|
408 |
+
$price *= 1000;
|
409 |
+
}
|
410 |
+
|
411 |
+
if ( $currency == 'IRR' && $to_currency == 'IRT' ) {
|
412 |
+
$price /= 10;
|
413 |
+
}
|
414 |
+
|
415 |
+
if ( $currency == 'IRT' && $to_currency == 'IRR' ) {
|
416 |
+
$price *= 10;
|
417 |
+
}
|
418 |
+
|
419 |
+
return $price;
|
420 |
+
}
|
421 |
+
|
422 |
+
protected function needs_payment( $order = 0 ) {
|
423 |
+
|
424 |
+
if ( empty( $order ) && empty( $this->order_id ) ) {
|
425 |
+
return true;
|
426 |
+
}
|
427 |
+
|
428 |
+
$order = $this->get_order( $order );
|
429 |
+
|
430 |
+
if ( method_exists( $order, 'needs_payment' ) ) {
|
431 |
+
return $order->needs_payment();
|
432 |
+
}
|
433 |
+
|
434 |
+
if ( empty( $this->order_id ) && ! empty( $order ) ) {
|
435 |
+
$this->order_id = $this->order_id( $order );
|
436 |
+
}
|
437 |
+
|
438 |
+
return ! in_array( $this->get_order_props( 'status' ), [ 'completed', 'processing' ] );
|
439 |
+
}
|
440 |
+
|
441 |
+
protected function get_verify_url() {
|
442 |
+
return add_query_arg( 'wc_order', $this->order_id, WC()->api_request_url( get_class( $this ) ) );
|
443 |
+
}
|
444 |
+
|
445 |
+
protected function get_checkout_url() {
|
446 |
+
if ( function_exists( 'wc_get_checkout_url' ) ) {
|
447 |
+
return wc_get_checkout_url();
|
448 |
+
} else {
|
449 |
+
global $woocommerce;
|
450 |
+
|
451 |
+
return $woocommerce->cart->get_checkout_url();
|
452 |
+
}
|
453 |
+
}
|
454 |
+
|
455 |
+
protected function empty_cart() {
|
456 |
+
if ( function_exists( 'wc_empty_cart' ) ) {
|
457 |
+
wc_empty_cart();
|
458 |
+
} elseif ( function_exists( 'WC' ) && ! empty( WC()->cart ) && method_exists( WC()->cart, 'empty_cart' ) ) {
|
459 |
+
WC()->cart->empty_cart();
|
460 |
+
} else {
|
461 |
+
global $woocommerce;
|
462 |
+
$woocommerce->cart->empty_cart();
|
463 |
+
}
|
464 |
+
}
|
465 |
+
|
466 |
+
protected function fields_shortcodes( $fields = [] ) {
|
467 |
+
|
468 |
+
$fields = ! empty( $fields ) ? $fields : $this->fields();
|
469 |
+
|
470 |
+
return ! empty( $fields['shortcodes'] ) && is_array( $fields['shortcodes'] ) ? $fields['shortcodes'] : [];
|
471 |
+
}
|
472 |
+
|
473 |
+
protected function get_shortcodes_values() {
|
474 |
+
|
475 |
+
$shortcodes = [];
|
476 |
+
foreach ( $this->fields_shortcodes() as $key => $value ) {
|
477 |
+
$key = trim( $key, '\{\}' );
|
478 |
+
$shortcodes[ $key ] = get_post_meta( $this->order_id, '_' . $key, true );
|
479 |
+
}
|
480 |
+
|
481 |
+
return $shortcodes;
|
482 |
+
}
|
483 |
+
|
484 |
+
protected function set_shortcodes( $shortcodes ) {
|
485 |
+
|
486 |
+
$fields_shortcodes = $this->fields_shortcodes();
|
487 |
+
|
488 |
+
foreach ( $shortcodes as $key => $value ) {
|
489 |
+
|
490 |
+
if ( is_numeric( $key ) ) {
|
491 |
+
$key = $fields_shortcodes[ $key ];
|
492 |
+
}
|
493 |
+
|
494 |
+
if ( ! empty( $key ) && ! is_array( $key ) ) {
|
495 |
+
$key = trim( $key, '\{\}' );
|
496 |
+
update_post_meta( $this->order_id, '_' . $key, $value );
|
497 |
+
}
|
498 |
+
}
|
499 |
+
}
|
500 |
+
|
501 |
+
protected function set_message( $status, $error = '', $notice = true, $redirect = false, $failed_note = false ) {
|
502 |
+
|
503 |
+
if ( ! in_array( $status, [ 'completed', 'cancelled', 'failed' ] ) ) {
|
504 |
+
$status = 'failed';
|
505 |
+
}
|
506 |
+
|
507 |
+
if ( ! empty( $error ) && $failed_note && ( $order = $this->get_order() ) && ! empty( $order ) ) {
|
508 |
+
$order->add_order_note( 'خطا: ' . $error, 1 );
|
509 |
+
}
|
510 |
+
|
511 |
+
$shortcodes = array_merge( $this->get_shortcodes_values(), [ '{fault}' => $error ] );
|
512 |
+
|
513 |
+
$message = $this->option( $status . '_massage' );
|
514 |
+
$find = array_map( function ( $value ) {
|
515 |
+
return '{' . trim( $value, '\{\}' ) . '}';
|
516 |
+
}, array_keys( $shortcodes ) );
|
517 |
+
$message = str_ireplace( $find, array_values( $shortcodes ), $message );
|
518 |
+
$message = wpautop( wptexturize( trim( $message ) ) );
|
519 |
+
|
520 |
+
if ( $notice ) {
|
521 |
+
wc_add_notice( $message, $status == 'completed' ? 'success' : 'error' );
|
522 |
+
}
|
523 |
+
|
524 |
+
if ( $redirect ) {
|
525 |
+
wp_redirect( $redirect );
|
526 |
+
exit;
|
527 |
+
}
|
528 |
+
|
529 |
+
return $message;
|
530 |
+
}
|
531 |
+
|
532 |
+
protected function check_verification( $params ) {
|
533 |
+
|
534 |
+
if ( function_exists( 'func_get_args' ) ) {
|
535 |
+
$args = func_get_args();
|
536 |
+
if ( count( $args ) > 1 ) {
|
537 |
+
$params = array_merge( array_values( $args ), $params );
|
538 |
+
$params = implode( '_', array_unique( $params ) );
|
539 |
+
}
|
540 |
+
}
|
541 |
+
|
542 |
+
if ( is_array( $params ) ) {
|
543 |
+
$params = implode( '_', $params );
|
544 |
+
}
|
545 |
+
$params = $this->id . '_' . $params;
|
546 |
+
|
547 |
+
global $wpdb;
|
548 |
+
$query = "SELECT * FROM {$wpdb->prefix}postmeta WHERE meta_key='_verification_params' AND meta_value='%s'";
|
549 |
+
$check = $wpdb->get_row( $wpdb->prepare( $query, $params ) );
|
550 |
+
if ( ! empty( $check ) ) {
|
551 |
+
return $this->set_message( 'failed', 'این تراکنش قبلا یکبار وریفای شده بود.', true, $this->get_checkout_url(), true );
|
552 |
+
}
|
553 |
+
$this->verification_params = $params;
|
554 |
+
}
|
555 |
+
|
556 |
+
protected function set_verification() {
|
557 |
+
if ( ! empty( $this->verification_params ) ) {
|
558 |
+
update_post_meta( $this->order_id, '_verification_params', $this->verification_params );
|
559 |
+
}
|
560 |
+
}
|
561 |
+
|
562 |
+
/*
|
563 |
+
* Helpers
|
564 |
+
* */
|
565 |
+
protected function option( $name ) {
|
566 |
+
|
567 |
+
$option = '';
|
568 |
+
if ( method_exists( $this, 'get_option' ) ) {
|
569 |
+
$option = $this->get_option( $name );
|
570 |
+
} elseif ( ! empty( $this->settings[ $name ] ) ) {
|
571 |
+
$option = $this->settings[ $name ];
|
572 |
+
}
|
573 |
+
|
574 |
+
if ( in_array( strtolower( $option ), [ 'yes', 'on', 'true' ] ) ) {
|
575 |
+
$option = '1';
|
576 |
+
}
|
577 |
+
if ( in_array( strtolower( $option ), [ 'no', 'off', 'false' ] ) ) {
|
578 |
+
$option = false;
|
579 |
+
}
|
580 |
+
|
581 |
+
return $option;
|
582 |
+
}
|
583 |
+
|
584 |
+
protected function get( $name, $default = '' ) {
|
585 |
+
return ! empty( $_GET[ $name ] ) ? sanitize_text_field( $_GET[ $name ] ) : $default;
|
586 |
+
}
|
587 |
+
|
588 |
+
protected function post( $name, $default = '' ) {
|
589 |
+
return ! empty( $_POST[ $name ] ) ? sanitize_text_field( $_POST[ $name ] ) : $default;
|
590 |
+
}
|
591 |
+
|
592 |
+
protected function store_date( $key, $value ) {
|
593 |
+
$this->session( 'set', $key, $value );
|
594 |
+
update_post_meta( $this->order_id, '_' . $this->id . '_' . $key, $value );
|
595 |
+
}
|
596 |
+
|
597 |
+
protected function get_stored( $key ) {
|
598 |
+
|
599 |
+
$value = get_post_meta( $this->order_id, '_' . $this->id . '_' . $key, true );
|
600 |
+
|
601 |
+
return ! empty( $value ) ? $value : $this->session( 'get', $key );
|
602 |
+
}
|
603 |
+
|
604 |
+
protected function session( $action, $name, $value = '' ) {
|
605 |
+
|
606 |
+
global $woocommerce;
|
607 |
+
|
608 |
+
$name = $this->id . '_' . $name;
|
609 |
+
|
610 |
+
$wc_session = function_exists( 'WC' ) && ! empty( WC()->session );
|
611 |
+
|
612 |
+
if ( $action == 'set' ) {
|
613 |
+
|
614 |
+
if ( $wc_session && method_exists( WC()->session, 'set' ) ) {
|
615 |
+
WC()->session->set( $name, $value );
|
616 |
+
} else {
|
617 |
+
$woocommerce->session->{$name} = $value;
|
618 |
+
}
|
619 |
+
|
620 |
+
} elseif ( $action == 'get' ) {
|
621 |
+
|
622 |
+
if ( $wc_session && method_exists( WC()->session, 'get' ) ) {
|
623 |
+
$value = WC()->session->get( $name );
|
624 |
+
unset( WC()->session->{$name} );
|
625 |
+
} else {
|
626 |
+
$value = $woocommerce->session->{$name};
|
627 |
+
unset( $woocommerce->session->{$name} );
|
628 |
+
}
|
629 |
+
|
630 |
+
return $value;
|
631 |
+
}
|
632 |
+
|
633 |
+
return '';
|
634 |
+
}
|
635 |
+
|
636 |
+
protected function redirect( $url ) {
|
637 |
+
if ( ! headers_sent() ) {
|
638 |
+
header( 'Location: ' . trim( $url ) );
|
639 |
+
} else {
|
640 |
+
$RedirectforPay = "<script type='text/javascript'>window.onload = function () { top.location.href = '" . $url . "'; };</script>";
|
641 |
+
echo strip_tags($RedirectforPay,"<script>");
|
642 |
+
}
|
643 |
+
exit;
|
644 |
+
}
|
645 |
+
|
646 |
+
protected function submit_form( $form ) {
|
647 |
+
|
648 |
+
$name = 'pw_gateway_name_' . $this->id;
|
649 |
+
|
650 |
+
$form = explode( '>', $form );
|
651 |
+
$form[0] = preg_replace( '/name=[\'\"].*?[\'\"]/i', '', $form[0] );
|
652 |
+
$form = implode( '>', $form );
|
653 |
+
$form = str_ireplace( "<form", "<form name=\"{$name}\"", $form );
|
654 |
+
|
655 |
+
echo 'در حال هدایت به درگاه ....';
|
656 |
+
$function = "document.{$name}.submit();";
|
657 |
+
if ( headers_sent() ) {
|
658 |
+
$script = "<script type=\"text/javascript\">function PWformSubmit(){ $function } PWformSubmit();";
|
659 |
+
$script .= $function;
|
660 |
+
$script .= "</script>";
|
661 |
+
|
662 |
+
echo strip_tags($script,"<script>");
|
663 |
+
echo strip_tags($form,"<form><input>");
|
664 |
+
} else {
|
665 |
+
$script = "<script type=\"text/javascript\">$function</script>";
|
666 |
+
|
667 |
+
echo strip_tags($form,"<form><input>");
|
668 |
+
echo strip_tags($script,"<script>");
|
669 |
+
}
|
670 |
+
die();
|
671 |
+
}
|
672 |
+
|
673 |
+
protected function nusoap() {
|
674 |
+
if ( ! class_exists( 'nusoap_client' ) ) {
|
675 |
+
include_once( 'lib/nusoap.php' );
|
676 |
+
}
|
677 |
+
}
|
678 |
+
|
679 |
+
/*
|
680 |
+
* Abstract methods and must be override
|
681 |
+
* */
|
682 |
+
|
683 |
+
abstract protected function fields();
|
684 |
+
|
685 |
+
abstract protected function request( $order );
|
686 |
+
|
687 |
+
abstract protected function verify( $order );
|
688 |
+
|
689 |
+
}
|
690 |
+
endif;
|
691 |
include 'gateways/class-payir.php';
|
include/class-notice.php
ADDED
@@ -0,0 +1,321 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
defined( 'ABSPATH' ) || exit;
|
4 |
+
|
5 |
+
class Persian_Woocommerce_Notice {
|
6 |
+
|
7 |
+
public function __construct() {
|
8 |
+
add_action( 'admin_notices', [ $this, 'admin_notices' ], 10 );
|
9 |
+
add_action( 'wp_ajax_pw_dismiss_notice', [ $this, 'dismiss_notice' ] );
|
10 |
+
add_action( 'wp_ajax_pw_update_notice', [ $this, 'update_notice' ] );
|
11 |
+
}
|
12 |
+
|
13 |
+
public function admin_notices() {
|
14 |
+
|
15 |
+
if ( ! current_user_can( 'manage_options' ) && ! current_user_can( 'manage_woocommerce' ) ) {
|
16 |
+
return;
|
17 |
+
}
|
18 |
+
|
19 |
+
if ( $this->is_dismiss( 'all' ) ) {
|
20 |
+
return;
|
21 |
+
}
|
22 |
+
|
23 |
+
foreach ( $this->notices() as $notice ) {
|
24 |
+
|
25 |
+
if ( $notice['condition'] == false || $this->is_dismiss( $notice['id'] ) ) {
|
26 |
+
continue;
|
27 |
+
}
|
28 |
+
|
29 |
+
$dismissible = $notice['dismiss'] ? 'is-dismissible' : '';
|
30 |
+
|
31 |
+
$notice_id = esc_attr( $notice['id'] );
|
32 |
+
$notice_content = strip_tags( $notice['content'], '<p><a><input><b><img><ul><ol><li>' );
|
33 |
+
|
34 |
+
printf( '<div class="notice pw_notice notice-success %s" id="pw_%s"><p>%s</p></div>', $dismissible, $notice_id, $notice_content );
|
35 |
+
|
36 |
+
break;
|
37 |
+
}
|
38 |
+
|
39 |
+
?>
|
40 |
+
<script type="text/javascript">
|
41 |
+
jQuery(document).ready(function ($) {
|
42 |
+
|
43 |
+
$(document.body).on('click', '.notice-dismiss', function () {
|
44 |
+
|
45 |
+
let notice = $(this).closest('.pw_notice');
|
46 |
+
notice = notice.attr('id');
|
47 |
+
|
48 |
+
if (notice !== undefined && notice.indexOf('pw_') !== -1) {
|
49 |
+
|
50 |
+
notice = notice.replace('pw_', '');
|
51 |
+
|
52 |
+
$.ajax({
|
53 |
+
url: "<?php echo admin_url( 'admin-ajax.php' ) ?>",
|
54 |
+
type: 'post',
|
55 |
+
data: {
|
56 |
+
notice: notice,
|
57 |
+
action: 'pw_dismiss_notice',
|
58 |
+
nonce: "<?php echo wp_create_nonce( 'pw_dismiss_notice' ); ?>"
|
59 |
+
}
|
60 |
+
});
|
61 |
+
}
|
62 |
+
|
63 |
+
});
|
64 |
+
|
65 |
+
$.ajax({
|
66 |
+
url: "<?php echo admin_url( 'admin-ajax.php' ) ?>",
|
67 |
+
type: 'post',
|
68 |
+
data: {
|
69 |
+
action: 'pw_update_notice',
|
70 |
+
nonce: '<?php echo wp_create_nonce( 'pw_update_notice' ); ?>'
|
71 |
+
}
|
72 |
+
});
|
73 |
+
});
|
74 |
+
</script>
|
75 |
+
<?php
|
76 |
+
}
|
77 |
+
|
78 |
+
public function notices(): array {
|
79 |
+
global $pagenow;
|
80 |
+
|
81 |
+
$post_type = sanitize_text_field( $_GET['post_type'] ?? null );
|
82 |
+
$page = sanitize_text_field( $_GET['page'] ?? null );
|
83 |
+
$tab = sanitize_text_field( $_GET['tab'] ?? null );
|
84 |
+
$has_shipping = wc_shipping_enabled();
|
85 |
+
|
86 |
+
$notices = [
|
87 |
+
[
|
88 |
+
'id' => 'tapin-orders',
|
89 |
+
'content' => '<b>با افزونه حمل و نقل ووکامرس فارسی یک دفتر پستی اختصاصی داشته باش و بدون مراجعه به پست همه سفارشاتتو ارسال کن.</b>
|
90 |
+
<ul>
|
91 |
+
<li>- تولید فاکتور پست همراه با بارکد پستی به صورت آنلاین</li>
|
92 |
+
<li>- جمع آوری مرسولات از محل شما توسط ماموران پست</li>
|
93 |
+
<li>- ارسال کد رهگیری پستی برای مشتریان به صورت پیامکی</li>
|
94 |
+
<li>- بروزرسانی خودکار آخرین وضعیت مرسوله در پنل ووکامرس</li>
|
95 |
+
</ul>
|
96 |
+
<a href="https://yun.ir/pwto" target="_blank">
|
97 |
+
<input type="button" class="button button-primary" value="اطلاعات بیشتر">
|
98 |
+
</a>
|
99 |
+
<a href="' . admin_url( 'plugin-install.php?tab=plugin-information&plugin=persian-woocommerce-shipping' ) . '" target="_blank">
|
100 |
+
<input type="button" class="button" value="نصب افزونه پیشخوان پست">
|
101 |
+
</a>',
|
102 |
+
'condition' => $pagenow == 'edit.php' && $post_type == 'shop_order' && $has_shipping,
|
103 |
+
'dismiss' => 6 * MONTH_IN_SECONDS,
|
104 |
+
],
|
105 |
+
[
|
106 |
+
'id' => 'tapin-shipping',
|
107 |
+
'content' => '<b>با افزونه حمل و نقل ووکامرس فارسی به رایگان هزینه پست سفارشی و پیشتاز رو بصورت دقیق و طبق آخرین تعرفه پست محاسبه کنید و سرویس پرداخت در محل رو در سراسر کشور فعال کنید.</b>
|
108 |
+
<ul>
|
109 |
+
<li>- محاسبه دقیق هزینه ارسال بر اساس وزن و شهر خریدار</li>
|
110 |
+
<li>- امکان تخفیف در هزینه ارسال بر اساس میزان خرید</li>
|
111 |
+
<li>- صدور آنلاین کد رهگیری پستی و تولید فاکتور</li>
|
112 |
+
<li>- ارسال کد رهگیری به خریدار به صورت پیامکی و در پنل کاربری</li>
|
113 |
+
</ul>
|
114 |
+
<a href="https://yun.ir/pwts" target="_blank">
|
115 |
+
<input type="button" class="button button-primary" value="اطلاعات بیشتر">
|
116 |
+
</a>
|
117 |
+
<a href="' . admin_url( 'plugin-install.php?tab=plugin-information&plugin=persian-woocommerce-shipping' ) . '" target="_blank">
|
118 |
+
<input type="button" class="button" value="نصب افزونه پیشخوان پست">
|
119 |
+
</a>',
|
120 |
+
'condition' => $page == 'wc-settings' && $tab == 'shipping' && $has_shipping,
|
121 |
+
'dismiss' => 6 * MONTH_IN_SECONDS,
|
122 |
+
],
|
123 |
+
[
|
124 |
+
'id' => 'tapin-tools',
|
125 |
+
'content' => '
|
126 |
+
<a href="https://yun.ir/pwtt" target="_blank">
|
127 |
+
<img src="' . PW()->plugin_url( 'assets/images/tapin.jpg' ) . '" style="width: 100%">
|
128 |
+
</a>',
|
129 |
+
'condition' => $page == 'persian-wc-tools' && $has_shipping,
|
130 |
+
'dismiss' => 6 * MONTH_IN_SECONDS,
|
131 |
+
],
|
132 |
+
[
|
133 |
+
'id' => 'tapin-dashboard',
|
134 |
+
'content' => '<b>پیشخوان وردپرس خود را رایگان به شرکت ملی پست متصل کنید و یک دفتر پستی اختصاصی داشته باشید.</b>
|
135 |
+
<ul>
|
136 |
+
<li>- محاسبه دقیق هزینه های پستی در سبد خرید</li>
|
137 |
+
<li>- جمع آری سفارشات از محل شما توسط ماموران پست در سراسر کشور</li>
|
138 |
+
<li>- صدور فاکتور استاندارد پست همراه با بارکد پست</li>
|
139 |
+
<li>- ارسال کد رهگیری پست به مشتری به صورت پیامکی و پنل کاربری</li>
|
140 |
+
</ul>
|
141 |
+
<a href="https://yun.ir/pwtd" target="_blank">
|
142 |
+
<input type="button" class="button button-primary" value="اطلاعات بیشتر">
|
143 |
+
</a>
|
144 |
+
<a href="' . admin_url( 'plugin-install.php?tab=plugin-information&plugin=persian-woocommerce-shipping' ) . '" target="_blank">
|
145 |
+
<input type="button" class="button" value="نصب افزونه پیشخوان پست">
|
146 |
+
</a>',
|
147 |
+
'condition' => $pagenow == 'index.php' && $has_shipping,
|
148 |
+
'dismiss' => 6 * MONTH_IN_SECONDS,
|
149 |
+
],
|
150 |
+
[
|
151 |
+
'id' => 'persian-date',
|
152 |
+
'content' => '<b>ووکامرس فارسی با طعم ووکامرس شمسی!</b>
|
153 |
+
<ul>
|
154 |
+
<li>- شمسی سازی محیط وردپرس بدون نیاز به افزونه جانبی</li>
|
155 |
+
<li>- شمسی سازی ووکامرس در محصولات، سفارشات، کوپن ها و گزارشات</li>
|
156 |
+
<li>- افزودن DatePicker شمسی در پنل ووکامرس</li>
|
157 |
+
<li>- برای فعالسازی شمسی ساز ووکامرس روی کلید زیر کلیک کنید:</li>
|
158 |
+
</ul>
|
159 |
+
<a href="' . admin_url( 'admin.php?page=persian-wc-tools' ) . '" target="_blank">
|
160 |
+
<input type="button" class="button button-primary" value="فعالسازی شمسی ساز وردپرس و ووکامرس">
|
161 |
+
</a>',
|
162 |
+
'condition' => PW()->get_options( 'enable_jalali_datepicker' ) !== 'yes',
|
163 |
+
'dismiss' => 6 * MONTH_IN_SECONDS,
|
164 |
+
],
|
165 |
+
[
|
166 |
+
'id' => 'pws',
|
167 |
+
'content' => sprintf( 'بنظر میرسه هنوز حمل و نقل (پست پیشتاز، سفارشی، پیک موتوری و...) فروشگاه رو پیکربندی نکردید؟ <a href="%s" target="_blank">نصب افزونه حمل و نقل فارسی ووکامرس و پیکربندی.</a>', admin_url( 'plugin-install.php?tab=plugin-information&plugin=persian-woocommerce-shipping' ) ),
|
168 |
+
'condition' => is_plugin_inactive( 'persian-woocommerce-shipping/woocommerce-shipping.php' ) && $has_shipping,
|
169 |
+
'dismiss' => 6 * MONTH_IN_SECONDS,
|
170 |
+
],
|
171 |
+
];
|
172 |
+
|
173 |
+
$_notices = get_option( 'pw_notices', [] );
|
174 |
+
|
175 |
+
foreach ( $_notices['notices'] ?? [] as $_notice ) {
|
176 |
+
|
177 |
+
$_notice['condition'] = 1;
|
178 |
+
|
179 |
+
$rules = $_notice['rules'];
|
180 |
+
|
181 |
+
if ( isset( $rules['pagenow'] ) && $rules['pagenow'] != $pagenow ) {
|
182 |
+
$_notice['condition'] = 0;
|
183 |
+
}
|
184 |
+
|
185 |
+
if ( isset( $rules['page'] ) && $rules['page'] != $page ) {
|
186 |
+
$_notice['condition'] = 0;
|
187 |
+
}
|
188 |
+
|
189 |
+
if ( isset( $rules['tab'] ) && $rules['tab'] != $tab ) {
|
190 |
+
$_notice['condition'] = 0;
|
191 |
+
}
|
192 |
+
|
193 |
+
if ( isset( $rules['active'] ) && is_plugin_inactive( $rules['active'] ) ) {
|
194 |
+
$_notice['condition'] = 0;
|
195 |
+
}
|
196 |
+
|
197 |
+
if ( isset( $rules['inactive'] ) && is_plugin_active( $rules['inactive'] ) ) {
|
198 |
+
$_notice['condition'] = 0;
|
199 |
+
}
|
200 |
+
|
201 |
+
if ( isset( $rules['has_shipping'] ) && $rules['has_shipping'] != $has_shipping ) {
|
202 |
+
$_notice['condition'] = 0;
|
203 |
+
}
|
204 |
+
|
205 |
+
unset( $_notice['rules'] );
|
206 |
+
|
207 |
+
array_unshift( $notices, $_notice );
|
208 |
+
}
|
209 |
+
|
210 |
+
return $notices;
|
211 |
+
}
|
212 |
+
|
213 |
+
public function dismiss_notice() {
|
214 |
+
|
215 |
+
check_ajax_referer( 'pw_dismiss_notice', 'nonce' );
|
216 |
+
|
217 |
+
$this->set_dismiss( $_POST['notice'] );
|
218 |
+
|
219 |
+
die();
|
220 |
+
}
|
221 |
+
|
222 |
+
public function update_notice() {
|
223 |
+
|
224 |
+
$update = get_transient( 'pw_update_notices' );
|
225 |
+
|
226 |
+
if ( $update ) {
|
227 |
+
return;
|
228 |
+
}
|
229 |
+
|
230 |
+
set_transient( 'pw_update_notices', 1, DAY_IN_SECONDS / 4 );
|
231 |
+
|
232 |
+
check_ajax_referer( 'pw_update_notice', 'nonce' );
|
233 |
+
|
234 |
+
$notices = wp_remote_get( 'https://woonotice.ir/pw.json', [ 'timeout' => 5, ] );
|
235 |
+
$sign = wp_remote_get( 'https://woohash.ir/pw.hash', [ 'timeout' => 5, ] );
|
236 |
+
|
237 |
+
if ( is_wp_error( $notices ) || is_wp_error( $sign ) ) {
|
238 |
+
die();
|
239 |
+
}
|
240 |
+
|
241 |
+
if ( ! is_array( $notices ) || ! is_array( $sign ) ) {
|
242 |
+
die();
|
243 |
+
}
|
244 |
+
|
245 |
+
$notices = trim( $notices['body'] );
|
246 |
+
$sign = trim( $sign['body'] );
|
247 |
+
|
248 |
+
if ( sha1( $notices ) !== $sign ) {
|
249 |
+
die();
|
250 |
+
}
|
251 |
+
|
252 |
+
$notices = json_decode( $notices, JSON_OBJECT_AS_ARRAY );
|
253 |
+
|
254 |
+
if ( empty( $notices ) || ! is_array( $notices ) ) {
|
255 |
+
die();
|
256 |
+
}
|
257 |
+
|
258 |
+
foreach ( $notices['notices'] as &$_notice ) {
|
259 |
+
|
260 |
+
$doc = new DOMDocument();
|
261 |
+
$content = strip_tags( $_notice['content'], '<p><a><b><img><ul><ol><li>' );
|
262 |
+
$content = str_replace( [ 'javascript', 'java', 'script' ], '', $content );
|
263 |
+
$doc->loadHTML( mb_convert_encoding( $content, 'HTML-ENTITIES', 'UTF-8' ) );
|
264 |
+
|
265 |
+
foreach ( $doc->getElementsByTagName( '*' ) as $element ) {
|
266 |
+
|
267 |
+
$href = null;
|
268 |
+
$src = null;
|
269 |
+
$style = $element->getAttribute( 'style' );
|
270 |
+
|
271 |
+
if ( $element->nodeName == 'a' ) {
|
272 |
+
$href = $element->getAttribute( 'href' );
|
273 |
+
}
|
274 |
+
|
275 |
+
if ( $element->nodeName == 'img' ) {
|
276 |
+
$src = $element->getAttribute( 'src' );
|
277 |
+
}
|
278 |
+
|
279 |
+
foreach ( $element->attributes as $attribute ) {
|
280 |
+
$element->removeAttribute( $attribute->name );
|
281 |
+
}
|
282 |
+
|
283 |
+
if ( $href && filter_var( $href, FILTER_VALIDATE_URL ) ) {
|
284 |
+
$element->setAttribute( 'href', $href );
|
285 |
+
$element->setAttribute( 'target', '_blank' );
|
286 |
+
}
|
287 |
+
|
288 |
+
if ( $src && filter_var( $src, FILTER_VALIDATE_URL ) && strpos( $src, 'https://woonotice.ir' ) === 0 ) {
|
289 |
+
$element->setAttribute( 'src', $src );
|
290 |
+
}
|
291 |
+
|
292 |
+
if ( $style ) {
|
293 |
+
$element->setAttribute( 'style', $style );
|
294 |
+
}
|
295 |
+
}
|
296 |
+
|
297 |
+
$_notice['content'] = $doc->saveHTML();
|
298 |
+
}
|
299 |
+
|
300 |
+
update_option( 'pw_notices', $notices );
|
301 |
+
|
302 |
+
die();
|
303 |
+
}
|
304 |
+
|
305 |
+
public function set_dismiss( $notice_id ) {
|
306 |
+
|
307 |
+
$notices = wp_list_pluck( $this->notices(), 'dismiss', 'id' );
|
308 |
+
|
309 |
+
if ( isset( $notices[ $notice_id ] ) && $notices[ $notice_id ] ) {
|
310 |
+
set_transient( 'pw_notice_' . $notice_id, 'DISMISS', intval( $notices[ $notice_id ] ) );
|
311 |
+
set_transient( 'pw_notice_all', 'DISMISS', HOUR_IN_SECONDS );
|
312 |
+
}
|
313 |
+
}
|
314 |
+
|
315 |
+
public function is_dismiss( $notice_id ): bool {
|
316 |
+
return get_transient( 'pw_notice_' . $notice_id ) !== false;
|
317 |
+
}
|
318 |
+
|
319 |
+
}
|
320 |
+
|
321 |
+
new Persian_Woocommerce_Notice();
|
include/class-tools.php
CHANGED
@@ -1,461 +1,490 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
|
4 |
|
5 |
-
|
|
|
|
|
|
|
|
|
|
|
6 |
|
7 |
-
|
|
|
|
|
|
|
|
|
8 |
|
9 |
-
|
10 |
-
|
11 |
-
add_filter( 'woocommerce_admin_field_multi_select_states', array( $this, 'specific_states_field' ) );
|
12 |
}
|
13 |
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
|
20 |
-
|
21 |
-
$current = 'general';
|
22 |
-
}
|
23 |
|
24 |
-
|
25 |
-
'general' => 'گزینه های اصلی',
|
26 |
-
'price' => 'گزینه های قیمت',
|
27 |
-
'checkout' => 'تسویه حساب',
|
28 |
-
) );
|
29 |
|
30 |
-
|
|
|
31 |
|
32 |
-
|
33 |
|
34 |
-
|
35 |
-
echo '<h2 class="nav-tab-wrapper">';
|
36 |
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
$class = ' nav-tab-active';
|
41 |
-
} else {
|
42 |
-
$class = "";
|
43 |
-
}
|
44 |
-
echo sprintf( "<a class='nav-tab%s' href='?page=persian-wc-tools&tab=%s'>%s</a>", $class, $tab, $name );
|
45 |
-
|
46 |
-
if ( $tab == $current && isset( $sections[ $tab ] ) ) {
|
47 |
-
foreach ( $sections[ $tab ] as $section => $name ) {
|
48 |
-
if ( $section == $current_section || ! count( $html_sections ) ) {
|
49 |
-
$active['section'] = $section;
|
50 |
-
$class = 'current';
|
51 |
-
} else {
|
52 |
-
$class = '';
|
53 |
-
}
|
54 |
-
$html_sections[] = sprintf( "<li><a href='?page=persian-wc-tools&tab=%s§ion=%s' class='%s'>%s</a></li>", $tab, $section, $class, $name );
|
55 |
-
}
|
56 |
-
}
|
57 |
}
|
58 |
|
59 |
-
|
60 |
|
61 |
-
if (
|
62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
}
|
|
|
64 |
|
65 |
-
|
|
|
|
|
|
|
66 |
}
|
67 |
|
68 |
-
|
|
|
|
|
|
|
69 |
|
70 |
-
|
71 |
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
<p><b>پیشنهاد:</b> برای کارکردن صحیح افزونه و عملکرد مناسب این ابزار، پیشنهاد می کنیم هیچ افزونه شمسی ساز دیگری را همزمان فعال نکنید.</p>',
|
92 |
-
],
|
93 |
-
[
|
94 |
-
'type' => 'sectionend',
|
95 |
-
'id' => 'general_options'
|
96 |
-
],
|
97 |
],
|
|
|
|
|
|
|
|
|
|
|
98 |
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
[
|
162 |
-
'title' => 'قیمت فارسی',
|
163 |
-
'type' => 'title',
|
164 |
-
'id' => 'persian_price_option'
|
165 |
-
],
|
166 |
-
[
|
167 |
-
'title' => 'فارسی سازی قیمت ها',
|
168 |
-
'desc' => 'استفاده از اعداد فارسی در قیمت ها',
|
169 |
-
'id' => 'PW_Options[persian_price]',
|
170 |
-
'default' => 'no',
|
171 |
-
'type' => 'checkbox',
|
172 |
-
],
|
173 |
-
[
|
174 |
-
'type' => 'sectionend',
|
175 |
-
'id' => 'persian_price_option'
|
176 |
-
],
|
177 |
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
192 |
],
|
193 |
],
|
|
|
|
|
|
|
|
|
194 |
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
],
|
213 |
-
[
|
214 |
-
'title' => 'استان های خاص',
|
215 |
-
'desc' => '',
|
216 |
-
'id' => 'PW_Options[specific_allowed_states]',
|
217 |
-
'css' => 'min-width: 350px;',
|
218 |
-
'default' => '',
|
219 |
-
'class' => 'wc-enhanced-select',
|
220 |
-
'type' => 'multi_select_states'
|
221 |
-
],
|
222 |
-
[
|
223 |
-
'title' => 'فعالسازی شهرهای ایران',
|
224 |
-
'id' => 'PW_Options[enable_iran_cities]',
|
225 |
-
'type' => 'checkbox',
|
226 |
-
'default' => 'yes',
|
227 |
-
'desc' => 'فعالسازی شهرهای ایران در صفحه تسویه حساب',
|
228 |
-
],
|
229 |
-
[
|
230 |
-
'title' => 'جابجایی فیلد استان و شهر',
|
231 |
-
'id' => 'PW_Options[flip_state_city]',
|
232 |
-
'type' => 'checkbox',
|
233 |
-
'default' => 'no',
|
234 |
-
'desc' => 'در صورتی که گزینه "فعالسازی شهر های ایران" را انتخاب نمایید، در برخی قالب ها ممکن است فیلد شهر قبل از فیلد استان قرار بگیرد که با فعالسازی این گزینه میتوانید جایگاه آنها را با هم عوض نمایید.',
|
235 |
-
],
|
236 |
-
[
|
237 |
-
'title' => 'حل مشکل لیست استان ها',
|
238 |
-
'id' => 'PW_Options[fix_load_states]',
|
239 |
-
'type' => 'checkbox',
|
240 |
-
'default' => 'no',
|
241 |
-
'desc' => 'برای حل مشکل بارگذاری لیست استان ها در صفحه تسویه حساب تیک بزنید.',
|
242 |
-
],
|
243 |
-
[
|
244 |
-
'type' => 'sectionend',
|
245 |
-
'id' => 'address_options'
|
246 |
-
],
|
247 |
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
'
|
263 |
-
'
|
264 |
-
'default' => 'no',
|
265 |
-
'desc' => 'برای بررسی صحت کدپستی و ده رقمی بودن آن تیک بزنید.',
|
266 |
-
],
|
267 |
-
[
|
268 |
-
'type' => 'sectionend',
|
269 |
-
'id' => 'postcode_options'
|
270 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
271 |
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
313 |
|
314 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
315 |
|
316 |
-
|
317 |
-
}
|
318 |
|
319 |
-
|
320 |
-
|
321 |
-
$settings = $this->tools_sections();
|
322 |
-
wp_enqueue_style( 'woocommerce_admin_styles' );
|
323 |
-
wp_enqueue_script( 'wc-enhanced-select' );
|
324 |
-
wp_enqueue_script( 'pw-admin-script' );
|
325 |
-
?>
|
326 |
|
327 |
-
|
328 |
-
|
329 |
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
|
|
334 |
|
335 |
-
|
336 |
-
|
337 |
|
338 |
-
<div id="poststuff">
|
339 |
-
<form method="post" action="<?php admin_url( 'themes.php?page=persian-wc-tools' ); ?>">
|
340 |
-
<?php
|
341 |
-
wp_nonce_field( "persian-wc-tools" );
|
342 |
-
|
343 |
-
if ( $pagenow == 'admin.php' && $_GET['page'] == 'persian-wc-tools' && isset( $settings[ $tab ] ) ) {
|
344 |
-
|
345 |
-
|
346 |
-
WC_Admin_Settings::output_fields( empty( $section ) ? $settings[ $tab ] : $settings[ $tab ][ $section ] );
|
347 |
-
}
|
348 |
-
|
349 |
-
?>
|
350 |
-
<p class="submit" style="clear: both;">
|
351 |
-
<input type="submit" name="Submit" class="button-primary" value="ذخیره تنظیمات"/>
|
352 |
-
<input type="hidden" name="pw-settings-submit" value="Y"/>
|
353 |
-
<input type="hidden" name="pw-tab" value="<?php echo $tab; ?>"/>
|
354 |
-
<input type="hidden" name="pw-section" value="<?php echo $section; ?>"/>
|
355 |
-
</p>
|
356 |
-
</form>
|
357 |
-
</div>
|
358 |
-
|
359 |
-
</div>
|
360 |
-
<script type="text/javascript">
|
361 |
-
jQuery(document).ready(function ( $ ) {
|
362 |
-
$('.persian-woocommerce').on('click', '.select_all', function () {
|
363 |
-
jQuery(this).closest('td').find('select option').attr('selected', 'selected');
|
364 |
-
jQuery(this).closest('td').find('select').trigger('change');
|
365 |
-
return false;
|
366 |
-
}).on('click', '.select_none', function () {
|
367 |
-
jQuery(this).closest('td').find('select option').removeAttr('selected');
|
368 |
-
jQuery(this).closest('td').find('select').trigger('change');
|
369 |
-
return false;
|
370 |
-
});
|
371 |
-
|
372 |
-
$('select#PW_Options\\[allowed_states\\]').change(function () {
|
373 |
-
if( jQuery(this).val() === 'specific' ) {
|
374 |
-
jQuery(this).parent().parent().next('tr').show();
|
375 |
-
} else {
|
376 |
-
jQuery(this).parent().parent().next('tr').hide();
|
377 |
-
}
|
378 |
-
}).change();
|
379 |
-
});
|
380 |
-
</script>
|
381 |
<?php
|
382 |
-
|
383 |
-
|
384 |
-
public function tools_save() {
|
385 |
|
386 |
-
if (
|
387 |
-
|
388 |
}
|
389 |
|
390 |
-
|
391 |
-
|
392 |
-
$tab = $_POST['pw-tab'];
|
393 |
-
$section = $_POST['pw-section'];
|
394 |
-
check_admin_referer( "persian-wc-tools" );
|
395 |
-
do_action( "PW_before_save_tools", $_POST, $settings, $tab, $section );
|
396 |
-
WC_Admin_Settings::save_fields( empty( $section ) ? $settings[ $tab ] : $settings[ $tab ][ $section ] );
|
397 |
-
do_action( "PW_after_save_tools", $_POST, $settings, $tab, $section );
|
398 |
-
$url_parameters = empty( $section ) ? 'updated=true&tab=' . $tab : 'updated=true&tab=' . $tab . '§ion=' . $section;
|
399 |
-
wp_redirect( admin_url( 'admin.php?page=persian-wc-tools&' . $url_parameters ) );
|
400 |
-
exit;
|
401 |
-
}
|
402 |
-
}
|
403 |
|
404 |
-
|
405 |
-
|
406 |
-
$selections = (array) PW()->get_options( 'specific_allowed_states' );
|
407 |
?>
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
</th>
|
412 |
-
<td class="forminp">
|
413 |
-
<select multiple="multiple" name="<?php echo esc_attr( $value['id'] ); ?>[]" style="width:350px"
|
414 |
-
data-placeholder="استان (ها) مورد نظر خود را انتخاب کنید ..." title="استان"
|
415 |
-
class="wc-enhanced-select">
|
416 |
<?php
|
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 |
PW()->tools = new Persian_Woocommerce_Tools();
|
454 |
|
455 |
do_action( 'PW_Tools_load', PW()->get_options() );
|
456 |
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
1 |
+
<?php
|
2 |
+
|
3 |
+
defined( 'ABSPATH' ) || exit;
|
4 |
|
5 |
+
class Persian_Woocommerce_Tools extends Persian_Woocommerce_Core {
|
6 |
+
|
7 |
+
public function __construct() {
|
8 |
+
add_action( 'admin_init', [ $this, 'tools_save' ] );
|
9 |
+
add_filter( 'woocommerce_admin_field_multi_select_states', [ $this, 'specific_states_field' ] );
|
10 |
+
}
|
11 |
|
12 |
+
public function tools_tabs( $current_tab = 'general', $current_section = '' ): array {
|
13 |
+
$active = [
|
14 |
+
'tab' => '',
|
15 |
+
'section' => '',
|
16 |
+
];
|
17 |
|
18 |
+
if ( empty( $current_tab ) ) {
|
19 |
+
$current_tab = 'general';
|
|
|
20 |
}
|
21 |
|
22 |
+
$tabs = apply_filters( 'PW_Tools_tabs', [
|
23 |
+
'general' => 'گزینه های اصلی',
|
24 |
+
'price' => 'گزینه های قیمت',
|
25 |
+
'checkout' => 'تسویه حساب',
|
26 |
+
] );
|
27 |
|
28 |
+
$sections['fields'] = apply_filters( 'PW_Tools_sections', [] );
|
|
|
|
|
29 |
|
30 |
+
$html_sections = [];
|
|
|
|
|
|
|
|
|
31 |
|
32 |
+
echo '<div id="icon-themes" class="icon32"><br></div>';
|
33 |
+
echo '<h2 class="nav-tab-wrapper">';
|
34 |
|
35 |
+
foreach ( $tabs as $tab => $tab_name ) {
|
36 |
|
37 |
+
$class = '';
|
|
|
38 |
|
39 |
+
if ( $tab == $current_tab ) {
|
40 |
+
$active['tab'] = $tab;
|
41 |
+
$class = ' nav-tab-active';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
}
|
43 |
|
44 |
+
printf( "<a class='nav-tab%s' href='?page=persian-wc-tools&tab=%s'>%s</a>", $class, $tab, $tab_name );
|
45 |
|
46 |
+
if ( $tab == $current_tab && isset( $sections[ $tab ] ) ) {
|
47 |
+
foreach ( $sections[ $tab ] as $section => $section_name ) {
|
48 |
+
|
49 |
+
$class = '';
|
50 |
+
|
51 |
+
if ( $section == $current_section || ! count( $html_sections ) ) {
|
52 |
+
$active['section'] = $section;
|
53 |
+
$class = 'current';
|
54 |
+
}
|
55 |
+
|
56 |
+
$html_sections[] = sprintf( "<li><a href='?page=persian-wc-tools&tab=%s§ion=%s' class='%s'>%s</a></li>", $tab, $section, $class, $section_name );
|
57 |
+
}
|
58 |
}
|
59 |
+
}
|
60 |
|
61 |
+
echo '</h2>';
|
62 |
+
|
63 |
+
if ( count( $html_sections ) ) {
|
64 |
+
printf( '<ul class="subsubsub">%s</ul><br>', implode( $html_sections, " | " ) );
|
65 |
}
|
66 |
|
67 |
+
return array_values( $active );
|
68 |
+
}
|
69 |
+
|
70 |
+
public function tools_sections() {
|
71 |
|
72 |
+
$tools = [
|
73 |
|
74 |
+
'general' => [
|
75 |
+
[
|
76 |
+
'title' => 'همگانی',
|
77 |
+
'type' => 'title',
|
78 |
+
'id' => 'general_options',
|
79 |
+
],
|
80 |
+
[
|
81 |
+
'title' => 'مرتب سازی لیست سفارشات',
|
82 |
+
'id' => 'PW_Options[fix_orders_list]',
|
83 |
+
'type' => 'checkbox',
|
84 |
+
'default' => 'no',
|
85 |
+
'desc' => 'برای مرتب سازی لیست سفارشات بر اساس تاریخ پرداخت تیک بزنید (قبل از فعالسازی این گزینه، حتما <a href="https://forum.persianscript.ir/threads/%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-%D8%A7%D8%A8%D8%B2%D8%A7%D8%B1-%D9%85%D8%B1%D8%AA%D8%A8-%D8%B3%D8%A7%D8%B2%DB%8C-%D9%84%DB%8C%D8%B3%D8%AA-%D8%B3%D9%81%D8%A7%D8%B1%D8%B4%D8%A7%D8%AA.26864/" target="_blank">اینجا</a> را کامل مطالعه نمایید)',
|
86 |
+
],
|
87 |
+
[
|
88 |
+
'title' => 'تاریخ شمسی',
|
89 |
+
'id' => 'PW_Options[enable_jalali_datepicker]',
|
90 |
+
'type' => 'checkbox',
|
91 |
+
'default' => 'no',
|
92 |
+
'desc' => 'فعالسازی تاریخ شمسی در وردپرس و ووکامرس (محصولات، سفارشات، کوپن ها و گزارشات)<br>
|
93 |
<p><b>پیشنهاد:</b> برای کارکردن صحیح افزونه و عملکرد مناسب این ابزار، پیشنهاد می کنیم هیچ افزونه شمسی ساز دیگری را همزمان فعال نکنید.</p>',
|
|
|
|
|
|
|
|
|
|
|
94 |
],
|
95 |
+
[
|
96 |
+
'type' => 'sectionend',
|
97 |
+
'id' => 'general_options',
|
98 |
+
],
|
99 |
+
],
|
100 |
|
101 |
+
'price' => [
|
102 |
+
[
|
103 |
+
'title' => 'تماس بگیرید',
|
104 |
+
'type' => 'title',
|
105 |
+
'id' => 'call_for_price_options',
|
106 |
+
],
|
107 |
+
[
|
108 |
+
'title' => 'فعالسازی تماس برای قیمت',
|
109 |
+
'desc' => 'فعالسازی برچسب "تماس بگیرید" بجای قیمت در صورتی که قیمت محصول وارد نشده باشد',
|
110 |
+
'desc_tip' => 'دقت کنید که قیمت 0 به معنای رایگان بودن محصول می باشد. قسمت قیمت را خالی بگذارید.',
|
111 |
+
'id' => 'PW_Options[enable_call_for_price]',
|
112 |
+
'type' => 'checkbox',
|
113 |
+
'default' => 'no',
|
114 |
+
],
|
115 |
+
[
|
116 |
+
'title' => 'برچسب در صفحه محصول',
|
117 |
+
// 'desc' => 'این مورد بجای قیمت محصول در صفحه محصول نمایش داده می شود. برای غیرفعال کردن خالی بگذارید.',
|
118 |
+
// 'desc_tip' => true,
|
119 |
+
'id' => 'PW_Options[call_for_price_text]',
|
120 |
+
'default' => '<strong>تماس بگیرید</strong>',
|
121 |
+
'type' => 'textarea',
|
122 |
+
'css' => 'width:50%;min-width:300px;',
|
123 |
+
],
|
124 |
+
[
|
125 |
+
'title' => 'برچسب در قسمت آرشیو ها',
|
126 |
+
// 'desc' => 'این مورد بجای قیمت محصول در آرشیو ها نمایش داده می شود. برای غیرفعال کردن خالی بگذارید.',
|
127 |
+
// 'desc_tip' => true,
|
128 |
+
'id' => 'PW_Options[call_for_price_text_on_archive]',
|
129 |
+
'default' => '<strong>تماس بگیرید</strong>',
|
130 |
+
'type' => 'textarea',
|
131 |
+
'css' => 'width:50%;min-width:300px;',
|
132 |
+
],
|
133 |
+
[
|
134 |
+
'title' => 'برچسب در صفحه اصلی',
|
135 |
+
// 'desc' => 'این مورد بجای قیمت محصول در صفحه اصلی نمایش داده می شود. برای غیرفعال کردن خالی بگذارید.',
|
136 |
+
// 'desc_tip' => true,
|
137 |
+
'id' => 'PW_Options[call_for_price_text_on_home]',
|
138 |
+
'default' => '<strong>تماس بگیرید</strong>',
|
139 |
+
'type' => 'textarea',
|
140 |
+
'css' => 'width:50%;min-width:300px;',
|
141 |
+
],
|
142 |
+
[
|
143 |
+
'title' => 'برچسب در محصولات مرتبط',
|
144 |
+
// 'desc' => 'این مورد بجای قیمت محصول در محصولات مرتبط نمایش داده می شود. برای غیرفعال کردن خالی بگذارید.',
|
145 |
+
// 'desc_tip' => true,
|
146 |
+
'id' => 'PW_Options[call_for_price_text_on_related]',
|
147 |
+
'default' => '<strong>تماس بگیرید</strong>',
|
148 |
+
'type' => 'textarea',
|
149 |
+
'css' => 'width:50%;min-width:300px;',
|
150 |
+
],
|
151 |
+
[
|
152 |
+
'title' => 'برچسب "فروش ویژه"',
|
153 |
+
'desc' => 'حذف برچسب فروش ویژه',
|
154 |
+
'id' => 'PW_Options[call_for_price_hide_sale_sign]',
|
155 |
+
'default' => 'no',
|
156 |
+
'type' => 'checkbox',
|
157 |
+
],
|
158 |
+
[
|
159 |
+
'type' => 'sectionend',
|
160 |
+
'id' => 'call_for_price_options',
|
161 |
+
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
162 |
|
163 |
+
[
|
164 |
+
'title' => 'نمایش قیمت',
|
165 |
+
'type' => 'title',
|
166 |
+
'id' => 'price_option',
|
167 |
+
],
|
168 |
+
[
|
169 |
+
'title' => 'فارسی سازی قیمت ها',
|
170 |
+
'desc' => 'استفاده از اعداد فارسی در قیمت ها',
|
171 |
+
'id' => 'PW_Options[persian_price]',
|
172 |
+
'default' => 'no',
|
173 |
+
'type' => 'checkbox',
|
174 |
+
],
|
175 |
+
[
|
176 |
+
'title' => 'قیمت محصولات متغیر',
|
177 |
+
'desc' => 'نحوه نمایش قیمت محصولات متغیر در صفحات لیست محصولات',
|
178 |
+
'id' => 'PW_Options[variable_price]',
|
179 |
+
'default' => 'range',
|
180 |
+
'type' => 'select',
|
181 |
+
'options' => [
|
182 |
+
'range' => 'بازه قیمتی (پیشفرض)',
|
183 |
+
'min_regular' => 'حداقل قیمت اصلی',
|
184 |
+
'max_regular' => 'حداکثر قیمت اصلی',
|
185 |
+
'min_sale' => 'حداقل قیمت فروش فوق العاده',
|
186 |
+
'max_sale' => 'حداکثر قیمت فروش فوق العاده',
|
187 |
],
|
188 |
],
|
189 |
+
[
|
190 |
+
'type' => 'sectionend',
|
191 |
+
'id' => 'price_option',
|
192 |
+
],
|
193 |
|
194 |
+
[
|
195 |
+
'title' => 'سایر',
|
196 |
+
'type' => 'title',
|
197 |
+
'id' => 'other_price_option',
|
198 |
+
],
|
199 |
+
[
|
200 |
+
'title' => 'حداقل مبلغ سفارش',
|
201 |
+
'id' => 'PW_Options[minimum_order_amount]',
|
202 |
+
'default' => 0,
|
203 |
+
'desc' => 'در صورتی که قصد دارید برای امکان ثبت سفارشات در فروشگاه خود یک حداقل مبلغ مشخص کنید میتوانید مبلغ را در اینجا وارد نمایید در غیر اینصورت تنظیمات را دستکاری نکنید.',
|
204 |
+
'type' => 'number',
|
205 |
+
],
|
206 |
+
[
|
207 |
+
'type' => 'sectionend',
|
208 |
+
'id' => 'other_price_option',
|
209 |
+
],
|
210 |
+
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
211 |
|
212 |
+
'checkout' => [
|
213 |
+
[
|
214 |
+
'title' => 'استان ها و شهرها',
|
215 |
+
'type' => 'title',
|
216 |
+
'id' => 'address_options',
|
217 |
+
],
|
218 |
+
[
|
219 |
+
'title' => 'فروش به استان های',
|
220 |
+
'id' => 'PW_Options[allowed_states]',
|
221 |
+
'default' => 'all',
|
222 |
+
'type' => 'select',
|
223 |
+
'class' => 'wc-enhanced-select',
|
224 |
+
'css' => 'width: 350px;',
|
225 |
+
'options' => [
|
226 |
+
'all' => 'فروش به همه استان ها',
|
227 |
+
'specific' => 'فروش به استان های خاص',
|
|
|
|
|
|
|
|
|
|
|
|
|
228 |
],
|
229 |
+
],
|
230 |
+
[
|
231 |
+
'title' => 'استان های خاص',
|
232 |
+
'desc' => '',
|
233 |
+
'id' => 'PW_Options[specific_allowed_states]',
|
234 |
+
'css' => 'min-width: 350px;',
|
235 |
+
'default' => '',
|
236 |
+
'class' => 'wc-enhanced-select',
|
237 |
+
'type' => 'multi_select_states',
|
238 |
+
],
|
239 |
+
[
|
240 |
+
'title' => 'فعالسازی شهرهای ایران',
|
241 |
+
'id' => 'PW_Options[enable_iran_cities]',
|
242 |
+
'type' => 'checkbox',
|
243 |
+
'default' => 'yes',
|
244 |
+
'desc' => 'فعالسازی شهرهای ایران در صفحه تسویه حساب',
|
245 |
+
],
|
246 |
+
[
|
247 |
+
'title' => 'جابجایی فیلد استان و شهر',
|
248 |
+
'id' => 'PW_Options[flip_state_city]',
|
249 |
+
'type' => 'checkbox',
|
250 |
+
'default' => 'no',
|
251 |
+
'desc' => 'در صورتی که گزینه "فعالسازی شهر های ایران" را انتخاب نمایید، در برخی قالب ها ممکن است فیلد شهر قبل از فیلد استان قرار بگیرد که با فعالسازی این گزینه میتوانید جایگاه آنها را با هم عوض نمایید.',
|
252 |
+
],
|
253 |
+
[
|
254 |
+
'title' => 'حل مشکل لیست استان ها',
|
255 |
+
'id' => 'PW_Options[fix_load_states]',
|
256 |
+
'type' => 'checkbox',
|
257 |
+
'default' => 'no',
|
258 |
+
'desc' => 'برای حل مشکل بارگذاری لیست استان ها در صفحه تسویه حساب تیک بزنید.',
|
259 |
+
],
|
260 |
+
[
|
261 |
+
'type' => 'sectionend',
|
262 |
+
'id' => 'address_options',
|
263 |
+
],
|
264 |
|
265 |
+
[
|
266 |
+
'title' => 'کدپستی',
|
267 |
+
'type' => 'title',
|
268 |
+
'id' => 'postcode_options',
|
269 |
+
],
|
270 |
+
[
|
271 |
+
'title' => 'اعداد فارسی در کدپستی',
|
272 |
+
'id' => 'PW_Options[fix_postcode_persian_number]',
|
273 |
+
'type' => 'checkbox',
|
274 |
+
'default' => 'no',
|
275 |
+
'desc' => 'برای تبدیل اعداد فارسی به انگلیسی در کدپستی تیک بزنید.',
|
276 |
+
],
|
277 |
+
[
|
278 |
+
'title' => 'بررسی صحت کدپستی',
|
279 |
+
'id' => 'PW_Options[postcode_validation]',
|
280 |
+
'type' => 'checkbox',
|
281 |
+
'default' => 'no',
|
282 |
+
'desc' => 'برای بررسی صحت کدپستی و ده رقمی بودن آن تیک بزنید.',
|
283 |
+
],
|
284 |
+
[
|
285 |
+
'type' => 'sectionend',
|
286 |
+
'id' => 'postcode_options',
|
287 |
+
],
|
288 |
|
289 |
+
[
|
290 |
+
'title' => 'تلفن همراه',
|
291 |
+
'type' => 'title',
|
292 |
+
'id' => 'phone_options',
|
293 |
+
],
|
294 |
+
[
|
295 |
+
'title' => 'اعداد فارسی در تلفن همراه',
|
296 |
+
'id' => 'PW_Options[fix_phone_persian_number]',
|
297 |
+
'type' => 'checkbox',
|
298 |
+
'default' => 'no',
|
299 |
+
'desc' => 'برای تبدیل اعداد فارسی به انگلیسی در تلفن همراه تیک بزنید.',
|
300 |
+
],
|
301 |
+
[
|
302 |
+
'title' => 'بررسی صحت تلفن همراه',
|
303 |
+
'id' => 'PW_Options[phone_validation]',
|
304 |
+
'type' => 'checkbox',
|
305 |
+
'default' => 'no',
|
306 |
+
'desc' => 'برای بررسی صحت تلفن همراه و یازده رقمی بودن آن تیک بزنید.',
|
307 |
+
],
|
308 |
+
[
|
309 |
+
'type' => 'sectionend',
|
310 |
+
'id' => 'phone_options',
|
311 |
+
],
|
312 |
|
313 |
+
[
|
314 |
+
'title' => 'سایر',
|
315 |
+
'type' => 'title',
|
316 |
+
'id' => 'other_options',
|
317 |
+
],
|
318 |
+
[
|
319 |
+
'title' => 'حذف فیلدهای غیرضروری',
|
320 |
+
'id' => 'PW_Options[remove_extra_field_physical]',
|
321 |
+
'type' => 'checkbox',
|
322 |
+
'default' => 'no',
|
323 |
+
'desc' => 'برای حذف فیلدهای غیرضروری از محصولات دانلودی ووکامرس تیک بزنید.',
|
324 |
+
],
|
325 |
+
[
|
326 |
+
'type' => 'sectionend',
|
327 |
+
'id' => 'other_options',
|
328 |
+
],
|
329 |
+
],
|
330 |
|
331 |
+
];
|
|
|
332 |
|
333 |
+
return apply_filters( 'PW_Tools_settings', $tools );
|
334 |
+
}
|
|
|
|
|
|
|
|
|
|
|
335 |
|
336 |
+
public function tools_page() {
|
337 |
+
global $pagenow;
|
338 |
|
339 |
+
$settings = $this->tools_sections();
|
340 |
+
wp_enqueue_style( 'woocommerce_admin_styles' );
|
341 |
+
wp_enqueue_script( 'wc-enhanced-select' );
|
342 |
+
wp_enqueue_script( 'pw-admin-script' );
|
343 |
+
?>
|
344 |
|
345 |
+
<div class="wrap persian-woocommerce">
|
346 |
+
<h2>ابزارهای ووکامرس فارسی</h2>
|
347 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
348 |
<?php
|
349 |
+
$updated = intval( $_GET['updated'] ?? 0 );
|
|
|
|
|
350 |
|
351 |
+
if ( $updated ) {
|
352 |
+
echo '<div class="updated" ><p>تنظیمات با موفقیت ذخیره شد.</p></div>';
|
353 |
}
|
354 |
|
355 |
+
$current_tab = sanitize_text_field( $_GET['tab'] ?? null );
|
356 |
+
$current_section = sanitize_text_field( $_GET['section'] ?? null );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
357 |
|
358 |
+
[ $tab, $section ] = $this->tools_tabs( $current_tab, $current_section );
|
|
|
|
|
359 |
?>
|
360 |
+
|
361 |
+
<div id="poststuff">
|
362 |
+
<form method="post" action="<?php admin_url( 'themes.php?page=persian-wc-tools' ); ?>">
|
|
|
|
|
|
|
|
|
|
|
363 |
<?php
|
364 |
+
wp_nonce_field( "persian-wc-tools" );
|
365 |
+
|
366 |
+
if ( $pagenow == 'admin.php' && $_GET['page'] == 'persian-wc-tools' && isset( $settings[ $tab ] ) ) {
|
367 |
+
WC_Admin_Settings::output_fields( empty( $section ) ? $settings[ $tab ] : $settings[ $tab ][ $section ] );
|
368 |
}
|
369 |
+
|
370 |
?>
|
371 |
+
<p class="submit" style="clear: both;">
|
372 |
+
<input type="submit" name="Submit" class="button-primary" value="ذخیره تنظیمات"/>
|
373 |
+
<input type="hidden" name="pw-settings-submit" value="Y"/>
|
374 |
+
<input type="hidden" name="pw-tab" value="<?php echo esc_attr( $tab ); ?>"/>
|
375 |
+
<input type="hidden" name="pw-section" value="<?php echo esc_attr( $section ); ?>"/>
|
376 |
+
</p>
|
377 |
+
</form>
|
378 |
+
</div>
|
379 |
+
|
380 |
+
</div>
|
381 |
+
<script type="text/javascript">
|
382 |
+
jQuery(document).ready(function ($) {
|
383 |
+
$('.persian-woocommerce').on('click', '.select_all', function () {
|
384 |
+
jQuery(this).closest('td').find('select option').attr('selected', 'selected');
|
385 |
+
jQuery(this).closest('td').find('select').trigger('change');
|
386 |
+
return false;
|
387 |
+
}).on('click', '.select_none', function () {
|
388 |
+
jQuery(this).closest('td').find('select option').removeAttr('selected');
|
389 |
+
jQuery(this).closest('td').find('select').trigger('change');
|
390 |
+
return false;
|
391 |
+
});
|
392 |
+
|
393 |
+
$('select#PW_Options\\[allowed_states\\]').change(function () {
|
394 |
+
if (jQuery(this).val() === 'specific') {
|
395 |
+
jQuery(this).parent().parent().next('tr').show();
|
396 |
+
} else {
|
397 |
+
jQuery(this).parent().parent().next('tr').hide();
|
398 |
+
}
|
399 |
+
}).change();
|
400 |
+
});
|
401 |
+
</script>
|
402 |
+
<?php
|
403 |
+
}
|
404 |
+
|
405 |
+
public function tools_save() {
|
406 |
+
|
407 |
+
$page = sanitize_text_field( $_GET['page'] ?? null );
|
408 |
+
|
409 |
+
if ( $page != 'persian-wc-tools' ) {
|
410 |
+
return;
|
411 |
}
|
412 |
|
413 |
+
if ( isset( $_POST['pw-settings-submit'] ) && $_POST['pw-settings-submit'] == 'Y' ) {
|
414 |
|
415 |
+
$settings = $this->tools_sections();
|
416 |
+
$tab = sanitize_text_field( $_POST['pw-tab'] );
|
417 |
+
$section = sanitize_text_field( $_POST['pw-section'] );
|
418 |
+
|
419 |
+
check_admin_referer( 'persian-wc-tools' );
|
420 |
+
|
421 |
+
do_action( 'PW_before_save_tools', $_POST, $settings, $tab, $section );
|
422 |
+
|
423 |
+
WC_Admin_Settings::save_fields( empty( $section ) ? $settings[ $tab ] : $settings[ $tab ][ $section ] );
|
424 |
+
|
425 |
+
do_action( 'PW_after_save_tools', $_POST, $settings, $tab, $section );
|
426 |
|
427 |
+
$url_parameters = empty( $section ) ? $tab : $tab . '§ion=' . $section;
|
428 |
|
429 |
+
wp_redirect( admin_url( 'admin.php?page=persian-wc-tools&updated=1&tab=' . $url_parameters ) );
|
430 |
+
exit;
|
431 |
+
}
|
432 |
+
}
|
433 |
+
|
434 |
+
public function specific_states_field( $value ) {
|
435 |
+
|
436 |
+
$selections = (array) PW()->get_options( 'specific_allowed_states' );
|
437 |
+
?>
|
438 |
+
<tr valign="top">
|
439 |
+
<th scope="row" class="titledesc">
|
440 |
+
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
|
441 |
+
</th>
|
442 |
+
<td class="forminp">
|
443 |
+
<select multiple="multiple" name="<?php echo esc_attr( $value['id'] ); ?>[]" style="width:350px"
|
444 |
+
data-placeholder="استان (ها) مورد نظر خود را انتخاب کنید ..." title="استان"
|
445 |
+
class="wc-enhanced-select">
|
446 |
+
<?php
|
447 |
+
if ( ! empty( PW()->address->states ) ) {
|
448 |
+
foreach ( PW()->address->states as $key => $val ) {
|
449 |
+
echo '<option value="' . esc_attr( $key ) . '" ' . selected( in_array( $key, $selections ), true, false ) . '>' . esc_attr( $val ) . '</option>';
|
450 |
}
|
451 |
}
|
452 |
+
?>
|
453 |
+
</select> <br/><a class="select_all button" href="#"><?php _e( 'Select all', 'woocommerce' ); ?></a> <a
|
454 |
+
class="select_none button" href="#"><?php _e( 'Select none', 'woocommerce' ); ?></a>
|
455 |
+
</td>
|
456 |
+
</tr><?php
|
457 |
+
}
|
458 |
+
|
459 |
+
public function get_tools_default( $tools = null ): array {
|
460 |
|
461 |
+
if ( is_null( $tools ) ) {
|
462 |
+
$tools = $this->tools_sections();
|
463 |
}
|
464 |
+
|
465 |
+
$output = [];
|
466 |
+
|
467 |
+
foreach ( $tools as $tool => $tool_name ) {
|
468 |
+
if ( isset( $tool_name['id'], $tool_name['default'] ) ) {
|
469 |
+
$output[ $tool_name['id'] ] = $tool_name['default'];
|
470 |
+
} elseif ( is_array( $tool_name ) ) {
|
471 |
+
$array = $this->get_tools_default( $tool_name );
|
472 |
+
if ( count( $array ) ) {
|
473 |
+
$output += $array;
|
474 |
+
}
|
475 |
+
}
|
476 |
+
}
|
477 |
+
|
478 |
+
return $output;
|
479 |
}
|
480 |
+
}
|
481 |
|
482 |
PW()->tools = new Persian_Woocommerce_Tools();
|
483 |
|
484 |
do_action( 'PW_Tools_load', PW()->get_options() );
|
485 |
|
486 |
+
require_once 'tools/class-general.php';
|
487 |
+
require_once 'tools/class-price.php';
|
488 |
+
require_once 'tools/class-datepicker.php';
|
489 |
+
require_once 'tools/class-date.php';
|
490 |
+
require_once 'tools/class-checkout.php';
|
include/class-translate.php
CHANGED
@@ -1,247 +1,254 @@
|
|
1 |
-
<?php
|
2 |
-
exit;
|
3 |
-
}
|
4 |
-
|
5 |
-
if ( ! class_exists( 'Persian_Woocommerce_Translate' ) ) :
|
6 |
|
7 |
-
|
8 |
|
9 |
-
|
10 |
|
11 |
-
|
12 |
|
13 |
-
|
14 |
|
15 |
-
|
16 |
-
add_filter( 'load_textdomain_mofile', array( $this, 'load_textdomain' ), 10, 2 );
|
17 |
|
18 |
-
|
19 |
-
|
20 |
|
21 |
-
|
22 |
-
|
23 |
-
}
|
24 |
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
}
|
33 |
|
34 |
-
|
|
|
|
|
35 |
}
|
36 |
|
37 |
-
|
38 |
-
|
39 |
|
40 |
-
|
|
|
41 |
|
42 |
-
|
43 |
-
$wpdb->suppress_errors = true;
|
44 |
-
$result = $wpdb->get_results( "SELECT * FROM {$this->table};" );
|
45 |
-
$wpdb->suppress_errors = false;
|
46 |
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
|
52 |
-
if (
|
53 |
-
|
54 |
-
add_filter( 'ngettext_with_context', array( $this, 'gettext' ) );
|
55 |
-
add_filter( 'gettext', array( $this, 'gettext' ) );
|
56 |
-
add_filter( 'ngettext', array( $this, 'gettext' ) );
|
57 |
}
|
58 |
}
|
59 |
|
60 |
-
|
61 |
-
|
|
|
|
|
|
|
62 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
<div id="postbox-container-1" class="postbox-container">
|
73 |
-
<?php do_meta_boxes( 'woocommerce_persian_translate', 'side', null ); ?>
|
74 |
-
</div>
|
75 |
-
|
76 |
-
<div id="postbox-container-2" class="postbox-container">
|
77 |
-
<?php settings_errors();
|
78 |
-
echo '<form method="POST" id="list-project">';
|
79 |
-
echo '<input type="hidden" name="page" value="persian-wc" />';
|
80 |
-
wp_nonce_field( 'delete_item', 'woocommerce_persian_translate_nonce' );
|
81 |
-
$list = new Persian_Woocommerce_Translate_List_Table();
|
82 |
-
$list->search_box( 'جستجو', 'PW-search-input' );
|
83 |
-
$list->prepare_items();
|
84 |
-
$list->display();
|
85 |
-
echo '</form>';
|
86 |
-
?>
|
87 |
-
<div class="clear"></div>
|
88 |
-
</div>
|
89 |
-
</div>
|
90 |
-
<br class="clear">
|
91 |
-
</div>
|
92 |
-
</div>
|
93 |
-
</div>
|
94 |
-
<script type="text/javascript">
|
95 |
-
jQuery(document).ready(function ( $ ) {
|
96 |
-
$("#woocommerce_persian_translate").submit(function () {
|
97 |
-
$("#save_loop_button").val("در حال ذخیره ...");
|
98 |
-
jQuery.post(ajaxurl, $("#woocommerce_persian_translate").serialize(), function ( response ) {
|
99 |
-
var obj = jQuery.parseJSON(response);
|
100 |
-
if( obj.success ) {
|
101 |
-
$("#the-list").prepend(obj.code);
|
102 |
-
$(".displaying-num").html(obj.count);
|
103 |
-
document.getElementById("woocommerce_persian_translate").reset();
|
104 |
-
if( obj.count === "1 مورد" ) {
|
105 |
-
$("tr.no-items").remove();
|
106 |
-
$(".tablenav-pages").removeClass("no-pages").addClass("one-page");
|
107 |
-
}
|
108 |
-
}
|
109 |
-
setTimeout(function () {
|
110 |
-
$("#setting-error-pw_msg_" + obj.rand).slideUp('slow', function () {
|
111 |
-
$("#setting-error-pw_msg_" + obj.rand).remove();
|
112 |
-
})
|
113 |
-
}, 3000);
|
114 |
-
$(".wrap h2#title").after(obj.message);
|
115 |
-
});
|
116 |
-
setTimeout(function () {
|
117 |
-
$("#save_loop_button").val("ذخیره حلقه");
|
118 |
-
}, 2000);
|
119 |
-
return false;
|
120 |
-
});
|
121 |
-
});
|
122 |
-
</script>
|
123 |
-
<?php
|
124 |
}
|
125 |
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
|
|
131 |
}
|
132 |
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
<label for="input_text_1">کلمهی مورد نظر :</label>
|
142 |
-
<input type="text" class="widefat" id="input_text_1" name="text1"/>
|
143 |
-
<br>
|
144 |
-
<label for="input_text_2">جایگزین شود با :</label>
|
145 |
-
<input type="text" class="widefat" id="input_text_2" name="text2"/>
|
146 |
-
<?php echo '</div>'; ?>
|
147 |
-
<div id="major-publishing-actions">
|
148 |
-
<div id="publishing-action">
|
149 |
-
<span class="spinner"></span>
|
150 |
-
<?php submit_button( esc_attr( 'ذخیره حلقه' ), 'primary', 'submit', false, array( 'id' => 'save_loop_button' ) ); ?>
|
151 |
-
</div>
|
152 |
-
<div class="clear"></div>
|
153 |
-
</form>
|
154 |
-
<?php
|
155 |
}
|
156 |
|
157 |
-
|
158 |
-
|
159 |
|
160 |
-
|
161 |
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
];
|
|
|
167 |
|
168 |
-
|
169 |
|
170 |
-
|
171 |
|
172 |
-
|
173 |
-
|
174 |
-
'text2' => $_POST['text2']
|
175 |
-
] );
|
176 |
|
177 |
-
|
|
|
178 |
|
179 |
-
|
180 |
-
$json['message'] = sprintf( '<div id="setting-error-pw_msg_%d" class="updated settings-error notice is-dismissible"><p><strong>حلقه (%s => %s) با موفقیت افزوده شد.</strong></p><button type="button" class="notice-dismiss"><span class="screen-reader-text">بستن این اعلان.</span></button></div>', $json['rand'], $_POST['text1'], $_POST['text2'] );
|
181 |
|
182 |
-
|
|
|
|
|
183 |
|
184 |
-
|
185 |
-
|
186 |
-
$_POST['text2']
|
187 |
-
] ) !== false ) {
|
188 |
-
$json['code'] = sprintf( '<tr id="PW_item_%1$d" data-id="%1$d"><th scope="row" class="check-column"><input name="text_delete_id[]" value="%1$d" type="checkbox"></th><td class="text1 column-text1 has-row-actions column-primary" data-colname="حلقهی اصلی">%2$s<button type="button" class="toggle-row"><span class="screen-reader-text">نمایش جزئیات بیشتر</span></button></td><td class="text2 column-text2" data-colname="حلقهی جایگزین شده">%3$s</td></tr>', $wpdb->insert_id, $_POST['text1'], $_POST['text2'] );
|
189 |
-
}
|
190 |
|
191 |
-
|
192 |
|
193 |
-
|
194 |
|
195 |
-
|
196 |
-
|
197 |
-
}
|
198 |
} else {
|
199 |
-
$
|
200 |
}
|
201 |
}
|
202 |
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
public function search_delete() {
|
207 |
-
|
208 |
-
if ( empty( $_GET['page'] ) || $_GET['page'] != 'persian-wc' ) {
|
209 |
-
return;
|
210 |
}
|
211 |
|
212 |
-
if (
|
213 |
-
|
214 |
-
wp_redirect( remove_query_arg( array( 's' ), stripslashes( $_SERVER['REQUEST_URI'] ) ) );
|
215 |
-
exit;
|
216 |
-
} else if ( ! empty( $_POST['s'] ) ) {
|
217 |
-
wp_redirect( add_query_arg( array( 's' => $_POST['s'] ), stripslashes( $_SERVER['REQUEST_URI'] ) ) );
|
218 |
-
exit;
|
219 |
-
}
|
220 |
}
|
|
|
221 |
|
222 |
-
|
223 |
-
$success = $failed = 0;
|
224 |
-
foreach ( $_POST['text_delete_id'] as $delete_id ) {
|
225 |
-
global $wpdb;
|
226 |
-
$delete = $wpdb->delete( $wpdb->prefix . 'woocommerce_ir', array( 'id' => intval( $delete_id ) ) );
|
227 |
-
if ( $delete ) {
|
228 |
-
$success ++;
|
229 |
-
} else {
|
230 |
-
$failed ++;
|
231 |
-
}
|
232 |
-
}
|
233 |
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
if ( $failed ) {
|
239 |
-
add_settings_error( 'delete_text', 'pw_msg', sprintf( 'حذف %d حلقه با شکست مواجه شد.', $failed ) );
|
240 |
-
}
|
241 |
}
|
|
|
|
|
242 |
}
|
243 |
}
|
244 |
-
|
|
|
245 |
PW()->translate = new Persian_Woocommerce_Translate();
|
246 |
|
247 |
if ( ! class_exists( 'WP_List_Table' ) ) {
|
@@ -250,7 +257,7 @@ if ( ! class_exists( 'WP_List_Table' ) ) {
|
|
250 |
|
251 |
class Persian_Woocommerce_Translate_List_Table extends WP_List_Table {
|
252 |
|
253 |
-
private $data
|
254 |
|
255 |
public function __construct() {
|
256 |
|
@@ -267,56 +274,48 @@ class Persian_Woocommerce_Translate_List_Table extends WP_List_Table {
|
|
267 |
|
268 |
$this->data = $wpdb->get_results( "SELECT * FROM `{$wpdb->prefix}woocommerce_ir`{$search} ORDER BY id DESC LIMIT $db_page, $perPage;", ARRAY_A );
|
269 |
|
270 |
-
$this->set_pagination_args(
|
271 |
'total_items' => $wpdb->get_var( "SELECT COUNT(*) FROM `{$wpdb->prefix}woocommerce_ir`{$search};" ),
|
272 |
-
'per_page' => $perPage
|
273 |
-
|
274 |
|
275 |
-
parent::__construct(
|
276 |
'singular' => 'text',
|
277 |
'plural' => 'texts',
|
278 |
-
'ajax' => false
|
279 |
-
|
280 |
}
|
281 |
|
282 |
-
public function column_default( $item, $column_name ) {
|
283 |
-
return
|
284 |
}
|
285 |
|
286 |
-
public function get_columns() {
|
287 |
-
return
|
288 |
'cb' => '<input type="checkbox" />',
|
289 |
'text1' => 'کلمه اصلی',
|
290 |
'text2' => 'کلمه جایگزین شده',
|
291 |
-
|
292 |
}
|
293 |
|
294 |
-
public function column_cb( $item ) {
|
295 |
-
return sprintf( '<input type="checkbox" name="text_delete_id[]" value="%
|
296 |
}
|
297 |
|
298 |
public function prepare_items() {
|
299 |
-
$this->_column_headers =
|
300 |
$this->items = $this->data;;
|
301 |
}
|
302 |
|
303 |
public function single_row( $item ) {
|
304 |
-
|
305 |
$this->single_row_columns( $item );
|
306 |
echo '</tr>';
|
307 |
}
|
308 |
|
309 |
-
public function get_bulk_actions() {
|
310 |
-
return
|
311 |
-
|
312 |
-
|
313 |
-
public function search_box( $text, $input_id ) {
|
314 |
-
?>
|
315 |
-
<p class="search-box">
|
316 |
-
<label class="screen-reader-text" for="<?php echo $input_id; ?>"><?php echo $text; ?>:</label>
|
317 |
-
<input type="search" id="<?php echo $input_id; ?>" name="s" value="<?php _admin_search_query(); ?>"/>
|
318 |
-
<?php submit_button( $text, 'button', '', false, array( 'id' => 'search-submit' ) ); ?>
|
319 |
-
</p>
|
320 |
-
<?php
|
321 |
}
|
322 |
}
|
1 |
+
<?php
|
|
|
|
|
|
|
|
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || exit;
|
4 |
|
5 |
+
class Persian_Woocommerce_Translate extends Persian_Woocommerce_Core {
|
6 |
|
7 |
+
public $table, $translates;
|
8 |
|
9 |
+
public function __construct() {
|
10 |
|
11 |
+
$this->translates();
|
|
|
12 |
|
13 |
+
add_filter( 'override_unload_textdomain', [ $this, 'unload_textdomain' ], 9999, 2 );
|
14 |
+
add_filter( 'load_textdomain_mofile', [ $this, 'load_textdomain' ], 10, 2 );
|
15 |
|
16 |
+
add_action( 'add_meta_boxes', [ $this, 'add_meta_box' ] );
|
17 |
+
add_action( 'admin_init', [ $this, 'search_delete' ] );
|
|
|
18 |
|
19 |
+
add_action( 'wp_ajax_pw_save_translates', [ $this, 'save_translates' ] );
|
20 |
+
add_action( 'wp_ajax_nopriv_pw_save_translates', [ $this, 'save_translates' ] );
|
21 |
+
}
|
22 |
|
23 |
+
public function unload_textdomain( $override, $domain ) {
|
24 |
+
return get_locale() == 'fa_IR' && $domain === 'woocommerce' ? true : $override;
|
25 |
+
}
|
|
|
26 |
|
27 |
+
public function load_textdomain( $mo_file, $domain ) {
|
28 |
+
if ( get_locale() == 'fa_IR' && $domain === 'woocommerce' ) {
|
29 |
+
$mo_file = dirname( plugin_dir_path( __FILE__ ) ) . '/languages/woocommerce-fa_IR.mo';
|
30 |
}
|
31 |
|
32 |
+
return $mo_file;
|
33 |
+
}
|
34 |
|
35 |
+
public function translates() {
|
36 |
+
global $wpdb;
|
37 |
|
38 |
+
$this->table = $wpdb->prefix . 'woocommerce_ir';
|
|
|
|
|
|
|
39 |
|
40 |
+
if ( ! is_array( $this->translates ) ) {
|
41 |
+
$wpdb->suppress_errors = true;
|
42 |
+
$result = $wpdb->get_results( "SELECT * FROM {$this->table};" );
|
43 |
+
$wpdb->suppress_errors = false;
|
44 |
|
45 |
+
if ( ! $wpdb->last_error ) {
|
46 |
+
$this->translates = wp_list_pluck( $result, 'text2', 'text1' );
|
|
|
|
|
|
|
47 |
}
|
48 |
}
|
49 |
|
50 |
+
if ( is_array( $this->translates ) && count( $this->translates ) ) {
|
51 |
+
add_filter( 'gettext_with_context', [ $this, 'gettext' ] );
|
52 |
+
add_filter( 'ngettext_with_context', [ $this, 'gettext' ] );
|
53 |
+
add_filter( 'gettext', [ $this, 'gettext' ] );
|
54 |
+
add_filter( 'ngettext', [ $this, 'gettext' ] );
|
55 |
}
|
56 |
+
}
|
57 |
+
|
58 |
+
public function gettext( $text ) {
|
59 |
+
return $this->translates[ $text ] ?? $text;
|
60 |
+
}
|
61 |
+
|
62 |
+
public function translate_page() {
|
63 |
+
do_action( 'add_meta_boxes', 'woocommerce_persian_translate', 0 );
|
64 |
+
?>
|
65 |
+
<div class="wrap">
|
66 |
+
<h2 id="title">حلقه های ترجمه</h2>
|
67 |
+
<div class="fx-settings-meta-box-wrap">
|
68 |
+
<div id="poststuff">
|
69 |
+
<div id="post-body" class="metabox-holder columns-2">
|
70 |
+
<div id="postbox-container-1" class="postbox-container">
|
71 |
+
<?php do_meta_boxes( 'woocommerce_persian_translate', 'side', null ); ?>
|
72 |
+
</div>
|
73 |
+
|
74 |
+
<div id="postbox-container-2" class="postbox-container">
|
75 |
+
<?php settings_errors();
|
76 |
+
echo '<form method="POST" id="list-project">';
|
77 |
+
echo '<input type="hidden" name="page" value="persian-wc" />';
|
78 |
+
wp_nonce_field( 'delete_item', 'pw_translate_nonce' );
|
79 |
+
$list = new Persian_Woocommerce_Translate_List_Table();
|
80 |
+
$list->prepare_items();
|
81 |
+
$list->search_box( 'جستجو', 'PW-search-input' );
|
82 |
+
$list->display();
|
83 |
+
echo '</form>';
|
84 |
+
?>
|
85 |
+
<div class="clear"></div>
|
86 |
+
</div>
|
87 |
+
</div>
|
88 |
+
<br class="clear">
|
89 |
+
</div>
|
90 |
+
</div>
|
91 |
+
</div>
|
92 |
+
<script type="text/javascript">
|
93 |
+
jQuery(document).ready(function ($) {
|
94 |
+
$("#woocommerce_persian_translate").submit(function () {
|
95 |
+
$("#save_loop_button").val("در حال ذخیره ...");
|
96 |
+
jQuery.post(ajaxurl, $("#woocommerce_persian_translate").serialize(), function (response) {
|
97 |
+
var obj = jQuery.parseJSON(response);
|
98 |
+
if (obj.success) {
|
99 |
+
$("#the-list").prepend(obj.code);
|
100 |
+
$(".displaying-num").html(obj.count);
|
101 |
+
document.getElementById("woocommerce_persian_translate").reset();
|
102 |
+
if (obj.count === "1 مورد") {
|
103 |
+
$("tr.no-items").remove();
|
104 |
+
$(".tablenav-pages").removeClass("no-pages").addClass("one-page");
|
105 |
+
}
|
106 |
+
}
|
107 |
+
setTimeout(function () {
|
108 |
+
$("#setting-error-pw_msg_" + obj.rand).slideUp('slow', function () {
|
109 |
+
$("#setting-error-pw_msg_" + obj.rand).remove();
|
110 |
+
})
|
111 |
+
}, 3000);
|
112 |
+
$(".wrap h2#title").after(obj.message);
|
113 |
+
});
|
114 |
+
setTimeout(function () {
|
115 |
+
$("#save_loop_button").val("ذخیره حلقه");
|
116 |
+
}, 2000);
|
117 |
+
return false;
|
118 |
+
});
|
119 |
+
});
|
120 |
+
</script>
|
121 |
+
<?php
|
122 |
+
}
|
123 |
+
|
124 |
+
public function add_meta_box() {
|
125 |
+
add_meta_box( 'add_form', 'افزودن حلقه ترجمه', [
|
126 |
+
$this,
|
127 |
+
'meta_box_form',
|
128 |
+
], 'woocommerce_persian_translate', 'side', 'high' );
|
129 |
+
}
|
130 |
+
|
131 |
+
public function meta_box_form() {
|
132 |
+
?>
|
133 |
+
<form action="" method="post" id="woocommerce_persian_translate">
|
134 |
+
<input type="hidden" name="s" value="<?php echo esc_attr( $_GET['s'] ?? null ); ?>"/>
|
135 |
+
<input type="hidden" name="action" value="pw_save_translates"/>
|
136 |
+
<input type="hidden" name="security"
|
137 |
+
value="<?php echo wp_create_nonce( 'pw_save_translates' ); ?>"/>
|
138 |
+
<label for="input_text_1">کلمهی مورد نظر:</label>
|
139 |
+
<input type="text" class="widefat" id="input_text_1" name="text1"/>
|
140 |
+
<br>
|
141 |
+
<label for="input_text_2">جایگزین شود با:</label>
|
142 |
+
<input type="text" class="widefat" id="input_text_2" name="text2"/>
|
143 |
+
<?php echo '</div>'; ?>
|
144 |
+
<div id="major-publishing-actions">
|
145 |
+
<div id="publishing-action">
|
146 |
+
<span class="spinner"></span>
|
147 |
+
<?php submit_button( 'ذخیره حلقه', 'primary', 'submit', false, [ 'id' => 'save_loop_button' ] ); ?>
|
148 |
+
</div>
|
149 |
+
<div class="clear"></div>
|
150 |
+
</form>
|
151 |
+
<?php
|
152 |
+
}
|
153 |
+
|
154 |
+
public function save_translates() {
|
155 |
+
global $wpdb;
|
156 |
+
|
157 |
+
check_ajax_referer( 'pw_save_translates', 'security' );
|
158 |
|
159 |
+
$json = [
|
160 |
+
'success' => false,
|
161 |
+
'message' => 'مشکلی هنگام افزودن حلقه رخ داده است. لطفا مجددا تلاش کنید.',
|
162 |
+
'rand' => mt_rand(),
|
163 |
+
];
|
164 |
+
|
165 |
+
if ( ! isset( $_POST['text1'], $_POST['text2'], $_POST['s'] ) ) {
|
166 |
+
die( json_encode( $json ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
167 |
}
|
168 |
|
169 |
+
$text1 = wp_kses_data( $_POST['text1'] );
|
170 |
+
$text2 = wp_kses_data( $_POST['text2'] );
|
171 |
+
$s = sanitize_text_field( $_POST['s'] );
|
172 |
+
|
173 |
+
if ( empty( $text1 ) ) {
|
174 |
+
$json['message'] = sprintf( '<div id="setting-error-pw_msg_%d" class="error settings-error notice is-dismissible"><p><strong>پر کردن فیلد کلمهی مورد نظر اجباری می باشد.</strong></p><button type="button" class="notice-dismiss"><span class="screen-reader-text">بستن این اعلان.</span></button></div>', $json['rand'] );
|
175 |
+
die( json_encode( $json ) );
|
176 |
}
|
177 |
|
178 |
+
$insert = $wpdb->insert( $this->table, [
|
179 |
+
'text1' => esc_html( $text1 ),
|
180 |
+
'text2' => esc_html( $text2 ),
|
181 |
+
] );
|
182 |
+
|
183 |
+
if ( ! $insert ) {
|
184 |
+
$json['message'] = sprintf( '<div id="setting-error-pw_msg_%d" class="error settings-error notice is-dismissible"><p><strong>خطایی در زمان افزودن حلقه (%s => %s) به دیتابیس رخ داده است. لطفا مجددا تلاش کنید</strong></p><button type="button" class="notice-dismiss"><span class="screen-reader-text">بستن این اعلان.</span></button></div>', $json['rand'], $text1, $text2 );
|
185 |
+
die( json_encode( $json ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
}
|
187 |
|
188 |
+
$json['success'] = true;
|
189 |
+
$json['message'] = sprintf( '<div id="setting-error-pw_msg_%d" class="updated settings-error notice is-dismissible"><p><strong>حلقه (%s => %s) با موفقیت افزوده شد.</strong></p><button type="button" class="notice-dismiss"><span class="screen-reader-text">بستن این اعلان.</span></button></div>', $json['rand'], $text1, $text2 );
|
190 |
|
191 |
+
$json['code'] = '';
|
192 |
|
193 |
+
if ( empty( $s ) || array_search( $s, [
|
194 |
+
$text1,
|
195 |
+
$text2,
|
196 |
+
] ) !== false ) {
|
197 |
+
$json['code'] = sprintf( '<tr id="PW_item_%1$d" data-id="%1$d"><th scope="row" class="check-column"><input name="text_delete_id[]" value="%1$d" type="checkbox"></th><td class="text1 column-text1 has-row-actions column-primary" data-colname="حلقهی اصلی">%2$s<button type="button" class="toggle-row"><span class="screen-reader-text">نمایش جزئیات بیشتر</span></button></td><td class="text2 column-text2" data-colname="حلقهی جایگزین شده">%3$s</td></tr>', $wpdb->insert_id, $text1, $text2 );
|
198 |
+
}
|
199 |
|
200 |
+
$search = empty( $s ) ? '' : sprintf( ' WHERE text1 LIKE "%%%1$s%%" OR text2 LIKE "%%%1$s%%"', $s );
|
201 |
|
202 |
+
$json['count'] = $wpdb->get_var( "SELECT COUNT(*) FROM $this->table{$search}" ) . " مورد";
|
203 |
|
204 |
+
die( json_encode( $json ) );
|
205 |
+
}
|
|
|
|
|
206 |
|
207 |
+
public function search_delete() {
|
208 |
+
global $wpdb;
|
209 |
|
210 |
+
$page = sanitize_text_field( $_GET['page'] ?? null );
|
|
|
211 |
|
212 |
+
if ( $page != 'persian-wc' ) {
|
213 |
+
return;
|
214 |
+
}
|
215 |
|
216 |
+
if ( isset( $_POST['action'], $_POST['text_delete_id'] ) && check_admin_referer( 'delete_item', 'pw_translate_nonce' ) ) {
|
217 |
+
$success = $failed = 0;
|
|
|
|
|
|
|
|
|
218 |
|
219 |
+
foreach ( (array) $_POST['text_delete_id'] as $delete_id ) {
|
220 |
|
221 |
+
$delete = $wpdb->delete( $wpdb->prefix . 'woocommerce_ir', [ 'id' => intval( $delete_id ) ] );
|
222 |
|
223 |
+
if ( $delete ) {
|
224 |
+
$success ++;
|
|
|
225 |
} else {
|
226 |
+
$failed ++;
|
227 |
}
|
228 |
}
|
229 |
|
230 |
+
if ( $success ) {
|
231 |
+
add_settings_error( 'delete_text', 'pw_msg', sprintf( '%d حلقه با موفقیت حذف شد.', $success ), 'updated' );
|
|
|
|
|
|
|
|
|
|
|
232 |
}
|
233 |
|
234 |
+
if ( $failed ) {
|
235 |
+
add_settings_error( 'delete_text', 'pw_msg', sprintf( 'حذف %d حلقه با شکست مواجه شد.', $failed ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
236 |
}
|
237 |
+
}
|
238 |
|
239 |
+
if ( isset( $_POST['s'] ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
240 |
|
241 |
+
if ( empty( $_POST['s'] ) ) {
|
242 |
+
wp_redirect( remove_query_arg( [ 's' ], stripslashes( $_SERVER['REQUEST_URI'] ) ) );
|
243 |
+
} else {
|
244 |
+
wp_redirect( add_query_arg( [ 's' => urlencode( $_POST['s'] ) ], stripslashes( $_SERVER['REQUEST_URI'] ) ) );
|
|
|
|
|
|
|
245 |
}
|
246 |
+
|
247 |
+
exit;
|
248 |
}
|
249 |
}
|
250 |
+
}
|
251 |
+
|
252 |
PW()->translate = new Persian_Woocommerce_Translate();
|
253 |
|
254 |
if ( ! class_exists( 'WP_List_Table' ) ) {
|
257 |
|
258 |
class Persian_Woocommerce_Translate_List_Table extends WP_List_Table {
|
259 |
|
260 |
+
private $data;
|
261 |
|
262 |
public function __construct() {
|
263 |
|
274 |
|
275 |
$this->data = $wpdb->get_results( "SELECT * FROM `{$wpdb->prefix}woocommerce_ir`{$search} ORDER BY id DESC LIMIT $db_page, $perPage;", ARRAY_A );
|
276 |
|
277 |
+
$this->set_pagination_args( [
|
278 |
'total_items' => $wpdb->get_var( "SELECT COUNT(*) FROM `{$wpdb->prefix}woocommerce_ir`{$search};" ),
|
279 |
+
'per_page' => $perPage,
|
280 |
+
] );
|
281 |
|
282 |
+
parent::__construct( [
|
283 |
'singular' => 'text',
|
284 |
'plural' => 'texts',
|
285 |
+
'ajax' => false,
|
286 |
+
] );
|
287 |
}
|
288 |
|
289 |
+
public function column_default( $item, $column_name ): string {
|
290 |
+
return esc_html( $item[ $column_name ] ?? null );
|
291 |
}
|
292 |
|
293 |
+
public function get_columns(): array {
|
294 |
+
return [
|
295 |
'cb' => '<input type="checkbox" />',
|
296 |
'text1' => 'کلمه اصلی',
|
297 |
'text2' => 'کلمه جایگزین شده',
|
298 |
+
];
|
299 |
}
|
300 |
|
301 |
+
public function column_cb( $item ): string {
|
302 |
+
return sprintf( '<input type="checkbox" name="text_delete_id[]" value="%d" />', $item['id'] );
|
303 |
}
|
304 |
|
305 |
public function prepare_items() {
|
306 |
+
$this->_column_headers = [ $this->get_columns(), [], [] ];
|
307 |
$this->items = $this->data;;
|
308 |
}
|
309 |
|
310 |
public function single_row( $item ) {
|
311 |
+
printf( "<tr id='PW_item_$1%d' data-id='$1%d'>", $item['id'] );
|
312 |
$this->single_row_columns( $item );
|
313 |
echo '</tr>';
|
314 |
}
|
315 |
|
316 |
+
public function get_bulk_actions(): array {
|
317 |
+
return [
|
318 |
+
'delete' => 'حذف',
|
319 |
+
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
320 |
}
|
321 |
}
|
include/class-widget.php
CHANGED
@@ -1,77 +1,75 @@
|
|
1 |
-
<?php
|
2 |
-
exit;
|
3 |
-
}
|
4 |
|
5 |
-
|
6 |
|
7 |
-
|
8 |
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
|
20 |
-
|
21 |
|
22 |
-
|
23 |
|
24 |
-
|
25 |
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
|
45 |
-
|
46 |
|
47 |
-
|
48 |
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
}
|
53 |
-
?>
|
54 |
-
<p>
|
55 |
-
<label for="posts_number">تعداد نوشته های قابل نمایش در ابزارک ووکامرس پارسی:
|
56 |
-
<select id="posts_number" name="posts_number">
|
57 |
-
<?php for ( $i = 3; $i <= 20; $i ++ ) {
|
58 |
-
echo "<option value='$i'" . ' ' . selected( $options['posts_number'], $i, false ) . ">$i</option>";
|
59 |
-
}
|
60 |
-
?>
|
61 |
-
</select>
|
62 |
-
</label>
|
63 |
-
</p>
|
64 |
-
<?php
|
65 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
}
|
72 |
-
|
73 |
-
return array_merge( $defaults, $options );
|
74 |
}
|
|
|
|
|
75 |
}
|
76 |
-
|
77 |
-
|
|
1 |
+
<?php
|
|
|
|
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || exit;
|
4 |
|
5 |
+
class Persian_Woocommerce_Widget extends Persian_Woocommerce_Core {
|
6 |
|
7 |
+
public function __construct() {
|
8 |
+
add_action( 'wp_dashboard_setup', [ $this, 'widget_setup' ] );
|
9 |
+
}
|
10 |
|
11 |
+
public function widget_setup() {
|
12 |
+
wp_add_dashboard_widget( 'persian_woocommerce_feed',
|
13 |
+
'آخرین اخبار و اطلاعیه های ووکامرس پارسی',
|
14 |
+
[ $this, 'widget_render' ],
|
15 |
+
[ $this, 'widget_settings' ] );
|
16 |
+
}
|
17 |
|
18 |
+
public function widget_render() { ?>
|
19 |
|
20 |
+
<div class="rss-widget">
|
21 |
|
22 |
+
<?php $widget_options = $this->widget_options();
|
23 |
|
24 |
+
wp_widget_rss_output( [
|
25 |
+
'url' => 'http://woocommerce.ir/feed/',
|
26 |
+
'title' => 'آخرین اخبار و اطلاعیه های ووکامرس پارسی',
|
27 |
+
'meta' => [ 'target' => '_new' ],
|
28 |
+
'items' => intval( $widget_options['posts_number'] ),
|
29 |
+
'show_summary' => 1,
|
30 |
+
'show_author' => 0,
|
31 |
+
'show_date' => 1,
|
32 |
+
] );
|
33 |
+
?>
|
34 |
|
35 |
+
<div style="border-top: 1px solid #e7e7e7; padding-top: 12px !important; font-size: 12px;">
|
36 |
+
<img src="<?php echo PW()->plugin_url( 'assets/images/feed.png' ); ?>" width="16" height="16">
|
37 |
+
<a href="http://woocommerce.ir" target="_new" title="خانه">وب سایت پشتیبان ووکامرس پارسی</a>
|
38 |
+
</div>
|
39 |
+
</div>
|
40 |
+
<?php
|
41 |
+
}
|
42 |
|
43 |
+
public function widget_settings() {
|
44 |
|
45 |
+
$options = $this->widget_options();
|
46 |
|
47 |
+
if ( 'post' == strtolower( $_SERVER['REQUEST_METHOD'] ) && isset( $_POST['widget_id'] ) && 'persian_woocommerce_feed' == $_POST['widget_id'] ) {
|
48 |
+
$options['posts_number'] = intval( $_POST['posts_number'] );
|
49 |
+
update_option( 'persian_woocommerce_feed', $options );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
}
|
51 |
+
?>
|
52 |
+
<p>
|
53 |
+
<label for="posts_number">تعداد نوشته های قابل نمایش در ابزارک ووکامرس پارسی:
|
54 |
+
<select id="posts_number" name="posts_number">
|
55 |
+
<?php for ( $i = 3; $i <= 20; $i ++ ) {
|
56 |
+
printf( '<option value="%d" %s>%d</option>', $i, selected( $options['posts_number'], $i, false ), $i );
|
57 |
+
}
|
58 |
+
?>
|
59 |
+
</select>
|
60 |
+
</label>
|
61 |
+
</p>
|
62 |
+
<?php
|
63 |
+
}
|
64 |
|
65 |
+
public function widget_options() {
|
66 |
+
$defaults = [ 'posts_number' => 5 ];
|
67 |
+
if ( ( ! $options = get_option( 'persian_woocommerce_feed' ) ) || ! is_array( $options ) ) {
|
68 |
+
$options = [];
|
|
|
|
|
|
|
69 |
}
|
70 |
+
|
71 |
+
return array_merge( $defaults, $options );
|
72 |
}
|
73 |
+
}
|
74 |
+
|
75 |
+
new Persian_Woocommerce_Widget();
|
include/gateways/class-payir.php
CHANGED
@@ -1,7 +1,6 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
-
|
4 |
-
}
|
5 |
|
6 |
if ( ! class_exists( 'Woocommerce_Ir_Gateway_PayIr' ) ) :
|
7 |
|
@@ -19,35 +18,31 @@ if ( ! class_exists( 'Woocommerce_Ir_Gateway_PayIr' ) ) :
|
|
19 |
|
20 |
public function fields() {
|
21 |
|
22 |
-
return
|
23 |
-
'api' =>
|
24 |
'title' => 'API',
|
25 |
'type' => 'text',
|
26 |
'description' => 'API درگاه Pay.ir',
|
27 |
'default' => '',
|
28 |
-
'desc_tip' => true
|
29 |
-
|
30 |
-
'sandbox' =>
|
31 |
'title' => 'فعالسازی حالت آزمایشی',
|
32 |
'type' => 'checkbox',
|
33 |
'label' => 'فعالسازی حالت آزمایشی Pay.ir',
|
34 |
'description' => 'برای فعال سازی حالت آزمایشی Pay.ir چک باکس را تیک بزنید.',
|
35 |
'default' => 'no',
|
36 |
'desc_tip' => true,
|
37 |
-
|
38 |
-
'cancelled_massage' =>
|
39 |
-
'shortcodes' =>
|
40 |
'transaction_id' => 'شماره تراکنش',
|
41 |
-
|
42 |
-
|
43 |
}
|
44 |
|
45 |
public function request( $order ) {
|
46 |
|
47 |
-
if ( ! extension_loaded( 'curl' ) ) {
|
48 |
-
return 'تابع cURL روی هاست شما فعال نیست.';
|
49 |
-
}
|
50 |
-
|
51 |
$amount = $this->get_total( 'IRR' );
|
52 |
$callback = $this->get_verify_url();
|
53 |
$mobile = $this->get_order_mobile();
|
@@ -55,56 +50,73 @@ if ( ! class_exists( 'Woocommerce_Ir_Gateway_PayIr' ) ) :
|
|
55 |
$description = 'شماره سفارش #' . $order_number;
|
56 |
$apiID = $this->option( 'sandbox' ) == '1' ? 'test' : $this->option( 'api' );
|
57 |
|
58 |
-
$
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
} else {
|
70 |
-
return ! empty( $
|
71 |
}
|
72 |
}
|
73 |
|
74 |
public function verify( $order ) {
|
75 |
|
76 |
-
$apiID
|
77 |
-
$
|
78 |
-
//$factorNumber = $this->post( 'factorNumber' );
|
79 |
|
80 |
-
$this->check_verification( $
|
81 |
|
82 |
$error = '';
|
83 |
$status = 'failed';
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
}
|
100 |
|
101 |
} else {
|
102 |
$error = $this->post( 'message' );
|
103 |
}
|
104 |
|
105 |
-
$this->set_shortcodes(
|
106 |
|
107 |
-
return compact( 'status', '
|
108 |
}
|
109 |
|
110 |
private function errors( $error ) {
|
@@ -152,7 +164,7 @@ if ( ! class_exists( 'Woocommerce_Ir_Gateway_PayIr' ) ) :
|
|
152 |
break;
|
153 |
|
154 |
case '-21' :
|
155 |
-
$message = 'ارسال
|
156 |
break;
|
157 |
|
158 |
case '-31' :
|
1 |
<?php
|
2 |
+
|
3 |
+
defined( 'ABSPATH' ) || exit;
|
|
|
4 |
|
5 |
if ( ! class_exists( 'Woocommerce_Ir_Gateway_PayIr' ) ) :
|
6 |
|
18 |
|
19 |
public function fields() {
|
20 |
|
21 |
+
return [
|
22 |
+
'api' => [
|
23 |
'title' => 'API',
|
24 |
'type' => 'text',
|
25 |
'description' => 'API درگاه Pay.ir',
|
26 |
'default' => '',
|
27 |
+
'desc_tip' => true,
|
28 |
+
],
|
29 |
+
'sandbox' => [
|
30 |
'title' => 'فعالسازی حالت آزمایشی',
|
31 |
'type' => 'checkbox',
|
32 |
'label' => 'فعالسازی حالت آزمایشی Pay.ir',
|
33 |
'description' => 'برای فعال سازی حالت آزمایشی Pay.ir چک باکس را تیک بزنید.',
|
34 |
'default' => 'no',
|
35 |
'desc_tip' => true,
|
36 |
+
],
|
37 |
+
'cancelled_massage' => [],
|
38 |
+
'shortcodes' => [
|
39 |
'transaction_id' => 'شماره تراکنش',
|
40 |
+
],
|
41 |
+
];
|
42 |
}
|
43 |
|
44 |
public function request( $order ) {
|
45 |
|
|
|
|
|
|
|
|
|
46 |
$amount = $this->get_total( 'IRR' );
|
47 |
$callback = $this->get_verify_url();
|
48 |
$mobile = $this->get_order_mobile();
|
50 |
$description = 'شماره سفارش #' . $order_number;
|
51 |
$apiID = $this->option( 'sandbox' ) == '1' ? 'test' : $this->option( 'api' );
|
52 |
|
53 |
+
$pay = wp_remote_post( 'https://pay.ir/pg/send', [
|
54 |
+
'body' => [
|
55 |
+
'api' => $apiID,
|
56 |
+
'amount' => $amount,
|
57 |
+
'redirect' => urlencode( $callback ),
|
58 |
+
'mobile' => $mobile,
|
59 |
+
'factorNumber' => $order_number,
|
60 |
+
'description' => $description,
|
61 |
+
'resellerId' => '1000000800',
|
62 |
+
],
|
63 |
+
] );
|
64 |
+
|
65 |
+
$pay = wp_remote_retrieve_body( $pay );
|
66 |
+
|
67 |
+
if ( empty( $pay ) ) {
|
68 |
+
return 'خطایی در اتصال به درگاه رخ داده است!';
|
69 |
+
}
|
70 |
+
|
71 |
+
$pay = json_decode( $pay );
|
72 |
+
|
73 |
+
if ( $pay->status ) {
|
74 |
+
$this->redirect( 'https://pay.ir/pg/' . $pay->token );
|
75 |
} else {
|
76 |
+
return ! empty( $pay->errorMessage ) ? $pay->errorMessage : ( ! empty( $pay->errorCode ) ? $this->errors( $pay->errorCode ) : '' );
|
77 |
}
|
78 |
}
|
79 |
|
80 |
public function verify( $order ) {
|
81 |
|
82 |
+
$apiID = $this->option( 'sandbox' ) == '1' ? 'test' : $this->option( 'api' );
|
83 |
+
$token = $this->get( 'token' );
|
|
|
84 |
|
85 |
+
$this->check_verification( $token );
|
86 |
|
87 |
$error = '';
|
88 |
$status = 'failed';
|
89 |
+
|
90 |
+
if ( $this->get( 'status' ) ) {
|
91 |
+
|
92 |
+
$pay = wp_remote_post( 'https://pay.ir/pg/verify', [
|
93 |
+
'body' => [
|
94 |
+
'api' => $apiID,
|
95 |
+
'token' => $token,
|
96 |
+
],
|
97 |
+
] );
|
98 |
+
|
99 |
+
$pay = wp_remote_retrieve_body( $pay );
|
100 |
+
|
101 |
+
if ( ! empty( $pay ) ) {
|
102 |
+
|
103 |
+
$pay = json_decode( $pay );
|
104 |
+
|
105 |
+
if ( $pay->status ) {
|
106 |
+
$status = 'completed';
|
107 |
+
} else {
|
108 |
+
$error = ! empty( $pay->errorMessage ) ? $pay->errorMessage : ( ! empty( $pay->errorCode ) ? $this->errors( ( $pay->errorCode . '1' ) ) : '' );
|
109 |
+
}
|
110 |
+
|
111 |
}
|
112 |
|
113 |
} else {
|
114 |
$error = $this->post( 'message' );
|
115 |
}
|
116 |
|
117 |
+
$this->set_shortcodes( [ 'token' => $token ] );
|
118 |
|
119 |
+
return compact( 'status', 'token', 'error' );
|
120 |
}
|
121 |
|
122 |
private function errors( $error ) {
|
164 |
break;
|
165 |
|
166 |
case '-21' :
|
167 |
+
$message = 'ارسال token الزامی می باشد.';
|
168 |
break;
|
169 |
|
170 |
case '-31' :
|
include/tools/class-checkout.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
|
4 |
|
5 |
if ( ! class_exists( 'PW_Tools_Checkout' ) ) :
|
6 |
|
@@ -9,34 +9,14 @@ if ( ! class_exists( 'PW_Tools_Checkout' ) ) :
|
|
9 |
public function __construct() {
|
10 |
|
11 |
if ( PW()->get_options( 'remove_extra_field_physical' ) == 'yes' ) {
|
12 |
-
add_filter( 'woocommerce_checkout_fields',
|
13 |
}
|
14 |
-
|
15 |
}
|
16 |
|
17 |
public function remove_extra_field_physical( $fields ) {
|
18 |
|
19 |
-
|
20 |
-
|
21 |
-
if ( ! empty( WC()->cart->cart_contents ) ) {
|
22 |
-
|
23 |
-
$cart = WC()->cart->get_cart();
|
24 |
-
|
25 |
-
foreach ( $cart as $key => $values ) {
|
26 |
-
|
27 |
-
/** @var WC_Product $_product */
|
28 |
-
$_product = wc_get_product( $values['variation_id'] ? $values['variation_id'] : $values['product_id'] );
|
29 |
-
|
30 |
-
if ( ! empty( $_product ) && $_product->exists() && $values['quantity'] > 0 ) {
|
31 |
-
if ( $_product->virtual == 'no' && $_product->downloadable == 'no' ) {
|
32 |
-
$has_physical_product = true;
|
33 |
-
break;
|
34 |
-
}
|
35 |
-
}
|
36 |
-
}
|
37 |
-
}
|
38 |
-
|
39 |
-
if ( ! $has_physical_product ) {
|
40 |
unset( $fields['billing']['billing_address_1'] );
|
41 |
unset( $fields['billing']['billing_address_2'] );
|
42 |
unset( $fields['billing']['billing_company'] );
|
@@ -44,6 +24,7 @@ if ( ! class_exists( 'PW_Tools_Checkout' ) ) :
|
|
44 |
unset( $fields['billing']['billing_postcode'] );
|
45 |
unset( $fields['billing']['billing_country'] );
|
46 |
unset( $fields['billing']['billing_state'] );
|
|
|
47 |
add_filter( 'woocommerce_enable_order_notes_field', '__return_false' );
|
48 |
}
|
49 |
|
1 |
+
<?php
|
2 |
+
|
3 |
+
defined( 'ABSPATH' ) || exit;
|
4 |
|
5 |
if ( ! class_exists( 'PW_Tools_Checkout' ) ) :
|
6 |
|
9 |
public function __construct() {
|
10 |
|
11 |
if ( PW()->get_options( 'remove_extra_field_physical' ) == 'yes' ) {
|
12 |
+
add_filter( 'woocommerce_checkout_fields', [ $this, 'remove_extra_field_physical' ] );
|
13 |
}
|
14 |
+
|
15 |
}
|
16 |
|
17 |
public function remove_extra_field_physical( $fields ) {
|
18 |
|
19 |
+
if ( ! WC()->cart->needs_shipping() ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
unset( $fields['billing']['billing_address_1'] );
|
21 |
unset( $fields['billing']['billing_address_2'] );
|
22 |
unset( $fields['billing']['billing_company'] );
|
24 |
unset( $fields['billing']['billing_postcode'] );
|
25 |
unset( $fields['billing']['billing_country'] );
|
26 |
unset( $fields['billing']['billing_state'] );
|
27 |
+
|
28 |
add_filter( 'woocommerce_enable_order_notes_field', '__return_false' );
|
29 |
}
|
30 |
|
include/tools/class-date.php
CHANGED
@@ -12,7 +12,7 @@ use Morilog\Jalali\Jalalian;
|
|
12 |
/**
|
13 |
* Class Persian_Woocommerce_Date
|
14 |
*
|
15 |
-
* @author
|
16 |
* @package https://wordpress.org/plugins/persian-date/
|
17 |
*/
|
18 |
class Persian_Woocommerce_Date {
|
@@ -45,11 +45,11 @@ class Persian_Woocommerce_Date {
|
|
45 |
/** @var WC_Order $order */
|
46 |
$order = wc_get_order( $order_id );
|
47 |
|
48 |
-
$hour = str_pad( $_POST['order_date_hour'], 2, 0, STR_PAD_LEFT );
|
49 |
-
$minute = str_pad( $_POST['order_date_minute'], 2, 0, STR_PAD_LEFT );
|
50 |
-
$second = str_pad( $_POST['order_date_second'], 2, 0, STR_PAD_LEFT );
|
51 |
|
52 |
-
$timestamp = $_POST['order_date'] . " {$hour}:{$minute}:{$second}";
|
53 |
|
54 |
$jDate = Jalalian::fromFormat( 'Y-m-d H:i:s', self::en( $timestamp ) );
|
55 |
|
@@ -178,9 +178,9 @@ class Persian_Woocommerce_Date {
|
|
178 |
$expiry_date = $jDate->toCarbon()->format( 'Y-m-d' );
|
179 |
}
|
180 |
|
181 |
-
$coupon->set_props(
|
182 |
'date_expires' => $expiry_date,
|
183 |
-
|
184 |
|
185 |
$coupon->save();
|
186 |
}
|
@@ -200,9 +200,11 @@ class Persian_Woocommerce_Date {
|
|
200 |
|
201 |
public function wp_date( $date, $format, $timestamp, $timezone ) {
|
202 |
|
|
|
|
|
203 |
try {
|
204 |
return Jalalian::fromDateTime( $timestamp, $timezone )->format( $format );
|
205 |
-
} catch( Exception $e ) {
|
206 |
return $date;
|
207 |
}
|
208 |
}
|
@@ -215,7 +217,7 @@ class Persian_Woocommerce_Date {
|
|
215 |
* @return mixed
|
216 |
*/
|
217 |
private static function en( $number ) {
|
218 |
-
return str_replace(
|
219 |
}
|
220 |
}
|
221 |
|
12 |
/**
|
13 |
* Class Persian_Woocommerce_Date
|
14 |
*
|
15 |
+
* @author mahdiy
|
16 |
* @package https://wordpress.org/plugins/persian-date/
|
17 |
*/
|
18 |
class Persian_Woocommerce_Date {
|
45 |
/** @var WC_Order $order */
|
46 |
$order = wc_get_order( $order_id );
|
47 |
|
48 |
+
$hour = str_pad( intval( $_POST['order_date_hour'] ), 2, 0, STR_PAD_LEFT );
|
49 |
+
$minute = str_pad( intval( $_POST['order_date_minute'] ), 2, 0, STR_PAD_LEFT );
|
50 |
+
$second = str_pad( intval( $_POST['order_date_second'] ), 2, 0, STR_PAD_LEFT );
|
51 |
|
52 |
+
$timestamp = wc_clean( $_POST['order_date'] ) . " {$hour}:{$minute}:{$second}";
|
53 |
|
54 |
$jDate = Jalalian::fromFormat( 'Y-m-d H:i:s', self::en( $timestamp ) );
|
55 |
|
178 |
$expiry_date = $jDate->toCarbon()->format( 'Y-m-d' );
|
179 |
}
|
180 |
|
181 |
+
$coupon->set_props( [
|
182 |
'date_expires' => $expiry_date,
|
183 |
+
] );
|
184 |
|
185 |
$coupon->save();
|
186 |
}
|
200 |
|
201 |
public function wp_date( $date, $format, $timestamp, $timezone ) {
|
202 |
|
203 |
+
$format = str_replace( 'M', 'F', $format );
|
204 |
+
|
205 |
try {
|
206 |
return Jalalian::fromDateTime( $timestamp, $timezone )->format( $format );
|
207 |
+
} catch ( Exception $e ) {
|
208 |
return $date;
|
209 |
}
|
210 |
}
|
217 |
* @return mixed
|
218 |
*/
|
219 |
private static function en( $number ) {
|
220 |
+
return str_replace( [ '۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹' ], range( 0, 9 ), $number );
|
221 |
}
|
222 |
}
|
223 |
|
include/tools/class-datepicker.php
CHANGED
@@ -1,7 +1,5 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
-
exit;
|
4 |
-
} // Exit if accessed directly
|
5 |
|
6 |
if ( ! class_exists( 'PW_Tools_DatePicker' ) ) :
|
7 |
|
@@ -11,14 +9,14 @@ if ( ! class_exists( 'PW_Tools_DatePicker' ) ) :
|
|
11 |
'product' => 'product',
|
12 |
'shop_order' => 'shop_order',
|
13 |
'shop_coupon' => 'shop_coupon',
|
14 |
-
'ووکامرس_page_wc-reports' => 'report'
|
15 |
];
|
16 |
|
17 |
public function __construct() {
|
18 |
|
19 |
if ( PW()->get_options( 'enable_jalali_datepicker' ) == 'yes' ) {
|
20 |
-
add_action( 'admin_enqueue_scripts',
|
21 |
-
add_action( 'admin_print_footer_scripts',
|
22 |
}
|
23 |
|
24 |
}
|
@@ -42,11 +40,11 @@ if ( ! class_exists( 'PW_Tools_DatePicker' ) ) :
|
|
42 |
$method_name = "inline_js_" . self::SCREENS[ urldecode( $screen ) ];
|
43 |
|
44 |
?>
|
45 |
-
|
46 |
#ui-datepicker-div {
|
47 |
display: none !important;
|
48 |
}
|
49 |
-
|
50 |
<?php
|
51 |
|
52 |
$this->{$method_name}();
|
@@ -54,68 +52,68 @@ if ( ! class_exists( 'PW_Tools_DatePicker' ) ) :
|
|
54 |
|
55 |
public function inline_js_product() {
|
56 |
?>
|
57 |
-
|
58 |
-
|
59 |
|
60 |
-
|
61 |
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
|
68 |
-
|
69 |
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
|
76 |
-
|
77 |
-
|
78 |
|
79 |
-
|
80 |
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
|
87 |
-
|
88 |
|
89 |
-
|
90 |
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
|
97 |
-
|
98 |
|
99 |
-
|
100 |
-
|
101 |
<?php
|
102 |
}
|
103 |
|
104 |
public function inline_js_shop_order() {
|
105 |
?>
|
106 |
-
|
107 |
-
|
108 |
|
109 |
-
|
110 |
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
|
117 |
-
|
118 |
-
|
119 |
<?php
|
120 |
}
|
121 |
|
@@ -126,40 +124,45 @@ if ( ! class_exists( 'PW_Tools_DatePicker' ) ) :
|
|
126 |
$expiry_date = $coupon->get_date_expires( 'edit' ) ? $coupon->get_date_expires( 'edit' )->date_i18n( 'Y/m/d' ) : '';
|
127 |
|
128 |
?>
|
129 |
-
|
130 |
-
|
131 |
|
132 |
-
|
133 |
-
|
134 |
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
});
|
140 |
|
141 |
-
|
142 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
143 |
<?php
|
144 |
}
|
145 |
|
146 |
public function inline_js_report() {
|
147 |
?>
|
148 |
-
|
149 |
-
|
150 |
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
|
161 |
-
|
162 |
-
|
163 |
<?php
|
164 |
}
|
165 |
}
|
1 |
<?php
|
2 |
+
defined( 'ABSPATH' ) || exit;
|
|
|
|
|
3 |
|
4 |
if ( ! class_exists( 'PW_Tools_DatePicker' ) ) :
|
5 |
|
9 |
'product' => 'product',
|
10 |
'shop_order' => 'shop_order',
|
11 |
'shop_coupon' => 'shop_coupon',
|
12 |
+
'ووکامرس_page_wc-reports' => 'report',
|
13 |
];
|
14 |
|
15 |
public function __construct() {
|
16 |
|
17 |
if ( PW()->get_options( 'enable_jalali_datepicker' ) == 'yes' ) {
|
18 |
+
add_action( 'admin_enqueue_scripts', [ $this, 'datepicker' ], 1000 );
|
19 |
+
add_action( 'admin_print_footer_scripts', [ $this, 'inline_js' ] );
|
20 |
}
|
21 |
|
22 |
}
|
40 |
$method_name = "inline_js_" . self::SCREENS[ urldecode( $screen ) ];
|
41 |
|
42 |
?>
|
43 |
+
<style type="text/css">
|
44 |
#ui-datepicker-div {
|
45 |
display: none !important;
|
46 |
}
|
47 |
+
</style>
|
48 |
<?php
|
49 |
|
50 |
$this->{$method_name}();
|
52 |
|
53 |
public function inline_js_product() {
|
54 |
?>
|
55 |
+
<script type="text/javascript">
|
56 |
+
jQuery(function ($) {
|
57 |
|
58 |
+
let _sale_price_dates_from = $("#_sale_price_dates_from").val();
|
59 |
|
60 |
+
$("#_sale_price_dates_from").persianDatepicker({
|
61 |
+
formatDate: "YYYY-0M-0D",
|
62 |
+
selectedBefore: _sale_price_dates_from.length ? 1 : 0,
|
63 |
+
selectedDate: _sale_price_dates_from.length ? _sale_price_dates_from.replace(/-/gi, "/") : null
|
64 |
+
});
|
65 |
|
66 |
+
let _sale_price_dates_to = $("#_sale_price_dates_to").val();
|
67 |
|
68 |
+
$("#_sale_price_dates_to").persianDatepicker({
|
69 |
+
formatDate: "YYYY-0M-0D",
|
70 |
+
selectedBefore: _sale_price_dates_to.length ? 1 : 0,
|
71 |
+
selectedDate: _sale_price_dates_to.length ? _sale_price_dates_to.replace(/-/gi, "/") : null
|
72 |
+
});
|
73 |
|
74 |
+
$("div.woocommerce_variations").on("click", "a.sale_schedule", function () {
|
75 |
+
let el_to = $(this).parent().parent().next().find("input[name*=to]");
|
76 |
|
77 |
+
let el_date_to = el_to.val();
|
78 |
|
79 |
+
el_to.persianDatepicker({
|
80 |
+
formatDate: "YYYY-0M-0D",
|
81 |
+
selectedBefore: el_date_to.length ? 1 : 0,
|
82 |
+
selectedDate: el_date_to.length ? el_date_to.replace(/-/gi, "/") : null
|
83 |
+
});
|
84 |
|
85 |
+
let el_from = $(this).parent().parent().next().find("input[name*=from]");
|
86 |
|
87 |
+
let el_date_from = el_from.val();
|
88 |
|
89 |
+
el_from.persianDatepicker({
|
90 |
+
formatDate: "YYYY-0M-0D",
|
91 |
+
selectedBefore: el_date_from.length ? 1 : 0,
|
92 |
+
selectedDate: el_date_from.length ? el_date_from.replace(/-/gi, "/") : null
|
93 |
+
});
|
94 |
|
95 |
+
});
|
96 |
|
97 |
+
});
|
98 |
+
</script>
|
99 |
<?php
|
100 |
}
|
101 |
|
102 |
public function inline_js_shop_order() {
|
103 |
?>
|
104 |
+
<script type="text/javascript">
|
105 |
+
jQuery(function ($) {
|
106 |
|
107 |
+
let order_date = $("input[name=order_date]").val();
|
108 |
|
109 |
+
$("input[name=order_date]").persianDatepicker({
|
110 |
+
formatDate: "YYYY-0M-0D",
|
111 |
+
selectedBefore: 1,
|
112 |
+
selectedDate: order_date.length ? order_date.replace(/-/gi, "/") : null
|
113 |
+
});
|
114 |
|
115 |
+
});
|
116 |
+
</script>
|
117 |
<?php
|
118 |
}
|
119 |
|
124 |
$expiry_date = $coupon->get_date_expires( 'edit' ) ? $coupon->get_date_expires( 'edit' )->date_i18n( 'Y/m/d' ) : '';
|
125 |
|
126 |
?>
|
127 |
+
<script type="text/javascript">
|
128 |
+
jQuery(function ($) {
|
129 |
|
130 |
+
$("input[name=expiry_date]").val('<?php echo esc_attr( $expiry_date ); ?>');
|
131 |
+
let expiry_date = $("input[name=expiry_date]").val();
|
132 |
|
133 |
+
let args = {
|
134 |
+
formatDate: "YYYY-0M-0D",
|
135 |
+
selectedDate: null
|
136 |
+
};
|
|
|
137 |
|
138 |
+
if (expiry_date.length) {
|
139 |
+
args.selectedBefore = 1;
|
140 |
+
args.selectedDate = expiry_date.replace(/-/gi, "/");
|
141 |
+
}
|
142 |
+
|
143 |
+
$("input[name=expiry_date]").persianDatepicker(args);
|
144 |
+
});
|
145 |
+
</script>
|
146 |
<?php
|
147 |
}
|
148 |
|
149 |
public function inline_js_report() {
|
150 |
?>
|
151 |
+
<script type="text/javascript">
|
152 |
+
jQuery(function ($) {
|
153 |
|
154 |
+
$("input[name=start_date]").persianDatepicker({
|
155 |
+
formatDate: "YYYY-0M-0D",
|
156 |
+
showGregorianDate: 1,
|
157 |
+
});
|
158 |
|
159 |
+
$("input[name=end_date]").persianDatepicker({
|
160 |
+
formatDate: "YYYY-0M-0D",
|
161 |
+
showGregorianDate: 1,
|
162 |
+
});
|
163 |
|
164 |
+
});
|
165 |
+
</script>
|
166 |
<?php
|
167 |
}
|
168 |
}
|
include/tools/class-general.php
ADDED
@@ -0,0 +1,124 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class PW_Tools_General {
|
4 |
+
|
5 |
+
public function __construct() {
|
6 |
+
add_filter( 'pre_get_posts', [ $this, 'fix_arabic_characters' ] );
|
7 |
+
|
8 |
+
if ( PW()->get_options( 'fix_load_states' ) != 'no' ) {
|
9 |
+
add_action( 'wp_footer', [ $this, 'checkout_state_dropdown_fix' ], 50 );
|
10 |
+
}
|
11 |
+
|
12 |
+
if ( is_admin() && PW()->get_options( 'fix_orders_list' ) != 'no' ) {
|
13 |
+
add_filter( 'pre_get_posts', [ $this, 'sort_orders_list_by_pay_date' ] );
|
14 |
+
}
|
15 |
+
|
16 |
+
if ( PW()->get_options( 'fix_postcode_persian_number' ) != 'no' ) {
|
17 |
+
add_filter( 'woocommerce_checkout_process', [ $this, 'checkout_process_postcode' ], 20, 1 );
|
18 |
+
}
|
19 |
+
|
20 |
+
if ( PW()->get_options( 'postcode_validation' ) != 'no' ) {
|
21 |
+
add_filter( 'woocommerce_validate_postcode', [ $this, 'validate_postcode' ], 10, 3 );
|
22 |
+
}
|
23 |
+
|
24 |
+
if ( PW()->get_options( 'fix_phone_persian_number' ) != 'no' ) {
|
25 |
+
add_filter( 'woocommerce_checkout_process', [ $this, 'checkout_process_phone' ], 20, 1 );
|
26 |
+
}
|
27 |
+
}
|
28 |
+
|
29 |
+
function fix_arabic_characters( $query ) {
|
30 |
+
|
31 |
+
if ( $query->is_search ) {
|
32 |
+
$query->set( 's', str_replace( [ 'ك', 'ي', ], [ 'ک', 'ی' ], $query->get( 's' ) ) );
|
33 |
+
}
|
34 |
+
|
35 |
+
return $query;
|
36 |
+
}
|
37 |
+
|
38 |
+
function checkout_state_dropdown_fix() {
|
39 |
+
|
40 |
+
if ( function_exists( 'is_checkout' ) && ! is_checkout() ) {
|
41 |
+
return;
|
42 |
+
}
|
43 |
+
|
44 |
+
?>
|
45 |
+
<script>
|
46 |
+
jQuery(function () {
|
47 |
+
// Snippets.ir
|
48 |
+
jQuery('#billing_country').trigger('change');
|
49 |
+
jQuery('#billing_state_field').removeClass('woocommerce-invalid');
|
50 |
+
});
|
51 |
+
</script>
|
52 |
+
<?php
|
53 |
+
}
|
54 |
+
|
55 |
+
function sort_orders_list_by_pay_date( $query ) {
|
56 |
+
|
57 |
+
if ( ! function_exists( 'get_current_screen' ) ) {
|
58 |
+
return $query;
|
59 |
+
}
|
60 |
+
|
61 |
+
$screen = get_current_screen();
|
62 |
+
|
63 |
+
if ( is_null( $screen ) || $screen->id != 'edit-shop_order' ) {
|
64 |
+
return $query;
|
65 |
+
}
|
66 |
+
|
67 |
+
$query->set( 'order', 'DESC' );
|
68 |
+
$query->set( 'meta_key', '_paid_date' );
|
69 |
+
$query->set( 'orderby', 'meta_value' );
|
70 |
+
|
71 |
+
return $query;
|
72 |
+
}
|
73 |
+
|
74 |
+
function checkout_process_postcode() {
|
75 |
+
|
76 |
+
if ( isset( $_POST['billing_postcode'] ) ) {
|
77 |
+
$_POST['billing_postcode'] = self::en( sanitize_text_field( $_POST['billing_postcode'] ) );
|
78 |
+
}
|
79 |
+
|
80 |
+
if ( isset( $_POST['shipping_postcode'] ) ) {
|
81 |
+
$_POST['shipping_postcode'] = self::en( sanitize_text_field( $_POST['shipping_postcode'] ) );
|
82 |
+
}
|
83 |
+
|
84 |
+
if ( PW()->get_options( 'phone_validation' ) != 'no' ) {
|
85 |
+
add_action( 'woocommerce_after_checkout_validation', 'validate_phone', 10, 3 );
|
86 |
+
}
|
87 |
+
}
|
88 |
+
|
89 |
+
function validate_postcode( $valid, $postcode, $country ): bool {
|
90 |
+
|
91 |
+
if ( $country != 'IR' ) {
|
92 |
+
return $valid;
|
93 |
+
}
|
94 |
+
|
95 |
+
return (bool) preg_match( '/^([13456789]{5}[0-9]{5})$/', $postcode );
|
96 |
+
}
|
97 |
+
|
98 |
+
function checkout_process_phone() {
|
99 |
+
|
100 |
+
if ( isset( $_POST['billing_phone'] ) ) {
|
101 |
+
$_POST['billing_phone'] = self::en( sanitize_text_field( $_POST['billing_phone'] ) );
|
102 |
+
}
|
103 |
+
|
104 |
+
if ( isset( $_POST['shipping_phone'] ) ) {
|
105 |
+
$_POST['shipping_phone'] = self::en( sanitize_text_field( $_POST['shipping_phone'] ) );
|
106 |
+
}
|
107 |
+
|
108 |
+
}
|
109 |
+
|
110 |
+
function validate_phone( $data, $errors ) {
|
111 |
+
|
112 |
+
if ( (bool) preg_match( '/^(09[0-9]{9})$/', $data['billing_phone'] ) ) {
|
113 |
+
return false;
|
114 |
+
}
|
115 |
+
|
116 |
+
$errors->add( 'validation', '<b>تلفن همراه</b> وارد شده، معتبر نمی باشد.' );
|
117 |
+
}
|
118 |
+
|
119 |
+
private static function en( $number ) {
|
120 |
+
return str_replace( [ '۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹' ], range( 0, 9 ), $number );
|
121 |
+
}
|
122 |
+
}
|
123 |
+
|
124 |
+
new PW_Tools_General();
|
include/tools/class-price.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
|
4 |
|
5 |
if ( ! class_exists( 'PW_Tools_Price' ) ) :
|
6 |
|
@@ -9,25 +9,34 @@ if ( ! class_exists( 'PW_Tools_Price' ) ) :
|
|
9 |
public function __construct() {
|
10 |
|
11 |
if ( PW()->get_options( 'enable_call_for_price' ) == 'yes' ) {
|
12 |
-
add_filter( 'woocommerce_empty_price_html',
|
13 |
-
add_filter( 'woocommerce_sale_flash',
|
14 |
}
|
15 |
|
16 |
if ( PW()->get_options( 'persian_price' ) == 'yes' ) {
|
17 |
-
add_filter( 'wc_price',
|
18 |
-
add_filter( 'woocommerce_get_price_html',
|
19 |
-
|
20 |
-
add_filter( 'woocommerce_cart_item_price',
|
21 |
-
add_filter( 'woocommerce_cart_item_subtotal',
|
22 |
-
add_filter( 'woocommerce_cart_subtotal',
|
23 |
-
add_filter( 'woocommerce_cart_totals_coupon_html',
|
24 |
-
add_filter( 'woocommerce_cart_shipping_method_full_label',
|
25 |
-
add_filter( 'woocommerce_cart_total',
|
26 |
}
|
27 |
|
28 |
if ( PW()->get_options( 'minimum_order_amount' ) != 0 ) {
|
29 |
-
add_action( 'woocommerce_checkout_process',
|
30 |
-
add_action( 'woocommerce_before_cart',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
}
|
32 |
}
|
33 |
|
@@ -58,7 +67,7 @@ if ( ! class_exists( 'PW_Tools_Price' ) ) :
|
|
58 |
}
|
59 |
|
60 |
public function persian_number( $price ) {
|
61 |
-
return str_replace( range( 0, 9 ),
|
62 |
}
|
63 |
|
64 |
public function wc_minimum_order_amount() {
|
@@ -80,6 +89,23 @@ if ( ! class_exists( 'PW_Tools_Price' ) ) :
|
|
80 |
}
|
81 |
}
|
82 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
}
|
84 |
|
85 |
endif;
|
1 |
+
<?php
|
2 |
+
|
3 |
+
defined( 'ABSPATH' ) || exit;
|
4 |
|
5 |
if ( ! class_exists( 'PW_Tools_Price' ) ) :
|
6 |
|
9 |
public function __construct() {
|
10 |
|
11 |
if ( PW()->get_options( 'enable_call_for_price' ) == 'yes' ) {
|
12 |
+
add_filter( 'woocommerce_empty_price_html', [ $this, 'on_empty_price' ], PHP_INT_MAX - 1 );
|
13 |
+
add_filter( 'woocommerce_sale_flash', [ $this, 'hide_sales_flash' ], PHP_INT_MAX, 3 );
|
14 |
}
|
15 |
|
16 |
if ( PW()->get_options( 'persian_price' ) == 'yes' ) {
|
17 |
+
add_filter( 'wc_price', [ $this, 'persian_number' ] );
|
18 |
+
add_filter( 'woocommerce_get_price_html', [ $this, 'persian_number' ] );
|
19 |
+
|
20 |
+
add_filter( 'woocommerce_cart_item_price', [ $this, 'persian_number' ] );
|
21 |
+
add_filter( 'woocommerce_cart_item_subtotal', [ $this, 'persian_number' ] );
|
22 |
+
add_filter( 'woocommerce_cart_subtotal', [ $this, 'persian_number' ] );
|
23 |
+
add_filter( 'woocommerce_cart_totals_coupon_html', [ $this, 'persian_number' ] );
|
24 |
+
add_filter( 'woocommerce_cart_shipping_method_full_label', [ $this, 'persian_number' ] );
|
25 |
+
add_filter( 'woocommerce_cart_total', [ $this, 'persian_number' ] );
|
26 |
}
|
27 |
|
28 |
if ( PW()->get_options( 'minimum_order_amount' ) != 0 ) {
|
29 |
+
add_action( 'woocommerce_checkout_process', [ $this, 'wc_minimum_order_amount' ] );
|
30 |
+
add_action( 'woocommerce_before_cart', [ $this, 'wc_minimum_order_amount' ] );
|
31 |
+
}
|
32 |
+
|
33 |
+
if ( PW()->get_options( 'variable_price', 'range' ) != 'range' ) {
|
34 |
+
add_action( 'woocommerce_variable_sale_price_html', [ $this, 'get_variation_price_format' ], 10, 2 );
|
35 |
+
add_action( 'woocommerce_variable_price_html', [ $this, 'get_variation_price_format' ], 10, 2 );
|
36 |
+
add_action( 'woocommerce_dropdown_variation_attribute_options_args', [
|
37 |
+
$this,
|
38 |
+
'remove_dropdown_variation_options',
|
39 |
+
] );
|
40 |
}
|
41 |
}
|
42 |
|
67 |
}
|
68 |
|
69 |
public function persian_number( $price ) {
|
70 |
+
return str_replace( range( 0, 9 ), [ '۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹' ], $price );
|
71 |
}
|
72 |
|
73 |
public function wc_minimum_order_amount() {
|
89 |
}
|
90 |
}
|
91 |
}
|
92 |
+
|
93 |
+
public function get_variation_price_format( string $price, WC_Product $product ): string {
|
94 |
+
|
95 |
+
[ $min_or_max, $type ] = explode( '_', PW()->get_options( 'variable_price' ) );
|
96 |
+
|
97 |
+
// Validation
|
98 |
+
$min_or_max = $min_or_max == 'min' ? 'min' : 'max';
|
99 |
+
$type = $type == 'regular' ? 'regular' : 'sale';
|
100 |
+
|
101 |
+
return wc_price( $product->{"get_variation_{$type}_price"}( $min_or_max ) );
|
102 |
+
}
|
103 |
+
|
104 |
+
public function remove_dropdown_variation_options( array $args ): array {
|
105 |
+
$args['show_option_none'] = false;
|
106 |
+
|
107 |
+
return $args;
|
108 |
+
}
|
109 |
}
|
110 |
|
111 |
endif;
|
include/tools/general.php
DELETED
@@ -1,111 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( PW()->get_options( 'fix_load_states' ) != 'no' ) {
|
4 |
-
add_action( 'wp_footer', 'pw_checkout_state_dropdown_fix', 50 );
|
5 |
-
}
|
6 |
-
|
7 |
-
function pw_checkout_state_dropdown_fix() {
|
8 |
-
|
9 |
-
if ( function_exists( 'is_checkout' ) && ! is_checkout() ) {
|
10 |
-
return false;
|
11 |
-
}
|
12 |
-
|
13 |
-
?>
|
14 |
-
<script>
|
15 |
-
jQuery(function () {
|
16 |
-
// Snippets.ir
|
17 |
-
jQuery('#billing_country').trigger('change');
|
18 |
-
jQuery('#billing_state_field').removeClass('woocommerce-invalid');
|
19 |
-
});
|
20 |
-
</script>
|
21 |
-
<?php
|
22 |
-
}
|
23 |
-
|
24 |
-
if ( is_admin() && PW()->get_options( 'fix_orders_list' ) != 'no' ) {
|
25 |
-
add_filter( 'pre_get_posts', 'pw_sort_orders_list_by_pay_date' );
|
26 |
-
}
|
27 |
-
|
28 |
-
function pw_sort_orders_list_by_pay_date( $query ) {
|
29 |
-
|
30 |
-
if ( ! function_exists( 'get_current_screen' ) ) {
|
31 |
-
return $query;
|
32 |
-
}
|
33 |
-
|
34 |
-
$screen = get_current_screen();
|
35 |
-
|
36 |
-
if ( is_null( $screen ) || $screen->id != 'edit-shop_order' ) {
|
37 |
-
return $query;
|
38 |
-
}
|
39 |
-
|
40 |
-
$query->set( 'order', 'DESC' );
|
41 |
-
$query->set( 'meta_key', '_date_paid' );
|
42 |
-
$query->set( 'orderby', 'meta_value' );
|
43 |
-
|
44 |
-
return $query;
|
45 |
-
}
|
46 |
-
|
47 |
-
if ( ! function_exists( 'pw_convert_number' ) ) {
|
48 |
-
|
49 |
-
function pw_convert_number( $num ) {
|
50 |
-
return str_replace( array( '۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹' ), range( 0, 9 ), $num );
|
51 |
-
}
|
52 |
-
|
53 |
-
}
|
54 |
-
|
55 |
-
if ( PW()->get_options( 'fix_postcode_persian_number' ) != 'no' ) {
|
56 |
-
add_filter( 'woocommerce_checkout_process', 'pw_checkout_process_postcode', 20, 1 );
|
57 |
-
}
|
58 |
-
|
59 |
-
function pw_checkout_process_postcode() {
|
60 |
-
|
61 |
-
if ( isset( $_POST['billing_postcode'] ) ) {
|
62 |
-
$_POST['billing_postcode'] = pw_convert_number( $_POST['billing_postcode'] );
|
63 |
-
}
|
64 |
-
|
65 |
-
if ( isset( $_POST['shipping_postcode'] ) ) {
|
66 |
-
$_POST['shipping_postcode'] = pw_convert_number( $_POST['shipping_postcode'] );
|
67 |
-
}
|
68 |
-
|
69 |
-
}
|
70 |
-
|
71 |
-
if ( PW()->get_options( 'postcode_validation' ) != 'no' ) {
|
72 |
-
add_filter( 'woocommerce_validate_postcode', 'pw_validate_postcode', 10, 3 );
|
73 |
-
}
|
74 |
-
|
75 |
-
function pw_validate_postcode( $valid, $postcode, $country ) {
|
76 |
-
|
77 |
-
if ( $country != 'IR' ) {
|
78 |
-
return $valid;
|
79 |
-
}
|
80 |
-
|
81 |
-
return (bool) preg_match( '/^([0-9]{10})$/', $postcode );
|
82 |
-
}
|
83 |
-
|
84 |
-
if ( PW()->get_options( 'fix_phone_persian_number' ) != 'no' ) {
|
85 |
-
add_filter( 'woocommerce_checkout_process', 'pw_checkout_process_phone', 20, 1 );
|
86 |
-
}
|
87 |
-
|
88 |
-
function pw_checkout_process_phone() {
|
89 |
-
|
90 |
-
if ( isset( $_POST['billing_phone'] ) ) {
|
91 |
-
$_POST['billing_phone'] = pw_convert_number( $_POST['billing_phone'] );
|
92 |
-
}
|
93 |
-
|
94 |
-
if ( isset( $_POST['shipping_phone'] ) ) {
|
95 |
-
$_POST['shipping_phone'] = pw_convert_number( $_POST['shipping_phone'] );
|
96 |
-
}
|
97 |
-
|
98 |
-
}
|
99 |
-
|
100 |
-
if ( PW()->get_options( 'phone_validation' ) != 'no' ) {
|
101 |
-
add_action( 'woocommerce_after_checkout_validation', 'pw_validate_phone', 10, 3 );
|
102 |
-
}
|
103 |
-
|
104 |
-
function pw_validate_phone( $data, $errors ) {
|
105 |
-
|
106 |
-
if ( (bool) preg_match( '/^(09[0-9]{9})$/', $data['billing_phone'] ) ) {
|
107 |
-
return false;
|
108 |
-
}
|
109 |
-
|
110 |
-
$errors->add( 'validation', '<b>تلفن همراه</b> وارد شده، معتبر نمی باشد.' );
|
111 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
include/view/html-admin-page-plugins.php
CHANGED
@@ -1,108 +1,108 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Admin View: Gateways
|
4 |
-
*/
|
5 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
6 |
-
exit;
|
7 |
-
}
|
8 |
-
|
9 |
-
for ( $i = 0; $i < 3; $i ++ ) {
|
10 |
-
$response = wp_remote_get( 'http://woocommerce.ir/api/gateways.json' );
|
11 |
-
if ( empty( $response->errors ) ) {
|
12 |
-
break;
|
13 |
-
}
|
14 |
-
}
|
15 |
-
|
16 |
-
if ( ! empty( $response->errors ) ) {
|
17 |
-
echo '<br><h1>در اتصال به سرور خطایی رخ داده است. لطفا چند دقیقه دیگر تلاش کنید.</h1>';
|
18 |
-
|
19 |
-
return;
|
20 |
-
}
|
21 |
-
|
22 |
-
if ( is_array( $response ) ) {
|
23 |
-
$response = json_decode( $response['body'] );
|
24 |
-
}
|
25 |
-
|
26 |
-
$count = 0;
|
27 |
-
?>
|
28 |
-
<div class="wrap woocommerce wc_addons_wrap">
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
<?php foreach ( $response as $item ) : ?>
|
42 |
-
<?php if ( $count ++ % 3 == 0 ) {
|
43 |
-
echo '<div class="addons-banner-block-items">';
|
44 |
-
} ?>
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
$string = strip_tags( $item->desc );
|
57 |
-
|
58 |
-
if ( strlen( $string ) > 220 ) {
|
59 |
-
$stringCut = substr( $string, 0, 220 );
|
60 |
-
$string = substr( $stringCut, 0, strrpos( $stringCut, ' ' ) ) . '... <a href="' . esc_url( $item->url ) . '">اطلاعات بیشتر</a>';
|
61 |
-
}
|
62 |
-
echo $string; ?></p>
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
<?php if ( $count % 3 == 0 ) {
|
69 |
-
echo '</div>';
|
70 |
-
} ?>
|
71 |
-
<?php endforeach; ?>
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
</div>
|
76 |
-
|
77 |
-
|
78 |
-
<style type="text/css">
|
79 |
-
.ver {
|
80 |
-
-webkit-transform: rotate(-45deg);
|
81 |
-
-moz-transform: rotate(-45deg);
|
82 |
-
-o-transform: rotate(-45deg);
|
83 |
-
-ms-transform: rotate(-45deg);
|
84 |
-
transform: rotate(-45deg);
|
85 |
-
position: relative;
|
86 |
-
top: 0px;
|
87 |
-
left: -40px;
|
88 |
-
}
|
89 |
-
|
90 |
-
img.addons-img {
|
91 |
-
height: 100% !important;
|
92 |
-
opacity: 1.0;
|
93 |
-
border-right: 1px solid #e4e4e4;
|
94 |
-
border-left: 1px solid #e4e4e4;
|
95 |
-
}
|
96 |
-
|
97 |
-
.addons-banner-block-item-icon {
|
98 |
-
height: 200px;
|
99 |
-
}
|
100 |
-
|
101 |
-
.addons-button {
|
102 |
-
width: auto !important;
|
103 |
-
}
|
104 |
-
|
105 |
-
.addons-banner-block-item-content p {
|
106 |
-
text-align: justify;
|
107 |
-
}
|
108 |
-
</style>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Admin View: Gateways
|
4 |
+
*/
|
5 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
6 |
+
exit;
|
7 |
+
}
|
8 |
+
|
9 |
+
for ( $i = 0; $i < 3; $i ++ ) {
|
10 |
+
$response = wp_remote_get( 'http://woocommerce.ir/api/gateways.json' );
|
11 |
+
if ( empty( $response->errors ) ) {
|
12 |
+
break;
|
13 |
+
}
|
14 |
+
}
|
15 |
+
|
16 |
+
if ( ! empty( $response->errors ) ) {
|
17 |
+
echo '<br><h1>در اتصال به سرور خطایی رخ داده است. لطفا چند دقیقه دیگر تلاش کنید.</h1>';
|
18 |
+
|
19 |
+
return;
|
20 |
+
}
|
21 |
+
|
22 |
+
if ( is_array( $response ) ) {
|
23 |
+
$response = json_decode( $response['body'] );
|
24 |
+
}
|
25 |
+
|
26 |
+
$count = 0;
|
27 |
+
?>
|
28 |
+
<div class="wrap woocommerce wc_addons_wrap">
|
29 |
+
<h1><?php echo get_admin_page_title(); ?></h1>
|
30 |
+
|
31 |
+
|
32 |
+
<div class="addons-featured">
|
33 |
+
<div class="addons-banner-block">
|
34 |
+
<h1>افزونه های ووکامرس فارسی</h1>
|
35 |
+
<h3>ارائه افزونه های معتبر و فارسی با امنیت بالا و پشتیبانی 24 ساعته</h3>
|
36 |
+
<p>ارائه برترین افزونه ها با پشتیبانی دائمی و امنیت بالا برای ووکامرس فارسی ، پیاده سازی و توسعه توسط
|
37 |
+
متخصصین ووکامرس در ایران. افزونه های معتبر و اصلی تنها در ووکامرس فارسی عرضه می گردند. برای اطلاع از
|
38 |
+
آخرین تخفیف ها و اطلاعیه های ووکامرس ، <a target="_blank" href="https://t.me/woocommerce_ir">کانال
|
39 |
+
تلگرام ووکامرس فارسی</a> را دنبال کنید</p>
|
40 |
+
|
41 |
+
<?php foreach ( $response as $item ) : ?>
|
42 |
+
<?php if ( $count ++ % 3 == 0 ) {
|
43 |
+
echo '<div class="addons-banner-block-items">';
|
44 |
+
} ?>
|
45 |
+
<div class="addons-banner-block-item">
|
46 |
+
<div class="addons-banner-block-item-icon"
|
47 |
+
style="background: linear-gradient(rgba(255,255,255,0.9),rgba(255,255,255,0.9)),url('<?php echo esc_url( $item->image ); ?>')!important;">
|
48 |
+
<img class="addons-img" src="<?php echo esc_url( $item->image ); ?>">
|
49 |
+
|
50 |
+
</div>
|
51 |
+
<div class="addons-banner-block-item-content">
|
52 |
+
<h3><?php echo esc_html( $item->title ); ?></h3>
|
53 |
+
|
54 |
+
<p><?php
|
55 |
+
|
56 |
+
$string = strip_tags( $item->desc );
|
57 |
+
|
58 |
+
if ( strlen( $string ) > 220 ) {
|
59 |
+
$stringCut = substr( $string, 0, 220 );
|
60 |
+
$string = substr( $stringCut, 0, strrpos( $stringCut, ' ' ) ) . '... <a href="' . esc_url( $item->url ) . '">اطلاعات بیشتر</a>';
|
61 |
+
}
|
62 |
+
echo wp_kses_data( $string ); ?></p>
|
63 |
+
<a class="addons-button addons-button-solid"
|
64 |
+
href="<?php echo esc_url( $item->url ); ?>"><?php echo esc_html( $item->price ); ?> / اطلاعات
|
65 |
+
بیشتر</a>
|
66 |
+
</div>
|
67 |
+
</div>
|
68 |
+
<?php if ( $count % 3 == 0 ) {
|
69 |
+
echo '</div>';
|
70 |
+
} ?>
|
71 |
+
<?php endforeach; ?>
|
72 |
+
|
73 |
+
</div>
|
74 |
+
</div>
|
75 |
+
</div>
|
76 |
+
|
77 |
+
|
78 |
+
<style type="text/css">
|
79 |
+
.ver {
|
80 |
+
-webkit-transform: rotate(-45deg);
|
81 |
+
-moz-transform: rotate(-45deg);
|
82 |
+
-o-transform: rotate(-45deg);
|
83 |
+
-ms-transform: rotate(-45deg);
|
84 |
+
transform: rotate(-45deg);
|
85 |
+
position: relative;
|
86 |
+
top: 0px;
|
87 |
+
left: -40px;
|
88 |
+
}
|
89 |
+
|
90 |
+
img.addons-img {
|
91 |
+
height: 100% !important;
|
92 |
+
opacity: 1.0;
|
93 |
+
border-right: 1px solid #e4e4e4;
|
94 |
+
border-left: 1px solid #e4e4e4;
|
95 |
+
}
|
96 |
+
|
97 |
+
.addons-banner-block-item-icon {
|
98 |
+
height: 200px;
|
99 |
+
}
|
100 |
+
|
101 |
+
.addons-button {
|
102 |
+
width: auto !important;
|
103 |
+
}
|
104 |
+
|
105 |
+
.addons-banner-block-item-content p {
|
106 |
+
text-align: justify;
|
107 |
+
}
|
108 |
+
</style>
|
include/view/html-admin-page-themes.php
CHANGED
@@ -1,109 +1,109 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Admin View: Themes
|
4 |
-
*/
|
5 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
6 |
-
exit;
|
7 |
-
}
|
8 |
-
|
9 |
-
for ( $i = 0; $i < 3; $i ++ ) {
|
10 |
-
$response = wp_remote_get( 'http://woocommerce.ir/api/themes.json' );
|
11 |
-
if ( empty( $response->errors ) ) {
|
12 |
-
break;
|
13 |
-
}
|
14 |
-
}
|
15 |
-
|
16 |
-
if ( ! empty( $response->errors ) ) {
|
17 |
-
echo '<br><h1>در اتصال به سرور خطایی رخ داده است. لطفا چند دقیقه دیگر تلاش کنید.</h1>';
|
18 |
-
|
19 |
-
return;
|
20 |
-
}
|
21 |
-
|
22 |
-
if ( is_array( $response ) ) {
|
23 |
-
$response = json_decode( $response['body'] );
|
24 |
-
}
|
25 |
-
|
26 |
-
$count = 0;
|
27 |
-
|
28 |
-
?>
|
29 |
-
<div class="wrap woocommerce wc_addons_wrap">
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
<?php foreach ( $response as $item ) : ?>
|
43 |
-
<?php if ( $count ++ % 3 == 0 ) {
|
44 |
-
echo '<div class="addons-banner-block-items">';
|
45 |
-
} ?>
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
$string = strip_tags( $item->desc );
|
58 |
-
|
59 |
-
if ( strlen( $string ) > 220 ) {
|
60 |
-
$stringCut = substr( $string, 0, 220 );
|
61 |
-
$string = substr( $stringCut, 0, strrpos( $stringCut, ' ' ) ) . '... <a href="' . esc_url( $item->url ) . '">اطلاعات بیشتر</a>';
|
62 |
-
}
|
63 |
-
echo $string; ?></p>
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
<?php if ( $count % 3 == 0 ) {
|
70 |
-
echo '</div>';
|
71 |
-
} ?>
|
72 |
-
<?php endforeach; ?>
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
</div>
|
78 |
-
|
79 |
-
<style type="text/css">
|
80 |
-
.ver {
|
81 |
-
-webkit-transform: rotate(-45deg);
|
82 |
-
-moz-transform: rotate(-45deg);
|
83 |
-
-o-transform: rotate(-45deg);
|
84 |
-
-ms-transform: rotate(-45deg);
|
85 |
-
transform: rotate(-45deg);
|
86 |
-
position: relative;
|
87 |
-
top: 0px;
|
88 |
-
left: -40px;
|
89 |
-
}
|
90 |
-
|
91 |
-
img.addons-img {
|
92 |
-
height: 100% !important;
|
93 |
-
opacity: 1.0;
|
94 |
-
border-right: 1px solid #e4e4e4;
|
95 |
-
border-left: 1px solid #e4e4e4;
|
96 |
-
}
|
97 |
-
|
98 |
-
.addons-banner-block-item-icon {
|
99 |
-
height: 200px;
|
100 |
-
}
|
101 |
-
|
102 |
-
.addons-button {
|
103 |
-
width: auto !important;
|
104 |
-
}
|
105 |
-
|
106 |
-
.addons-banner-block-item-content p {
|
107 |
-
text-align: justify;
|
108 |
-
}
|
109 |
-
</style>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Admin View: Themes
|
4 |
+
*/
|
5 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
6 |
+
exit;
|
7 |
+
}
|
8 |
+
|
9 |
+
for ( $i = 0; $i < 3; $i ++ ) {
|
10 |
+
$response = wp_remote_get( 'http://woocommerce.ir/api/themes.json' );
|
11 |
+
if ( empty( $response->errors ) ) {
|
12 |
+
break;
|
13 |
+
}
|
14 |
+
}
|
15 |
+
|
16 |
+
if ( ! empty( $response->errors ) ) {
|
17 |
+
echo '<br><h1>در اتصال به سرور خطایی رخ داده است. لطفا چند دقیقه دیگر تلاش کنید.</h1>';
|
18 |
+
|
19 |
+
return;
|
20 |
+
}
|
21 |
+
|
22 |
+
if ( is_array( $response ) ) {
|
23 |
+
$response = json_decode( $response['body'] );
|
24 |
+
}
|
25 |
+
|
26 |
+
$count = 0;
|
27 |
+
|
28 |
+
?>
|
29 |
+
<div class="wrap woocommerce wc_addons_wrap">
|
30 |
+
<h1><?php echo get_admin_page_title(); ?></h1>
|
31 |
+
|
32 |
+
|
33 |
+
<div class="addons-featured">
|
34 |
+
<div class="addons-banner-block">
|
35 |
+
<h1>پوسته های فروشگاه ساز ووکامرس</h1>
|
36 |
+
<h3>ارائه برترین پوسته ها توسط ووکامرس فارسی همراه با پشتیبانی</h3>
|
37 |
+
<p>انتخاب یک قالب خوب ، رابطه مستقیمی با فروش و ارتباط بیشتر با مخاطبان شما دارد. همچنین انتخاب یک قالب ایده
|
38 |
+
آل و استاندارد باعث بهبود رتبه در موتور های جستجو می گردد. در انتخاب پوسته فروشگاه خود دقت کنید! برای
|
39 |
+
اطلاع از آخرین تخفیف ها و اطلاعیه های ووکامرس ، <a target="_blank" href="https://t.me/woocommerce_ir">کانال
|
40 |
+
تلگرام ووکامرس فارسی</a> را دنبال کنید</p>
|
41 |
+
|
42 |
+
<?php foreach ( $response as $item ) : ?>
|
43 |
+
<?php if ( $count ++ % 3 == 0 ) {
|
44 |
+
echo '<div class="addons-banner-block-items">';
|
45 |
+
} ?>
|
46 |
+
<div class="addons-banner-block-item">
|
47 |
+
<div class="addons-banner-block-item-icon"
|
48 |
+
style="background: linear-gradient(rgba(255,255,255,0.9),rgba(255,255,255,0.9)),url('<?php echo esc_url( $item->image ); ?>')!important;">
|
49 |
+
<img class="addons-img" src="<?php echo esc_url( $item->image ); ?>">
|
50 |
+
|
51 |
+
</div>
|
52 |
+
<div class="addons-banner-block-item-content">
|
53 |
+
<h3><?php echo esc_html( $item->title ); ?></h3>
|
54 |
+
|
55 |
+
<p><?php
|
56 |
+
|
57 |
+
$string = strip_tags( $item->desc );
|
58 |
+
|
59 |
+
if ( strlen( $string ) > 220 ) {
|
60 |
+
$stringCut = substr( $string, 0, 220 );
|
61 |
+
$string = substr( $stringCut, 0, strrpos( $stringCut, ' ' ) ) . '... <a href="' . esc_url( $item->url ) . '">اطلاعات بیشتر</a>';
|
62 |
+
}
|
63 |
+
echo wp_kses_data( $string ); ?></p>
|
64 |
+
<a class="addons-button addons-button-solid"
|
65 |
+
href="<?php echo esc_url( $item->url ); ?>"><?php echo esc_html( $item->price ); ?> / اطلاعات
|
66 |
+
بیشتر</a>
|
67 |
+
</div>
|
68 |
+
</div>
|
69 |
+
<?php if ( $count % 3 == 0 ) {
|
70 |
+
echo '</div>';
|
71 |
+
} ?>
|
72 |
+
<?php endforeach; ?>
|
73 |
+
|
74 |
+
</div>
|
75 |
+
</div>
|
76 |
+
|
77 |
+
</div>
|
78 |
+
|
79 |
+
<style type="text/css">
|
80 |
+
.ver {
|
81 |
+
-webkit-transform: rotate(-45deg);
|
82 |
+
-moz-transform: rotate(-45deg);
|
83 |
+
-o-transform: rotate(-45deg);
|
84 |
+
-ms-transform: rotate(-45deg);
|
85 |
+
transform: rotate(-45deg);
|
86 |
+
position: relative;
|
87 |
+
top: 0px;
|
88 |
+
left: -40px;
|
89 |
+
}
|
90 |
+
|
91 |
+
img.addons-img {
|
92 |
+
height: 100% !important;
|
93 |
+
opacity: 1.0;
|
94 |
+
border-right: 1px solid #e4e4e4;
|
95 |
+
border-left: 1px solid #e4e4e4;
|
96 |
+
}
|
97 |
+
|
98 |
+
.addons-banner-block-item-icon {
|
99 |
+
height: 200px;
|
100 |
+
}
|
101 |
+
|
102 |
+
.addons-button {
|
103 |
+
width: auto !important;
|
104 |
+
}
|
105 |
+
|
106 |
+
.addons-banner-block-item-content p {
|
107 |
+
text-align: justify;
|
108 |
+
}
|
109 |
+
</style>
|
readme.txt
CHANGED
@@ -1,12 +1,13 @@
|
|
1 |
-
===
|
2 |
author: ووکامرس فارسی
|
3 |
-
Contributors: Persianscript,
|
4 |
author URI: https://www.woosupport.ir/
|
5 |
plugin URI: https://www.woosupport.ir/download/
|
6 |
-
Tags:
|
7 |
Requires at least: 5.0
|
8 |
-
Tested up to: 5.
|
9 |
Requires PHP: 7.1
|
|
|
10 |
|
11 |
بسته ووکامرس پارسی به راحتی سیستم فروشگاه ساز ووکامرس را فارسی می کند و امکانات جدید متناسب با ایران را به ووکامرس اضافه میکند.
|
12 |
|
@@ -27,15 +28,17 @@ Requires PHP: 7.1
|
|
27 |
* واحد های پولی تومان، ریال، هزار تومان و هزار ریال
|
28 |
* شمسی سازی محیط وردپرس و ووکامرس
|
29 |
* لیست استان های ایران
|
30 |
-
* بخش کاربری و مدیریت ووکامرس به صورت فارسی
|
31 |
* لیست شهر های ایران (جدید)
|
32 |
-
* راست چین سازی بخش مدیریت فروشگاه
|
33 |
* ابزار جایگزین کننده عبارات و ترجمه ها (جدید)
|
34 |
* ابزار محدودیت فروش در استان های خاص (جدید)
|
35 |
* ابزار متن دلخواه جایگزین قیمت محصولات (جدید)
|
36 |
* ابزار پذیرش اعداد فارسی در بخش شماره موبایل و کد پستی (جدید)
|
37 |
* ابزار تایید صحت شماره موبایل
|
38 |
* ابزار تایید کدپستی
|
|
|
|
|
|
|
|
|
39 |
* و...
|
40 |
|
41 |
== Installation ==
|
@@ -44,11 +47,46 @@ Requires PHP: 7.1
|
|
44 |
|
45 |
== Frequently asked questions ==
|
46 |
|
47 |
-
=
|
48 |
|
49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
|
51 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
= 5.2.2 =
|
53 |
* بروزرسانی ترجمه
|
54 |
= 4.0.5 =
|
@@ -195,7 +233,7 @@ You can read complete documentations on the [WooSupport.ir](https://www.woosuppo
|
|
195 |
* نسخه اولیه
|
196 |
|
197 |
== Upgrade Notice ==
|
198 |
-
= 5.
|
199 |
-
*
|
200 |
== Traducciones ==
|
201 |
پشتیبانی در سایت [WooSupport.ir](https://www.woosupport.ir) انجام میشود.
|
1 |
+
=== ووکامرس فارسی ===
|
2 |
author: ووکامرس فارسی
|
3 |
+
Contributors: Persianscript, mahdiy
|
4 |
author URI: https://www.woosupport.ir/
|
5 |
plugin URI: https://www.woosupport.ir/download/
|
6 |
+
Tags: ووکامرس,ووکامرس فارسی,persian woocommerce,woocommerce,iran,persian,farsi,jalali,shamsi
|
7 |
Requires at least: 5.0
|
8 |
+
Tested up to: 5.8.2
|
9 |
Requires PHP: 7.1
|
10 |
+
Stable tag: 5.8.0
|
11 |
|
12 |
بسته ووکامرس پارسی به راحتی سیستم فروشگاه ساز ووکامرس را فارسی می کند و امکانات جدید متناسب با ایران را به ووکامرس اضافه میکند.
|
13 |
|
28 |
* واحد های پولی تومان، ریال، هزار تومان و هزار ریال
|
29 |
* شمسی سازی محیط وردپرس و ووکامرس
|
30 |
* لیست استان های ایران
|
|
|
31 |
* لیست شهر های ایران (جدید)
|
|
|
32 |
* ابزار جایگزین کننده عبارات و ترجمه ها (جدید)
|
33 |
* ابزار محدودیت فروش در استان های خاص (جدید)
|
34 |
* ابزار متن دلخواه جایگزین قیمت محصولات (جدید)
|
35 |
* ابزار پذیرش اعداد فارسی در بخش شماره موبایل و کد پستی (جدید)
|
36 |
* ابزار تایید صحت شماره موبایل
|
37 |
* ابزار تایید کدپستی
|
38 |
+
* ابزار نمایش کمترین قیمت برای محصولات متغیر
|
39 |
+
* ابزار مشخص نمودن حداقل میزان مبلغ برای ثبت سفارش
|
40 |
+
* ابزار حذف خودکار فیلد های اضافه تسویه حساب برای محصولات دانلودی
|
41 |
+
* تبدیل حروف عربی به فارسی در هنگام جستجو در فروشگاه
|
42 |
* و...
|
43 |
|
44 |
== Installation ==
|
47 |
|
48 |
== Frequently asked questions ==
|
49 |
|
50 |
+
= آیا با نصب ووکامرس فارسی از هسته اصلی ووکامرس بی نیاز می شوم؟ =
|
51 |
|
52 |
+
خیر! شما باید هسته اصلی وردپرس را از [اینجا](https://wordpress.org/plugins/woocommerce/) دانلود کنید و در کنار ووکامرس فارسی استفاده نمایید.
|
53 |
+
|
54 |
+
= من ووکامرس رو نصب کردم و فارسی هست چرا باید بسته بومی ساز رو نصب کنم؟ =
|
55 |
+
|
56 |
+
* ووکامرس فارسی یک بسته بومی ساز کامله . یک سری ابزارهای کاربردی برای شما در این بسته قرار داده شده که بر اساس نیازهای کاربر ایرانی شخصی سازی شده.
|
57 |
+
* برای مثال ، در صفحه تسویه حساب اگر در قسمت کدپستی و شماره موبایل اعداد فارسی وارد بشه (مثلا در حالت زبان فارسی در موبایل های هوشمند) در ووکامرس یک خطا رخ میده که لطفا شماره موبایل و کدپستی صحیح را وارد کنید! چون حروف فارسی رو به عنوان عدد شناسایی نمیکنه و کاربر شما این رو نمیدونه! ووکامرس فارسی یک ابزار ویژه برای تبدیل اعداد فارسی به انگلیسی قرار داده که این مشکل رفع شده!
|
58 |
+
* شما میتونید در صفحه تسویه حساب بدون اینکه نیاز باشه ، کاری کنید تا کاربر بجای وارد کردن اسم شهرش ، از لیست موجود شهرش رو انتخاب کنه!
|
59 |
+
* ابزار تاریخ شمسی ووکامرس به شما کمک میکنه تا به راحتی تاریخ تخفیف ها و سایر بخش های مربوط به ووکامرس رو به صورت کامل شمسی مشاهده کنید.
|
60 |
+
* میتونید به راحتی کمترین قیمت رو به عنوان قیمت اصلی برای نمایش به کاربر ، در محصولات ووکامرس به کاربر نمایش بدید!
|
61 |
+
* ترجمه کاملا روان و ساده بسته فارسی ساز ووکامرس باعث میشه کاربر با وب سایت شما ارتباط بگیره. ترجمه موجود در ووکامرس اصلی کاملا به صورت ماشینی ثبت شده و افراد متفاوت با تخصص های معمولا پایین کلمات با معانی و مفاهیم نادرست اقدام به ترجمه کردن.
|
62 |
+
* ابزار جایگزین کننده عبارات به شما کمک میکنه هر جای سایتت که کلمات انگلیسی وجود داره ، واژه فارسی شو جایگزین کنی تا به راحتی در سایتت جایگزین بشه
|
63 |
+
* حروف عربی رو به راحتی در هنگام جستجوی کاربران به حروف فارسی تبدیل کنید!
|
64 |
+
* میخوای فروشت رو به یک استان محدود کنی؟ خب کافیه ابزار ما رو تست کنی! چنین قابلیتی رو برای شما فراهم کردیم
|
65 |
+
* نمیخوای برای محصولت قیمت بزاری؟ میخوای در قسمت قیمت نوشته بشه "تماس بگیرید" ؟ کافیه ابزار ما رو امتحان کنی
|
66 |
+
* هنوز راضی نشدی؟ کافیه یک بار تستش کنی!...
|
67 |
+
|
68 |
+
= تاریخ شمسی ووکامرس فارسی به چه صورت عمل میکنه؟ =
|
69 |
+
|
70 |
+
ووکامرس فارسی طوری شمسی ساز رو طراحی کرده تا در صورتی که افزونه رو غیر فعال کردید ، هیچ اتفاقی برای داده های موجود در دیتابیس رخ نده.
|
71 |
+
|
72 |
+
= چه درگاه های بانکی در بسته فارسی ساز وجود داره =
|
73 |
+
|
74 |
+
تا الان یک درگاه بانکی درون بسته وجود داره ، اما به زودی کلی درگاه رایگان دیگه در این بسته اضافه میشه.
|
75 |
+
|
76 |
+
= پاسخم را نیافتم. از چه طریقی میتوانم اقدام کنم؟ =
|
77 |
+
|
78 |
+
میتوانید راهنما و مستندات را از طریق سایت [WooSupport.ir](https://www.woosupport.ir) بدست بیاورید
|
79 |
|
80 |
== Changelog ==
|
81 |
+
= 5.8.0 =
|
82 |
+
* بروزرسانی درگاه پرداخت پی.آی.آر
|
83 |
+
* بهبود ابزار بررسی صحت کدپستی
|
84 |
+
* افزودن ابزار تبدیل حروف عربی به فارسی در جستجو
|
85 |
+
* بازنویسی سیستم نوتیفیکیشن
|
86 |
+
* بهبود ابزار حذف فیلدهای تسویه حساب برای محصولات دانلودی و مجازی
|
87 |
+
* افزودن ابزار مدیریت قیمت محصولات متغیر
|
88 |
+
= 5.7.1 =
|
89 |
+
* بروزرسانی ترجمه
|
90 |
= 5.2.2 =
|
91 |
* بروزرسانی ترجمه
|
92 |
= 4.0.5 =
|
233 |
* نسخه اولیه
|
234 |
|
235 |
== Upgrade Notice ==
|
236 |
+
= 5.8.0 =
|
237 |
+
* Bug Fix in Translate Class
|
238 |
== Traducciones ==
|
239 |
پشتیبانی در سایت [WooSupport.ir](https://www.woosupport.ir) انجام میشود.
|
woocommerce-persian.php
CHANGED
@@ -2,20 +2,18 @@
|
|
2 |
/*
|
3 |
Plugin Name: ووکامرس فارسی
|
4 |
Plugin URI: https://woosupport.ir
|
5 |
-
Description: بسته فارسی ساز ووکامرس پارسی به راحتی سیستم فروشگاه ساز ووکامرس را فارسی می کند. با فعال سازی افزونه ، بسیاری از قابلیت های مخصوص ایران به افزونه افزوده می شوند. پشتیبانی در <a href="http://
|
6 |
-
Version: 5.
|
7 |
Author: ووکامرس فارسی
|
8 |
Author URI: https://woosupport.ir
|
9 |
-
WC requires at least:
|
10 |
-
WC tested up to: 5.
|
11 |
*/
|
12 |
|
13 |
-
|
14 |
-
exit;
|
15 |
-
} // Exit if accessed directly
|
16 |
|
17 |
if ( ! defined( 'PW_VERSION' ) ) {
|
18 |
-
define( 'PW_VERSION', '5.
|
19 |
}
|
20 |
|
21 |
if ( ! defined( 'PW_DIR' ) ) {
|
@@ -37,7 +35,7 @@ function PW() {
|
|
37 |
return Persian_Woocommerce_Core::instance();
|
38 |
}
|
39 |
|
40 |
-
add_action( 'woocommerce_loaded', function() {
|
41 |
|
42 |
require_once( 'vendor/autoload.php' );
|
43 |
require_once( 'include/class-core.php' );
|
@@ -46,9 +44,10 @@ add_action( 'woocommerce_loaded', function() {
|
|
46 |
require_once( 'include/class-tools.php' );
|
47 |
require_once( 'include/class-address.php' );
|
48 |
require_once( 'include/class-currencies.php' );
|
|
|
49 |
|
50 |
} );
|
51 |
|
52 |
-
register_activation_hook( PW_FILE, function() {
|
53 |
file_put_contents( PW_DIR . '/.activated', '' );
|
54 |
} );
|
2 |
/*
|
3 |
Plugin Name: ووکامرس فارسی
|
4 |
Plugin URI: https://woosupport.ir
|
5 |
+
Description: بسته فارسی ساز ووکامرس پارسی به راحتی سیستم فروشگاه ساز ووکامرس را فارسی می کند. با فعال سازی افزونه ، بسیاری از قابلیت های مخصوص ایران به افزونه افزوده می شوند. پشتیبانی در <a href="http://woosupport.ir" target="_blank">ووکامرس پارسی</a>.
|
6 |
+
Version: 5.8.0
|
7 |
Author: ووکامرس فارسی
|
8 |
Author URI: https://woosupport.ir
|
9 |
+
WC requires at least: 4.0.0
|
10 |
+
WC tested up to: 5.9.0
|
11 |
*/
|
12 |
|
13 |
+
defined( 'ABSPATH' ) || exit;
|
|
|
|
|
14 |
|
15 |
if ( ! defined( 'PW_VERSION' ) ) {
|
16 |
+
define( 'PW_VERSION', '5.8.1' );
|
17 |
}
|
18 |
|
19 |
if ( ! defined( 'PW_DIR' ) ) {
|
35 |
return Persian_Woocommerce_Core::instance();
|
36 |
}
|
37 |
|
38 |
+
add_action( 'woocommerce_loaded', function () {
|
39 |
|
40 |
require_once( 'vendor/autoload.php' );
|
41 |
require_once( 'include/class-core.php' );
|
44 |
require_once( 'include/class-tools.php' );
|
45 |
require_once( 'include/class-address.php' );
|
46 |
require_once( 'include/class-currencies.php' );
|
47 |
+
require_once( 'include/class-notice.php' );
|
48 |
|
49 |
} );
|
50 |
|
51 |
+
register_activation_hook( PW_FILE, function () {
|
52 |
file_put_contents( PW_DIR . '/.activated', '' );
|
53 |
} );
|