From d74d02d76a8dfcfe1139dafbf65ca19651fb55ff Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Tue, 29 Oct 2024 11:21:41 +0000 Subject: [PATCH] Wip --- assets/css/jquery-ui.min.css | 7 ++ includes/Admin.php | 68 ++++++++++++++++---- includes/Assets.php | 3 +- includes/Documents/OrderDocument.php | 41 ++++++------ includes/Documents/SequentialNumberStore.php | 23 +++---- includes/Main.php | 39 +++++------ includes/Settings.php | 55 +++++++++------- includes/Settings/SettingsDebug.php | 33 ++++++---- includes/Settings/SettingsDocuments.php | 8 ++- includes/Settings/SettingsGeneral.php | 10 ++- includes/Settings/SettingsUbl.php | 8 ++- includes/SetupWizard.php | 11 ++-- includes/Tables/NumberStoreListTable.php | 20 ++++-- views/advanced-numbers.php | 2 +- views/advanced-tools.php | 6 +- views/settings-page.php | 13 +++- woocommerce-pdf-invoices-packingslips.php | 14 ++-- 17 files changed, 231 insertions(+), 130 deletions(-) create mode 100644 assets/css/jquery-ui.min.css diff --git a/assets/css/jquery-ui.min.css b/assets/css/jquery-ui.min.css new file mode 100644 index 000000000..b7babfd2e --- /dev/null +++ b/assets/css/jquery-ui.min.css @@ -0,0 +1,7 @@ +/*! jQuery UI - v1.14.0 - 2024-08-05 +* https://jqueryui.com +* Includes: core.css, accordion.css, autocomplete.css, menu.css, button.css, controlgroup.css, checkboxradio.css, datepicker.css, dialog.css, draggable.css, resizable.css, progressbar.css, selectable.css, selectmenu.css, slider.css, sortable.css, spinner.css, tabs.css, tooltip.css, theme.css +* To view and modify this theme, visit https://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px +* Copyright OpenJS Foundation and other contributors; Licensed MIT */ + +.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important;pointer-events:none}.ui-icon{display:inline-block;vertical-align:middle;margin-top:-.25em;position:relative;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-icon-block{left:50%;margin-left:-8px;display:block}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin:2px 0 0 0;padding:.5em .5em .5em .7em;font-size:100%}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:0}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{margin:0;cursor:pointer}.ui-menu .ui-menu-item-wrapper{position:relative;padding:3px 1em 3px .4em}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item-wrapper{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0}.ui-button{padding:.4em 1em;display:inline-block;position:relative;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;-webkit-user-select:none;user-select:none}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2em;box-sizing:border-box;text-indent:-9999px;white-space:nowrap}input.ui-button.ui-button-icon-only{text-indent:0}.ui-button-icon-only .ui-icon{position:absolute;top:50%;left:50%;margin-top:-8px;margin-left:-8px}.ui-button.ui-icon-notext .ui-icon{padding:0;width:2.1em;height:2.1em;text-indent:-9999px;white-space:nowrap}input.ui-button.ui-icon-notext .ui-icon{width:auto;height:auto;text-indent:0;white-space:normal;padding:.4em 1em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-controlgroup{vertical-align:middle;display:inline-block}.ui-controlgroup > .ui-controlgroup-item{float:left;margin-left:0;margin-right:0}.ui-controlgroup > .ui-controlgroup-item:focus,.ui-controlgroup > .ui-controlgroup-item.ui-visual-focus{z-index:9999}.ui-controlgroup-vertical > .ui-controlgroup-item{display:block;float:none;width:100%;margin-top:0;margin-bottom:0;text-align:left}.ui-controlgroup-vertical .ui-controlgroup-item{box-sizing:border-box}.ui-controlgroup .ui-controlgroup-label{padding:.4em 1em}.ui-controlgroup .ui-controlgroup-label span{font-size:80%}.ui-controlgroup-horizontal .ui-controlgroup-label + .ui-controlgroup-item{border-left:none}.ui-controlgroup-vertical .ui-controlgroup-label + .ui-controlgroup-item{border-top:none}.ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content{border-right:none}.ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content{border-bottom:none}.ui-controlgroup-vertical .ui-spinner-input{width:calc( 100% - 2.4em )}.ui-controlgroup-vertical .ui-spinner .ui-spinner-up{border-top-style:solid}.ui-checkboxradio-label .ui-icon-background{box-shadow:inset 1px 1px 1px #ccc;border-radius:.12em;border:none}.ui-checkboxradio-radio-label .ui-icon-background{width:16px;height:16px;border-radius:1em;overflow:visible;border:none}.ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon,.ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon{background-image:none;width:8px;height:8px;border-width:4px;border-style:solid}.ui-checkboxradio-disabled{pointer-events:none}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:45%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-datepicker .ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat;left:.5em;top:.3em}.ui-dialog{position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-n{height:2px;top:0}.ui-dialog .ui-resizable-e{width:2px;right:0}.ui-dialog .ui-resizable-s{height:2px;bottom:0}.ui-dialog .ui-resizable-w{width:2px;left:0}.ui-dialog .ui-resizable-se,.ui-dialog .ui-resizable-sw,.ui-dialog .ui-resizable-ne,.ui-dialog .ui-resizable-nw{width:7px;height:7px}.ui-dialog .ui-resizable-se{right:0;bottom:0}.ui-dialog .ui-resizable-sw{left:0;bottom:0}.ui-dialog .ui-resizable-ne{right:0;top:0}.ui-dialog .ui-resizable-nw{left:0;top:0}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-draggable-handle{touch-action:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");height:100%;opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-selectable{touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-selectmenu-menu{padding:0;margin:0;position:absolute;top:0;left:0;display:none}.ui-selectmenu-menu .ui-menu{overflow:auto;overflow-x:hidden;padding-bottom:1px}.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup{font-size:1em;font-weight:bold;line-height:1.5;padding:2px 0.4em;margin:0.5em 0 0 0;height:auto;border:0}.ui-selectmenu-open{display:block}.ui-selectmenu-text{display:block;margin-right:20px;overflow:hidden;text-overflow:ellipsis}.ui-selectmenu-button.ui-button{text-align:left;white-space:nowrap;width:14em}.ui-selectmenu-icon.ui-icon{float:right;margin-top:0}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:pointer;touch-action:none}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-sortable-handle{touch-action:none}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:.222em 0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:2em}.ui-spinner-button{width:1.6em;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top-style:none;border-bottom-style:none;border-right-style:none}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Verdana,Arial,sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Verdana,Arial,sans-serif;font-size:1em}.ui-widget.ui-widget-content{border:1px solid #d3d3d3}.ui-widget-content{border:1px solid #aaa;background:#fff;color:#222}.ui-widget-content a{color:#222}.ui-widget-header{border:1px solid #aaa;background:#ccc url("images/ui-bg_highlight-soft_75_cccccc_1x100.png") 50% 50% repeat-x;color:#222;font-weight:bold}.ui-widget-header a{color:#222}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default,.ui-button,html .ui-button.ui-state-disabled:hover,html .ui-button.ui-state-disabled:active{border:1px solid #d3d3d3;background:#e6e6e6 url("images/ui-bg_glass_75_e6e6e6_1x400.png") 50% 50% repeat-x;font-weight:normal;color:#555}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited,a.ui-button,a:link.ui-button,a:visited.ui-button,.ui-button{color:#555;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus,.ui-button:hover,.ui-button:focus{border:1px solid #999;background:#dadada url("images/ui-bg_glass_75_dadada_1x400.png") 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited,a.ui-button:hover,a.ui-button:focus{color:#212121;text-decoration:none}.ui-visual-focus{box-shadow:0 0 3px 1px rgb(94,158,214)}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active,a.ui-button:active,.ui-button:active,.ui-button.ui-state-active:hover{border:1px solid #aaa;background:#fff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-icon-background,.ui-state-active .ui-icon-background{border:#aaa;background-color:#212121}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#212121;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fcefa1;background:#fbf9ee url("images/ui-bg_glass_55_fbf9ee_1x400.png") 50% 50% repeat-x;color:#363636}.ui-state-checked{border:1px solid #fcefa1;background:#fbf9ee}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#fef1ec url("images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x;color:#cd0a0a}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;background-image:none}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_222222_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_222222_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon,.ui-button:hover .ui-icon,.ui-button:focus .ui-icon{background-image:url("images/ui-icons_454545_256x240.png")}.ui-state-active .ui-icon,.ui-button:active .ui-icon{background-image:url("images/ui-icons_454545_256x240.png")}.ui-state-highlight .ui-icon,.ui-button .ui-state-highlight.ui-icon{background-image:url("images/ui-icons_2e83ff_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cd0a0a_256x240.png")}.ui-button .ui-icon{background-image:url("images/ui-icons_888888_256x240.png")}.ui-icon-blank.ui-icon-blank.ui-icon-blank{background-image:none}.ui-icon-caret-1-n{background-position:0 0}.ui-icon-caret-1-ne{background-position:-16px 0}.ui-icon-caret-1-e{background-position:-32px 0}.ui-icon-caret-1-se{background-position:-48px 0}.ui-icon-caret-1-s{background-position:-65px 0}.ui-icon-caret-1-sw{background-position:-80px 0}.ui-icon-caret-1-w{background-position:-96px 0}.ui-icon-caret-1-nw{background-position:-112px 0}.ui-icon-caret-2-n-s{background-position:-128px 0}.ui-icon-caret-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-65px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-65px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:1px -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:4px}.ui-widget-overlay{background:#aaa;opacity:.3}.ui-widget-shadow{box-shadow:-8px -8px 8px #aaa} \ No newline at end of file diff --git a/includes/Admin.php b/includes/Admin.php index 1d1ffb58b..f36ebf66c 100644 --- a/includes/Admin.php +++ b/includes/Admin.php @@ -189,7 +189,7 @@ public function install_wizard_notice() { public function setup_wizard() { // Setup/welcome - if ( ! empty( $_GET['page'] ) && 'wpo-wcpdf-setup' === $_GET['page'] && wp_verify_nonce( $_GET['_wpnonce'], 'wpo_wcpdf_setup' ) ) { + if ( ! empty( $_GET['page'] ) && 'wpo-wcpdf-setup' === $_GET['page'] && isset( $_GET['_wpnonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'wpo_wcpdf_setup' ) ) { delete_transient( 'wpo_wcpdf_new_install' ); SetupWizard::instance(); } @@ -331,7 +331,9 @@ public function add_listing_actions( $order ) { * @param array $columns shop order columns */ public function add_invoice_columns( $columns ) { - if ( WPO_WCPDF()->order_util->custom_orders_table_usage_is_enabled() && isset( $_REQUEST['page'] ) && $_REQUEST['page'] == 'wc-orders' && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'edit' ) { + $current_screen = get_current_screen(); + + if ( WPO_WCPDF()->order_util->custom_orders_table_usage_is_enabled() && 'woocommerce_page_wc-orders' !== $current_screen->id ) { return $columns; } @@ -635,15 +637,35 @@ public function pdf_actions_meta_box( $post_or_order_object ) { $unmark_printed = isset( $data['unmark_printed_url'] ) && $data['unmark_printed_url'] ? ''.__( 'Unmark', 'woocommerce-pdf-invoices-packing-slips' ).'' : ''; $printed_data = isset( $data['printed'] ) && $data['printed'] && ! empty( $data['printed_data']['date'] ) ? '

↳ '.$printed.''.date_i18n( 'Y/m/d g:i:s a', strtotime( $data['printed_data']['date'] ) ).''.$unmark_printed.'

' : ''; + $allowed_tags = array( + 'svg' => array( + 'class' => true, + 'xmlns' => true, + 'viewbox' => true, // Lowercase 'viewbox' because wp_kses() converts attribute names to lowercase + ), + 'path' => array( + 'fill-rule' => true, + 'clip-rule' => true, + 'd' => true, + ), + 'p' => array( + 'class' => true, + ), + 'a' => array( + 'href' => true, + 'class' => true, + ), + ); + printf( '
  • %4$s%5$s%6$s%7$s
  • ', esc_url( $url ), esc_attr( $class ), esc_attr( $alt ), esc_html( $title ), - esc_html( $exists ), - esc_html( $manually_mark_printed ), - esc_html( $printed_data ) + str_replace( 'viewbox=', 'viewBox=', wp_kses( $exists, $allowed_tags ) ), + wp_kses( $manually_mark_printed, $allowed_tags ), + str_replace( 'viewbox=', 'viewBox=', wp_kses( $printed_data, $allowed_tags ) ) ); } ?> @@ -994,9 +1016,9 @@ public function save_invoice_number_date( $order_id, $order ) { $order_type = $order->get_type(); - if ( $order_type == 'shop_order' ) { - // bail if this is not an actual 'Save order' action - if ( ! isset( $_POST['action'] ) || $_POST['action'] != 'editpost' ) { + if ( 'shop_order' === $order_type ) { + // Check the nonce. + if ( empty( $_POST['woocommerce_meta_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['woocommerce_meta_nonce'] ) ), 'woocommerce_save_data' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized return; } @@ -1058,9 +1080,14 @@ public function return_false() { */ public function send_emails( $post_or_order_object_id, $post_or_order_object ) { $order = ( $post_or_order_object instanceof \WP_Post ) ? wc_get_order( $post_or_order_object->ID ) : $post_or_order_object; + + // Check the nonce. + if ( empty( $_POST['woocommerce_meta_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['woocommerce_meta_nonce'] ) ), 'woocommerce_save_data' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + return; + } if ( ! empty( $_POST['wpo_wcpdf_send_emails'] ) ) { - $action = wc_clean( $_POST['wpo_wcpdf_send_emails'] ); + $action = sanitize_text_field( wp_unslash( $_POST['wpo_wcpdf_send_emails'] ) ); if ( ! empty( $action ) && strstr( $action, 'send_email_' ) ) { $email_to_send = str_replace( 'send_email_', '', $action ); // Switch back to the site locale. @@ -1143,7 +1170,7 @@ public function ajax_crud_document() { ) ); } - if ( ! $this->user_can_manage_document( sanitize_text_field( $_POST['document_type'] ) ) ) { + if ( ! $this->user_can_manage_document( sanitize_text_field( wp_unslash( $_POST['document_type'] ) ) ) ) { wp_send_json_error( array( 'message' => esc_html__( 'No permissions!', 'woocommerce-pdf-invoices-packing-slips' ), ) ); @@ -1151,12 +1178,14 @@ public function ajax_crud_document() { $order_id = absint( $_POST['order_id'] ); $order = wc_get_order( $order_id ); - $document_type = sanitize_text_field( $_POST['document_type'] ); - $action_type = sanitize_text_field( $_POST['action_type'] ); - $notice = sanitize_text_field( $_POST['wpcdf_document_data_notice'] ); + $document_type = sanitize_text_field( wp_unslash( $_POST['document_type'] ) ); + $action_type = sanitize_text_field( wp_unslash( $_POST['action_type'] ) ); + $notice = isset( $_POST['wpcdf_document_data_notice'] ) ? sanitize_text_field( wp_unslash( $_POST['wpcdf_document_data_notice'] ) ) : 'saved'; + $request_data = isset( $_POST['form_data'] ) ? sanitize_text_field( wp_unslash( $_POST['form_data'] ) ) : ''; // parse form data - parse_str( $_POST['form_data'], $form_data ); + parse_str( $request_data, $form_data ); + if ( is_array( $form_data ) ) { foreach ( $form_data as $key => &$value ) { if ( is_array( $value ) && !empty( $value[$order_id] ) ) { @@ -1164,6 +1193,7 @@ public function ajax_crud_document() { } } } + $form_data = stripslashes_deep( $form_data ); // notice messages @@ -1291,6 +1321,16 @@ public function debug_enabled_warning( $wp_admin_bar ) { public function process_order_document_form_data( $form_data, $document_slug ) { $data = array(); + + if ( + check_ajax_referer( 'wpo_wcpdf_regenerate_document', 'security', false ) === false && + check_ajax_referer( 'wpo_wcpdf_save_document', 'security', false ) === false && + check_ajax_referer( 'wpo_wcpdf_delete_document', 'security', false ) === false && + ( empty( $_POST['woocommerce_meta_nonce'] ) || + ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['woocommerce_meta_nonce'] ) ), 'woocommerce_save_data' ) ) // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + ) { + return $data; + } if( isset( $form_data['_wcpdf_'.$document_slug.'_number'] ) ) { $data['number'] = sanitize_text_field( $form_data['_wcpdf_'.$document_slug.'_number'] ); diff --git a/includes/Assets.php b/includes/Assets.php index e0d272d33..73ecef634 100644 --- a/includes/Assets.php +++ b/includes/Assets.php @@ -213,7 +213,8 @@ public function backend_scripts_styles ( $hook ) { if ( 'debug' === $tab ) { wp_enqueue_style( 'wpo-wcpdf-jquery-ui-styles', - 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/smoothness/jquery-ui.css' + WPO_WCPDF()->plugin_url() . '/assets/css/jquery-ui' . $suffix . '.css', + '1.14.0' ); wp_enqueue_script( 'jquery-ui-datepicker' ); diff --git a/includes/Documents/OrderDocument.php b/includes/Documents/OrderDocument.php index 0d5c8903a..dd0c85635 100644 --- a/includes/Documents/OrderDocument.php +++ b/includes/Documents/OrderDocument.php @@ -155,7 +155,7 @@ public function init_settings() { public function init_settings_data() { // don't override/save settings on Preview requests - if ( isset( $_REQUEST['action'] ) && 'wpo_wcpdf_preview' === $_REQUEST['action'] && wp_verify_nonce( $_REQUEST['security'], 'wpo_wcpdf_preview' ) ) { + if ( isset( $_REQUEST['action'] ) && 'wpo_wcpdf_preview' === $_REQUEST['action'] && isset( $_REQUEST['security'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['security'] ) ), 'wpo_wcpdf_preview' ) ) { return; } @@ -1547,7 +1547,12 @@ public function render_template( $file, $args = array() ) { public function get_wc_emails() { // only run this in the context of the settings page or setup wizard // prevents WPML language mixups - if ( empty( $_GET['page'] ) || !in_array( $_GET['page'], array('wpo-wcpdf-setup','wpo_wcpdf_options_page') ) ) { + + if ( ! empty( $_GET['page'] ) && 'wpo-wcpdf-setup' === $_GET['page'] && ( isset( $_GET['_wpnonce'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'wpo_wcpdf_setup' ) ) ) { + return array(); + } + + if ( ! in_array( $_GET['page'], array( 'wpo-wcpdf-setup', 'wpo_wcpdf_options_page' ) ) ) { return array(); } @@ -1728,9 +1733,9 @@ public function maybe_retire_number_store( $date, $store_base_name, $method ) { $current_year_table_name = "{$default_table_name}_{$current_year}"; // first, remove last year if it already exists - $retired_exists = $wpdb->get_var( "SHOW TABLES LIKE '{$retired_table_name}'" ) == $retired_table_name; - if( $retired_exists ) { - $table_removed = $wpdb->query( "DROP TABLE IF EXISTS {$retired_table_name}" ); + $retired_exists = $wpdb->get_var( "SHOW TABLES LIKE '" . esc_sql( $retired_table_name ) . "'" ) == $retired_table_name; + if ( $retired_exists ) { + $table_removed = $wpdb->query( "DROP TABLE IF EXISTS `" . esc_sql( $retired_table_name ) . "`" ); if( ! $table_removed ) { wcpdf_log_error( sprintf( 'An error occurred while trying to remove the duplicate number store %s: %s', $retired_table_name, $wpdb->last_error ) ); @@ -1739,9 +1744,9 @@ public function maybe_retire_number_store( $date, $store_base_name, $method ) { } // rename current to last year - $default_exists = $wpdb->get_var( "SHOW TABLES LIKE '{$default_table_name}'" ) == $default_table_name; - if( $default_exists ) { - $table_renamed = $wpdb->query( "ALTER TABLE {$default_table_name} RENAME {$retired_table_name}" ); + $default_exists = $wpdb->get_var( "SHOW TABLES LIKE '" . esc_sql( $default_table_name ) . "'" ) == $default_table_name; + if ( $default_exists ) { + $table_renamed = $wpdb->query( "ALTER TABLE `" . esc_sql( $default_table_name ) . "` RENAME `" . esc_sql( $retired_table_name ) . "`" ); if( ! $table_renamed ) { wcpdf_log_error( sprintf( 'An error occurred while trying to rename the number store from %s to %s: %s', $default_table_name, $retired_table_name, $wpdb->last_error ) ); @@ -1750,9 +1755,9 @@ public function maybe_retire_number_store( $date, $store_base_name, $method ) { } // if the current year table name already exists (created earlier as a 'future' year), rename that to default - $current_year_exists = $wpdb->get_var( "SHOW TABLES LIKE '{$current_year_table_name}'" ) == $current_year_table_name; - if( $current_year_exists ) { - $table_renamed = $wpdb->query( "ALTER TABLE {$current_year_table_name} RENAME {$default_table_name}" ); + $current_year_exists = $wpdb->get_var( "SHOW TABLES LIKE '" . esc_sql( $current_year_table_name ) . "'" ) == $current_year_table_name; + if ( $current_year_exists ) { + $table_renamed = $wpdb->query( "ALTER TABLE `" . esc_sql( $current_year_table_name ) . "` RENAME `" . esc_sql( $default_table_name ) . "`" ); if( ! $table_renamed ) { wcpdf_log_error( sprintf( 'An error occurred while trying to rename the number store from %s to %s: %s', $current_year_table_name, $default_table_name, $wpdb->last_error ) ); @@ -1760,7 +1765,7 @@ public function maybe_retire_number_store( $date, $store_base_name, $method ) { } } - if( $was_showing_errors ) { + if ( $was_showing_errors ) { $wpdb->show_errors(); } @@ -1786,17 +1791,17 @@ public function get_number_store_year( $table_name ) { $current_year = intval( $next_year->date_i18n( 'Y' ) ); } - $table_exists = $wpdb->get_var( "SHOW TABLES LIKE '{$table_name}'") == $table_name; - if( $table_exists ) { + $table_exists = $wpdb->get_var( "SHOW TABLES LIKE '" . esc_sql( $table_name ) . "'" ) == $table_name; + if ( $table_exists ) { // get year for the last row - $year = $wpdb->get_var( "SELECT YEAR(date) FROM {$table_name} ORDER BY id DESC LIMIT 1" ); + $year = $wpdb->get_var( "SELECT YEAR(date) FROM `" . esc_sql( $table_name ) . "` ORDER BY id DESC LIMIT 1" ); // default to current year if no results - if( ! $year ) { + if ( ! $year ) { $year = $current_year; // if we don't get a result, this could either mean there's an error, // OR that the first number simply has not been created yet (=no rows) // we only log when there's an actual error - if( ! empty( $wpdb->last_error ) ) { + if ( ! empty( $wpdb->last_error ) ) { wcpdf_log_error( sprintf( 'An error occurred while trying to get the current year from the %s table: %s', $table_name, $wpdb->last_error ) ); } } @@ -1804,7 +1809,7 @@ public function get_number_store_year( $table_name ) { $year = $current_year; } - if( $was_showing_errors ) { + if ( $was_showing_errors ) { $wpdb->show_errors(); } diff --git a/includes/Documents/SequentialNumberStore.php b/includes/Documents/SequentialNumberStore.php index 609d07cc2..4f3e64a0a 100644 --- a/includes/Documents/SequentialNumberStore.php +++ b/includes/Documents/SequentialNumberStore.php @@ -61,7 +61,7 @@ public function init() { if ( $this->method == 'calculate' ) { $column_exists = $this->wpdb->get_var( "SHOW COLUMNS FROM `" . esc_sql( $this->table_name ) . "` LIKE 'calculated_number'" ); if ( empty( $column_exists ) ) { - $this->wpdb->query("ALTER TABLE {$this->table_name} ADD calculated_number int (16)"); + $this->wpdb->query( "ALTER TABLE `" . esc_sql( $this->table_name ) . "` ADD `calculated_number` INT(16)" ); } } return; // no further business @@ -128,10 +128,11 @@ public function get_next() { $this->wpdb->query( "SET SESSION information_schema_stats_expiry = 0" ); } // get next auto_increment value - $table_status = $this->wpdb->get_row("SHOW TABLE STATUS LIKE '{$this->table_name}'"); + $table_status = $this->wpdb->get_row( "SHOW TABLE STATUS LIKE '" . esc_sql( $this->table_name ) . "'" ); $next = $table_status->Auto_increment; } elseif ( $this->method == 'calculate' ) { - $last_row = $this->wpdb->get_row( "SELECT * FROM {$this->table_name} WHERE id = ( SELECT MAX(id) from {$this->table_name} )" ); + $last_row = $this->wpdb->get_row( "SELECT * FROM `" . esc_sql( $this->table_name ) . "` WHERE id = ( SELECT MAX(id) FROM `" . esc_sql( $this->table_name ) . "` )" ); + if ( empty( $last_row ) ) { $next = 1; } elseif ( ! empty( $last_row->calculated_number ) ) { @@ -151,14 +152,14 @@ public function set_next( $number = 1 ) { $wpdb = $this->wpdb; // delete all rows - $delete = $wpdb->query( "TRUNCATE TABLE {$table_name}" ); + $delete = $wpdb->query( "TRUNCATE TABLE `" . esc_sql( $table_name ) . "`" ); // set auto_increment if ( $number > 1 ) { // if AUTO_INCREMENT is not 1, we need to make sure we have a 'highest value' in case of server restarts // https://serverfault.com/questions/228690/mysql-auto-increment-fields-resets-by-itself $highest_number = (int) $number - 1; - $wpdb->query( $wpdb->prepare( "ALTER TABLE {$table_name} AUTO_INCREMENT=%d;", $highest_number ) ); + $wpdb->query( $wpdb->prepare( "ALTER TABLE `" . esc_sql( $table_name ) . "` AUTO_INCREMENT=%d;", $highest_number ) ); $data = array( 'order_id' => 0, 'date' => get_date_from_gmt( gmdate( 'Y-m-d H:i:s' ) ), @@ -172,27 +173,23 @@ public function set_next( $number = 1 ) { $wpdb->insert( $table_name, $data ); } else { // simple scenario, no need to insert any rows - $wpdb->query( $wpdb->prepare( "ALTER TABLE {$table_name} AUTO_INCREMENT=%d;", $number ) ); + $wpdb->query( $wpdb->prepare( "ALTER TABLE `" . esc_sql( $table_name ) . "` AUTO_INCREMENT=%d;", $number ) ); } } public function get_last_date( $format = 'Y-m-d H:i:s' ) { - $row = $this->wpdb->get_row( "SELECT * FROM {$this->table_name} WHERE id = ( SELECT MAX(id) from {$this->table_name} )" ); + $row = $this->wpdb->get_row( "SELECT * FROM `" . esc_sql( $this->table_name ) . "` WHERE id = ( SELECT MAX(id) FROM `" . esc_sql( $this->table_name ) . "` )" ); $date = isset( $row->date ) ? $row->date : 'now'; return gmdate( $format, strtotime( $date ) ); } /** + * Check if the number store table exists * @return bool */ public function store_name_exists() { - // check if table exists - if ( $this->wpdb->get_var("SHOW TABLES LIKE '{$this->table_name}'") == $this->table_name ) { - return true; - } else { - return false; - } + return $this->wpdb->get_var( "SHOW TABLES LIKE '" . esc_sql( $this->table_name ) . "'" ) === $this->table_name; } } diff --git a/includes/Main.php b/includes/Main.php index 377ee7bba..3a99c2fe9 100644 --- a/includes/Main.php +++ b/includes/Main.php @@ -350,28 +350,29 @@ public function get_documents_for_email( $email_id, $order ) { public function generate_document_ajax() { $access_type = WPO_WCPDF()->endpoint->get_document_link_access_type(); $redirect_url = WPO_WCPDF()->endpoint->get_document_denied_frontend_redirect_url(); + $request = stripslashes_deep( $_REQUEST ); // handle bulk actions access key (_wpnonce) and legacy access key (order_key) - if ( empty( $_REQUEST['access_key'] ) ) { + if ( empty( $request['access_key'] ) ) { foreach ( array( '_wpnonce', 'order_key' ) as $legacy_key ) { - if ( ! empty( $_REQUEST[ $legacy_key ] ) ) { - $_REQUEST['access_key'] = sanitize_text_field( wp_unslash( $_REQUEST[ $legacy_key ] ) ); + if ( ! empty( $request[ $legacy_key ] ) ) { + $request['access_key'] = sanitize_text_field( wp_unslash( $request[ $legacy_key ] ) ); } } } - $access_key = isset( $_REQUEST['access_key'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['access_key'] ) ) : ''; - $action = isset( $_REQUEST['action'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['action'] ) ) : ''; + $access_key = isset( $request['access_key'] ) ? sanitize_text_field( wp_unslash( $request['access_key'] ) ) : ''; + $action = isset( $request['action'] ) ? sanitize_text_field( wp_unslash( $request['action'] ) ) : ''; $valid_nonce = ! empty( $access_key ) && ! empty( $action ) && wp_verify_nonce( $access_key, $action ); // check if we have the access key set - if ( empty( $_REQUEST['access_key'] ) ) { + if ( empty( $request['access_key'] ) ) { $message = esc_attr__( 'You do not have sufficient permissions to access this page. Reason: empty access key', 'woocommerce-pdf-invoices-packing-slips' ); wcpdf_safe_redirect_or_die( $redirect_url, $message ); } // check if we have the action - if ( empty( $_REQUEST['action'] ) ) { + if ( empty( $request['action'] ) ) { $message = esc_attr__( 'You do not have sufficient permissions to access this page. Reason: empty action', 'woocommerce-pdf-invoices-packing-slips' ); wcpdf_safe_redirect_or_die( $redirect_url, $message ); } @@ -383,27 +384,27 @@ public function generate_document_ajax() { } // Check if all parameters are set - if ( empty( $_REQUEST['document_type'] ) && ! empty( $_REQUEST['template_type'] ) ) { - $_REQUEST['document_type'] = sanitize_text_field( wp_unslash( $_REQUEST['template_type'] ) ); + if ( empty( $request['document_type'] ) && ! empty( $request['template_type'] ) ) { + $request['document_type'] = sanitize_text_field( wp_unslash( $request['template_type'] ) ); } - if ( empty( $_REQUEST['order_ids'] ) ) { + if ( empty( $request['order_ids'] ) ) { $message = esc_attr__( "You haven't selected any orders", 'woocommerce-pdf-invoices-packing-slips' ); wcpdf_safe_redirect_or_die( null, $message ); } - if ( empty( $_REQUEST['document_type'] ) ) { + if ( empty( $request['document_type'] ) ) { $message = esc_attr__( 'Some of the export parameters are missing.', 'woocommerce-pdf-invoices-packing-slips' ); wcpdf_safe_redirect_or_die( null, $message ); } // debug enabled by URL - if ( isset( $_REQUEST['debug'] ) && ! ( is_user_logged_in() || isset( $_REQUEST['my-account'] ) ) ) { + if ( isset( $request['debug'] ) && ! ( is_user_logged_in() || isset( $request['my-account'] ) ) ) { $this->enable_debug(); } - $document_type = sanitize_text_field( wp_unslash( $_REQUEST['document_type'] ) ); - $order_ids = isset( $_REQUEST['order_ids'] ) ? array_map( 'absint', explode( 'x', sanitize_text_field( wp_unslash( $_REQUEST['order_ids'] ) ) ) ) : array(); + $document_type = sanitize_text_field( wp_unslash( $request['document_type'] ) ); + $order_ids = isset( $request['order_ids'] ) ? array_map( 'absint', explode( 'x', sanitize_text_field( wp_unslash( $request['order_ids'] ) ) ) ) : array(); $order = false; // single order @@ -460,7 +461,7 @@ public function generate_document_ajax() { } if ( ! $full_permission ) { - if ( ! isset( $_REQUEST['my-account'] ) && ! isset( $_REQUEST['shortcode'] ) ) { + if ( ! isset( $request['my-account'] ) && ! isset( $request['shortcode'] ) ) { $allowed = false; break; } @@ -474,7 +475,7 @@ public function generate_document_ajax() { break; case 'full': // check if we have a valid access key only when it's not from bulk actions - if ( ! isset( $_REQUEST['bulk'] ) && $order && ! hash_equals( $order->get_order_key(), wp_unslash( $_REQUEST['access_key'] ) ) ) { + if ( ! isset( $request['bulk'] ) && $order && ! hash_equals( $order->get_order_key(), wp_unslash( $request['access_key'] ) ) ) { $allowed = false; break; } @@ -491,13 +492,13 @@ public function generate_document_ajax() { // if we got here, we're safe to go! try { // log document creation to order notes - if ( count( $order_ids ) > 1 && isset( $_REQUEST['bulk'] ) ) { + if ( count( $order_ids ) > 1 && isset( $request['bulk'] ) ) { add_action( 'wpo_wcpdf_init_document', function( $document ) { $this->log_document_creation_to_order_notes( $document, 'bulk' ); $this->log_document_creation_trigger_to_order_meta( $document, 'bulk' ); $this->mark_document_printed( $document, 'bulk' ); } ); - } elseif ( isset( $_REQUEST['my-account'] ) ) { + } elseif ( isset( $request['my-account'] ) ) { add_action( 'wpo_wcpdf_init_document', function( $document ) { $this->log_document_creation_to_order_notes( $document, 'my_account' ); $this->log_document_creation_trigger_to_order_meta( $document, 'my_account' ); @@ -517,7 +518,7 @@ public function generate_document_ajax() { if ( $document ) { do_action( 'wpo_wcpdf_document_created_manually', $document, $order_ids ); // note that $order_ids is filtered and may not be the same as the order IDs used for the document (which can be fetched from the document object itself with $document->order_ids) - $output_format = WPO_WCPDF()->settings->get_output_format( $document ); + $output_format = WPO_WCPDF()->settings->get_output_format( $document, $request ); switch ( $output_format ) { case 'ubl': diff --git a/includes/Settings.php b/includes/Settings.php index 0d9502ff8..349441cd6 100644 --- a/includes/Settings.php +++ b/includes/Settings.php @@ -77,7 +77,7 @@ public function __construct() { add_action( "update_option_wpo_wcpdf_settings_debug", array( $this, 'debug_settings_updated' ), 10, 3 ); add_action( 'init', array( $this, 'maybe_delete_flush_rewrite_rules_transient' ) ); // migrate old template paths to template IDs before loading settings page - add_action( 'wpo_wcpdf_settings_output_general', array( $this, 'maybe_migrate_template_paths' ), 9, 1 ); + add_action( 'wpo_wcpdf_settings_output_general', array( $this, 'maybe_migrate_template_paths' ), 9, 2 ); // AJAX preview add_action( 'wp_ajax_wpo_wcpdf_preview', array( $this, 'ajax_preview' ) ); @@ -164,7 +164,6 @@ function check_auto_increment_increment() { } } - public function settings_page() { // feedback on settings save settings_errors(); @@ -199,12 +198,11 @@ public function settings_page() { 'preview_states' => 1, ); - $settings_tabs = $this->maybe_disable_preview_on_settings_tabs( $settings_tabs ); // disable preview on debug setting - $default_tab = apply_filters( 'wpo_wcpdf_settings_tabs_default', ! empty( $settings_tabs['general'] ) ? 'general' : key( $settings_tabs ) ); - $active_tab = isset( $_GET[ 'tab' ] ) ? sanitize_text_field( $_GET[ 'tab' ] ) : $default_tab; - $active_section = isset( $_GET[ 'section' ] ) ? sanitize_text_field( $_GET[ 'section' ] ) : ''; + $settings_tabs = $this->maybe_disable_preview_on_settings_tabs( $settings_tabs ); // disable preview on debug setting + $default_tab = apply_filters( 'wpo_wcpdf_settings_tabs_default', ! empty( $settings_tabs['general'] ) ? 'general' : key( $settings_tabs ) ); + $nonce = wp_create_nonce( 'wp_wcpdf_settings_page_nonce' ); - include( WPO_WCPDF()->plugin_path() . '/views/settings-page.php' ); + include WPO_WCPDF()->plugin_path() . '/views/settings-page.php'; } public function maybe_disable_preview_on_settings_tabs( $settings_tabs ) { @@ -233,14 +231,14 @@ public function ajax_preview() { // get document type if ( ! empty( $_POST['document_type'] ) ) { - $document_type = sanitize_text_field( $_POST['document_type'] ); + $document_type = sanitize_text_field( wp_unslash( $_POST['document_type'] ) ); } else { $document_type = 'invoice'; } // get order ID if ( ! empty( $_POST['order_id'] ) ) { - $order_id = sanitize_text_field( $_POST['order_id'] ); + $order_id = sanitize_text_field( wp_unslash( $_POST['order_id'] ) ); if ( $document_type == 'credit-note' ) { // get last refund ID of the order if available @@ -277,7 +275,8 @@ public function ajax_preview() { // process settings data if ( ! empty( $_POST['data'] ) ) { // parse form data - parse_str( $_POST['data'], $form_data ); + $posted_data = sanitize_text_field( wp_unslash( $_POST['data'] ) ); + parse_str( $posted_data, $form_data ); $form_data = stripslashes_deep( $form_data ); foreach ( $form_data as $option_key => $form_settings ) { @@ -323,7 +322,7 @@ public function ajax_preview() { } // preview - $output_format = ( ! empty( $_REQUEST['output_format'] ) && $_REQUEST['output_format'] != 'pdf' && in_array( $_REQUEST['output_format'], $document->output_formats ) ) ? esc_attr( $_REQUEST['output_format'] ) : 'pdf'; + $output_format = ( ! empty( $_REQUEST['output_format'] ) && $_REQUEST['output_format'] != 'pdf' && in_array( $_REQUEST['output_format'], $document->output_formats ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['output_format'] ) ) : 'pdf'; switch ( $output_format ) { default: case 'pdf': @@ -380,8 +379,8 @@ public function preview_order_search() { } if ( ! empty( $_POST['search'] ) && ! empty( $_POST['document_type'] ) ) { - $search = sanitize_text_field( $_POST['search'] ); - $document_type = sanitize_text_field( $_POST['document_type'] ); + $search = sanitize_text_field( wp_unslash( $_POST['search'] ) ); + $document_type = sanitize_text_field( wp_unslash( $_POST['document_type'] ) ); $results = array(); // we have an order ID @@ -529,15 +528,15 @@ public function get_document_settings( $document_type, $output_format = 'pdf' ) } } - public function get_output_format( $document = null ) { + public function get_output_format( $document = null, $request = null ) { $output_format = 'pdf'; // default - if ( isset( $this->debug_settings['html_output'] ) || ( isset( $_REQUEST['output'] ) && 'html' === $_REQUEST['output'] ) ) { + if ( isset( $this->debug_settings['html_output'] ) || ( isset( $request['output'] ) && 'html' === $request['output'] ) ) { $output_format = 'html'; - } elseif ( isset( $_REQUEST['output'] ) && ! empty( $_REQUEST['output'] ) && ! empty( $document ) && in_array( $_REQUEST['output'], $document->output_formats ) ) { - $document_settings = $this->get_document_settings( $document->get_type(), esc_attr( $_REQUEST['output'] ) ); + } elseif ( isset( $request['output'] ) && ! empty( $request['output'] ) && ! empty( $document ) && in_array( $request['output'], $document->output_formats ) ) { + $document_settings = $this->get_document_settings( $document->get_type(), esc_attr( $request['output'] ) ); if ( isset( $document_settings['enabled'] ) ) { - $output_format = esc_attr( $_REQUEST['output'] ); + $output_format = esc_attr( $request['output'] ); } } @@ -720,7 +719,11 @@ public function get_relative_template_path( $absolute_path ) { return str_replace( $base_path, '', wp_normalize_path( $absolute_path ) ); } - public function maybe_migrate_template_paths( $settings_section = null ) { + public function maybe_migrate_template_paths( $settings_section = null, $nonce = null ) { + if ( ! wp_verify_nonce( $nonce, 'wp_wcpdf_settings_page_nonce' ) ) { + wp_die( 'Security check' ); + } + // bail if no template is selected yet (fresh install) if ( empty( $this->general_settings['template_path'] ) ) { return; @@ -760,7 +763,10 @@ public function maybe_migrate_template_paths( $settings_section = null ) { } public function set_number_store() { - check_ajax_referer( "wpo_wcpdf_next_{$_POST['store']}", 'security' ); + $store = ! empty( $_POST['store'] ) ? sanitize_text_field( wp_unslash( $_POST['store'] ) ) : ''; + + check_ajax_referer( "wpo_wcpdf_next_{$store}", 'security' ); + // check permissions if ( ! $this->user_can_manage_settings() ) { die(); @@ -769,9 +775,9 @@ public function set_number_store() { $number = ! empty( $_POST['number'] ) ? (int) $_POST['number'] : 0; if ( $number > 0 ) { $number_store_method = $this->get_sequential_number_store_method(); - $number_store = new SequentialNumberStore( $_POST['store'], $number_store_method ); + $number_store = new SequentialNumberStore( $store, $number_store_method ); $number_store->set_next( $number ); - echo wp_kses_post( "next number ({$_POST['store']}) set to {$number}" ); + echo wp_kses_post( "next number ({$store}) set to {$number}" ); } die(); } @@ -954,14 +960,15 @@ public function yearly_reset_action_is_scheduled() { public function get_media_upload_setting_html() { check_ajax_referer( 'wpo_wcpdf_get_media_upload_setting_html', 'security' ); + // check permissions if ( ! $this->user_can_manage_settings() ) { wp_send_json_error(); } // get previous (default) args and preset current - $args = $_POST['args']; - $args['current'] = absint( $_POST['attachment_id'] ); + $args = isset( $_POST['args'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['args'] ) ) : array(); + $args['current'] = isset( $_POST['attachment_id'] ) ? absint( sanitize_text_field( wp_unslash( $_POST['attachment_id'] ) ) ) : 0; if ( isset( $args['translatable'] ) ) { $args['translatable'] = wc_string_to_bool( $args['translatable'] ); diff --git a/includes/Settings/SettingsDebug.php b/includes/Settings/SettingsDebug.php index 1c7d09775..9b3d33f0d 100644 --- a/includes/Settings/SettingsDebug.php +++ b/includes/Settings/SettingsDebug.php @@ -23,13 +23,17 @@ public static function instance() { public function __construct() { add_action( 'admin_init', array( $this, 'init_settings' ) ); - add_action( 'wpo_wcpdf_settings_output_debug', array( $this, 'output' ), 10, 1 ); + add_action( 'wpo_wcpdf_settings_output_debug', array( $this, 'output' ), 10, 2 ); add_action( 'wp_ajax_wpo_wcpdf_debug_tools', array( $this, 'ajax_process_settings_debug_tools' ) ); add_action( 'wp_ajax_wpo_wcpdf_danger_zone_tools', array( $this, 'ajax_process_danger_zone_tools' ) ); } - public function output( $active_section ) { + public function output( $active_section, $nonce ) { + if ( ! wp_verify_nonce( $nonce, 'wp_wcpdf_settings_page_nonce' ) ) { + wp_die( 'Security check' ); + } + $active_section = ! empty( $active_section ) ? $active_section : 'settings'; $sections = $this->get_settings_sections(); @@ -57,7 +61,7 @@ public function output( $active_section ) { $this->display_tools(); break; case 'numbers': - $this->display_numbers(); + $this->display_numbers( $nonce ); break; default: do_action( 'wpo_wcpdf_settings_debug_section_output', $active_section ); @@ -82,15 +86,20 @@ public function display_tools() { include( WPO_WCPDF()->plugin_path() . '/views/advanced-tools.php' ); } - public function display_numbers() { + public function display_numbers( $nonce ) { + if ( ! wp_verify_nonce( $nonce, 'wp_wcpdf_settings_page_nonce' ) ) { + wp_die( 'Security check' ); + } + global $wpdb; - + + $_GET['_wpnonce'] = $nonce; $number_store_tables = $this->get_number_store_tables(); $invoice_number_store_doc_types = $this->get_additional_invoice_number_store_document_types(); $store_name = 'invoice_number'; if ( isset( $_GET['table_name'] ) ) { - $selected_table_name = esc_attr( $_GET['table_name'] ); + $selected_table_name = sanitize_text_field( wp_unslash( $_GET['table_name'] ) ); } else { $_GET['table_name'] = $selected_table_name = apply_filters( 'wpo_wcpdf_number_store_table_name', "{$wpdb->prefix}wcpdf_{$store_name}", $store_name, null ); // i.e. wp_wcpdf_invoice_number or wp_wcpdf_invoice_number_2021 } @@ -99,16 +108,16 @@ public function display_numbers() { $_GET['table_name'] = $selected_table_name = null; } - $document_type = $this->get_document_type_from_store_table_name( esc_attr( $_GET['table_name'] ) ); + $document_type = $this->get_document_type_from_store_table_name( sanitize_text_field( wp_unslash( $_GET['table_name'] ) ) ); $list_table = new NumberStoreListTable(); $list_table->prepare_items(); - $list_table_name = $_GET['table_name']; - $search_value = isset( $_REQUEST['s'] ) ? esc_attr( $_REQUEST['s'] ) : ''; + $list_table_name = sanitize_text_field( wp_unslash( $_GET['table_name'] ) ); + $search_value = isset( $_REQUEST['s'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['s'] ) ) : ''; $disable_reset = empty( $search_value ) ? 'disabled' : ''; - include( WPO_WCPDF()->plugin_path() . '/views/advanced-numbers.php' ); + include WPO_WCPDF()->plugin_path() . '/views/advanced-numbers.php'; } public function get_number_store_tables() { @@ -344,13 +353,15 @@ private function export_settings( $data ) { } private function import_settings( $data ) { + check_ajax_referer( 'wpo_wcpdf_debug_nonce', 'nonce' ); + extract( $data ); $file_data = []; if ( ! empty( $_FILES['file']['tmp_name'] ) && ! empty( $_FILES['file']['name'] ) ) { $wp_filesystem = wpo_wcpdf_get_wp_filesystem(); - $json_data = $wp_filesystem->get_contents( $_FILES['file']['tmp_name'] ); + $json_data = $wp_filesystem->get_contents( sanitize_text_field( wp_unslash( $_FILES['file']['tmp_name'] ) ) ); if ( ! $json_data ) { $message = __( 'Failed to get contents from JSON file!', 'woocommerce-pdf-invoices-packing-slips' ); diff --git a/includes/Settings/SettingsDocuments.php b/includes/Settings/SettingsDocuments.php index 429f29de2..38e47366e 100644 --- a/includes/Settings/SettingsDocuments.php +++ b/includes/Settings/SettingsDocuments.php @@ -20,7 +20,7 @@ public static function instance() { public function __construct() { add_action( 'admin_init', array( $this, 'init_settings' ) ); - add_action( 'wpo_wcpdf_settings_output_documents', array( $this, 'output' ), 10, 1 ); + add_action( 'wpo_wcpdf_settings_output_documents', array( $this, 'output' ), 10, 2 ); } public function init_settings() { @@ -32,7 +32,11 @@ public function init_settings() { } } - public function output( $section ) { + public function output( $section, $nonce ) { + if ( ! wp_verify_nonce( $nonce, 'wp_wcpdf_settings_page_nonce' ) ) { + wp_die( 'Security check' ); + } + $section = ! empty( $section ) ? $section : 'invoice'; $documents = WPO_WCPDF()->documents->get_documents( 'all' ); $output_format = 'pdf'; diff --git a/includes/Settings/SettingsGeneral.php b/includes/Settings/SettingsGeneral.php index 5f27d347b..46b891574 100644 --- a/includes/Settings/SettingsGeneral.php +++ b/includes/Settings/SettingsGeneral.php @@ -22,11 +22,15 @@ public static function instance() { public function __construct() { add_action( 'admin_init', array( $this, 'init_settings' ) ); - add_action( 'wpo_wcpdf_settings_output_general', array( $this, 'output' ), 10, 1 ); + add_action( 'wpo_wcpdf_settings_output_general', array( $this, 'output' ), 10, 2 ); add_action( 'wpo_wcpdf_before_settings', array( $this, 'attachment_settings_hint' ), 10, 2 ); } - public function output( $section ) { + public function output( $section, $nonce ) { + if ( ! wp_verify_nonce( $nonce, 'wp_wcpdf_settings_page_nonce' ) ) { + wp_die( 'Security check' ); + } + settings_fields( $this->option_name ); do_settings_sections( $this->option_name ); @@ -290,7 +294,7 @@ public function attachment_settings_hint( $active_tab, $active_section ) { // save or check option to hide attachments settings hint if ( isset( $_REQUEST['wpo_wcpdf_hide_attachments_hint'] ) && isset( $_REQUEST['_wpnonce'] ) ) { // validate nonce - if ( ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'hide_attachments_hint_nonce' ) ) { + if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'hide_attachments_hint_nonce' ) ) { wcpdf_log_error( 'You do not have sufficient permissions to perform this action: wpo_wcpdf_hide_attachments_hint' ); $hide_hint = false; } else { diff --git a/includes/Settings/SettingsUbl.php b/includes/Settings/SettingsUbl.php index fca2e5b43..c4afc9c4a 100644 --- a/includes/Settings/SettingsUbl.php +++ b/includes/Settings/SettingsUbl.php @@ -28,7 +28,7 @@ function __construct() { ]; add_action( 'admin_init', array( $this, 'init_tax_settings' ) ); - add_action( 'wpo_wcpdf_settings_output_ubl', array( $this, 'output' ), 10, 1 ); + add_action( 'wpo_wcpdf_settings_output_ubl', array( $this, 'output' ), 10, 2 ); add_action( 'woocommerce_order_after_calculate_totals', array( $this, 'save_taxes_on_order_totals' ), 10, 2 ); add_action( 'woocommerce_checkout_order_processed', array( $this, 'save_taxes_on_checkout' ), 10, 3 ); @@ -37,7 +37,11 @@ function __construct() { add_action( 'admin_notices', array( $this, 'vat_coc_required_for_ubl_invoice') ); } - public function output( $active_section ) { + public function output( $active_section, $nonce ) { + if ( ! wp_verify_nonce( $nonce, 'wp_wcpdf_settings_page_nonce' ) ) { + wp_die( 'Security check' ); + } + $active_section = ! empty( $active_section ) ? $active_section : 'taxes'; ?>
    diff --git a/includes/SetupWizard.php b/includes/SetupWizard.php index b47615fdc..a46119480 100644 --- a/includes/SetupWizard.php +++ b/includes/SetupWizard.php @@ -29,7 +29,6 @@ public function __construct() { add_action( 'admin_menu', array( $this, 'admin_menus' ) ); add_action( 'admin_init', array( $this, 'setup_wizard' ) ); } - } /** @@ -45,7 +44,7 @@ public function admin_menus() { public function setup_wizard() { $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; - if ( empty( $_GET['page'] ) || 'wpo-wcpdf-setup' !== $_GET['page'] ) { + if ( empty( $_GET['page'] ) || 'wpo-wcpdf-setup' !== $_GET['page'] || empty( $_GET['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'wpo_wcpdf_setup' ) ) { return; } @@ -83,7 +82,7 @@ public function setup_wizard() { 'view' => WPO_WCPDF()->plugin_path() . '/views/setup-wizard/good-to-go.php', ), ); - $this->step = isset( $_GET['step'] ) ? sanitize_key( $_GET['step'] ) : current( array_keys( $this->steps ) ); + $this->step = isset( $_GET['step'] ) ? sanitize_text_field( wp_unslash( $_GET['step'] ) ) : current( array_keys( $this->steps ) ); wp_enqueue_style( 'wpo-wcpdf-setup', @@ -241,7 +240,9 @@ public function save_step() { $hidden = get_user_meta( $user_id, 'manageedit-shop_ordercolumnshidden', true ); if ( ! empty( $_POST['wcpdf_settings'] ) && is_array( $_POST['wcpdf_settings'] ) ) { check_admin_referer( 'wpo-wcpdf-setup' ); - foreach ( $_POST['wcpdf_settings'] as $option => $settings ) { + $request_settings = isset( $_POST['wcpdf_settings'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['wcpdf_settings'] ) ) : array(); + + foreach ( $request_settings as $option => $settings ) { // sanitize posted settings foreach ( $settings as $key => $value ) { if ( $key == 'shop_address' && function_exists( 'sanitize_textarea_field' ) ) { @@ -262,7 +263,7 @@ public function save_step() { $new_settings = $settings + $current_settings; update_option( $option, $new_settings ); } - } elseif ( $_POST['wpo_wcpdf_step'] == 'show-action-buttons' ) { + } elseif ( ! empty( $_POST['wpo_wcpdf_step'] ) && 'show-action-buttons' === $_POST['wpo_wcpdf_step'] ) { if ( ! empty( $_POST['wc_show_action_buttons'] ) ) { $hidden = array_filter( $hidden, function( $setting ){ return $setting !== 'wc_actions'; } ); update_user_meta( $user_id, 'manageedit-shop_ordercolumnshidden', $hidden ); diff --git a/includes/Tables/NumberStoreListTable.php b/includes/Tables/NumberStoreListTable.php index 54cdcbd6d..8922bf5f3 100644 --- a/includes/Tables/NumberStoreListTable.php +++ b/includes/Tables/NumberStoreListTable.php @@ -124,8 +124,10 @@ public function get_columns() { 'order_status' => __( 'Order Status', 'woocommerce-pdf-invoices-packing-slips' ), ); - $table_name = isset( $_GET['table_name'] ) ? sanitize_text_field( $_GET['table_name'] ) : null; - $document_type = WPO_WCPDF()->settings->debug->get_document_type_from_store_table_name( $table_name ); + if ( isset( $_GET['_wpnonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'wp_wcpdf_settings_page_nonce' ) ) { + $table_name = isset( $_GET['table_name'] ) ? sanitize_text_field( wp_unslash( $_GET['table_name'] ) ) : null; + $document_type = WPO_WCPDF()->settings->debug->get_document_type_from_store_table_name( $table_name ); + } if ( empty( $document_type ) || 'invoice' !== $document_type ) { unset( $columns['type'] ); @@ -191,6 +193,10 @@ public function get_search( $request ) { */ public function get_numbers() { global $wpdb; + + if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'wp_wcpdf_settings_page_nonce' ) ) { + return array(); + } $request = stripslashes_deep( $_GET ); $results = array(); @@ -218,9 +224,15 @@ public function get_numbers() { if ( ! empty( $table_name ) ) { if ( $search ) { - $results = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table_name} WHERE `id` = %d OR `order_id` = %d ORDER BY {$orderby} {$order}", $search, $search ) ); + $results = $wpdb->get_results( + $wpdb->prepare( + "SELECT * FROM `" . esc_sql( $table_name ) . "` WHERE `id` = %d OR `order_id` = %d ORDER BY " . esc_sql( $orderby ) . " " . esc_sql( $order ), + $search, + $search + ) + ); } else { - $results = $wpdb->get_results( "SELECT * FROM {$table_name} ORDER BY {$orderby} {$order}" ); + $results = $wpdb->get_results( "SELECT * FROM `" . esc_sql( $table_name ) . "` ORDER BY `" . esc_sql( $orderby ) . "` " . esc_sql( $order ) ); } } diff --git a/views/advanced-numbers.php b/views/advanced-numbers.php index 18738ef78..9d577c710 100644 --- a/views/advanced-numbers.php +++ b/views/advanced-numbers.php @@ -26,7 +26,7 @@ next %s number value in the settings).', 'woocommerce-pdf-invoices-packing-slips' ), + wp_kses_post( 'Below is a list of all the document numbers generated since the last reset (which happens when you set the next %s number value in the settings).', 'woocommerce-pdf-invoices-packing-slips' ), esc_html( $choose_table_title ) ); ?> diff --git a/views/advanced-tools.php b/views/advanced-tools.php index b6ca16da0..b746f6501 100644 --- a/views/advanced-tools.php +++ b/views/advanced-tools.php @@ -149,7 +149,7 @@

    - +
    @@ -248,7 +248,7 @@
    -

    DANGER ZONE: Create a backup before using these tools, the actions they perform are irreversible!', 'woocommerce-pdf-invoices-packing-slips' ); ?>

    +

    DANGER ZONE: Create a backup before using these tools, the actions they perform are irreversible!', 'woocommerce-pdf-invoices-packing-slips' ); ?>

    @@ -259,7 +259,7 @@ next document number setting %s to the number you want to use for the first document. ', 'woocommerce-pdf-invoices-packing-slips' ), + wp_kses_post( 'Set the next document number setting %s to the number you want to use for the first document. ', 'woocommerce-pdf-invoices-packing-slips' ), 'WooCommerce > PDF Invoices > Documents > Select document' ); ?> diff --git a/views/settings-page.php b/views/settings-page.php index 52ac2faf2..a0c4f534c 100644 --- a/views/settings-page.php +++ b/views/settings-page.php @@ -1,12 +1,19 @@ ★★★★★', $review_url ); + +if ( ! wp_verify_nonce( $nonce, 'wp_wcpdf_settings_page_nonce' ) ) { + wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce-pdf-invoices-packing-slips' ) ); +} + +$review_url = 'https://wordpress.org/support/plugin/woocommerce-pdf-invoices-packing-slips/reviews/#new-post'; +$review_link = sprintf( '★★★★★', $review_url ); $review_invitation = sprintf( /* translators: ★★★★★ (5-star) */ __( 'If you like PDF Invoices & Packing Slips for WooCommerce please leave us a %s rating. A huge thank you in advance!', 'woocommerce-pdf-invoices-packing-slips' ), $review_link ); +$active_tab = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : $default_tab; +$active_section = isset( $_GET['section'] ) ? sanitize_text_field( wp_unslash( $_GET['section'] ) ) : ''; ?>