WooCommerce PDF Invoices & Packing Slips - Version 2.10.0

Version Description

  • New: Use minified JS & CSS files to reduce load time on live sites (enabling SCRIPT_DEBUG will load full versions)
  • New: Selected template setting is now stored as a reference ID rather than a fixed path (#209)
  • Fix: Fallback to first available translation for settings when migrating from multilingual to single language setup
  • Fix: Undefined variable notice when using [wcpdf_download_invoice] on non-order pages
  • Fix: Updated documentation links
  • Marked tested up to WooCommerce 5.7
Download this release

Release Info

Developer pomegranate
Plugin Icon 128x128 WooCommerce PDF Invoices & Packing Slips
Version 2.10.0
Comparing to
See all releases

Code changes from version 2.9.3 to 2.10.0

assets/css/order-styles-buttons-wc20.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .type-shop_order .column-order_actions a.button.wpo_wcpdf{padding:0 2px}
assets/css/order-styles-buttons-wc38.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .type-shop_order .column-order_actions a.button.wpo_wcpdf{float:left;width:26px;height:26px;padding:3px 2px}
assets/css/order-styles-buttons-wc39.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .type-shop_order .column-order_actions a.button.wpo_wcpdf{float:left;width:26px;height:26px;padding:3px 2px}.type-shop_order .column-wc_actions a.button.wpo_wcpdf img{margin-top:3px}
assets/css/order-styles.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .type-shop_order .column-wc_actions a.button.wpo_wcpdf{padding:3px 2px 1px 1px!important}.type-shop_order .column-wc_actions a.button.wpo_wcpdf.exists::after{content:"\f147";position:absolute;font-size:16px;left:7px;color:#2aad2a}.wpo_wcpdf-actions a.button.exists::after{font-family:Dashicons;content:"\f147";font-size:16px;margin-left:4px;color:#2aad2a;vertical-align:middle}.type-shop_order .column-order_actions a.button.wpo_wcpdf img,.type-shop_order .column-wc_actions a.button.wpo_wcpdf img{width:16px}.widefat .column-pdf_invoice_number{width:110px}@media screen and (max-width:782px){.wp-list-table .column-pdf_invoice_number,.wp-list-table tr:not(.inline-edit-row):not(.no-items) td.column-pdf_invoice_number:not(.check-column){display:none}.wp-list-table tr:not(.inline-edit-row):not(.no-items) td.column-pdf_invoice_number{padding:3px 8px 3px 35%}}#wpo_wcpdf-data-input-box>.inside{margin:0;padding:10px 0;background-color:#f8f8f8}#wpo_wcpdf-data-input-box h4{font-size:14px;line-height:1.4;margin:0}#wpo_wcpdf-data-input-box p{margin:.5em 0}#wpo_wcpdf-data-input-box .form-field input{width:auto}.wcpdf-data-fields{margin-left:10px;margin-right:10px;margin-bottom:10px;background-color:#fff;border:1px solid #c3c4c7;box-shadow:0 1px 1px rgba(0,0,0,.04)}.wcpdf-data-fields:last-child{margin-bottom:0}.wcpdf-data-fields .read-only{height:auto;display:block;padding:10px}.wcpdf-data-fields .editable,.wcpdf-data-fields .editable-notes{height:auto;display:none;padding:10px}.wcpdf-data-fields h4{padding:10px;border-bottom:1px solid #dfdfdf}.wcpdf-data-fields h4 .dashicons:first-of-type{margin-left:20px!important}.wcpdf-data-fields .wpo-wcpdf-delete-document,.wcpdf-data-fields .wpo-wcpdf-edit-date-number,.wcpdf-data-fields .wpo-wcpdf-edit-document-notes,.wcpdf-data-fields .wpo-wcpdf-regenerate-document{opacity:.5}.wcpdf-data-fields .wpo-wcpdf-delete-document:hover,.wcpdf-data-fields .wpo-wcpdf-edit-date-number:hover,.wcpdf-data-fields .wpo-wcpdf-edit-document-notes:hover,.wcpdf-data-fields .wpo-wcpdf-regenerate-document:hover{opacity:1;cursor:pointer}.wcpdf-data-fields .wpo-wcpdf-document-buttons{display:none;padding:10px;border-top:1px solid #dfdfdf}.wcpdf-data-fields h4 .wcpdf-regenerate-spin{opacity:1;-webkit-animation:spin 1.6s linear infinite;animation:spin 1.6s linear infinite;pointer-events:none}@-webkit-keyframes wcpdf-regenerate-spin{0%{-webkit-transform:rotate(0)}100%{-webkit-transform:rotate(-360deg)}}@keyframes wcpdf-regenerate-spin{0%{transform:rotate(0)}100%{transform:rotate(-360deg)}}
assets/css/settings-styles.min.css ADDED
@@ -0,0 +1 @@
 
1
+ span.wpo-warning{display:inline-block;border:1px solid red;border-left:4px solid red;padding:5px 15px;background-color:#fff}.wcpdf-extensions-ad{position:relative;min-height:90px;border:1px solid #3d5c99;background-color:#ebf5ff;border-radius:5px;padding:15px;padding-left:100px;margin-top:15px}img.wpo-helper{position:absolute;bottom:0;left:3px}.wcpdf-extensions-ad h3{margin:0}.wcpdf-extensions-ad ul{margin:0;margin-left:1.5em}.extensions li{margin:0}.extensions li ul{list-style-type:square;margin-top:.5em;margin-bottom:.5em}.extensions>li:before{content:"";border-color:transparent transparent transparent #111;border-style:solid;border-width:.35em .35em .35em .45em;display:block;height:0;width:0;left:-1em;top:.9em;position:relative}.extensions li:not(.expanded){cursor:pointer}.extensions .expanded:before{border-color:#111 transparent transparent transparent;left:-1.17em;border-width:.45em .45em .35em .35em!important}.extensions .more{padding:10px;background-color:#fff;border:1px solid #ccc;border-radius:5px}.extensions table td{vertical-align:top}.dropbox-logo{margin-bottom:-10px;margin-right:10px}.cloud-logo{margin-bottom:-10px;margin-top:-5px;margin-right:10px}#img-header_logo{max-height:200px;width:auto}.multiple-text-input label{min-width:120px;display:inline-block}table.wcpdf_documents_settings_list{width:100%;border-collapse:collapse;border-spacing:0;background-color:#fff;border-top:2px solid #000}table.wcpdf_documents_settings_list tr.odd{background-color:#ebf5ff}table.wcpdf_documents_settings_list td{padding:5px}table.wcpdf_documents_settings_list a{text-decoration:none}table.wcpdf_documents_settings_list td.settings-icon{text-align:right}table.wcpdf_documents_settings_list td.title{font-weight:700}.wcpdf_document_settings_sections{margin-top:10px;font-size:120%}.wcpdf_document_settings_sections li,.wcpdf_document_settings_sections ul{display:inline}.wcpdf_document_settings_sections li+li:before{content:" | "}.wcpdf_document_settings_sections a.active{text-decoration:none;font-weight:700;color:#000}.edit-next-number{opacity:.5}.edit-next-number:hover{opacity:1;cursor:pointer}
assets/css/setup-wizard.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .wpo-wizzard{background:#f9f9f9}.wpo-wcpdf-setup{padding:0;font-family:Ubuntu,sans-serif;font-size:14px;line-height:22px;color:#444;background:0 0;-webkit-box-shadow:none;box-shadow:none}.wpo-wcpdf-setup h1,.wpo-wcpdf-setup h2{border:none;color:#444;margin:0}#confetti{width:100%;height:100%;position:absolute;left:0;top:0;z-index:-999}.wpo-setup{background-color:#f9f9f9;font-family:Ubuntu,sans-serif;font-size:14px;line-height:22px;color:#444;width:100%;height:100%;margin:0;padding:0}.confetti{width:100%;height:100%;z-index:-999;position:relative}.wpo-setup-card{display:block;background-color:#f2fafa;max-width:900px;margin:100px auto 100px auto;padding:0;border-radius:10px;box-shadow:10px 10px 80px rgba(0,0,0,.05);overflow:hidden}.wpo-plugin-title{width:100%;padding:30px 0 50px 0;margin:0;background-color:#fdfdfd;text-align:center;display:block;color:#61707d}.wpo-progress-bar{width:100%;height:36px;overflow:hidden;list-style:none;margin:-18px 0 0 0;padding:0}.wpo-progress-bar li{width:14.285%;float:left;box-sizing:border-box}.wpo-progress-marker{height:24px;width:24px;background-color:#fdfdfd;border:6px solid #3e9b9a;border-radius:50%;margin:0 auto}.wpo-progress-bar .completed{background-color:#3e9b9a}.wpo-progress-bar .active{background-color:#2d7170}.wpo-setup-content{float:left;width:100%;overflow:hidden}.wpo-step-description{width:50%;float:left;padding:50px;box-sizing:border-box}.wpo-step-description ul{padding-left:16px}.wpo-setup-input{width:50%;float:left;padding:50px 50px 50px 0;box-sizing:border-box;position:relative}.wpo-setup-input select{width:100%;border:none;font-size:1.4em;background-color:#fdfdfd;color:#444;border:1px solid #3e9b9a;height:40px}.wpo-setup-buttons{width:100%;float:left;padding:0 50px 50px 50px;box-sizing:border-box}.wpo-button-next,.wpo-button-previous,.wpo-skip-step{background-color:#3e9b9a;border-radius:5px;padding:10px 20px;border:none;box-sizing:border-box;font-size:1em;text-decoration:none;cursor:pointer;color:#fdfdfd;font-size:1.4em;box-sizing:border-box}.wpo-button-next:hover,.wpo-button-previous:hover{background-color:#2d7170}.wpo-button-next,.wpo-skip-step{float:right;margin-left:10px}.wpo-button-previous{float:left}.wpo-skip-step{background-color:#fdfdfd;color:#61707d}.wpo-skip-step:hover{color:#333}.wpo-setup-input .shop-name{width:100%;height:40px;padding:10px 15px;box-sizing:border-box;font-size:1.2em;margin-bottom:20px;border:1px solid #3e9b9a;font-family:Ubuntu,sans-serif}.wpo-setup-input .shop-address{width:100%;height:200px;padding:15px 15px;font-size:1.2em;line-height:1.4em;box-sizing:border-box;border:1px solid #3e9b9a;resize:none;float:left;margin:0;font-family:Ubuntu,sans-serif;text-align:left!important}.wpo-setup-input #img-header_logo{width:100%;height:auto;background:#fdfdfd;margin-bottom:20px;padding:20px;box-sizing:border-box;position:relative}.wpo-setup-input #logo-preview img{height:80%;position:absolute;left:50%;-ms-transform:translate(-50%,0);-webkit-transform:translate(-50%,0);transform:translate(-50%,0)}.wpo-setup-input input[type=checkbox]{background-color:#fdfdfd;border:1px solid #cacece;border-radius:3px;vertical-align:text-bottom;margin-right:20px}.wpo-setup-input .checkbox{font-size:1.1em}.wpo-setup-input .how-to-box{float:right;width:auto;max-width:100%;height:auto;border:1px solid #3e9b9a;overflow:hidden;background:#fff}.wpo-setup-input .how-to-box img{width:100%}.wpo-step-description a:link,.wpo-step-description a:visited{color:#3e9b9a;text-decoration:none}.wpo-final{text-align:center;width:100%;padding:50px 200px}.wpo-final h1{font-size:3em;line-height:1em}@media (min-width:768px) and (max-width:991px){.wpo-setup-card{width:80%}}@media (max-width:767px){.wpo-setup-card{width:100%;min-height:100%;border-radius:0;margin:0}.wpo-setup-input,.wpo-step-description{width:100%;padding-left:50px}.wpo-final{padding:50px}.wpo-progress-bar{margin-top:-12px}.wpo-progress-marker{height:16px;width:16px;border-width:4px}.wpo-button-next,.wpo-button-previous,.wpo-skip-step{font-size:1em;padding:8px 12px}}@media (max-width:480px){.wpo-wcpdf-setup,.wpo-wizzard{margin:0;height:100%}.wpo-wcpdf-setup form{height:100%}.wpo-setup-card{width:100%;min-height:100%;border-radius:0;margin:0}.wpo-plugin-title{padding:25px 0 30px 0;font-size:1.4em}.wpo-setup-buttons,.wpo-setup-input,.wpo-step-description{width:100%;padding:20px}.wpo-step-description{padding-bottom:0}.wpo-progress-bar{margin-top:-12px}.wpo-progress-marker{height:16px;width:16px;border-width:4px}.wpo-button-next,.wpo-button-previous,.wpo-skip-step{font-size:1em;padding:8px 12px}.wpo-setup-input .checkbox{font-size:1em}}
assets/js/admin-script.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(function(a){a(".edit-next-number").on("click",function(){a(this).hide(),a(this).siblings("input").prop("disabled",!1),a(this).siblings(".save-next-number.button").show()}),a(".save-next-number").on("click",function(){$input=a(this).siblings("input"),$input.addClass("ajax-waiting");var b={security:$input.data("nonce"),action:"wpo_wcpdf_set_next_number",store:$input.data("store"),number:$input.val()};xhr=a.ajax({type:"POST",url:wpo_wcpdf_admin.ajaxurl,data:b,success:function(){$input.removeClass("ajax-waiting"),$input.siblings(".edit-next-number").show(),$input.prop("disabled","disabled"),$input.siblings(".save-next-number.button").hide()}})}),a("[name='wpo_wcpdf_documents_settings_invoice[display_number]']").on("change",function(){"order_number"==a(this).val()?a(this).closest("td").find(".description").slideDown():a(this).closest("td").find(".description").hide()}).trigger("change")});
assets/js/confetti.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(document).ready(function(a){var b=Math.PI,c=Math.sin,d=Math.cos,e=Math.round,f=Math.sqrt;function g(a,b){this.x=a,this.y=b,this.Length=function(){return f(this.SqrLength())},this.SqrLength=function(){return this.x*this.x+this.y*this.y},this.Equals=function(a,b){return a.x==b.x&&a.y==b.y},this.Add=function(a){this.x+=a.x,this.y+=a.y},this.Sub=function(a){this.x-=a.x,this.y-=a.y},this.Div=function(a){this.x/=a,this.y/=a},this.Mul=function(a){this.x*=a,this.y*=a},this.Normalize=function(){var a=this.SqrLength();if(0!=a){var b=1/f(a);this.x*=b,this.y*=b}},this.Normalized=function(){var a=this.SqrLength();if(0!=a){var b=1/f(a);return new g(this.x*b,this.y*b)}return new g(0,0)}}function h(a,b,c,d){this.position=new g(a,b),this.mass=c,this.drag=d,this.force=new g(0,0),this.velocity=new g(0,0),this.AddForce=function(a){this.force.Add(a)},this.Integrate=function(a){var b=this.CurrentForce(this.position);b.Div(this.mass);var c=new g(this.velocity.x,this.velocity.y);c.Mul(a),this.position.Add(c),b.Mul(a),this.velocity.Add(b),this.force=new g(0,0)},this.CurrentForce=function(){var a=new g(this.force.x,this.force.y),b=this.velocity.Length(),c=new g(this.velocity.x,this.velocity.y);return c.Mul(this.drag*this.mass*b),a.Sub(c),a}}function j(a,b){this.pos=new g(a,b),this.rotationSpeed=600*Math.random()+800,this.angle=360*(m*Math.random()),this.rotation=360*(m*Math.random()),this.cosA=1,this.size=5,this.oscillationSpeed=1.5*Math.random()+.5,this.xSpeed=40,this.ySpeed=60*Math.random()+50,this.corners=[],this.time=Math.random();var f=e(Math.random()*(n.length-1));this.frontColor=n[f][0],this.backColor=n[f][1];for(var h=0;4>h;h++){var k=d(this.angle+m*(90*h+45)),l=c(this.angle+m*(90*h+45));this.corners[h]=new g(k,l)}this.Update=function(a){this.time+=a,this.rotation+=this.rotationSpeed*a,this.cosA=d(m*this.rotation),this.pos.x+=d(this.time*this.oscillationSpeed)*this.xSpeed*a,this.pos.y+=this.ySpeed*a,this.pos.y>j.bounds.y&&(this.pos.x=Math.random()*j.bounds.x,this.pos.y=0)},this.Draw=function(a){a.fillStyle=0<this.cosA?this.frontColor:this.backColor,a.beginPath(),a.moveTo(this.pos.x+this.corners[0].x*this.size,this.pos.y+this.corners[0].y*this.size*this.cosA);for(var b=1;4>b;b++)a.lineTo(this.pos.x+this.corners[b].x*this.size,this.pos.y+this.corners[b].y*this.size*this.cosA);a.closePath(),a.fill()}}function k(a,b,j,l,o,p,q,r){this.particleDist=l,this.particleCount=j,this.particleMass=q,this.particleDrag=r,this.particles=[];var s=e(Math.random()*(n.length-1));this.frontColor=n[s][0],this.backColor=n[s][1],this.xOff=d(m*p)*o,this.yOff=c(m*p)*o,this.position=new g(a,b),this.prevPosition=new g(a,b),this.velocityInherit=2*Math.random()+4,this.time=100*Math.random(),this.oscillationSpeed=2*Math.random()+2,this.oscillationDistance=40*Math.random()+40,this.ySpeed=40*Math.random()+80;for(var t=0;t<this.particleCount;t++)this.particles[t]=new h(a,b-t*this.particleDist,this.particleMass,this.particleDrag);this.Update=function(a){var b=0;this.time+=a*this.oscillationSpeed,this.position.y+=this.ySpeed*a,this.position.x+=d(this.time)*this.oscillationDistance*a,this.particles[0].position=this.position;var c=this.prevPosition.x-this.position.x,e=this.prevPosition.y-this.position.y,h=f(c*c+e*e);for(this.prevPosition=new g(this.position.x,this.position.y),b=1;b<this.particleCount;b++){var j=g.Sub(this.particles[b-1].position,this.particles[b].position);j.Normalize(),j.Mul(h/a*this.velocityInherit),this.particles[b].AddForce(j)}for(b=1;b<this.particleCount;b++)this.particles[b].Integrate(a);for(b=1;b<this.particleCount;b++){var l=new g(this.particles[b].position.x,this.particles[b].position.y);l.Sub(this.particles[b-1].position),l.Normalize(),l.Mul(this.particleDist),l.Add(this.particles[b-1].position),this.particles[b].position=l}this.position.y>k.bounds.y+this.particleDist*this.particleCount&&this.Reset()},this.Reset=function(){this.position.y=-Math.random()*k.bounds.y,this.position.x=Math.random()*k.bounds.x,this.prevPosition=new g(this.position.x,this.position.y),this.velocityInherit=2*Math.random()+4,this.time=100*Math.random(),this.oscillationSpeed=2*Math.random()+1.5,this.oscillationDistance=40*Math.random()+40,this.ySpeed=40*Math.random()+80;var a=e(Math.random()*(n.length-1));this.frontColor=n[a][0],this.backColor=n[a][1],this.particles=[];for(var b=0;b<this.particleCount;b++)this.particles[b]=new h(this.position.x,this.position.y-b*this.particleDist,this.particleMass,this.particleDrag)},this.Draw=function(a){for(var b=0;b<this.particleCount-1;b++){var c=new g(this.particles[b].position.x+this.xOff,this.particles[b].position.y+this.yOff),d=new g(this.particles[b+1].position.x+this.xOff,this.particles[b+1].position.y+this.yOff);0>this.Side(this.particles[b].position.x,this.particles[b].position.y,this.particles[b+1].position.x,this.particles[b+1].position.y,d.x,d.y)?(a.fillStyle=this.frontColor,a.strokeStyle=this.frontColor):(a.fillStyle=this.backColor,a.strokeStyle=this.backColor),0==b?(a.beginPath(),a.moveTo(this.particles[b].position.x,this.particles[b].position.y),a.lineTo(this.particles[b+1].position.x,this.particles[b+1].position.y),a.lineTo(.5*(this.particles[b+1].position.x+d.x),.5*(this.particles[b+1].position.y+d.y)),a.closePath(),a.stroke(),a.fill(),a.beginPath(),a.moveTo(d.x,d.y),a.lineTo(c.x,c.y),a.lineTo(.5*(this.particles[b+1].position.x+d.x),.5*(this.particles[b+1].position.y+d.y)),a.closePath(),a.stroke(),a.fill()):b==this.particleCount-2?(a.beginPath(),a.moveTo(this.particles[b].position.x,this.particles[b].position.y),a.lineTo(this.particles[b+1].position.x,this.particles[b+1].position.y),a.lineTo(.5*(this.particles[b].position.x+c.x),.5*(this.particles[b].position.y+c.y)),a.closePath(),a.stroke(),a.fill(),a.beginPath(),a.moveTo(d.x,d.y),a.lineTo(c.x,c.y),a.lineTo(.5*(this.particles[b].position.x+c.x),.5*(this.particles[b].position.y+c.y)),a.closePath(),a.stroke(),a.fill()):(a.beginPath(),a.moveTo(this.particles[b].position.x,this.particles[b].position.y),a.lineTo(this.particles[b+1].position.x,this.particles[b+1].position.y),a.lineTo(d.x,d.y),a.lineTo(c.x,c.y),a.closePath(),a.stroke(),a.fill())}},this.Side=function(a,b,c,d,e,f){return(a-c)*(f-d)-(b-d)*(e-c)}}var l=1/30,m=b/180,n=[["#df0049","#660671"],["#00e857","#005291"],["#2bebbc","#05798a"],["#ffd200","#b06c00"]];g.Lerp=function(a,b,c){return new g((b.x-a.x)*c+a.x,(b.y-a.y)*c+a.y)},g.Distance=function(a,b){return f(g.SqrDistance(a,b))},g.SqrDistance=function(a,b){var c=a.x-b.x,d=a.y-b.y;return c*c+d*d+z*z},g.Scale=function(a,b){return new g(a.x*b.x,a.y*b.y)},g.Min=function(a,b){var c=Math.min;return new g(c(a.x,b.x),c(a.y,b.y))},g.Max=function(a,b){var c=Math.max;return new g(c(a.x,b.x),c(a.y,b.y))},g.ClampMagnitude=function(a,b){var c=a.Normalized;return new g(c.x*b,c.y*b)},g.Sub=function(a,b){return new g(a.x-b.x,a.y-b.y,a.z-b.z)},j.bounds=new g(0,0),k.bounds=new g(0,0),o={},o.Context=function(a){var b=0,c=document.getElementById(a),d=document.createElement("canvas");d.width=c.offsetWidth,d.height=c.offsetHeight,c.appendChild(d);var e=d.getContext("2d"),f=7,h=[];for(k.bounds=new g(d.width,d.height),b=0;b<f;b++)h[b]=new k(Math.random()*d.width,2*(-Math.random()*d.height),30,8,8,45,1,.05);var m=[];for(j.bounds=new g(d.width,d.height),b=0;b<25;b++)m[b]=new j(Math.random()*d.width,Math.random()*d.height);this.resize=function(){d.width=c.offsetWidth,d.height=c.offsetHeight,j.bounds=new g(d.width,d.height),k.bounds=new g(d.width,d.height)},this.start=function(){this.stop();this;this.interval=setInterval(function(){o.update()},1e3/30)},this.stop=function(){clearInterval(this.interval)},this.update=function(){var a=0;for(e.clearRect(0,0,d.width,d.height),a=0;a<25;a++)m[a].Update(l),m[a].Draw(e);for(a=0;a<f;a++)h[a].Update(l),h[a].Draw(e)}};var o=new o.Context("confetti");o.start(),a(window).resize(function(){o.resize()})});
assets/js/media-upload.js CHANGED
@@ -55,7 +55,7 @@ jQuery(document).ready(function($) {
55
  });
56
 
57
  $('#wpo-wcpdf-settings').on('click', '.wpo_remove_image_button', function( event ){
58
- // get corresponding input fields
59
  $row = $(this).parent();
60
  $id = $row.find('input#header_logo');
61
  $logo = $row.find('img#img-header_logo');
55
  });
56
 
57
  $('#wpo-wcpdf-settings').on('click', '.wpo_remove_image_button', function( event ){
58
+ // Get corresponding input fields
59
  $row = $(this).parent();
60
  $id = $row.find('input#header_logo');
61
  $logo = $row.find('img#img-header_logo');
assets/js/media-upload.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(document).ready(function(a){var b;a("#wpo-wcpdf-settings, .wpo-wcpdf-setup").on("click",".wpo_upload_image_button",function(c){return $row=a(this).parent(),$id=$row.find("input#header_logo"),$logo=$row.find("img#img-header_logo"),remove_button_text=a(this).data("remove_button_text"),c.preventDefault(),b?void b.open():void(b=wp.media.frames.file_frame=wp.media({title:a(this).data("uploader_title"),button:{text:a(this).data("uploader_button_text")},multiple:!1}),b.on("select",function(){attachment=b.state().get("selection").first().toJSON(),$id.val(attachment.id),0==$logo.length?(attachment_img="<img src=\""+attachment.url+"\" style=\"display:block\" id=\"img-header_logo\"/>",remove_button="<span class=\"button wpo_remove_image_button\" data-input_id=\"header_logo\">"+remove_button_text+"</span>",$id.before(attachment_img+remove_button)):$logo.attr("src",attachment.url)}),b.open())}),a("#wpo-wcpdf-settings").on("click",".wpo_remove_image_button",function(){$row=a(this).parent(),$id=$row.find("input#header_logo"),$logo=$row.find("img#img-header_logo"),$id.val(""),$logo.remove(),a(this).remove(),a(".attachment-resolution").remove()})});
assets/js/my-account-link.js CHANGED
@@ -1,6 +1,6 @@
1
  jQuery( function( $ ) {
2
  $('a').each(function(e){
3
- //check if href attribute exists
4
  if ( $(this).attr('href') ) {
5
  // for lack of specific classes on the my account action buttons we check the url
6
  if( $(this).attr('href').indexOf('generate_wpo_wcpdf') != -1 ){
@@ -8,4 +8,4 @@ jQuery( function( $ ) {
8
  };
9
  }
10
  });
11
- });
1
  jQuery( function( $ ) {
2
  $('a').each(function(e){
3
+ // check if href attribute exists
4
  if ( $(this).attr('href') ) {
5
  // for lack of specific classes on the my account action buttons we check the url
6
  if( $(this).attr('href').indexOf('generate_wpo_wcpdf') != -1 ){
8
  };
9
  }
10
  });
11
+ });
assets/js/my-account-link.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(function(a){a("a").each(function(){a(this).attr("href")&&-1!=a(this).attr("href").indexOf("generate_wpo_wcpdf")&&a(this).attr("target","_blank")})});
assets/js/order-script.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(function(a){function b(a,b=null){a.find(".read-only").is(":visible")?("notes"==b?a.find(".editable-notes :input").attr("disabled",!1):(a.find(".editable").show(),a.find(":input").attr("disabled",!1)),a.find(".read-only").hide(),a.find(".editable-notes").show(),a.closest(".wcpdf-data-fields").find(".wpo-wcpdf-document-buttons").show()):(a.find(".read-only").show(),a.find(".editable").hide(),a.find(".editable-notes").hide(),a.find(":input").attr("disabled",!0),a.closest(".wcpdf-data-fields").find(".wpo-wcpdf-document-buttons").hide())}a("#doaction, #doaction2").on("click",function(b){let c=a(this).attr("id").substr(2),d=a("select[name=\""+c+"\"]").val();if(-1!==a.inArray(d,wpo_wcpdf_ajax.bulk_actions)){b.preventDefault();let c=d,e=[];if(a("tbody th.check-column input[type=\"checkbox\"]:checked").each(function(){e.push(a(this).val())}),!e.length)return void alert("You have to select order(s) first!");let f=e.join("x");url=-1==wpo_wcpdf_ajax.ajaxurl.indexOf("?")?wpo_wcpdf_ajax.ajaxurl+"?action=generate_wpo_wcpdf&document_type="+c+"&order_ids="+f+"&bulk&_wpnonce="+wpo_wcpdf_ajax.nonce:wpo_wcpdf_ajax.ajaxurl+"&action=generate_wpo_wcpdf&document_type="+c+"&order_ids="+f+"&bulk&_wpnonce="+wpo_wcpdf_ajax.nonce,window.open(url,"_blank")}}),a("#wpo_wcpdf-data-input-box").insertAfter("#woocommerce-order-data"),a("#wpo_wcpdf-data-input-box").on("click",".wpo-wcpdf-set-date-number, .wpo-wcpdf-edit-date-number, .wpo-wcpdf-edit-document-notes",function(){let c=a(this).closest(".wcpdf-data-fields-section");0==c.length&&(c=a(this).closest(".wcpdf-data-fields"));let d=a(this).data("edit");b(c,d)}),a("#wpo_wcpdf-data-input-box").on("click",".wpo-wcpdf-cancel",function(){let c=a(this).closest(".wcpdf-data-fields");b(c)}),a("#wpo_wcpdf-data-input-box").on("click",".wpo-wcpdf-save-document, .wpo-wcpdf-regenerate-document, .wpo-wcpdf-delete-document",function(c){c.preventDefault();let d=a(this).closest(".wcpdf-data-fields"),e=a(this).data("action"),f=a(this).data("nonce"),g=d.data(),h=d.find(":input:visible:not(:disabled)").serialize();if("regenerate"==e){if(!1===window.confirm(wpo_wcpdf_ajax.confirm_regenerate))return;d.find(".wpo-wcpdf-regenerate-document").addClass("wcpdf-regenerate-spin")}else if("delete"==e){if(!1===window.confirm(wpo_wcpdf_ajax.confirm_delete))return;d.find(".wpo-wcpdf-regenerate-document").hide()}d.block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),a.ajax({url:wpo_wcpdf_ajax.ajaxurl,data:{action:"wpo_wcpdf_"+e+"_document",security:f,form_data:h,order_id:g.order_id,document_type:g.document,action_type:e,wpcdf_document_data_notice:e+"d"},type:"POST",context:d,success:function(c){b(d),d.closest("#wpo_wcpdf-data-input-box").load(document.URL+" #wpo_wcpdf-data-input-box .postbox-header, #wpo_wcpdf-data-input-box .inside",function(){let b;b=c.success?"success":"error",a(this).find(".wcpdf-data-fields[data-document='"+g.document+"'][data-order_id='"+g.order_id+"']").before("<div class=\"notice notice-"+b+" inline\" style=\"margin:0 10px 10px 10px;\"><p>"+c.data.message+"</p></div>")}),"regenerate"==e&&(d.find(".wpo-wcpdf-regenerate-document").removeClass("wcpdf-regenerate-spin"),b(d)),d.unblock()}})})});
assets/js/setup-wizard.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(function(a){a(".tab").on("click",function(){a(this).closest(".extra-field").find(".tab").removeClass("active"),a(this).addClass("active");var b=a(this).attr("id");a(this).siblings(".extra-field-input").hide(),a("."+b).show()}),a("#file-upload").on("change",function(b){if(b.target.files[0]){var c=URL.createObjectURL(b.target.files[0]);a("#logo-preview").find("img").attr("src",c)}})});
includes/class-wcpdf-assets.php CHANGED
@@ -25,14 +25,17 @@ class Assets {
25
  * Load styles & scripts
26
  */
27
  public function backend_scripts_styles ( $hook ) {
 
 
28
  global $wp_version;
29
  if( $this->is_order_page() ) {
 
30
  // STYLES
31
  wp_enqueue_style( 'thickbox' );
32
 
33
  wp_enqueue_style(
34
  'wpo-wcpdf-order-styles',
35
- WPO_WCPDF()->plugin_url() . '/assets/css/order-styles.css',
36
  array(),
37
  WPO_WCPDF_VERSION
38
  );
@@ -43,7 +46,7 @@ class Assets {
43
  // legacy WC2.0 styles
44
  wp_enqueue_style(
45
  'wpo-wcpdf-order-styles-buttons',
46
- WPO_WCPDF()->plugin_url() . '/assets/css/order-styles-buttons-wc20.css',
47
  array(),
48
  WPO_WCPDF_VERSION
49
  );
@@ -52,7 +55,7 @@ class Assets {
52
  // also applied to WC3.3+ but without affect due to .column-order_actions class being deprecated in 3.3+
53
  wp_enqueue_style(
54
  'wpo-wcpdf-order-styles-buttons',
55
- WPO_WCPDF()->plugin_url() . '/assets/css/order-styles-buttons-wc38.css',
56
  array(),
57
  WPO_WCPDF_VERSION
58
  );
@@ -60,7 +63,7 @@ class Assets {
60
  // WP5.3 or newer is used: realign img inside buttons
61
  wp_enqueue_style(
62
  'wpo-wcpdf-order-styles-buttons',
63
- WPO_WCPDF()->plugin_url() . '/assets/css/order-styles-buttons-wc39.css',
64
  array(),
65
  WPO_WCPDF_VERSION
66
  );
@@ -69,7 +72,7 @@ class Assets {
69
  // SCRIPTS
70
  wp_enqueue_script(
71
  'wpo-wcpdf',
72
- WPO_WCPDF()->plugin_url() . '/assets/js/order-script.js',
73
  array( 'jquery', 'jquery-blockui' ),
74
  WPO_WCPDF_VERSION
75
  );
@@ -99,7 +102,7 @@ class Assets {
99
  if ( $hook == 'woocommerce_page_wpo_wcpdf_options_page' || $hook == 'settings_page_wpo_wcpdf_options_page' || ( isset($_GET['page']) && $_GET['page'] == 'wpo_wcpdf_options_page' ) ) {
100
  wp_enqueue_style(
101
  'wpo-wcpdf-settings-styles',
102
- WPO_WCPDF()->plugin_url() . '/assets/css/settings-styles.css',
103
  array('woocommerce_admin_styles'),
104
  WPO_WCPDF_VERSION
105
  );
@@ -113,7 +116,7 @@ class Assets {
113
  wp_enqueue_script( 'wc-enhanced-select' );
114
  wp_enqueue_script(
115
  'wpo-wcpdf-admin',
116
- WPO_WCPDF()->plugin_url() . '/assets/js/admin-script.js',
117
  array( 'jquery', 'wc-enhanced-select' ),
118
  WPO_WCPDF_VERSION
119
  );
@@ -121,14 +124,15 @@ class Assets {
121
  'wpo-wcpdf-admin',
122
  'wpo_wcpdf_admin',
123
  array(
124
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
 
125
  )
126
  );
127
 
128
  wp_enqueue_media();
129
  wp_enqueue_script(
130
  'wpo-wcpdf-media-upload',
131
- WPO_WCPDF()->plugin_url() . '/assets/js/media-upload.js',
132
  array( 'jquery' ),
133
  WPO_WCPDF_VERSION
134
  );
25
  * Load styles & scripts
26
  */
27
  public function backend_scripts_styles ( $hook ) {
28
+ $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
29
+
30
  global $wp_version;
31
  if( $this->is_order_page() ) {
32
+
33
  // STYLES
34
  wp_enqueue_style( 'thickbox' );
35
 
36
  wp_enqueue_style(
37
  'wpo-wcpdf-order-styles',
38
+ WPO_WCPDF()->plugin_url() . '/assets/css/order-styles'.$suffix.'.css',
39
  array(),
40
  WPO_WCPDF_VERSION
41
  );
46
  // legacy WC2.0 styles
47
  wp_enqueue_style(
48
  'wpo-wcpdf-order-styles-buttons',
49
+ WPO_WCPDF()->plugin_url() . '/assets/css/order-styles-buttons-wc20'.$suffix.'.css',
50
  array(),
51
  WPO_WCPDF_VERSION
52
  );
55
  // also applied to WC3.3+ but without affect due to .column-order_actions class being deprecated in 3.3+
56
  wp_enqueue_style(
57
  'wpo-wcpdf-order-styles-buttons',
58
+ WPO_WCPDF()->plugin_url() . '/assets/css/order-styles-buttons-wc38'.$suffix.'.css',
59
  array(),
60
  WPO_WCPDF_VERSION
61
  );
63
  // WP5.3 or newer is used: realign img inside buttons
64
  wp_enqueue_style(
65
  'wpo-wcpdf-order-styles-buttons',
66
+ WPO_WCPDF()->plugin_url() . '/assets/css/order-styles-buttons-wc39'.$suffix.'.css',
67
  array(),
68
  WPO_WCPDF_VERSION
69
  );
72
  // SCRIPTS
73
  wp_enqueue_script(
74
  'wpo-wcpdf',
75
+ WPO_WCPDF()->plugin_url() . '/assets/js/order-script'.$suffix.'.js',
76
  array( 'jquery', 'jquery-blockui' ),
77
  WPO_WCPDF_VERSION
78
  );
102
  if ( $hook == 'woocommerce_page_wpo_wcpdf_options_page' || $hook == 'settings_page_wpo_wcpdf_options_page' || ( isset($_GET['page']) && $_GET['page'] == 'wpo_wcpdf_options_page' ) ) {
103
  wp_enqueue_style(
104
  'wpo-wcpdf-settings-styles',
105
+ WPO_WCPDF()->plugin_url() . '/assets/css/settings-styles'.$suffix.'.css',
106
  array('woocommerce_admin_styles'),
107
  WPO_WCPDF_VERSION
108
  );
116
  wp_enqueue_script( 'wc-enhanced-select' );
117
  wp_enqueue_script(
118
  'wpo-wcpdf-admin',
119
+ WPO_WCPDF()->plugin_url() . '/assets/js/admin-script'.$suffix.'.js',
120
  array( 'jquery', 'wc-enhanced-select' ),
121
  WPO_WCPDF_VERSION
122
  );
124
  'wpo-wcpdf-admin',
125
  'wpo_wcpdf_admin',
126
  array(
127
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
128
+ 'template_paths' => WPO_WCPDF()->settings->get_installed_templates(),
129
  )
130
  );
131
 
132
  wp_enqueue_media();
133
  wp_enqueue_script(
134
  'wpo-wcpdf-media-upload',
135
+ WPO_WCPDF()->plugin_url() . '/assets/js/media-upload'.$suffix.'.js',
136
  array( 'jquery' ),
137
  WPO_WCPDF_VERSION
138
  );
includes/class-wcpdf-documents.php CHANGED
@@ -59,6 +59,8 @@ class Documents {
59
 
60
  // Allow plugins to add their own documents
61
  $this->documents = apply_filters( 'wpo_wcpdf_document_classes', $this->documents );
 
 
62
  }
63
 
64
  /**
59
 
60
  // Allow plugins to add their own documents
61
  $this->documents = apply_filters( 'wpo_wcpdf_document_classes', $this->documents );
62
+
63
+ do_action( 'wpo_wcpdf_init_documents' );
64
  }
65
 
66
  /**
includes/class-wcpdf-frontend.php CHANGED
@@ -71,7 +71,10 @@ class Frontend {
71
  if ( function_exists( 'is_account_page' ) && is_account_page() ) {
72
  if ( $general_settings = get_option( 'wpo_wcpdf_settings_general' ) ) {
73
  if ( isset( $general_settings['download_display'] ) && $general_settings['download_display'] == 'display' ) {
74
- if ( function_exists( 'file_get_contents' ) && $script = file_get_contents( WPO_WCPDF()->plugin_path() . '/assets/js/my-account-link.js' ) ) {
 
 
 
75
  wp_add_inline_script( 'jquery', $script );
76
  }
77
  }
@@ -120,7 +123,7 @@ class Frontend {
120
  } elseif( !empty($values['order_id']) ) {
121
  $order = wc_get_order( $values['order_id'] );
122
  }
123
- if( !is_object($order) || !isset($order) || empty($order) ) return;
124
 
125
  // Link text
126
  $link_text = __('Download invoice (PDF)', 'woocommerce-pdf-invoices-packing-slips');
71
  if ( function_exists( 'is_account_page' ) && is_account_page() ) {
72
  if ( $general_settings = get_option( 'wpo_wcpdf_settings_general' ) ) {
73
  if ( isset( $general_settings['download_display'] ) && $general_settings['download_display'] == 'display' ) {
74
+ $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
75
+
76
+ if ( function_exists( 'file_get_contents' ) && $script = file_get_contents( WPO_WCPDF()->plugin_path() . '/assets/js/my-account-link'.$suffix.'.js' ) ) {
77
+
78
  wp_add_inline_script( 'jquery', $script );
79
  }
80
  }
123
  } elseif( !empty($values['order_id']) ) {
124
  $order = wc_get_order( $values['order_id'] );
125
  }
126
+ if( empty($order) || !is_object($order) ) return;
127
 
128
  // Link text
129
  $link_text = __('Download invoice (PDF)', 'woocommerce-pdf-invoices-packing-slips');
includes/class-wcpdf-install.php CHANGED
@@ -347,6 +347,12 @@ class Install {
347
  update_option( 'wpo_wcpdf_settings_debug', $debug_settings );
348
  }
349
 
 
 
 
 
 
 
350
  }
351
 
352
  /**
347
  update_option( 'wpo_wcpdf_settings_debug', $debug_settings );
348
  }
349
 
350
+ // 2.10.0-dev: migrate template path to template ID
351
+ if ( version_compare( $installed_version, '2.10.0-dev', '<' ) ) {
352
+ if ( ! empty( WPO_WCPDF()->settings ) && is_callable( array( WPO_WCPDF()->settings, 'maybe_migrate_template_paths' ) ) ) {
353
+ WPO_WCPDF()->settings->maybe_migrate_template_paths();
354
+ }
355
+ }
356
  }
357
 
358
  /**
includes/class-wcpdf-settings-general.php CHANGED
@@ -64,7 +64,7 @@ class Settings_General {
64
  'args' => array(
65
  'option_name' => $option_name,
66
  'id' => 'template_path',
67
- 'options' => $this->find_templates(),
68
  /* translators: 1,2. template paths */
69
  'description' => sprintf( __( 'Want to use your own template? Copy all the files from <code>%1$s</code> to your (child) theme in <code>%2$s</code> to customize them' , 'woocommerce-pdf-invoices-packing-slips' ), $plugin_template_path, $theme_template_path),
70
  )
@@ -274,6 +274,27 @@ class Settings_General {
274
  }
275
  }
276
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
  /**
278
  * List templates in plugin folder, theme folder & child theme folder
279
  * @return array template path => template name
64
  'args' => array(
65
  'option_name' => $option_name,
66
  'id' => 'template_path',
67
+ 'options' => $this->get_installed_templates_list(),
68
  /* translators: 1,2. template paths */
69
  'description' => sprintf( __( 'Want to use your own template? Copy all the files from <code>%1$s</code> to your (child) theme in <code>%2$s</code> to customize them' , 'woocommerce-pdf-invoices-packing-slips' ), $plugin_template_path, $theme_template_path),
70
  )
274
  }
275
  }
276
 
277
+ public function get_installed_templates_list() {
278
+ $installed_templates = WPO_WCPDF()->settings->get_installed_templates();
279
+ $template_list = array();
280
+ foreach ( $installed_templates as $path => $template_id ) {
281
+ $template_name = basename( $template_id );
282
+ $group = dirname( $template_id );
283
+ switch ( $group ) {
284
+ case 'default':
285
+ case 'premium_plugin':
286
+ // no suffix
287
+ break;
288
+ case 'theme':
289
+ default:
290
+ $template_name = sprintf( '%s (%s)', $template_name, __( 'Custom', 'woocommerce-pdf-invoices-packing-slips' ) );
291
+ break;
292
+ }
293
+ $template_list[$template_id] = $template_name;
294
+ }
295
+ return $template_list;
296
+ }
297
+
298
  /**
299
  * List templates in plugin folder, theme folder & child theme folder
300
  * @return array template path => template name
includes/class-wcpdf-settings.php CHANGED
@@ -11,6 +11,8 @@ if ( !class_exists( '\\WPO\\WC\\PDF_Invoices\\Settings' ) ) :
11
 
12
  class Settings {
13
  public $options_page_hook;
 
 
14
 
15
  function __construct() {
16
  $this->callbacks = include( 'class-wcpdf-settings-callbacks.php' );
@@ -37,7 +39,12 @@ class Settings {
37
  // add_action( 'admin_notices', array( $this, 'check_auto_increment_increment') );
38
 
39
  // AJAX set number store
40
- add_action( 'wp_ajax_wpo_wcpdf_set_next_number', array($this, 'set_number_store' ));
 
 
 
 
 
41
  }
42
 
43
  public function menu() {
@@ -71,7 +78,7 @@ class Settings {
71
  public function add_support_links( $links, $file ) {
72
  if ( $file == WPO_WCPDF()->plugin_basename ) {
73
  $row_meta = array(
74
- 'docs' => '<a href="http://docs.wpovernight.com/woocommerce-pdf-invoices-packing-slips/" target="_blank" title="' . __( 'Documentation', 'woocommerce-pdf-invoices-packing-slips' ) . '">' . __( 'Documentation', 'woocommerce-pdf-invoices-packing-slips' ) . '</a>',
75
  'support' => '<a href="https://wordpress.org/support/plugin/woocommerce-pdf-invoices-packing-slips" target="_blank" title="' . __( 'Support Forum', 'woocommerce-pdf-invoices-packing-slips' ) . '">' . __( 'Support Forum', 'woocommerce-pdf-invoices-packing-slips' ) . '</a>',
76
  );
77
 
@@ -206,33 +213,188 @@ class Settings {
206
  return $output_mode;
207
  }
208
 
209
- public function get_template_path( $document_type = NULL ) {
210
  // return default path if no template selected
211
  if ( empty( $this->general_settings['template_path'] ) ) {
212
- $default_path = WPO_WCPDF()->plugin_path() . '/templates/Simple';
213
- if ( function_exists( 'wp_normalize_path' ) ) { // WP3.9+
214
- $default_path = wp_normalize_path( $default_path );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
  }
216
- return $default_path;
217
  }
218
 
219
- // forward slash for consistency
220
- $template_path = str_replace('\\','/', $this->general_settings['template_path']);
221
 
222
- // add base path, checking if it's not already there
223
- // alternative setups like Bedrock have WP_CONTENT_DIR & ABSPATH separated
224
- if ( defined('WP_CONTENT_DIR') && strpos( WP_CONTENT_DIR, ABSPATH ) !== false ) {
225
- $forwardslash_basepath = str_replace('\\','/', ABSPATH);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  } else {
227
- // bedrock e.a
228
- $forwardslash_basepath = str_replace('\\','/', WP_CONTENT_DIR);
229
  }
 
230
 
231
- if ( strpos( $template_path, $forwardslash_basepath ) === false ) {
232
- $template_path = $forwardslash_basepath . $template_path;
 
 
 
 
 
 
 
 
 
 
 
233
  }
 
234
 
235
- return $template_path;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  }
237
 
238
  public function set_number_store() {
11
 
12
  class Settings {
13
  public $options_page_hook;
14
+ private $installed_templates = array();
15
+ private $installed_templates_cache = array();
16
 
17
  function __construct() {
18
  $this->callbacks = include( 'class-wcpdf-settings-callbacks.php' );
39
  // add_action( 'admin_notices', array( $this, 'check_auto_increment_increment') );
40
 
41
  // AJAX set number store
42
+ add_action( 'wp_ajax_wpo_wcpdf_set_next_number', array( $this, 'set_number_store' ) );
43
+
44
+ // refresh template path cache each time the general settings are updated
45
+ add_action( "update_option_wpo_wcpdf_settings_general", array( $this, 'general_settings_updated' ), 10, 3 );
46
+ // migrate old template paths to template IDs before loading settings page
47
+ add_action( 'wpo_wcpdf_settings_output_general', array( $this, 'maybe_migrate_template_paths' ), 9, 1 );
48
  }
49
 
50
  public function menu() {
78
  public function add_support_links( $links, $file ) {
79
  if ( $file == WPO_WCPDF()->plugin_basename ) {
80
  $row_meta = array(
81
+ 'docs' => '<a href="https://docs.wpovernight.com/topic/woocommerce-pdf-invoices-packing-slips/" target="_blank" title="' . __( 'Documentation', 'woocommerce-pdf-invoices-packing-slips' ) . '">' . __( 'Documentation', 'woocommerce-pdf-invoices-packing-slips' ) . '</a>',
82
  'support' => '<a href="https://wordpress.org/support/plugin/woocommerce-pdf-invoices-packing-slips" target="_blank" title="' . __( 'Support Forum', 'woocommerce-pdf-invoices-packing-slips' ) . '">' . __( 'Support Forum', 'woocommerce-pdf-invoices-packing-slips' ) . '</a>',
83
  );
84
 
213
  return $output_mode;
214
  }
215
 
216
+ public function get_template_path() {
217
  // return default path if no template selected
218
  if ( empty( $this->general_settings['template_path'] ) ) {
219
+ return $this->normalize_path( WPO_WCPDF()->plugin_path() . '/templates/Simple' );
220
+ }
221
+
222
+ $installed_templates = $this->get_installed_templates();
223
+ $selected_template = $this->general_settings['template_path'];
224
+ if ( in_array( $selected_template, $installed_templates ) ) {
225
+ return array_search( $selected_template, $installed_templates );
226
+ } else {
227
+ // unknown template or full template path (legacy settings or filter override)
228
+ $template_path = $this->normalize_path( $selected_template );
229
+
230
+ // add base path, checking if it's not already there
231
+ // alternative setups like Bedrock have WP_CONTENT_DIR & ABSPATH separated
232
+ if ( defined('WP_CONTENT_DIR') && strpos( WP_CONTENT_DIR, ABSPATH ) !== false ) {
233
+ $base_path = $this->normalize_path( ABSPATH );
234
+ } else {
235
+ $base_path = $this->normalize_path( WP_CONTENT_DIR );
236
+ }
237
+
238
+ if ( strpos( $template_path, $base_path ) === false ) {
239
+ $template_path = $this->normalize_path( $base_path . $template_path );
240
  }
 
241
  }
242
 
243
+ return $template_path;
244
+ }
245
 
246
+ public function get_installed_templates() {
247
+ // because this method can be called (too) early we load from a cached list in those cases
248
+ // this cache is updated each time the template settings are saved/updated
249
+ if ( ! did_action( 'wpo_wcpdf_init_documents' ) && ( $cached_template_list = $this->get_template_list_cache() ) ) {
250
+ return $cached_template_list;
251
+ }
252
+
253
+ // to save resources on the disk operations we only do this once
254
+ if ( ! empty ( $this->installed_templates ) ) {
255
+ return $this->installed_templates;
256
+ }
257
+
258
+ $installed_templates = array();
259
+
260
+ // get base paths
261
+ $template_base_path = ( function_exists( 'WC' ) && is_callable( 'WC', 'template_path' ) ) ? WC()->template_path() : 'woocommerce/';
262
+ $template_base_path = untrailingslashit( $template_base_path );
263
+ $template_paths = array (
264
+ // note the order: theme before child-theme, so that child theme is always preferred (overwritten)
265
+ 'default' => WPO_WCPDF()->plugin_path() . '/templates/',
266
+ 'theme' => get_template_directory() . "/{$template_base_path}/pdf/",
267
+ 'child-theme' => get_stylesheet_directory() . "/{$template_base_path}/pdf/",
268
+ );
269
+
270
+ $template_paths = apply_filters( 'wpo_wcpdf_template_paths', $template_paths );
271
+
272
+ foreach ($template_paths as $template_source => $template_path) {
273
+ $dirs = (array) glob( $template_path . '*' , GLOB_ONLYDIR );
274
+
275
+ foreach ( $dirs as $dir ) {
276
+ $clean_dir = $this->normalize_path( $dir );
277
+ $template_name = basename( $clean_dir );
278
+ // let child theme override parent theme
279
+ $group = ( $template_source == 'child-theme' ) ? 'theme' : $template_source;
280
+ $installed_templates[ $clean_dir ] = "{$group}/{$template_name}" ;
281
+ }
282
+ }
283
+
284
+ if ( empty( $installed_templates ) ) {
285
+ // fallback to Simple template for servers with glob() disabled
286
+ $simple_template_path = $this->normalize_path( $template_paths['default'] . 'Simple' );
287
+ $installed_templates[$simple_template_path] = 'default/Simple';
288
+ }
289
+
290
+ $installed_templates = apply_filters( 'wpo_wcpdf_installed_templates', $installed_templates );
291
+
292
+ $this->installed_templates = $installed_templates;
293
+
294
+ if ( ! empty( $this->template_list_cache ) && array_diff_assoc( $this->template_list_cache, $this->installed_templates ) ) {
295
+ $this->set_template_list_cache( $this->installed_templates );
296
+ }
297
+
298
+ return $installed_templates;
299
+ }
300
+
301
+ public function get_template_list_cache() {
302
+ $template_list = get_option( 'wpo_wcpdf_installed_template_paths', array() );
303
+ if ( ! empty( $template_list ) ) {
304
+ $checked_list = array();
305
+ $outdated = false;
306
+ // cache could be outdated, so we check whether the folders exist
307
+ foreach ( $template_list as $path => $template_id ) {
308
+ if ( @is_dir( $path ) ) {
309
+ $checked_list[$path] = $template_id; // folder exists
310
+ continue;
311
+ }
312
+
313
+ $outdated = true;
314
+ // folder does not exist, try replacing base if we can locate wp-content
315
+ $wp_content_folder = 'wp-content';
316
+ if ( strpos( $path, $wp_content_folder ) !== false && defined( WP_CONTENT_DIR ) ) {
317
+ // try wp-content
318
+ $relative_path = substr( $path, strrpos( $path, $wp_content_folder ) + strlen( $wp_content_folder ) );
319
+ $new_path = WP_CONTENT_DIR . $relative_path;
320
+ if ( @is_dir( $new_path ) ) {
321
+ $checked_list[$new_path] = $template_id;
322
+ }
323
+ }
324
+ }
325
+
326
+ if ( $outdated ) {
327
+ $this->set_template_list_cache( $checked_list );
328
+ }
329
+
330
+ $this->installed_templates_cache = $checked_list;
331
+
332
+ return $checked_list;
333
  } else {
334
+ return array();
 
335
  }
336
+ }
337
 
338
+ public function set_template_list_cache( $template_list ) {
339
+ $this->template_list_cache = $template_list;
340
+ update_option( 'wpo_wcpdf_installed_template_paths', $template_list );
341
+ }
342
+
343
+ public function delete_template_list_cache() {
344
+ delete_option( 'wpo_wcpdf_installed_template_paths' );
345
+ }
346
+
347
+ public function general_settings_updated( $old_settings, $settings, $option ) {
348
+ if ( is_array( $settings ) && ! empty ( $settings['template_path'] ) ) {
349
+ $this->delete_template_list_cache();
350
+ $this->set_template_list_cache( $this->get_installed_templates() );
351
  }
352
+ }
353
 
354
+ public function get_relative_template_path( $absolute_path ) {
355
+ if ( defined('WP_CONTENT_DIR') && strpos( WP_CONTENT_DIR, ABSPATH ) !== false ) {
356
+ $base_path = $this->normalize_path( ABSPATH );
357
+ } else {
358
+ $base_path = $this->normalize_path( WP_CONTENT_DIR );
359
+ }
360
+ return str_replace( $base_path, '', $this->normalize_path( $absolute_path ) );
361
+ }
362
+
363
+ public function normalize_path( $path ) {
364
+ return function_exists( 'wp_normalize_path' ) ? wp_normalize_path( $path ) : str_replace('\\','/', $path );
365
+ }
366
+
367
+ public function maybe_migrate_template_paths( $settings_section = null ) {
368
+ $installed_templates = $this->get_installed_templates();
369
+ $selected_template = $this->normalize_path( $this->general_settings['template_path'] );
370
+ $template_match = '';
371
+ if ( ! in_array( $selected_template, $installed_templates ) && substr_count( $selected_template, '/' ) > 1 ) {
372
+ // search for path match
373
+ foreach ( $installed_templates as $path => $template_id ) {
374
+ $path = $this->normalize_path( $path );
375
+ // check if the last part of the path matches
376
+ if ( substr( $path, -strlen( $selected_template ) ) === $selected_template ) {
377
+ $template_match = $template_id;
378
+ break;
379
+ }
380
+ }
381
+
382
+ // fallback to template name if no path match
383
+ if ( empty( $template_match ) ) {
384
+ $template_ids = array_flip( array_unique( array_combine( $installed_templates, array_map( 'basename', $installed_templates ) ) ) );
385
+ $template_name = basename( $selected_template );
386
+ if ( ! empty ( $template_ids[$template_name] ) ) {
387
+ $template_match = $template_ids[$template_name];
388
+ }
389
+ }
390
+
391
+ // migrate setting if we have a match
392
+ if ( ! empty( $template_match ) ) {
393
+ $this->general_settings['template_path'] = $template_match;
394
+ update_option( 'wpo_wcpdf_settings_general', $this->general_settings );
395
+ wcpdf_log_error( sprintf( __( 'Template setting migrated from %1$s to %2$s', 'woocommerce-pdf-invoices-packing-slips' ), $path, $template_id ), 'info' );
396
+ }
397
+ }
398
  }
399
 
400
  public function set_number_store() {
includes/class-wcpdf-setup-wizard.php CHANGED
@@ -34,6 +34,8 @@ class Setup_Wizard {
34
  * Show the setup wizard.
35
  */
36
  public function setup_wizard() {
 
 
37
  if ( empty( $_GET['page'] ) || 'wpo-wcpdf-setup' !== $_GET['page'] ) {
38
  return;
39
  }
@@ -76,19 +78,19 @@ class Setup_Wizard {
76
 
77
  wp_enqueue_style(
78
  'wpo-wcpdf-setup',
79
- WPO_WCPDF()->plugin_url() . '/assets/css/setup-wizard.css',
80
  array( 'dashicons', 'install' ),
81
  WPO_WCPDF_VERSION
82
  );
83
  wp_register_script(
84
  'wpo-wcpdf-media-upload',
85
- WPO_WCPDF()->plugin_url() . '/assets/js/media-upload.js',
86
  array( 'jquery', 'media-editor', 'mce-view' ),
87
  WPO_WCPDF_VERSION
88
  );
89
  wp_register_script(
90
  'wpo-wcpdf-setup',
91
- WPO_WCPDF()->plugin_url() . '/assets/js/setup-wizard.js',
92
  array( 'jquery', 'wpo-wcpdf-media-upload' ),
93
  WPO_WCPDF_VERSION
94
  );
@@ -100,7 +102,7 @@ class Setup_Wizard {
100
  if ( end( $step_keys ) === $this->step ) {
101
  wp_register_script(
102
  'wpo-wcpdf-setup-confetti',
103
- WPO_WCPDF()->plugin_url() . '/assets/js/confetti.js',
104
  array( 'jquery' ),
105
  WPO_WCPDF_VERSION
106
  );
34
  * Show the setup wizard.
35
  */
36
  public function setup_wizard() {
37
+ $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
38
+
39
  if ( empty( $_GET['page'] ) || 'wpo-wcpdf-setup' !== $_GET['page'] ) {
40
  return;
41
  }
78
 
79
  wp_enqueue_style(
80
  'wpo-wcpdf-setup',
81
+ WPO_WCPDF()->plugin_url() . '/assets/css/setup-wizard'.$suffix.'.css',
82
  array( 'dashicons', 'install' ),
83
  WPO_WCPDF_VERSION
84
  );
85
  wp_register_script(
86
  'wpo-wcpdf-media-upload',
87
+ WPO_WCPDF()->plugin_url() . '/assets/js/media-upload'.$suffix.'.js',
88
  array( 'jquery', 'media-editor', 'mce-view' ),
89
  WPO_WCPDF_VERSION
90
  );
91
  wp_register_script(
92
  'wpo-wcpdf-setup',
93
+ WPO_WCPDF()->plugin_url() . '/assets/js/setup-wizard'.$suffix.'.js',
94
  array( 'jquery', 'wpo-wcpdf-media-upload' ),
95
  WPO_WCPDF_VERSION
96
  );
102
  if ( end( $step_keys ) === $this->step ) {
103
  wp_register_script(
104
  'wpo-wcpdf-setup-confetti',
105
+ WPO_WCPDF()->plugin_url() . '/assets/js/confetti'.$suffix.'.js',
106
  array( 'jquery' ),
107
  WPO_WCPDF_VERSION
108
  );
includes/documents/abstract-wcpdf-order-document.php CHANGED
@@ -619,14 +619,27 @@ abstract class Order_Document {
619
  }
620
 
621
  public function get_settings_text( $settings_key, $default = false, $autop = true ) {
622
- if ( !empty( $this->settings[$settings_key]['default'] ) ) {
623
- $text = wptexturize( trim( $this->settings[$settings_key]['default'] ) );
624
- if ($autop === true) {
625
- $text = wpautop( $text );
626
- }
627
- } else {
 
 
 
 
628
  $text = $default;
629
  }
 
 
 
 
 
 
 
 
 
630
  // legacy filters
631
  if ( in_array( $settings_key, array( 'shop_name', 'shop_address', 'footer', 'extra_1', 'extra_2', 'extra_3' ) ) ) {
632
  $text = apply_filters( "wpo_wcpdf_{$settings_key}", $text, $this );
@@ -817,7 +830,7 @@ abstract class Order_Document {
817
  if (empty($file)) {
818
  $file = $this->type.'.php';
819
  }
820
- $path = WPO_WCPDF()->settings->get_template_path( $file );
821
  $file_path = "{$path}/{$file}";
822
 
823
  $fallback_file_path = WPO_WCPDF()->plugin_path() . '/templates/Simple/' . $file;
619
  }
620
 
621
  public function get_settings_text( $settings_key, $default = false, $autop = true ) {
622
+ // check for 'default' key existence
623
+ if ( ! empty( $this->settings[$settings_key] ) && is_array( $this->settings[$settings_key] ) && array_key_exists( 'default', $this->settings[$settings_key] ) ) {
624
+ $text = $this->settings[$settings_key]['default'];
625
+ // fallback to first array element if default is not present
626
+ } elseif( ! empty( $this->settings[$settings_key] ) && is_array( $this->settings[$settings_key] ) ) {
627
+ $text = reset( $this->settings[$settings_key] );
628
+ }
629
+
630
+ // fallback to default
631
+ if ( empty( $text ) ) {
632
  $text = $default;
633
  }
634
+
635
+ // clean up
636
+ $text = wptexturize( trim( $text ) );
637
+
638
+ // replacements
639
+ if ( $autop === true ) {
640
+ $text = wpautop( $text );
641
+ }
642
+
643
  // legacy filters
644
  if ( in_array( $settings_key, array( 'shop_name', 'shop_address', 'footer', 'extra_1', 'extra_2', 'extra_3' ) ) ) {
645
  $text = apply_filters( "wpo_wcpdf_{$settings_key}", $text, $this );
830
  if (empty($file)) {
831
  $file = $this->type.'.php';
832
  }
833
+ $path = $this->get_template_path();
834
  $file_path = "{$path}/{$file}";
835
 
836
  $fallback_file_path = WPO_WCPDF()->plugin_path() . '/templates/Simple/' . $file;
includes/views/setup-wizard/good-to-go.php CHANGED
@@ -2,6 +2,6 @@
2
  <div class="wpo-step-description wpo-final">
3
  <h1><?php _e( 'You are good to go!' , 'woocommerce-pdf-invoices-packing-slips' ); ?></h1>
4
  <p><?php _e( 'If you have any questions please have a look at our documentation:', 'woocommerce-pdf-invoices-packing-slips' ); ?><br>
5
- <a href="https://docs.wpovernight.com/category/woocommerce-pdf-invoices-packing-slips/" target="_blank"><?php _e( 'Invoices & Packing Slips' , 'woocommerce-pdf-invoices-packing-slips' ); ?></a></p>
6
  <h2><?php _e( 'Happy selling!' , 'woocommerce-pdf-invoices-packing-slips' ); ?></h2>
7
  </div>
2
  <div class="wpo-step-description wpo-final">
3
  <h1><?php _e( 'You are good to go!' , 'woocommerce-pdf-invoices-packing-slips' ); ?></h1>
4
  <p><?php _e( 'If you have any questions please have a look at our documentation:', 'woocommerce-pdf-invoices-packing-slips' ); ?><br>
5
+ <a href="https://docs.wpovernight.com/topic/woocommerce-pdf-invoices-packing-slips/" target="_blank"><?php _e( 'Invoices & Packing Slips' , 'woocommerce-pdf-invoices-packing-slips' ); ?></a></p>
6
  <h2><?php _e( 'Happy selling!' , 'woocommerce-pdf-invoices-packing-slips' ); ?></h2>
7
  </div>
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: woocommerce, pdf, invoices, packing slips, print, delivery notes, invoice,
5
  Requires at least: 3.5
6
  Tested up to: 5.8
7
  Requires PHP: 7.1
8
- Stable tag: 2.9.3
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -66,7 +66,7 @@ In the search field type "WooCommerce PDF Invoices & Packing Slips" and click Se
66
 
67
  = Where can I find the documentation? =
68
 
69
- [WooCommerce PDF Invoices & Packing Slips documentation](https://docs.wpovernight.com/woocommerce-pdf-invoices-packing-slips/)
70
 
71
  = It's not working! =
72
 
@@ -102,6 +102,14 @@ There's a setting on the Status tab of the settings page that allows you to togg
102
 
103
  == Changelog ==
104
 
 
 
 
 
 
 
 
 
105
  = 2.9.3 =
106
  * Fix: JavaScript errors on My Account page with empty link tags
107
  * Fix: Long URLs in notes area breaking layout
5
  Requires at least: 3.5
6
  Tested up to: 5.8
7
  Requires PHP: 7.1
8
+ Stable tag: 2.10.0
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
66
 
67
  = Where can I find the documentation? =
68
 
69
+ [WooCommerce PDF Invoices & Packing Slips documentation](https://docs.wpovernight.com/topic/woocommerce-pdf-invoices-packing-slips/)
70
 
71
  = It's not working! =
72
 
102
 
103
  == Changelog ==
104
 
105
+ = 2.10.0 =
106
+ * New: Use minified JS & CSS files to reduce load time on live sites (enabling `SCRIPT_DEBUG` will load full versions)
107
+ * New: Selected template setting is now stored as a reference ID rather than a fixed path ([#209](https://github.com/wpovernight/woocommerce-pdf-invoices-packing-slips/pull/209))
108
+ * Fix: Fallback to first available translation for settings when migrating from multilingual to single language setup
109
+ * Fix: Undefined variable notice when using [wcpdf_download_invoice] on non-order pages
110
+ * Fix: Updated documentation links
111
+ * Marked tested up to WooCommerce 5.7
112
+
113
  = 2.9.3 =
114
  * Fix: JavaScript errors on My Account page with empty link tags
115
  * Fix: Long URLs in notes area breaking layout
woocommerce-pdf-invoices-packingslips.php CHANGED
@@ -3,14 +3,14 @@
3
  * Plugin Name: WooCommerce PDF Invoices & Packing Slips
4
  * Plugin URI: http://www.wpovernight.com
5
  * Description: Create, print & email PDF invoices & packing slips for WooCommerce orders.
6
- * Version: 2.9.3
7
  * Author: Ewout Fernhout
8
  * Author URI: http://www.wpovernight.com
9
  * License: GPLv2 or later
10
  * License URI: http://www.opensource.org/licenses/gpl-license.php
11
  * Text Domain: woocommerce-pdf-invoices-packing-slips
12
  * WC requires at least: 2.2.0
13
- * WC tested up to: 5.6.0
14
  */
15
 
16
  if ( ! defined( 'ABSPATH' ) ) {
@@ -21,7 +21,7 @@ if ( !class_exists( 'WPO_WCPDF' ) ) :
21
 
22
  class WPO_WCPDF {
23
 
24
- public $version = '2.9.3';
25
  public $plugin_basename;
26
  public $legacy_mode;
27
  public $legacy_textdomain;
3
  * Plugin Name: WooCommerce PDF Invoices & Packing Slips
4
  * Plugin URI: http://www.wpovernight.com
5
  * Description: Create, print & email PDF invoices & packing slips for WooCommerce orders.
6
+ * Version: 2.10.0
7
  * Author: Ewout Fernhout
8
  * Author URI: http://www.wpovernight.com
9
  * License: GPLv2 or later
10
  * License URI: http://www.opensource.org/licenses/gpl-license.php
11
  * Text Domain: woocommerce-pdf-invoices-packing-slips
12
  * WC requires at least: 2.2.0
13
+ * WC tested up to: 5.7.0
14
  */
15
 
16
  if ( ! defined( 'ABSPATH' ) ) {
21
 
22
  class WPO_WCPDF {
23
 
24
+ public $version = '2.10.0';
25
  public $plugin_basename;
26
  public $legacy_mode;
27
  public $legacy_textdomain;