plugin updates

This commit is contained in:
Tony Volpe
2024-06-17 15:33:26 -04:00
parent 3751a5a1a6
commit e4e274a9a7
2674 changed files with 0 additions and 507851 deletions

View File

@@ -1,22 +0,0 @@
Copyright (c) 2013 Trent Richardson
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -1,427 +0,0 @@
/* Coupons By Location styles */
span.search label{
font-size: 1em !important;
float:left !important;
}
label.billing{
width: 75px !important;
margin-left: 1px !important;
}
label.shipping{
margin-left: 0px !important;
}
.chosen-container-multi .chosen-choices .search-field input{
height: 21px !important;
}
/*==============================
CHOSEN CSS - Added from woo 2.6
================================*/
.chosen-container {
position: relative;
display: inline-block;
vertical-align: middle;
font-size: 13px;
zoom: 1;
user-select: none
}
.chosen-container .chosen-drop {
position: absolute;
top: 100%;
left: -9999px;
z-index: 1010;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
border: 1px solid #aaa;
border-top: 0;
background: #fff;
box-shadow: 0 4px 5px rgba(0, 0, 0, .15)
}
.chosen-container.chosen-with-drop .chosen-drop {
left: 0
}
.chosen-container a {
cursor: pointer
}
.chosen-container-single .chosen-single {
position: relative;
display: block;
overflow: hidden;
padding: 0 0 0 8px;
height: 26px;
border: 1px solid #aaa;
border-radius: 5px;
background-color: #fff;
background: -webkit-gradient(linear, 50% 0, 50% 100%, color-stop(20%, #fff), color-stop(50%, #f6f6f6), color-stop(52%, #eee), color-stop(100%, #f4f4f4));
background: -webkit-linear-gradient(top, #fff 20%, #f6f6f6 50%, #eee 52%, #f4f4f4 100%);
background: -moz-linear-gradient(top, #fff 20%, #f6f6f6 50%, #eee 52%, #f4f4f4 100%);
background: -o-linear-gradient(top, #fff 20%, #f6f6f6 50%, #eee 52%, #f4f4f4 100%);
background: linear-gradient(top, #fff 20%, #f6f6f6 50%, #eee 52%, #f4f4f4 100%);
background-clip: padding-box;
box-shadow: 0 0 3px #fff inset, 0 1px 1px rgba(0, 0, 0, .1);
color: #444;
text-decoration: none;
white-space: nowrap;
line-height: 26px
}
.chosen-container-single .chosen-default {
color: #999
}
.chosen-container-single .chosen-single span {
display: block;
overflow: hidden;
margin-right: 26px;
text-overflow: ellipsis;
white-space: nowrap
}
.chosen-container-single .chosen-single-with-deselect span {
margin-right: 38px
}
.chosen-container-single .chosen-single abbr {
position: absolute;
top: 6px;
right: 26px;
display: block;
width: 12px;
height: 12px;
background: url(../images/chosen-sprite.png) -42px 1px no-repeat;
font-size: 1px
}
.chosen-container-single .chosen-single abbr:hover,
.chosen-container-single.chosen-disabled .chosen-single abbr:hover {
background-position: -42px -10px
}
.chosen-container-single .chosen-single div {
position: absolute;
top: 0;
right: 0;
display: block;
width: 18px;
height: 100%
}
.chosen-container-single .chosen-single div b {
display: block;
width: 100%;
height: 100%;
background: url(../images/chosen-sprite.png) 0 2px no-repeat
}
.chosen-container-single .chosen-search {
position: relative;
z-index: 1010;
margin: 0;
padding: 3px 4px;
white-space: nowrap
}
.chosen-container-single .chosen-search input[type=text] {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
margin: 1px 0;
padding: 4px 20px 4px 5px;
width: 100%;
height: auto;
outline: 0;
border: 1px solid #aaa;
background: url(../images/chosen-sprite.png) 100% -20px no-repeat #fff;
background: url(../images/chosen-sprite.png) 100% -20px no-repeat, -webkit-gradient(linear, 50% 0, 50% 100%, color-stop(1%, #eee), color-stop(15%, #fff));
background: url(../images/chosen-sprite.png) 100% -20px no-repeat, -webkit-linear-gradient(#eee 1%, #fff 15%);
background: url(../images/chosen-sprite.png) 100% -20px no-repeat, -moz-linear-gradient(#eee 1%, #fff 15%);
background: url(../images/chosen-sprite.png) 100% -20px no-repeat, -o-linear-gradient(#eee 1%, #fff 15%);
background: url(../images/chosen-sprite.png) 100% -20px no-repeat, linear-gradient(#eee 1%, #fff 15%);
font-size: 1em;
font-family: sans-serif;
line-height: normal;
border-radius: 0
}
.chosen-container-single .chosen-drop {
margin-top: -1px;
border-radius: 0 0 4px 4px;
background-clip: padding-box
}
.chosen-container-single.chosen-container-single-nosearch .chosen-search {
position: absolute;
left: -9999px
}
.chosen-container .chosen-results {
position: relative;
overflow-x: hidden;
overflow-y: auto;
margin: 0 4px 4px 0;
padding: 0 0 0 4px;
max-height: 240px;
-webkit-overflow-scrolling: touch
}
.chosen-container .chosen-results li {
display: none;
margin: 0;
padding: 5px 6px;
list-style: none;
line-height: 15px
}
.chosen-container .chosen-results li.active-result {
display: list-item;
cursor: pointer
}
.chosen-container .chosen-results li.disabled-result {
display: list-item;
color: #ccc;
cursor: default
}
.chosen-container .chosen-results li.highlighted {
background-color: #3875d7;
background-image: -webkit-gradient(linear, 50% 0, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%);
background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%);
background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%);
background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
color: #fff
}
.chosen-container .chosen-results li.no-results {
display: list-item;
background: #f4f4f4
}
.chosen-container .chosen-results li.group-result {
display: list-item;
font-weight: 700;
cursor: default
}
.chosen-container .chosen-results li.group-option {
padding-left: 15px
}
.chosen-container .chosen-results li em {
font-style: normal;
text-decoration: underline
}
.chosen-container-multi .chosen-choices {
position: relative;
overflow: hidden;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
margin: 0;
padding: 0;
width: 100%;
height: auto!important;
height: 1%;
border: 1px solid #aaa;
background-color: #fff;
background-image: -webkit-gradient(linear, 50% 0, 50% 100%, color-stop(1%, #eee), color-stop(15%, #fff));
background-image: -webkit-linear-gradient(#eee 1%, #fff 15%);
background-image: -moz-linear-gradient(#eee 1%, #fff 15%);
background-image: -o-linear-gradient(#eee 1%, #fff 15%);
background-image: linear-gradient(#eee 1%, #fff 15%);
cursor: text
}
.chosen-container-multi .chosen-choices li {
float: left;
list-style: none
}
.chosen-container-multi .chosen-choices li.search-field {
margin: 0;
padding: 0;
white-space: nowrap
}
.chosen-container-multi .chosen-choices li.search-field input[type=text] {
margin: 1px 0;
padding: 5px;
height: 15px;
outline: 0;
border: 0!important;
background: 0 0!important;
box-shadow: none;
color: #666;
font-size: 100%;
font-family: sans-serif;
line-height: normal;
border-radius: 0
}
.chosen-container-multi .chosen-choices li.search-field .default {
color: #999
}
.chosen-container-multi .chosen-choices li.search-choice {
position: relative;
margin: 3px 0 3px 5px;
padding: 3px 20px 3px 5px;
border: 1px solid #aaa;
border-radius: 3px;
background-color: #e4e4e4;
background-image: -webkit-gradient(linear, 50% 0, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eee));
background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
background-clip: padding-box;
box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, .05);
color: #333;
line-height: 13px;
cursor: default
}
.chosen-container-multi .chosen-choices li.search-choice .search-choice-close {
position: absolute;
top: 4px;
right: 3px;
display: block;
width: 12px;
height: 12px;
background: url(../images/chosen-sprite.png) -42px 1px no-repeat;
font-size: 1px
}
.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover {
background-position: -42px -10px
}
.chosen-container-multi .chosen-choices li.search-choice-disabled {
padding-right: 5px;
border: 1px solid #ccc;
background-color: #e4e4e4;
background-image: -webkit-gradient(linear, 50% 0, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eee));
background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
color: #666
}
.chosen-container-multi .chosen-choices li.search-choice-focus {
background: #d4d4d4
}
.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close {
background-position: -42px -10px
}
.chosen-container-multi .chosen-results {
margin: 0;
padding: 0
}
.chosen-container-multi .chosen-drop .result-selected {
display: list-item;
color: #ccc;
cursor: default
}
.chosen-container-active .chosen-single {
border: 1px solid #5897fb;
box-shadow: 0 0 5px rgba(0, 0, 0, .3)
}
.chosen-container-active.chosen-with-drop .chosen-single {
border: 1px solid #aaa;
-moz-border-radius-bottomright: 0;
border-bottom-right-radius: 0;
-moz-border-radius-bottomleft: 0;
border-bottom-left-radius: 0;
background-image: -webkit-gradient(linear, 50% 0, 50% 100%, color-stop(20%, #eee), color-stop(80%, #fff));
background-image: -webkit-linear-gradient(#eee 20%, #fff 80%);
background-image: -moz-linear-gradient(#eee 20%, #fff 80%);
background-image: -o-linear-gradient(#eee 20%, #fff 80%);
background-image: linear-gradient(#eee 20%, #fff 80%);
box-shadow: 0 1px 0 #fff inset
}
.chosen-container-active.chosen-with-drop .chosen-single div {
border-left: none;
background: 0 0
}
.chosen-container-active.chosen-with-drop .chosen-single div b {
background-position: -18px 2px
}
.chosen-container-active .chosen-choices {
border: 1px solid #5897fb;
box-shadow: 0 0 5px rgba(0, 0, 0, .3)
}
.chosen-container-active .chosen-choices li.search-field input[type=text] {
color: #111!important
}
.chosen-disabled {
opacity: .5!important;
cursor: default
}
.chosen-disabled .chosen-choices .search-choice .search-choice-close,
.chosen-disabled .chosen-single {
cursor: default
}
.chosen-rtl {
text-align: right
}
.chosen-rtl .chosen-single {
overflow: visible;
padding: 0 8px 0 0
}
.chosen-rtl .chosen-single span {
margin-right: 0;
margin-left: 26px;
direction: rtl
}
.chosen-rtl .chosen-single-with-deselect span {
margin-left: 38px
}
.chosen-rtl .chosen-single div {
right: auto;
left: 3px
}
.chosen-rtl .chosen-single abbr {
right: auto;
left: 26px
}
.chosen-rtl .chosen-choices li {
float: right
}
.chosen-rtl .chosen-choices li.search-field input[type=text] {
direction: rtl
}
.chosen-rtl .chosen-choices li.search-choice {
margin: 3px 5px 3px 0;
padding: 3px 5px 3px 19px
}
.chosen-rtl .chosen-choices li.search-choice .search-choice-close {
right: auto;
left: 4px
}
.chosen-rtl .chosen-drop,
.chosen-rtl.chosen-container-single-nosearch .chosen-search {
left: 9999px
}
.chosen-rtl.chosen-container-single .chosen-results {
margin: 0 0 4px 4px;
padding: 0 4px 0 0
}
.chosen-rtl .chosen-results li.group-option {
padding-right: 15px;
padding-left: 0
}
.chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div {
border-right: none
}
.chosen-rtl .chosen-search input[type=text] {
padding: 4px 5px 4px 20px;
background: url(../images/chosen-sprite.png) -30px -20px no-repeat #fff;
background: url(../images/chosen-sprite.png) -30px -20px no-repeat, -webkit-gradient(linear, 50% 0, 50% 100%, color-stop(1%, #eee), color-stop(15%, #fff));
background: url(../images/chosen-sprite.png) -30px -20px no-repeat, -webkit-linear-gradient(#eee 1%, #fff 15%);
background: url(../images/chosen-sprite.png) -30px -20px no-repeat, -moz-linear-gradient(#eee 1%, #fff 15%);
background: url(../images/chosen-sprite.png) -30px -20px no-repeat, -o-linear-gradient(#eee 1%, #fff 15%);
background: url(../images/chosen-sprite.png) -30px -20px no-repeat, linear-gradient(#eee 1%, #fff 15%);
direction: rtl
}
.chosen-rtl.chosen-container-single .chosen-single div b {
background-position: 6px 2px
}
.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b {
background-position: -12px 2px
}
@media only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and (min-resolution: 144dpi) {
.chosen-container .chosen-results-scroll-down span,
.chosen-container .chosen-results-scroll-up span,
.chosen-container-multi .chosen-choices .search-choice .search-choice-close,
.chosen-container-single .chosen-search input[type=text],
.chosen-container-single .chosen-single abbr,
.chosen-container-single .chosen-single div b,
.chosen-rtl .chosen-search input[type=text] {
background-image: url(../images/chosen-sprite@2x.png)!important;
background-size: 52px 37px!important;
background-repeat: no-repeat!important
}
}
#cc_list_chosen .search-field input {
width: 100% !important;
}

File diff suppressed because one or more lines are too long

View File

@@ -1,30 +0,0 @@
.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }
.ui-timepicker-div dl { text-align: left; }
.ui-timepicker-div dl dt { float: left; clear:left; padding: 0 0 0 5px; }
.ui-timepicker-div dl dd { margin: 0 10px 10px 40%; }
.ui-timepicker-div td { font-size: 90%; }
.ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; }
.ui-timepicker-div .ui_tpicker_unit_hide{ display: none; }
.ui-timepicker-div .ui_tpicker_time .ui_tpicker_time_input { background: none; color: inherit; border: none; outline: none; border-bottom: solid 1px #555; width: 95%; }
.ui-timepicker-div .ui_tpicker_time .ui_tpicker_time_input:focus { border-bottom-color: #aaa; }
.ui-timepicker-rtl{ direction: rtl; }
.ui-timepicker-rtl dl { text-align: right; padding: 0 5px 0 0; }
.ui-timepicker-rtl dl dt{ float: right; clear: right; }
.ui-timepicker-rtl dl dd { margin: 0 40% 10px 10px; }
/* Shortened version style */
.ui-timepicker-div.ui-timepicker-oneLine { padding-right: 2px; }
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time,
.ui-timepicker-div.ui-timepicker-oneLine dt { display: none; }
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time_label { display: block; padding-top: 2px; }
.ui-timepicker-div.ui-timepicker-oneLine dl { text-align: right; }
.ui-timepicker-div.ui-timepicker-oneLine dl dd,
.ui-timepicker-div.ui-timepicker-oneLine dl dd > div { display:inline-block; margin:0; }
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_minute:before,
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_second:before { content:':'; display:inline-block; }
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_millisec:before,
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_microsec:before { content:'.'; display:inline-block; }
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide,
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide:before{ display: none; }

View File

@@ -1,6 +0,0 @@
/* phpcs:ignoreFile */
/*! jQuery Timepicker Addon - v1.6.3 - 2016-04-20
* http://trentrichardson.com/examples/timepicker
* Copyright (c) 2016 Trent Richardson; Licensed MIT */
.ui-timepicker-div .ui-widget-header{margin-bottom:8px}.ui-timepicker-div dl{text-align:left}.ui-timepicker-div dl dt{float:left;clear:left;padding:0 0 0 5px}.ui-timepicker-div dl dd{margin:0 10px 10px 40%}.ui-timepicker-div td{font-size:90%}.ui-tpicker-grid-label{background:0 0;border:0;margin:0;padding:0}.ui-timepicker-div .ui_tpicker_unit_hide{display:none}.ui-timepicker-div .ui_tpicker_time .ui_tpicker_time_input{background:0 0;color:inherit;border:0;outline:0;border-bottom:solid 1px #555;width:95%}.ui-timepicker-div .ui_tpicker_time .ui_tpicker_time_input:focus{border-bottom-color:#aaa}.ui-timepicker-rtl{direction:rtl}.ui-timepicker-rtl dl{text-align:right;padding:0 5px 0 0}.ui-timepicker-rtl dl dt{float:right;clear:right}.ui-timepicker-rtl dl dd{margin:0 40% 10px 10px}.ui-timepicker-div.ui-timepicker-oneLine{padding-right:2px}.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time,.ui-timepicker-div.ui-timepicker-oneLine dt{display:none}.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time_label{display:block;padding-top:2px}.ui-timepicker-div.ui-timepicker-oneLine dl{text-align:right}.ui-timepicker-div.ui-timepicker-oneLine dl dd,.ui-timepicker-div.ui-timepicker-oneLine dl dd>div{display:inline-block;margin:0}.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_minute:before,.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_second:before{content:':';display:inline-block}.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_millisec:before,.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_microsec:before{content:'.';display:inline-block}.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide,.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide:before{display:none}

File diff suppressed because one or more lines are too long

View File

@@ -1,437 +0,0 @@
/* Smart Coupons Style */
.coupon-container {
line-height: 1.4em;
position: relative;
display: inline-table;
margin: 2px;
padding: .55em;
cursor: pointer;
text-align: center;
box-shadow: 0 0 5px #e0e0e0;
}
.coupon-container.previews {
cursor: inherit;
}
.coupon-content {
padding: .2em 1.2em;
}
.coupon-content .code {
font-family: monospace;
font-size: 1.2em;
font-weight: 700;
}
.coupon-content .coupon-expire,
.coupon-content .discount-info {
font-family: Helvetica, Arial, sans-serif;
font-size: 1em;
}
.coupon-content .discount-description {
font: .7em/1 Helvetica, Arial, sans-serif;
display: inline-block;
margin: 10px inherit;
}
.wc-sc-coupon-style-preview .coupon-container {
display: inline-block;
}
span.wc-sc-coupon-preview-container {
position: absolute;
display: inline-block;
margin: 0 0 0 1em;
font-size: initial;
}
.wc_sc_custom_design_css_doc_div {
margin: 15px 0;
}
/*Shortcode fields*/
#coupon-selector #coupon-option label span {
display: inline-block;
width: 100px;
}
#coupon-selector #coupon-option label select {
width: 175px;
margin-bottom: 6px;
margin-left: -.2em;
}
div#sc_shortcode_update {
float: right;
margin-top: -5px;
}
form#sc_coupons_attributes {
padding: 0 1em 1em;
}
div#coupon-selector {
float: left;
padding: 1em 1em 1em 0;
border-right: 1px solid #e6e6e6;
}
.coupon-preview {
float: left;
width: 175px;
padding: 1em 0 1em 1em;
}
.preview-heading {
font-size: 15px;
padding-bottom: 10px;
text-align: center;
}
#search-panel {
overflow-x: hidden;
width: 275px;
min-height: 80px;
max-height: 110px;
margin: 5px 0;
color: #333;
border: 1px solid #d4d4d4;
background-color: #fff;
}
#coupon-option #search-panel #search-results span {
width: 100%;
margin-left: 10px;
}
#search-results ul {
margin: 5px -2px;
}
#search-results ul li {
font-size: 12px;
margin-bottom: -1px;
padding: 3px 15px;
cursor: pointer;
border: 1px solid #f2f2f2;
}
#search-results ul li:hover {
color: #000;
background-color: #eaf2fa;
}
#coupon-option #search-panel #search-results ul li span {
width: 0;
color: #f00;
}
#sc_coupons_attributes .submitbox {
clear: both;
}
#default-text {
font-style: italic;
margin-bottom: -5px;
padding: 2px;
text-align: center;
background-color: #f2f2f2;
}
/* Gift Cerificate form */
input.gift_receiver_email, input.gift_sending_date_time {
min-width: 100%;
margin: 1% 0;
}
div#gift-certificate-receiver-form thead th {
text-align: center;
}
input#deliver_on_date {
text-align: center;
}
.email_sending_date_time_wrapper:not(.show),
.wc_sc_schedule_gift_sending_wrapper:not(.show) {
display: none;
}
.wc_sc_schedule_gift_sending_wrapper.show {
margin-left: 2em;
}
/* Coupon generation form */
form#generate_coupons p.form-field input[type=text] {
width: 30%;
}
form#generate_coupons p.form-field input[type=number] {
width: 15%;
}
form#generate_coupons p.form-field input[name="wc_sc_max_discount"] {
width: 30%;
}
div.gift-certificate-receiver-detail-form,
div#gift-certificate-receiver-form-multi {
display: none;
}
a#single_multi {
float: right;
}
.sc_info_box {
overflow: hidden;
margin-bottom: 2em !important;
padding: .5em 1em 0 !important;
background-color: #f7f6f7;
}
tr.wc_sc_custom_design_css_wrapper .CodeMirror + span.wc-sc-coupon-preview-container {
top: 15px;
}
tr.wc_sc_custom_design_css_wrapper td.forminp.forminp-textarea {
position: relative;
}
tr.wc_sc_custom_design_css_wrapper .CodeMirror {
width: 100%;
max-width: 400px;
height: 200px;
}
.sc-coupons-list details > summary {
list-style: none;
}
.sc-coupons-list details > summary::marker, /* Latest Chrome, Edge, Firefox */
.sc-coupons-list details > summary::-webkit-details-marker /* Safari */ {
display: none;
}
@media (min-width: 768px) {
.sc_info_box {
float: unset !important;
width: unset !important;
margin-right: unset !important;
padding: .5em 1em 0 !important;
}
.page-template-template-fullwidth-php .sc_info_box {
float: unset !important;
width: unset !important;
margin-right: unset !important;
margin-left: unset !important;
padding: .5em 1em 0 !important;
}
/* Fix for positioning 'Sell store credit at less price?' settings' tooltip */
label[for="smart_coupons_sell_store_credit_at_less_price"] span.woocommerce-help-tip,
label[for="smart_coupons_schedule_store_credit"] span.woocommerce-help-tip {
float: left;
margin: 1px 4px 1px -1.7em !important;
}
tr.wc_sc_custom_design_css_wrapper .CodeMirror + span.wc-sc-coupon-preview-container {
left: 415px;
}
}
textarea.gift_receiver_message {
width: 100%;
}
.form_table {
width: 97%;
padding: 20px 10px;
border-top: 2px;
border-top-style: solid;
border-top-color: #dbdbdb;
}
.message_row {
width: 100%;
}
.sc_message {
width: 100%;
}
.email_amount {
width: 100%;
}
.gift-certificate-show-form p {
margin: 0;
}
.gift-certificate-show-form lable {
display: inline;
}
.gift-certificate-show-form input[type=radio] {
margin-left: 1em;
}
.show_hide_list {
padding-left: 0;
margin-left: 25px;
}
.single_multi_list {
display: none;
}
div.mce-smart-coupon-shortcode {
cursor: pointer;
}
div.mce-smart-coupon-shortcode i:before {
font-family: 'WooCommerce';
content: '\e600';
}
div[aria-describedby='sc_coupons_attributes'] {
z-index: 1000;
}
.wc_sc_total_available_store_credit {
padding: 1em 0;
text-align: right;
}
.wc_sc_total_available_store_credit .amount {
font-size: 1.5em;
font-weight: bold;
}
div#invalid_coupons_list div#all_coupon_container .coupon-container {
cursor: initial !important;
opacity: .5;
}
div#invalid_coupons_list div#all_coupon_container .coupon-container .coupon-content .coupon-expire {
display: none;
}
.variation-sc_called_credit {
display: none;
}
/* Bulk Generate tab - Coupon Description */
.sc_bulk_description textarea#woocommerce-coupon-description {
width: 90%;
margin-left: 0.5em;
}
#call_for_credit {
position: relative;
}
input#credit_called {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.wc-sc-call-for-credit-container .wc-sc-label,
.wc-sc-call-for-credit-container .wc-sc-input {
width: 48%;
float: left;
}
.wc-sc-call-for-credit-container .wc-sc-row {
position: relative;
margin-top: 1em;
}
.wc-sc-call-for-credit-container .wc-sc-row:after {
content: "";
display: table;
clear: both;
}
.wc-sc-description {
display: inline-block;
}
#sc-cc input {
border: 1px solid #7e8993;
}
#sc-cc .sc-truncate {
overflow: hidden;
text-overflow: ellipsis;
height: 2rem;
}
.forminp-wc_sc_radio_with_html {
border-collapse: initial;
}
.forminp-wc_sc_radio_with_html .wc_sc_setting_coupon_design li {
padding: 10px 10px 5px 5px;
}
.forminp-wc_sc_radio_with_html .wc_sc_setting_coupon_design li input,
.forminp-wc_sc_radio_with_html .wc_sc_setting_coupon_design_colors li input {
vertical-align: top;
}
.forminp-wc_sc_radio_with_html .wc_sc_setting_coupon_design_colors.custom li input[type="color"] {
opacity: 0;
display: block;
width: 32px;
height: 20px;
border: none;
cursor: pointer;
}
.forminp-wc_sc_radio_with_html .wc_sc_setting_coupon_design_colors li span {
display: inline-block;
width: 32px;
height: 20px;
vertical-align: middle;
}
.forminp-wc_sc_radio_with_html .wc_sc_setting_coupon_design,
.forminp-wc_sc_radio_with_html .wc_sc_setting_coupon_design_colors {
margin-top: unset;
}
.forminp-wc_sc_radio_with_html .wc_sc_setting_coupon_design li,
.forminp-wc_sc_radio_with_html .wc_sc_setting_coupon_design_colors li {
cursor: pointer;
}
.forminp-wc_sc_radio_with_html .wc_sc_setting_coupon_design_colors li {
display: inline-block;
width: 150px;
padding: 5px;
}
.forminp-wc_sc_radio_with_html ul li:hover,
.forminp-wc_sc_radio_with_html ul li.selected {
background: #ddd;
}
.forminp-wc_sc_radio_with_html .wc_sc_setting_coupon_design {
align-items: unset !important;
}
@media screen and (max-width: 767px) {
.wc-sc-description {
margin-left: 0;
}
tr.wc_sc_custom_design_css_wrapper .CodeMirror + span.wc-sc-coupon-preview-container {
position: static;
margin-top: 15px;
}
}
@media screen and (min-width: 768px) and (max-width: 799px) {
.wc-sc-description {
margin-left: 5%;
}
}
@media screen and (min-width: 800px) and (max-width: 1023px) {
.wc-sc-description {
margin-left: 7%;
}
}
@media screen and (min-width: 1024px) and (max-width: 1199px) {
.wc-sc-description {
margin-left: 11%;
}
}
@media screen and (min-width: 1200px) and (max-width: 1279px) {
.wc-sc-description {
margin-left: 14%;
}
}
@media screen and (min-width: 1280px) and (max-width: 1365px) {
.wc-sc-description {
margin-left: 15%;
}
}
@media screen and (min-width: 1366px) and (max-width: 1599px) {
.wc-sc-description {
margin-left: 16%;
}
}
@media screen and (min-width: 1600px) {
.wc-sc-description {
margin-left: 20%;
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,42 +0,0 @@
/* Smart Coupons Admin CSS */
.smart-coupons-field,
#sc-share-link,
#sc_coupon_categorydiv,
#sc_coupon_categorydiv ul.category-tabs li.tabs,
#sc_coupon_categorydiv ul.add-menu-item-tabs li.tabs,
#sc_coupon_categorydiv .wp-tab-active,
#sc_coupon_categorydiv div.tabs-panel,
button#export_coupons,
a#wc_sc_print_coupons,
a#sc-manage-category,
#wc-sc-copy-coupon-code {
background-color: #f0fff0;
}
button#export_coupons > span.dashicons,
a#wc_sc_print_coupons > span.dashicons,
a#sc-manage-category > span.dashicons {
transform: translateX(-15%) translateY(15%);
}
div#smart_coupons_tabs h2 {
margin-bottom: 10px;
}
div#smart_coupons_tabs h2 .sc-quick-links {
text-align: right;
font-size: 0.8em;
}
.coupon_title_prefix_suffix_field input {
height: 2em;
}
li.wc_sc_actions_tab a::before {
font-family: WooCommerce !important;
content: '\e01c' !important;
}
div.sc-manage-category {
margin: 10px 0;
}
div.sc-manage-category a {
font-weight: 600;
}
div.smart_coupons_product_options_variable {
display: flow-root;
}

View File

@@ -1,2 +0,0 @@
/* phpcs:ignoreFile */
.smart-coupons-field,#sc-share-link,#sc_coupon_categorydiv,#sc_coupon_categorydiv ul.category-tabs li.tabs,#sc_coupon_categorydiv ul.add-menu-item-tabs li.tabs,#sc_coupon_categorydiv .wp-tab-active,#sc_coupon_categorydiv div.tabs-panel,button#export_coupons,a#wc_sc_print_coupons,a#sc-manage-category,#wc-sc-copy-coupon-code{background-color:#f0fff0}button#export_coupons>span.dashicons,a#wc_sc_print_coupons>span.dashicons,a#sc-manage-category>span.dashicons{transform:translateX(-15%) translateY(15%)}div#smart_coupons_tabs h2{margin-bottom:10px}div#smart_coupons_tabs h2 .sc-quick-links{text-align:right;font-size:.8em}.coupon_title_prefix_suffix_field input{height:2em}li.wc_sc_actions_tab a::before{font-family:WooCommerce!important;content:'\e01c'!important}div.sc-manage-category{margin:10px 0}div.sc-manage-category a{font-weight:600}div.smart_coupons_product_options_variable{display:flow-root}

View File

@@ -1,22 +0,0 @@
/* Coupon style for email-coupon */
.coupon-container.email-coupon .coupon-content {
border: 1px solid !important;
border-style: dashed !important;
}
.coupon-container.email-coupon {
transition-duration: .3s !important;
transition-property: border-radius !important;
-webkit-transform: perspective(1px) translateZ(0) !important;
transform: perspective(1px) translateZ(0) !important;
border-radius: .8em !important;
box-shadow: 0 0 1px rgba(0, 0, 0, 0) !important;
display: table;
margin: 0 auto;
}
.coupon-container.email-coupon:hover,
.coupon-container.email-coupon:focus,
.coupon-container.email-coupon:active {
border-radius: 0 !important;
}

View File

@@ -1,2 +0,0 @@
/* phpcs:ignoreFile */
.coupon-container.email-coupon .coupon-content{border:1px solid !important;border-style:dashed !important}.coupon-container.email-coupon{transition-duration:.3s !important;transition-property:border-radius !important;-webkit-transform:perspective(1px) translateZ(0) !important;transform:perspective(1px) translateZ(0) !important;border-radius:.8em !important;box-shadow:0 0 1px rgba(0,0,0,0) !important;display:table;margin:0 auto}.coupon-container.email-coupon:hover,.coupon-container.email-coupon:focus,.coupon-container.email-coupon:active{border-radius:0 !important}

View File

@@ -1 +0,0 @@
<svg enable-background="new 0 0 64 64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg"><path d="m51.9 23.4c.3 1-.2 2.1-1.2 2.5l-19 6.2h-11.9l-2.6-8h24.8c1.1 0 2-.9 2-2v-7h3c-.1 2.1 1.4 3.8 3.5 4z" fill="#e9edf5"/><path d="m41 11c-.5 0-1 .2-1.4.6-.1.1-.2.2-.2.3-.8-.3-1.3-1-1.3-1.9h-22.1c0 1.1-.9 2-2 2v6c1.1 0 2 .9 2 2h22c0-1.1.9-2 2-2v-3.3c.3.2.6.3 1 .3h3v7c0 1.1-.9 2-2 2h-30c-1.1 0-2-.9-2-2v-14c0-1.1.9-2 2-2h30c1.1 0 2 .9 2 2v3z" fill="#7e8596"/><path d="m40 14.7v3.3c-1.1 0-2 .9-2 2h-22c0-1.1-.9-2-2-2v-6c1.1 0 2-.9 2-2h22c0 .8.5 1.6 1.3 1.9-.2.3-.3.7-.3 1.1 0 .7.4 1.4 1 1.7z" fill="#f2f6fc"/><path d="m16 18v-6c1.1 0 2-.9 2-2h-2c0 1.1-.9 2-2 2v6c1.1 0 2 .9 2 2h2c0-1.1-.9-2-2-2z" fill="#dce1eb"/><path d="m44 11v-3c0-1.1-.9-2-2-2h-10l9-5 18 3h4v11h-4s0 4-4 4h-4c-.2 0-.4 0-.5 0-2-.2-3.6-1.9-3.5-3.9h-6c-1.1 0-2-.9-2-2 0-.4.1-.8.3-1.1.1-.1.2-.2.2-.3.5-.5 1-.7 1.5-.7z" fill="#ffcdbe"/><path d="m41 1-9 5h3l8.3-4.6z" fill="#ffbeaa"/><path d="m47 8c0-1.1-.9-2-2-2h-3c1.1 0 2 .9 2 2v3h3zm-5 5c0-.4.1-.8.3-1.1.1-.1.2-.2.2-.3.5-.4 1-.6 1.5-.6h-3c-.5 0-1 .2-1.4.6-.1.1-.2.2-.2.3-.3.3-.4.7-.4 1.1 0 1.1.9 2 2 2h3c-1.1 0-2-.9-2-2zm8 2h-3c-.1 2.1 1.4 3.8 3.5 4h.5 3c-.2 0-.4 0-.5 0-2.1-.2-3.6-2-3.5-4z" fill="#ffbeaa"/><path d="m23.7 42c.2.3.3.6.3 1 0 .7-.3 1.4-.9 1.7l-16.5 12.1-2.5 1.9c-1 .6-2.2.3-2.8-.7-.2-.3-.3-.6-.3-1 0-.7.3-1.4.9-1.7l3.8-2.8 15.3-11.2c.3-.2.6-.3 1-.3.7 0 1.3.4 1.7 1zm27.3 15c0 .4-.1.7-.3 1.1-.6.9-1.8 1.2-2.8.6l-2.5-1.9-16.5-12.1c-.6-.4-1-1-.9-1.7 0-.4.1-.7.3-1 .4-.6 1-1 1.7-1 .4 0 .7.1 1.1.3l15.2 11.1 3.8 2.8c.6.4.9 1.1.9 1.8z" fill="#7e8596"/><path d="m3.3 58c-.2-.3-.3-.6-.3-1 0-.7.3-1.4.9-1.7l3.8-2.8 15.3-11.2h.1c-.4-.2-.7-.3-1.1-.3s-.7.1-1.1.3l-15.1 11.2-3.8 2.8c-.6.4-1 1-.9 1.7 0 .4.1.7.3 1.1.5.9 1.7 1.2 2.6.6-.3-.1-.5-.4-.7-.7zm46.7.7-2.5-1.9-16.6-12.1c-.6-.4-1-1-.9-1.7 0-.4.1-.7.3-1s.4-.5.7-.7c-.9-.5-2.1-.2-2.7.7-.2.3-.3.6-.3 1 0 .7.3 1.4.9 1.7l16.5 12.1 2.6 1.9c.6.4 1.4.4 2 0z" fill="#636978"/><path d="m21 53h10c1.1 0 2 .9 2 2v2c0 1.1-.9 2-2 2h-10c-1.1 0-2-.9-2-2v-2c0-1.1.9-2 2-2z" fill="#ff808c"/><path d="m22 57v-2c0-1.1.9-2 2-2h-3c-1.1 0-2 .9-2 2v2c0 1.1.9 2 2 2h3c-1.1 0-2-.9-2-2z" fill="#f25a6b"/><path d="m51 34v2c0 1.1-.9 2-2 2h-46c-1.1 0-2-.9-2-2v-2c0-1.1.9-2 2-2h46c1.1 0 2 .9 2 2z" fill="#ff808c"/><path d="m4 36v-2c0-1.1.9-2 2-2h-3c-1.1 0-2 .9-2 2v2c0 1.1.9 2 2 2h3c-1.1 0-2-.9-2-2z" fill="#f25a6b"/><path d="m30 41c.4 0 .7.1 1.1.3l15.2 11.1 2.7-14.4h-46l2.8 14.5 15.2-11.2c.3-.2.6-.3 1-.3.7 0 1.3.4 1.7 1 .2.3.3.6.3 1 0 .7-.3 1.4-.9 1.7l-16.5 12.1.4 2.2c0 2.2 1.8 4 4 4h30c2.2 0 4-1.8 4-4l.4-2.2-16.5-12.1c-.6-.4-1-1-.9-1.7 0-.4.1-.7.3-1 .4-.6 1-1 1.7-1zm1 12c1.1 0 2 .9 2 2v2c0 1.1-.9 2-2 2h-10c-1.1 0-2-.9-2-2v-2c0-1.1.9-2 2-2z" fill="#e9edf5"/><path d="m6 38h-3l2.8 14.5 2.6-1.9z" fill="#cdd2e1"/><path d="m6.6 56.8.4 2.2c0 2.2 1.8 4 4 4h3c-2.2 0-4-1.8-4-4l-.8-4.1z" fill="#cdd2e1"/><g fill="none" stroke="#404040" stroke-linejoin="round"><path d="m42 38h-2"/><path d="m38 38h-35c-1.1 0-2-.9-2-2v-2c0-1.1.9-2 2-2h46c1.1 0 2 .9 2 2v2c0 1.1-.9 2-2 2h-5"/><path d="m6.6 56.8.4 2.2c0 2.2 1.8 4 4 4h30c2.2 0 4-1.8 4-4l.4-2.2"/><path d="m49 38-2.8 14.5"/><path d="m5.8 52.5-2.8-14.5"/><path d="m22 41c.7 0 1.3.4 1.7 1 .2.3.3.6.3 1 0 .7-.3 1.4-.9 1.7l-16.5 12.1-2.5 1.9c-1 .6-2.2.3-2.8-.7-.2-.3-.3-.6-.3-1 0-.7.3-1.4.9-1.7l3.8-2.8 15.3-11.2c.3-.2.6-.3 1-.3zm8 0c-.7 0-1.3.4-1.7 1-.2.3-.3.6-.3 1 0 .7.3 1.4.9 1.7l16.5 12.1 2.6 1.9c.9.6 2.2.3 2.8-.6.2-.3.3-.7.2-1 0-.7-.3-1.4-.9-1.7l-3.8-2.8-15.3-11.3c-.3-.2-.6-.3-1-.3z"/><path d="m21 53h10c1.1 0 2 .9 2 2v2c0 1.1-.9 2-2 2h-10c-1.1 0-2-.9-2-2v-2c0-1.1.9-2 2-2z"/><path d="m63 15h-4s0 4-4 4h-4c-.2 0-.4 0-.5 0-2-.2-3.6-1.9-3.5-3.9h-6c-1.1 0-2-.9-2-2 0-.4.1-.8.3-1.1.1-.1.2-.2.2-.3.5-.5 1-.7 1.5-.7h6"/><path d="m32 6 9-5 18 3h4"/><path d="m44 15v7c0 1.1-.9 2-2 2h-30c-1.1 0-2-.9-2-2v-14c0-1.1.9-2 2-2h30c1.1 0 2 .9 2 2v3"/><path d="m55 31 4-4"/><path d="m59 43-4-4"/><path d="m55 35h7"/><path d="m40 14.7v3.3c-1.1 0-2 .9-2 2h-22c0-1.1-.9-2-2-2v-6c1.1 0 2-.9 2-2h22c0 .8.5 1.6 1.3 1.9"/><path d="m19.8 32-2.6-8"/><path d="m50.5 19 1.4 4.4c.3 1-.2 2.1-1.2 2.5l-19 6.1"/></g></svg>

Before

Width:  |  Height:  |  Size: 4.0 KiB

View File

@@ -1 +0,0 @@
<svg enable-background="new 0 0 64 64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg"><path d="m45 38h-30c-.6 0-1-.4-1-1s.4-1 1-1h30c.6 0 1 .4 1 1s-.4 1-1 1zm1-5h-35c-.6 0-1-.4-1-1s.4-1 1-1h35c.6 0 1 .4 1 1s-.4 1-1 1zm2-5h-40c-.6 0-1-.4-1-1s.4-1 1-1h40c.6 0 1 .4 1 1s-.4 1-1 1z" fill="#f7b957"/><path d="m63 12h-8.5c-1.3 0-2.4.8-2.8 2.1l-2 5.9h-46.7c-1.7 0-3 1.3-3 3v.6c0 .4.1.7.2 1l6.4 17.2c.4 1.4 1.6 2.2 2.9 2.2h32.3l-.7 2.1c-.4 1.2-1.6 1.9-2.8 1.9h-28.3c-1.7 0-3 1.3-3 3v5c0 .6.4 1 1 1s1-.4 1-1v-5c0-.6.4-1 1-1h22.2c-.1.3-.2.7-.2 1v5c0 .6.4 1 1 1s1-.4 1-1v-5c0-.6.4-1 1-1h3.3c2.1 0 3.9-1.3 4.7-3.2l10.6-32.1c.1-.4.6-.7 1-.7h8.4c.6 0 1-.4 1-1s-.4-1-1-1zm-20.6 30h-32.9c-.5 0-.9-.3-1-.7l-6.4-17.3c-.1-.1-.1-.2-.1-.4v-.6c0-.6.4-1 1-1h46z" fill="#f7b957"/><circle cx="11" cy="56" fill="#a8b7d4" r="3"/><circle cx="36" cy="56" fill="#a8b7d4" r="3"/><path d="m11 60c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4-1.8 4-4 4zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm25 6c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4-1.8 4-4 4zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" fill="#404040"/><path d="m39.1 21c.7-.6 1.9-1.2 1.9-2 0-1-2.2-1.8-2.4-2.7s1.4-2.6 1-3.5-2.7-.6-3.3-1.4.2-3-.6-3.6-2.6.6-3.5.2-1.1-2.8-2.1-3-2.1 1.8-3.1 1.8-2.2-2-3.1-1.8-1.2 2.5-2 3-2.9-.8-3.6-.2 0 2.8-.6 3.6-2.9.5-3.3 1.4 1.2 2.5 1 3.5-2.4 1.7-2.4 2.7c0 .8 1.2 1.4 1.9 2 .2.2.4.4.5.7.2 1-1.4 2.6-1 3.5s2.7.6 3.3 1.4-.2 3 .6 3.6 2.7-.6 3.5-.2 1.1 2.8 2.1 3 2.1-1.8 3.1-1.8 2.2 2 3.1 1.8 1.2-2.5 2-3c.9-.5 2.8.8 3.6.2s0-2.8.6-3.6 2.9-.5 3.3-1.4-1.2-2.5-1-3.5c.1-.3.3-.5.5-.7z" fill="#d23b54"/><path d="m37.4 20.7c.6-.5 1.6-1.1 1.6-1.7 0-.9-1.8-1.5-2-2.3s1.2-2.2.8-3-2.3-.5-2.8-1.2.1-2.6-.5-3.1-2.3.6-3 .2-1-2.4-1.8-2.6-1.8 1.5-2.7 1.5-1.9-1.7-2.7-1.5-1 2.2-1.8 2.6-2.4-.7-3-.2 0 2.4-.5 3.1-2.5.4-2.8 1.2 1 2.2.9 3-2 1.5-2 2.3c0 .6 1 1.2 1.6 1.7.2.2.4.4.4.6.2.8-1.2 2.2-.9 3s2.3.5 2.8 1.2-.1 2.5.5 3.1 2.3-.5 3-.2 1 2.4 1.8 2.5 1.8-1.5 2.7-1.5 1.9 1.7 2.7 1.5 1-2.2 1.8-2.5 2.4.7 3 .2 0-2.4.5-3.1 2.5-.4 2.8-1.2-1-2.2-.8-3c0-.2.2-.4.4-.6z" fill="#d23b54"/><path d="m21 26c-.3 0-.5-.1-.7-.3-.4-.4-.4-1 0-1.4l12-12c.4-.4 1-.4 1.4 0s.4 1 0 1.4l-12 12c-.2.2-.4.3-.7.3zm9 1c-1.7 0-3-1.3-3-3s1.3-3 3-3 3 1.3 3 3-1.3 3-3 3zm0-4c-.6 0-1 .4-1 1s.4 1 1 1 1-.4 1-1-.4-1-1-1zm-6-6c-1.7 0-3-1.3-3-3s1.3-3 3-3 3 1.3 3 3-1.3 3-3 3zm0-4c-.6 0-1 .4-1 1s.4 1 1 1 1-.4 1-1-.4-1-1-1z" fill="#fbfbfb"/></svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 592 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 871 B

View File

@@ -1 +0,0 @@
<svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg"><path d="m31 13h-4a1 1 0 0 1 0-2h4a1 1 0 0 1 0 2z" fill="#919191"/><path d="m15 34a6 6 0 1 1 -9.12-5.12 6 6 0 0 1 9.12 5.12z" fill="#374f68"/><path d="m14.12 37.12c-5.3 3.26-11.53-2.9-8.24-8.24 5.32-3.28 11.51 2.93 8.24 8.24z" fill="#425b72"/><path d="m11 34a2 2 0 1 1 -2.82-1.82 2 2 0 0 1 2.82 1.82z" fill="#dad7e5"/><path d="m10.82 34.82a2 2 0 0 1 -2.64-2.64 2 2 0 0 1 2.64 2.64z" fill="#edebf2"/><path d="m47 34a6 6 0 1 1 -9.12-5.12 6 6 0 0 1 9.12 5.12z" fill="#374f68"/><path d="m46.12 37.12c-5.3 3.26-11.53-2.9-8.24-8.24 5.32-3.28 11.51 2.93 8.24 8.24z" fill="#425b72"/><path d="m43 34a2 2 0 1 1 -2.82-1.82 2 2 0 0 1 2.82 1.82z" fill="#dad7e5"/><path d="m42.82 34.82a2 2 0 0 1 -2.64-2.64 2 2 0 0 1 2.64 2.64z" fill="#edebf2"/><path d="m47 30.5c-1.16.67-.17.5-5.2.5-3.07 0-2.53 3-5.6 3h-2.26c0-7.16 9.54-9.67 13.06-3.5z" fill="#ffba55"/><path d="m45.84 29c-2.09 0-3.58-.28-4.9 1.58a3.37 3.37 0 0 1 -2.74 1.42 1.88 1.88 0 0 1 -1.79-2.52 6.83 6.83 0 0 1 .67-1.32 7 7 0 0 1 8.76.84z" fill="#fc6"/><path d="m22.4 21.4c-.83.81-1.14.6-7.4.6v-4.5l6.07.38a2.07 2.07 0 0 1 1.33 3.52z" fill="#7c7d7d"/><path d="m23 20h-3.63a2.37 2.37 0 0 1 -2.37-2.37l4.07.25a2.07 2.07 0 0 1 1.93 2.12z" fill="#919191"/><path d="m38 9v4a1 1 0 0 1 -1 1h-5a1 1 0 0 1 -1-1 5 5 0 0 1 2.61-4.39 6 6 0 0 1 3.39-.61 1 1 0 0 1 1 1z" fill="#ffba55"/><path d="m38 9v3h-4c-1.46 0-1.06-2.16-.39-3.39a6 6 0 0 1 3.39-.61 1 1 0 0 1 1 1z" fill="#fc6"/><path d="m40.21 27a7 7 0 0 0 -6.27 7h-14.94a4.39 4.39 0 0 0 -4.16-3h-12.72a1 1 0 0 1 -1-1.11l.39-3.44a5 5 0 0 1 5-4.45h14.49l2 8h8a15.06 15.06 0 0 0 1.51-14.86l-.51-1.14h4c2.19 4.37 4 7.44 4.21 13z" fill="#fc6"/><path d="m40.21 27a7 7 0 0 0 -6 5h-13.21a4.39 4.39 0 0 0 -4.16-3h-12.72a1 1 0 0 1 -1-1.11c.37-3.3.34-4.11 1-5.28 1.47-.83.88-.61 16.88-.61l2 8h8a15.09 15.09 0 0 0 1.51-14.86l-.51-1.14h4c2.11 4.22 4.1 7.59 4.21 13z" fill="#ffde76"/><path d="m42 11a2.35 2.35 0 0 1 -2.34 2.34 6.42 6.42 0 0 1 -1.66-.34v-4l1-.25a2.35 2.35 0 0 1 3 2.25z" fill="#9fdbf3"/><path d="m41.74 12.07c-1 .5-1.67.19-2.74-.07 0-3.61 0-3.24.09-3.27a2.34 2.34 0 0 1 2.65 3.34z" fill="#b2e5fb"/><path d="m11 28h-4a1 1 0 0 1 0-2h4a1 1 0 0 1 0 2z" fill="#ffba55"/><path d="m1 10h14v12h-14z" fill="#df8761"/><path d="m15 10v10h-9a3 3 0 0 1 -3-3v-7z" fill="#f29b75"/><path d="m10 10v5l-2-1-2 1v-5z" fill="#fc6"/><path d="m10 10v3a3 3 0 0 1 -3-3z" fill="#ffde76"/></svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -1 +0,0 @@
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><style>.st0{fill:#ffd180}.st1{fill:#bf3f49}.st2{fill:#d23b54}.st3{fill:#f7b957}.st4{fill:#edf4fa}.st5{fill:#2b2b37}.st6{fill:#b9c6de}.st7{fill:#d6e0eb}.st8{fill:#5c6979}.st9{fill:#393d48}</style><path class="st0" d="M63 7.2v33.5c0 1.2-.9 2.2-2.1 2.2H23V5h37.9C62.1 5 63 6 63 7.2z"/><path class="st1" d="M23 5v38H3c-1.1 0-2-.9-2-2V7c0-1.1.9-2 2-2h20z"/><path class="st2" d="M5 5H3c-1.1 0-2 .9-2 2v34c0 1.1.9 2 2 2h20V27.4C11.9 21.8 5 13.8 5 5z"/><path class="st3" d="M49.6 35.2c-.8-.1-1.7-.2-2.5-.4-.3 0-.7-.1-1-.2-3.6-.6-7.1-1.4-10.5-2.3-4.3-1.2-8.5-2.8-12.5-4.9V43H61c1.2 0 2.1-1 2.1-2.2V36c-4.6 0-9.1-.3-13.5-.8z"/><path class="st2" d="M56 24c0-1.1-2-1.9-2.3-2.9s1.1-2.7.6-3.6-2.7-.6-3.4-1.3c-.8-.7-.4-2.9-1.3-3.4s-2.6.8-3.6.6-1.9-2.4-3-2.4-1.9 2-2.9 2.3-2.7-1.1-3.6-.6-.6 2.7-1.3 3.4c-.7.8-2.9.4-3.4 1.3s.8 2.6.6 3.6-2.4 1.9-2.4 3 2 1.9 2.3 2.9-1.1 2.7-.6 3.6c.5.9 2.7.6 3.4 1.3.7.7.4 2.9 1.3 3.4s2.6-.8 3.6-.5 1.9 2.3 3 2.3 1.9-2 2.9-2.3 2.7 1.1 3.6.6.6-2.7 1.3-3.4 2.9-.4 3.4-1.3-.8-2.6-.5-3.6 2.3-1.9 2.3-3z"/><path class="st1" d="M54 24c0-.9-1.7-1.6-1.9-2.4s.9-2.3.5-3.1-2.3-.5-2.9-1.1-.4-2.4-1.1-2.9-2.2.7-3.1.5-1.6-2-2.5-2-1.6 1.7-2.4 1.9-2.3-.9-3.1-.5-.5 2.3-1.1 2.9-2.5.4-2.9 1.1.7 2.2.5 3.1-2 1.6-2 2.5 1.7 1.6 1.9 2.4-.9 2.3-.5 3.1 2.3.5 2.9 1.1.4 2.4 1.1 2.9 2.2-.7 3.1-.5 1.6 2 2.5 2 1.6-1.7 2.4-1.9 2.3.9 3.1.5.5-2.3 1.1-2.9 2.5-.4 2.9-1.1-.7-2.2-.5-3.1 2-1.6 2-2.5z"/><path class="st4" d="M13.5 23h-3C9.1 23 8 21.9 8 20.5S9.1 18 10.5 18H15c.6 0 1-.4 1-1s-.4-1-1-1h-2v-1c0-.6-.4-1-1-1s-1 .4-1 1v1h-.5C8 16 6 18 6 20.5S8 25 10.5 25h3c1.4 0 2.5 1.1 2.5 2.5S14.9 30 13.5 30H9c-.6 0-1 .4-1 1s.4 1 1 1h2v1c0 .6.4 1 1 1s1-.4 1-1v-1h.5c2.5 0 4.5-2 4.5-4.5S16 23 13.5 23zm36.2-5.7c-.4-.4-1-.4-1.4 0l-12 12c-.4.4-.4 1 0 1.4.4.4 1 .4 1.4 0l12-12c.4-.4.4-1 0-1.4zM46 26c-1.7 0-3 1.3-3 3s1.3 3 3 3 3-1.3 3-3-1.3-3-3-3zm0 4c-.6 0-1-.4-1-1s.4-1 1-1 1 .4 1 1-.4 1-1 1zm-6-8c1.7 0 3-1.3 3-3s-1.3-3-3-3-3 1.3-3 3 1.3 3 3 3zm0-4c.6 0 1 .4 1 1s-.4 1-1 1-1-.4-1-1 .4-1 1-1z"/><path class="st5" d="M22.3 5h1.4v4h-1.4V5zm0 6h1.4v4h-1.4v-4zm0 6h1.4v4h-1.4v-4zm0 6h1.4v4h-1.4v-4zm0 6h1.4v4h-1.4v-4zm0 6h1.4v4h-1.4v-4zm0 6h1.4v2h-1.4v-2z"/><path class="st6" d="M26.7 43l-1.6 3.4-1.8-3.4h3.4zm-5.4 4.2l1.7 3.6-2 4.2c0-1.4-.7-2.6-1.8-3.4l2.1-4.4z"/><path class="st4" d="M23.3 43l1.8 3.4 2.5 4.8C26 51.8 25 53.3 25 55l-2-4.2-1.7-3.6L16 36l2-3 5.3 10z"/><path class="st7" d="M25.9 49c-.4.4-1.1.3-1.4-.1 0-.1-.1-.1-.1-.2l-7.2-14.4L16 36l5.3 11.2 1.7 3.6 2 4.2c0-1.7 1-3.2 2.6-3.7l-1.3-2.5c-.2 0-.3.1-.4.2z"/><path class="st8" d="M29 60c-2.8 0-5-2.2-5-5s2.2-5 5-5 5 2.2 5 5-2.2 5-5 5zm0-8c-1.7 0-3 1.3-3 3s1.3 3 3 3 3-1.3 3-3-1.3-3-3-3z"/><path class="st9" d="M17 60c-2.8 0-5-2.2-5-5s2.2-5 5-5 5 2.2 5 5-2.2 5-5 5zm0-8c-1.7 0-3 1.3-3 3s1.3 3 3 3 3-1.3 3-3-1.3-3-3-3z"/></svg>

Before

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -1 +0,0 @@
<svg enable-background="new 0 0 64 64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg"><path d="m46.3 42 .7 2-35.6 12-4.9-14h30.5c1.1 0 2-.9 2-2v-1h3c0 1.6 1.3 3 2.9 3h.1z" fill="#e9edf5"/><path d="m63 24v18h-6v-3-13-2z" fill="#80dbff"/><path d="m60 24v18h-3v-3-13-2z" fill="#19cffc"/><path d="m39 33v-14h4l10 7h4v13h-4c0 1.6-1.3 3-2.9 3h-.1-5c-1.6 0-3-1.3-3-2.9v-.1h-6c-1.7 0-3-1.3-3-3 0-.7.3-1.5.8-2l.1-.1c.6-.6 1.3-.9 2.1-.9z" fill="#ffcdbe"/><path d="m42 30v-8-3h-3v3 8 3h3z" fill="#ffbeaa"/><path d="m36 36c0-.7.3-1.5.8-2l.1-.1c.6-.6 1.3-.9 2.1-.9h-3c-.8 0-1.6.3-2.1.9l-.1.1c-.5.5-.8 1.3-.8 2 0 1.7 1.3 3 3 3h3c-1.7 0-3-1.3-3-3z" fill="#ffbeaa"/><path d="m45 39h-3c0 1.6 1.3 3 2.9 3h.1 3c-1.6 0-3-1.3-3-3z" fill="#ffbeaa"/><path d="m39 39v1c0 1.1-.9 2-2 2h-15v-8h11.8c-.5.5-.8 1.3-.8 2 0 1.7 1.3 3 3 3z" fill="#e9edf5"/><path d="m39 30v3h-3c-.8 0-1.6.3-2.1.9l-.1.1h-11.8v-4z" fill="#d6475c"/><path d="m39 22v8h-17v-8h2z" fill="#e9edf5"/><path d="m39 19v3h-15v-6h13c1.1 0 2 .9 2 2z" fill="#9196aa"/><path d="m23 13c0-.6-.3-1.2-.8-1.6.7-2 2.6-3.4 4.8-3.4 4 0 4 1 4 3 0 1.1-.9 2-2 2 1.1.6 1.9 1.7 2 3h-8z" fill="#d6475c"/><path d="m24.2 11.4c.7-1.8 2.3-3.1 4.2-3.4-.4 0-.9 0-1.4 0-2.2 0-4.1 1.4-4.8 3.4.5.4.8 1 .8 1.6v3h2v-3c0-.6-.3-1.2-.8-1.6z" fill="#f25a6b"/><path d="m24 16v6h-2-4-2v-6h1 6z" fill="#d6475c"/><path d="m22.2 11.4c.5.4.8 1 .8 1.6v3h-6v-3c0-1.1.9-2 2-2h2c.4 0 .9.1 1.2.4z" fill="#ff808c"/><path d="m19.8 11.4c.3-.3.8-.4 1.2-.4h-2c-1.1 0-2 .9-2 2v3h2v-3c0-.6.3-1.2.8-1.6z" fill="#f25a6b"/><path d="m22 34v8h-4v-8-4-8h4v8z" fill="#f25a6b"/><path d="m18 34v8h-15c-1.1 0-2-.9-2-2v-6z" fill="#e9edf5"/><path d="m1 30h17v4h-17z" fill="#d6475c"/><path d="m1 30h3v4h-3z" fill="#ba4259"/><path d="m18 22v8h-17v-8h15z" fill="#e9edf5"/><path d="m17 13v3h-8c.1-1.3.9-2.4 2-3-1.1 0-2-.9-2-2 0-2 0-3 4-3 2.2 0 4.1 1.4 4.8 3.4-.5.4-.8 1-.8 1.6z" fill="#d6475c"/><path d="m13 13c-1.1 0-2-.9-2-2 0-1.7 0-2.7 2.6-2.9-.2-.1-.4-.1-.6-.1-4 0-4 1-4 3 0 1.1.9 2 2 2-1.1.6-1.9 1.7-2 3h2c.1-1.3.9-2.4 2-3z" fill="#f25a6b"/><path d="m16 16v6h-15v-4c0-1.1.9-2 2-2z" fill="#9196aa"/><path d="m4 40v-6h-3v6c0 1.1.9 2 2 2h3c-1.1 0-2-.9-2-2z" fill="#cdd2e1"/><path d="m1 22h3v8h-3z" fill="#cdd2e1"/><path d="m6 16h-3c-1.1 0-2 .9-2 2v4h3v-4c0-1.1.9-2 2-2z" fill="#636978"/><g fill="none" stroke="#404040" stroke-linejoin="round"><path d="m57 39h-4c0 1.6-1.3 3-2.9 3h-.1-5c-1.6 0-3-1.3-3-2.9v-.1h-6c-1.7 0-3-1.3-3-3s1.3-3 3-3h6l4-4"/><path d="m57 24h6v18h-6z"/><path d="m57 26h-4l-10-7h-4"/><path d="m39 33v-15c0-1.1-.9-2-2-2h-34c-1.1 0-2 .9-2 2v22c0 1.1.9 2 2 2h34c1.1 0 2-.9 2-2v-1"/><path d="m46.3 42 .7 2-35.6 12-4.9-14"/><path d="m1 22h38"/><path d="m16 16h8v6h-8z"/><path d="m18 22v20"/><path d="m22 22v20"/><path d="m1 30h17"/><path d="m22 30h17"/><path d="m1 34h17"/><path d="m22 34h12"/><path d="m17 16v-3c0-1.1.9-2 2-2h2c1.1 0 2 .9 2 2v3"/><path d="m22.2 11.4s.8-3.4 4.8-3.4 4 1 4 3c0 1.1-.9 2-2 2 1.1.6 1.9 1.7 2 3"/><path d="m17.8 11.4s-.8-3.4-4.8-3.4-4 1-4 3c0 1.1.9 2 2 2-1.1.6-1.9 1.7-2 3"/><path d="m23 13s4 0 4-2"/><path d="m17 13s-4 0-4-2"/><path d="m44 15v-6"/><path d="m56 20h-6"/><path d="m47 17.5 4.9-4.9"/></g></svg>

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -1 +0,0 @@
<svg enable-background="new 0 0 64 64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg"><path d="m9 52v-8h44c1.1 0 2-.9 2-2v-22h6c1.1 0 2 .9 2 2v30c0 1.1-.9 2-2 2h-50c-1.1 0-2-.9-2-2z" fill="#e9edf5"/><path d="m12 52v-8h-3v8c0 1.1.9 2 2 2h3c-1.1 0-2-.9-2-2zm46-10v-22h-3v22c0 1.1-.9 2-2 2h3c1.1 0 2-.9 2-2z" fill="#cdd2e1"/><path d="m14.5 34.5-5.5 5.5v-5h-4l4-4 2.4-2.4c.5.8 1.4 1.4 2.4 1.4-1 1.2-1 3 .1 4.1.2.2.4.3.6.4zm22.5.5h-4v5l-5.5-5.5c.2-.1.4-.3.6-.4 1.1-1.1 1.2-2.9.1-4.1 1-.1 1.8-.6 2.4-1.4l2.4 2.4z" fill="#f25a6b"/><path d="m1 23h12.2c.1.4.3.7.6 1-1.6.1-2.8 1.4-2.8 3 0 .6.1 1.1.4 1.6l-2.4 2.4h-8zm24 11.8v9.2h-8v-9.2c.4-.1.7-.3 1-.6 0 1.7 1.3 3 3 3s3-1.3 3-3c.3.3.6.5 1 .6zm3.8-11.8h26.2v8h-22l-2.4-2.4c.3-.5.4-1 .4-1.6 0-1.6-1.2-2.9-2.8-3 .3-.3.5-.6.6-1zm-3.8-13v9.2c-.4.1-.7.3-1 .6 0-1.7-1.3-3-3-3s-3 1.3-3 3c-.3-.3-.6-.5-1-.6v-9.2z" fill="#ff808c"/><circle cx="21" cy="27" fill="#f2f6fc" r="4"/><path d="m20 27c0-1.6 1-3.1 2.5-3.7-.5-.2-1-.3-1.5-.3-2.2 0-4 1.8-4 4s1.8 4 4 4c.5 0 1-.1 1.5-.3-1.5-.6-2.5-2.1-2.5-3.7z" fill="#dce1eb"/><path d="m11.4 28.6c-.3-.5-.4-1-.4-1.6 0-1.6 1.2-2.9 2.8-3-.3-.3-.5-.6-.6-1-.5-1.6.4-3.3 1.9-3.8.6-.2 1.3-.2 1.9 0 .4.1.7.3 1 .6 0-1.7 1.3-3 3-3s3 1.3 3 3c.3-.3.6-.5 1-.6 1.6-.5 3.3.4 3.8 1.9.2.6.2 1.3 0 1.9-.1.4-.3.7-.6 1 1.6.1 2.8 1.4 2.8 3 0 .6-.1 1.1-.4 1.6-.5.8-1.4 1.4-2.4 1.4 1 1.2 1 3-.1 4.1-.8.8-2 1.1-3.1.7-.4-.1-.7-.3-1-.6 0 1.7-1.3 3-3 3s-3-1.3-3-3c-.3.3-.6.5-1 .6-1.1.4-2.3.1-3.1-.7-1.1-1.1-1.2-2.9-.1-4.1-1-.1-1.9-.6-2.4-1.4zm13.6-1.6c0-2.2-1.8-4-4-4s-4 1.8-4 4 1.8 4 4 4 4-1.8 4-4z" fill="#d6475c"/><path d="m55 31v11c0 1.1-.9 2-2 2h-28v-9.2c.8.3 1.8.2 2.5-.3l5.5 5.5v-5h4l-4-4zm-38 3.8v9.2h-14c-1.1 0-2-.9-2-2v-11h8l-4 4h4v5l5.5-5.5c.7.5 1.7.6 2.5.3zm0-24.8v9.2c-1.6-.5-3.3.4-3.8 1.9-.2.6-.2 1.3 0 1.9h-12.2v-11c0-1.1.9-2 2-2zm38 13h-26.2c.5-1.6-.4-3.3-1.9-3.8-.6-.2-1.3-.2-1.9 0v-9.2h28c1.1 0 2 .9 2 2z" fill="#9196aa"/><path d="m1 23h3v8h-3z" fill="#f25a6b"/><path d="m1 31v11c0 1.1.9 2 2 2h1v-13zm3-21h-1c-1.1 0-2 .9-2 2v11h3z" fill="#636978"/><path d="m38 44h21v6h-21z" fill="#ff808c"/><path d="m38 44h4v6h-4z" fill="#d6475c"/><g fill="none" stroke="#404040" stroke-linejoin="round"><path d="m9 44v8c0 1.1.9 2 2 2h50c1.1 0 2-.9 2-2v-30c0-1.1-.9-2-2-2h-6"/><path d="m55 31v11c0 1.1-.9 2-2 2h-50c-1.1 0-2-.9-2-2v-30c0-1.1.9-2 2-2h50c1.1 0 2 .9 2 2z"/><path d="m17 19.2v-9.2"/><path d="m25 19.2v-9.2"/><path d="m17 44v-9.2"/><path d="m25 44v-9.2"/><path d="m28.8 23h26.2"/><path d="m33 31h22"/><path d="m1 23h12.2"/><path d="m1 31h8"/><circle cx="21" cy="27" r="4"/><path d="m27.5 34.5 5.5 5.5v-5h4l-4-4-2.4-2.4"/><path d="m14.5 34.5-5.5 5.5v-5h-4l4-4 2.4-2.4"/><path d="m57 44h2v6h-21v-4"/><path d="m35 50h-2"/><path d="m31 50h-19"/><path d="m30.6 28.6c.3-.5.4-1 .4-1.6 0-1.6-1.2-2.9-2.8-3 .3-.3.5-.6.6-1 .5-1.6-.4-3.3-1.9-3.8-.6-.2-1.3-.2-1.9 0-.4.1-.7.3-1 .6 0-1.7-1.3-3-3-3s-3 1.3-3 3c-.3-.3-.6-.5-1-.6-1.6-.5-3.3.4-3.8 1.9-.2.6-.2 1.3 0 1.9.1.4.3.7.6 1-1.6.1-2.8 1.4-2.8 3 0 .6.1 1.1.4 1.6.5.8 1.4 1.4 2.4 1.4-1 1.2-1 3 .1 4.1.8.8 2 1.1 3.1.7.4-.1.7-.3 1-.6 0 1.7 1.3 3 3 3s3-1.3 3-3c.3.3.6.5 1 .6 1.1.4 2.3.1 3.1-.7 1.1-1.1 1.2-2.9.1-4.1 1-.1 1.9-.6 2.4-1.4z"/></g></svg>

Before

Width:  |  Height:  |  Size: 3.1 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.3 KiB

View File

@@ -1 +0,0 @@
<svg enable-background="new 0 0 33.7 31.3" viewBox="0 0 33.7 31.3" xmlns="http://www.w3.org/2000/svg"><path d="m26.1 8.7c.3.6.5 1.3.5 2 .1 1.3-.6 2.4-1.7 3l-3.5-7.2c1.6-.8 3.7.3 4.7 2.2zm-19 13.8 1.5-.7 3.5 7.2c.1.2.2.4.2.7 0 .6-.4 1.2-1 1.4-.8.4-1.8 0-2.2-.8l-3.5-7.2v-.2c.5-.1 1-.2 1.5-.4z" fill="#d25065"/><path d="m4.4 13.2 4.2 8.6-1.5.7c-.5.2-1 .4-1.5.4-2.1.3-4.1-.8-5.1-2.7-.3-.6-.5-1.3-.5-2 0-1.9 1.2-3.6 2.9-4.3z" fill="#d23b54"/><path d="m24.8 13.7 3.2 6.5s-5.2-1.2-19.4 1.6l-4.2-8.6c12.1-9 13.7-13.2 13.7-13.2l3.2 6.5z" fill="#ffd180"/><path d="m7 18.5-1.5.7c-.5.2-1 .4-1.5.4-1.4.2-2.9-.3-4-1.2 0 .6.2 1.2.5 1.8.9 1.9 3 3 5.1 2.7.5-.1 1.1-.2 1.5-.4l1.5-.7z" fill="#bf3f49"/><path d="m7 18.5 1.6 3.3c14.2-2.8 19.4-1.6 19.4-1.6l-1.9-3.8c-4.1-.1-8.1.2-12.1.9-2.1.3-4.1-.7-5.1-2.6l-1.9-3.5c-.8.6-1.7 1.3-2.6 2z" fill="#f2b150"/><path d="m8.3 25.6c-.4-.9-.1-1.9.8-2.3 0 0 .1 0 .1-.1h.1l-.6-1.4-1.5.7c-.5.2-1 .4-1.5.4v.2l3.5 7.2c.4.7 1.2 1.1 2 .9zm15.4-16.8-1.2-2.5c-.4 0-.8.1-1.2.2l3.5 7.2c1.1-.6 1.8-1.7 1.7-3 0-.3 0-.6-.1-.9-1 .4-2.2 0-2.7-1z" fill="#bf3f49"/><path d="m9.5 13.2c-.4 0-.8-.2-1-.6-.4-.6-.2-1.3.3-1.7 1.2-.8 3.8-3 5.2-4.2.5-.4 1.3-.4 1.7.2.4.5.4 1.3-.2 1.7-2 1.6-4.2 3.5-5.4 4.3-.1.2-.4.3-.6.3zm9.8-8.3c0-.7-.5-1.2-1.2-1.2-.1 0-.2 0-.2 0-.1 0-.2 0-.2.1-.1 0-.1.1-.2.1 0 0-.1.1-.1.1l-.8.7c-.5.4-.6 1.2-.1 1.7.2.3.6.4.9.4s.6-.1.8-.3l.8-.7c.2-.2.3-.5.3-.9z" fill="#ffe0b3"/><path d="m27.2 8.2c-.5 0-.8-.3-.8-.8 0-.3.2-.6.4-.7l5.8-3.3c.4-.2.9-.1 1.1.3s.1.9-.3 1.1l-5.8 3.3c-.2.1-.3.1-.4.1zm-1.7-2.4c-.2 0-.4-.1-.5-.2-.3-.3-.4-.8-.1-1.1l3.5-4.1c.3-.3.8-.4 1.2-.1s.4.7.1 1.1l-3.5 4.1c-.2.2-.4.3-.7.3zm7.4 4.9h-4.9c-.5-.1-.8-.5-.7-.9 0-.4.3-.7.7-.7h4.9c.5.1.8.5.7.9 0 .4-.3.7-.7.7z" fill="#d23b54"/></svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1 +0,0 @@
<svg enable-background="new 0 0 64 64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg"><path d="m43 3v14c0 1.1-.9 2-2 2h-8v4l-4-4h-8c-1.1 0-2-.9-2-2v-14c0-1.1.9-2 2-2h20c1.1 0 2 .9 2 2z" fill="#ff808c"/><path d="m22 17v-14c0-1.1.9-2 2-2h-3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h3c-1.1 0-2-.9-2-2z" fill="#d6475c"/><path d="m32 19h-3l4 4v-3z" fill="#d6475c"/><path d="m33.3 60c1.1-.2 1.8-1.2 1.6-2.2 0 0 0 0 0-.1-.2-1.1-1.3-1.8-2.3-1.5-1.1.2-1.8 1.2-1.6 2.3.1 1 1.2 1.7 2.3 1.5zm-5.3-1c-.3-1.5.2-3.1 1.2-4.2.7-.8 1.7-1.3 2.8-1.5s2.2-.1 3.1.4c2.4 1.1 3.5 4 2.4 6.5-.7 1.5-2 2.5-3.6 2.8-2.7.4-5.3-1.3-5.9-4z" fill="#707789"/><path d="m34.8 57.7c.2 1.1-.5 2.1-1.5 2.3-1.1.2-2.1-.5-2.3-1.5-.2-1.1.5-2.1 1.6-2.3 1-.2 2 .5 2.2 1.5z" fill="#80dbff"/><path d="m29.2 54.8c-1 1.1-1.5 2.7-1.2 4.2l-2 .4c-.1 0-.3 0-.4 0-.9 0-1.6-.6-1.9-1.4v-.1c-.2-1.1.5-2.1 1.6-2.3l2.7-.6h.2z" fill="#dce1eb"/><path d="m61 51c0 1-.6 1.8-1.6 2l-21.6 4.1c-.3-1.5-1.3-2.8-2.7-3.5l20.6-3.9 2.9-.6c1.2-.1 2.2.7 2.4 1.9z" fill="#dce1eb"/><path d="m25.9 53.4c.2 1 1.1 1.7 2.1 1.5l-2.8.5c-1.1.2-1.8 1.2-1.6 2.3v.1h-2.6l-.8-5h5.5z" fill="#9196aa"/><path d="m20.2 53 .8 5h-4l-8-53h-4c-.5 0-1-.2-1.4-.6s-.6-.9-.6-1.4c0-1.1.9-2 2-2h7z" fill="#dce1eb"/><path d="m49.7 34.9 2.3 11.6-21.6 4.1-2.3-11.6z" fill="#f2f6fc"/><path d="m43.5 24.1 1.5 7.7-13.7 2.6-1.5-7.7z" fill="#ffde91"/><path d="m30.4 50.6 21.6-4.1-2.3-11.5-21.6 4zm-4.6 2.4-4.5-22.6c-.2-1.1.5-2.1 1.6-2.3l6.9-1.3 1.5 7.7 13.7-2.7-1.5-7.7 6.9-1.3c1.1-.2 2.1.5 2.3 1.5l4.6 23.1c.2 1.1-.5 2.1-1.6 2.3l-20.6 3.9c-1-.5-2.1-.6-3.1-.4-1.1.2-2 .7-2.8 1.5l-1 .2-.2.1c-1 .1-1.9-.6-2.1-1.6z" fill="#b2876d"/><path d="m43.5 24.1 1.5 7.7-13.7 2.6-1.5-7.7z" fill="#dce1eb"/><path d="m32.9 28.5-.5-2.3-2.7.5 1.5 7.7 13.8-2.6-.7-3.5-9.1 1.7c-1.1.3-2.1-.4-2.3-1.5z" fill="#cdd2e1"/><path d="m37.1 51.7c-1-.5-2.1-.6-3.1-.4-1.1.2-2 .7-2.8 1.5l-1 .2h-.2c-1 .1-1.9-.6-2.1-1.6l-.1-.4-4.5-22.6c0-.1 0-.2 0-.4l-.4.1c-1.1.2-1.8 1.2-1.6 2.3l4.5 22.6.1.5c.2 1 1.1 1.7 2.1 1.5h.2l1-.2c.7-.8 1.7-1.3 2.8-1.5s2.2-.1 3.1.4l20.6-3.9c.9-.2 1.6-1 1.6-1.9z" fill="#966857"/><path d="m31.6 41.2 15.7-3 .4 2-15.7 3z" fill="#bec3d2"/><path d="m46.1 42.4 2-.4.4 2-2 .4z" fill="#bec3d2"/><path d="m32.4 45 11.8-2.3.4 2-11.8 2.3z" fill="#bec3d2"/><ellipse cx="32.9" cy="58.1" fill="#dce1eb" rx="2" ry="2"/><g fill="none" stroke="#404040" stroke-linejoin="round"><path d="m35.1 53.7 23.6-4.5c1.1-.2 2.2.6 2.4 1.8 0 1-.6 1.8-1.6 2l-21.6 4.1"/><path d="m29.2 54.8-3.9.8c-1.1.2-1.8 1.2-1.6 2.3s1.3 1.8 2.3 1.5l2-.4"/><path d="m55.7 49.8c1.1-.2 1.8-1.2 1.6-2.3l-4.6-23.1c-.2-1.1-1.3-1.8-2.3-1.5l-27.5 5.2c-1.1.2-1.8 1.2-1.6 2.3l4.6 23.1c.2 1.1 1.3 1.8 2.3 1.5"/><path d="m43.5 24.1 1.5 7.7-13.7 2.6-1.5-7.7"/><path d="m30.4 50.6 21.6-4.1-2.3-11.5-21.6 4z"/><path d="m47.5 39.3-15.7 3"/><path d="m48.3 43.2-2 .4"/><path d="m44.3 43.9-11.8 2.2"/><path d="m24 58h-3l-9-57h-7c-1.1 0-2 .9-2 2s.9 2 2 2h4l8 53h4"/><path d="m20 53h6"/><path d="m43 3v14c0 1.1-.9 2-2 2h-8v4l-4-4h-8c-1.1 0-2-.9-2-2v-14c0-1.1.9-2 2-2h20c1.1 0 2 .9 2 2z"/><path d="m27 14 8-8"/><path d="m27 7h2"/><path d="m33 13h2"/><ellipse cx="32.9" cy="58.1" rx="5" ry="4.9"/></g></svg>

Before

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -1 +0,0 @@
<svg viewBox="0 0 77.94 73.68" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientTransform="matrix(-1 0 0 1 278.59 0)" gradientUnits="userSpaceOnUse" x1="253.22" x2="264.2" y1="24.57" y2="65.52"><stop offset="0" stop-color="#c7a58d"/><stop offset="1" stop-color="#b89882"/></linearGradient><linearGradient id="b" gradientTransform="matrix(-1 0 0 1 278.59 0)" gradientUnits="userSpaceOnUse" x1="223.88" x2="212.68" y1="33.32" y2="72.37"><stop offset="0" stop-color="#aa8c79"/><stop offset="1" stop-color="#9d8472"/></linearGradient><linearGradient id="c" x1="255.88" x2="262.69" xlink:href="#a" y1="13.47" y2="38.88"/><linearGradient id="d" x1="220.87" x2="212.77" xlink:href="#b" y1="22.77" y2="53.01"/><linearGradient id="e" gradientTransform="matrix(-1 0 0 1 278.59 0)" gradientUnits="userSpaceOnUse" x1="239.88" x2="239.88" y1="37.16" y2="27.02"><stop offset="0" stop-color="#bb9c85"/><stop offset="1" stop-color="#f2d3bb"/></linearGradient><linearGradient id="f" gradientTransform="matrix(-1 0 0 1 278.59 0)" gradientUnits="userSpaceOnUse" x1="259.31" x2="263.18" y1="36.21" y2="29.5"><stop offset="0" stop-color="#e9c4aa"/><stop offset=".34" stop-color="#aa8c79"/><stop offset="1" stop-color="#9d8472"/></linearGradient><linearGradient id="g" x1="240.2" x2="239.07" xlink:href="#e" y1="74.17" y2="9.38"/><g fill-rule="evenodd"><path d="m38.97 46.6-37.7 13.54 37.7 13.53 37.7-13.53z" fill="#8f8f8f"/><path d="m38.97 1.22-37.7 13.54 37.7 13.54 37.7-13.54z" fill="#edecec"/><path d="m1.27 60.02v-45.26l37.7 13.54v45.26z" fill="url(#a)"/><path d="m76.67 60.02v-45.26l-37.7 13.54v45.26z" fill="url(#b)"/><path d="m1.27 24.14v-9.38l37.73 13.54v9.38z" fill="#b89983"/><path d="m76.67 24.14v-9.38l-37.67 13.54v9.38z" fill="#9d816e"/><path d="m76.67 14.96v-.2l-37.7 13.54-37.7-13.54v.2l37.7 13.75z" fill="#fff"/><path d="m38.97 0-38.97 14 38.97 13.99 38.97-13.99z" fill="#e9c4aa"/><path d="m0 23.01v-9.01l38.97 13.99v9.01z" fill="url(#c)"/><path d="m77.94 23.01v-9.01l-38.97 13.99v9.01z" fill="url(#d)"/><path d="m38.45 27.8.52.19v9.01l-.52-.18z" fill="url(#e)"/><path d="m77.94 14.21v-.21l-38.97 13.99-38.97-13.99v.21l38.97 14.2z" fill="#f2d3bb"/><path d="m24.1 35.79-8.72-3.11a1.75 1.75 0 0 0 -2.38 1.86 4.38 4.38 0 0 0 2.42 3.81l8.72 3.11c1.33.47 2.42-.59 2.42-2.09a4 4 0 0 0 -2.46-3.58z" fill="url(#f)"/><path d="m24.1 35.79-8.72-3.11c-1.15-.5-2 .47-2 1.74a4 4 0 0 0 2.46 3.58l8.72 3.11c1.15.49 2-.48 2-1.75a4 4 0 0 0 -2.46-3.57z" fill="#5f5243"/><path d="m38.46 37.52.51.18v35.86l-.51-.18z" fill="url(#g)"/></g></svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><defs><style>.a{fill:#db5669}.b{fill:#f26674}.c{fill:#c4455e}.d{fill:#ffde76}.e{fill:#edebf2}</style></defs><path class="a" d="M45.93 26.39a3.2 3.2 0 0 0-.76 3.79 3.21 3.21 0 0 1-1.83 4.42 3.19 3.19 0 0 0-2.15 3v.39a3.21 3.21 0 0 1-3.4 3.2 3.19 3.19 0 0 0-3.21 2.14 3.2 3.2 0 0 1-4.42 1.83 3.2 3.2 0 0 0-3.79.76 3.2 3.2 0 0 1-4.78 0 3.2 3.2 0 0 0-3.79-.76 3.2 3.2 0 0 1-4.42-1.83 3.18 3.18 0 0 0-3.21-2.14 3.2 3.2 0 0 1-3.37-3.38 3.19 3.19 0 0 0-2.14-3.21 3.2 3.2 0 0 1-1.83-4.42 3.2 3.2 0 0 0-.76-3.79 3.2 3.2 0 0 1 0-4.78 3.2 3.2 0 0 0 .76-3.79 3.2 3.2 0 0 1 1.83-4.42 3.18 3.18 0 0 0 2.14-3.21 3.2 3.2 0 0 1 3.3-3.39h.29a3.19 3.19 0 0 0 3-2.15 3.21 3.21 0 0 1 4.42-1.83 3.2 3.2 0 0 0 3.79-.76 3.2 3.2 0 0 1 4.78 0 3.21 3.21 0 0 0 3.79.76 3.2 3.2 0 0 1 4.43 1.84 3.19 3.19 0 0 0 3 2.15h.39a3.21 3.21 0 0 1 3.2 3.4 3.19 3.19 0 0 0 2.14 3.21 3.19 3.19 0 0 1 2.15 3c0 1.29-.64 1.52-.64 2.79C44.85 21.68 47 21.53 47 24a3.19 3.19 0 0 1-1.07 2.39z"/><path class="b" d="M45.93 26.39a3.2 3.2 0 0 0-.76 3.79 3.12 3.12 0 0 1 .18 2.3c0 .1-.76 1.28-.82 1.38a3.08 3.08 0 0 1-1.19.74 3.19 3.19 0 0 0-2.15 3v.29C27.32 51.18 4 41.37 4 22a21.9 21.9 0 0 1 6.1-15.2 3.2 3.2 0 0 0 3.3-2.14c.38-1.13 1-1.39 2.11-2a2.89 2.89 0 0 1 .91-.14c1.29 0 1.52.64 2.79.64C21.68 3.15 21.53 1 24 1a3.19 3.19 0 0 1 2.39 1.07 3.21 3.21 0 0 0 3.79.76 3.2 3.2 0 0 1 4.42 1.83 3.18 3.18 0 0 0 3.21 2.14 3.2 3.2 0 0 1 3.39 3.39 3.19 3.19 0 0 0 2.14 3.21 3.2 3.2 0 0 1 1.83 4.42 3.2 3.2 0 0 0 .76 3.79 3.2 3.2 0 0 1 0 4.78z"/><path class="c" d="M41 24a17 17 0 0 1-17 17C8.17 41 1 21.21 13 11c10.87-9.18 28-1.64 28 13z"/><path class="a" d="M41 24a16.91 16.91 0 0 1-4 11 16.91 16.91 0 0 1-11 4C11.38 39 3.81 21.88 13 11c10.87-9.18 28-1.64 28 13z"/><path class="d" d="M31.77 16.23a11 11 0 0 0-15.54 0 1 1 0 0 1-1.42-1.42 13 13 0 0 1 18.38 0 1 1 0 0 1-1.42 1.42zM14.81 33.19a1 1 0 0 1 1.42-1.42 11 11 0 0 0 15.54 0 1 1 0 0 1 1.42 1.42 13 13 0 0 1-18.38 0z"/><path class="e" d="M13 21h2a1 1 0 0 0 0-2h-2a3 3 0 0 0 0 6 1 1 0 0 1 0 2h-2a1 1 0 0 0 0 2h2a3 3 0 0 0 0-6 1 1 0 0 1 0-2zm8.94-1.35a1 1 0 0 0-1.88 0l-3 8a1 1 0 0 0 1.88.7l.5-1.35h3.12l.5 1.35a1 1 0 0 0 1.88-.7zM20.19 25l.81-2.15.81 2.15zM30 27h-2v-7a1 1 0 0 0-2 0v8a1 1 0 0 0 1 1h3a1 1 0 0 0 0-2zm7-2a1 1 0 0 0 0-2h-3v-2h3a1 1 0 0 0 0-2h-4a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h4a1 1 0 0 0 0-2h-3v-2z"/></svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><defs><style>.a{fill:#6fabe6}.b{fill:#82bcf4}.c{fill:#5b9ad8}.d{fill:#dad7e5}.e{fill:#edebf2}.f{fill:#db5669}.g{fill:#f26674}.h{fill:#ffde76}</style></defs><path class="a" d="M1 5H47V15H1z"/><path class="b" d="M47 5v8H7a4 4 0 0 1-4-4V5z"/><path class="c" d="M10 10a2 2 0 1 1-2.82-1.82A2 2 0 0 1 10 10zm4 2a2 2 0 1 1 2-2 2 2 0 0 1-2 2zm0-2zm26 2a2 2 0 1 1 2-2 2 2 0 0 1-2 2zm0-2zm-6 2a2 2 0 1 1 2-2 2 2 0 0 1-2 2zm0-2z"/><path class="d" d="M1 15H47V47H1z"/><path class="e" d="M47 15v30H11a8 8 0 0 1-8-8V15z"/><path class="f" d="M25.72 19.76a2.32 2.32 0 0 0 2.42.65 2.32 2.32 0 0 1 3 1.71 2.29 2.29 0 0 0 1.77 1.77 2.32 2.32 0 0 1 1.71 3 2.33 2.33 0 0 0 .65 2.42 2.33 2.33 0 0 1 0 3.44 2.32 2.32 0 0 0-.65 2.42 2.32 2.32 0 0 1-1.71 3 2.29 2.29 0 0 0-1.77 1.77 2.32 2.32 0 0 1-3 1.71 2.33 2.33 0 0 0-2.42.65 2.33 2.33 0 0 1-3.44 0 2.32 2.32 0 0 0-2.42-.65 2.32 2.32 0 0 1-3-1.71 2.29 2.29 0 0 0-1.77-1.77 2.32 2.32 0 0 1-1.71-3 2.33 2.33 0 0 0-.65-2.42 2.33 2.33 0 0 1 0-3.44 2.32 2.32 0 0 0 .65-2.42 2.32 2.32 0 0 1 1.71-3 2.29 2.29 0 0 0 1.77-1.77 2.32 2.32 0 0 1 3-1.71 2.33 2.33 0 0 0 2.42-.65 2.33 2.33 0 0 1 3.44 0z"/><path class="g" d="M34.59 35.14a2.33 2.33 0 0 1-1.71 3 2.31 2.31 0 0 0-1.77 1.75c-10.14 4.77-20.74-5.84-16-16a2.31 2.31 0 0 0 1.75-1.77 2.33 2.33 0 0 1 2.26-1.82c.66 0 .79.22 1.41.22 1.78 0 1.72-1.52 3.47-1.52a2.34 2.34 0 0 1 1.72.76 2.33 2.33 0 0 0 2.42.65 2.33 2.33 0 0 1 3 1.71 2.3 2.3 0 0 0 1.77 1.77 2.33 2.33 0 0 1 1.82 2.26c0 .66-.22.79-.22 1.41C34.48 29.32 36 29.24 36 31c0 1.92-2.08 1.93-1.41 4.14z"/><path class="h" d="M19 37a1 1 0 0 1-.71-1.71l10-10a1 1 0 0 1 1.42 1.42C18.88 37.53 19.6 37 19 37z"/><path class="a" d="M9.82 10.82a2 2 0 0 1-2.64-2.64 2 2 0 0 1 2.64 2.64zm6 0a2 2 0 0 1-2.64-2.64 2 2 0 0 1 2.64 2.64zm20 0a2 2 0 0 1-2.64-2.64 2 2 0 0 1 2.64 2.64zm6 0a2 2 0 0 1-2.64-2.64 2 2 0 0 1 2.64 2.64z"/><path class="d" d="M7 9V1a1 1 0 0 1 2 0v8a1 1 0 0 1-2 0zm6 0V1a1 1 0 0 1 2 0v8a1 1 0 0 1-2 0zm26 0V1a1 1 0 0 1 2 0v8a1 1 0 0 1-2 0zm-6 0V1a1 1 0 0 1 2 0v8a1 1 0 0 1-2 0z"/><path class="h" d="M21 30a3 3 0 1 0-3-3 3 3 0 0 0 3 3zm0-4a1 1 0 0 1 0 2 1 1 0 0 1 0-2zm6 6a3 3 0 1 0 3 3 3 3 0 0 0-3-3zm0 4a1 1 0 0 1 0-2 1 1 0 0 1 0 2z"/></svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -1 +0,0 @@
<svg enable-background="new 0 0 64 64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg"><path d="m42 55h-39c-1.1 0-2-.9-2-2v-26c0-1.1.9-2 2-2h39z" fill="#ffd180"/><path d="m30.4 14.8-20.2-5.7c-.9-.3-1.9.2-2.2 1.1l-4.8 14.8h39.3l2-6.2z" fill="#f2b150"/><path d="m63 24.1-18.5-5.2-2 6.2h20.5z" fill="#d23b54"/><circle cx="27" cy="47" fill="#ff6161" r="1"/><circle cx="23" cy="41" fill="#ff6161" r="1"/><path d="m63 25h-21v30h21v-3l-2-3 2-3-2-3 2-3-2-3 2-3-2-3 2-3z" fill="#f17283"/><path d="m3 25c-1.1 0-2 .9-2 2v26c0 1.1.9 2 2 2h39v-7.3c-22.7-3.3-39-12.2-39-22.7z" fill="#f7b957"/><path d="m42 47.7v7.3h21v-3l-2-3c-6.4 0-12.7-.4-19-1.3z" fill="#d23b54"/><path d="m63 25h-2v3l-2 3 2 3-2 3 2 3-2 3 2 3-2 3 2 3v3h2v-3l-2-3 2-3-2-3 2-3-2-3 2-3-2-3 2-3z" fill="#d23b54"/><g fill="#2b2b37"><path d="m41.5 25h1v2h-1z"/><path d="m41.5 29h1v2h-1z"/><path d="m41.5 33h1v2h-1z"/><path d="m41.5 37h1v2h-1z"/><path d="m41.5 41h1v2h-1z"/><path d="m41.5 45h1v2h-1z"/><path d="m41.5 49h1v2h-1z"/><path d="m41.5 53h1v2h-1z"/></g><path d="m53.5 39h-3c-1.4 0-2.5-1.1-2.5-2.5s1.1-2.5 2.5-2.5h4.5c.6 0 1-.4 1-1s-.4-1-1-1h-2v-1c0-.6-.4-1-1-1s-1 .4-1 1v1h-.5c-2.5 0-4.5 2-4.5 4.5s2 4.5 4.5 4.5h3c1.4 0 2.5 1.1 2.5 2.5s-1.1 2.5-2.5 2.5h-4.5c-.6 0-1 .4-1 1s.4 1 1 1h2v1c0 .6.4 1 1 1s1-.4 1-1v-1h.5c2.5 0 4.5-2 4.5-4.5s-2-4.5-4.5-4.5z" fill="#fbfbfb"/><path d="m29 27.5h-3c-.2 0-.4.2-.5.4l-.6 2.6h-15.9c-.1 0-.3.1-.4.2s-.1.3-.1.4l2 10c0 .2.3.4.5.4h13c.8 0 1.5.7 1.5 1.5s-.7 1.5-1.5 1.5h-14c-.3 0-.5.2-.5.5v.6c-.8.3-1.2 1.1-.9 1.9s1.1 1.2 1.9.9 1.2-1.1.9-1.9c-.2-.4-.5-.8-.9-.9v-.1h12v.1c-.8.3-1.2 1.1-.9 1.9s1.1 1.2 1.9.9 1.2-1.1.9-1.9c-.2-.4-.5-.8-.9-.9v-.1h.5c1.4 0 2.5-1.1 2.5-2.5s-1.1-2.5-2.5-2.5h-.4l2.8-12h2.6c.3 0 .5-.2.5-.5s-.2-.5-.5-.5zm-19 20c-.3 0-.5-.2-.5-.5s.2-.5.5-.5.5.2.5.5-.2.5-.5.5zm13 0c-.3 0-.5-.2-.5-.5s.2-.5.5-.5.5.2.5.5-.2.5-.5.5zm-13.4-16h15.1l-.5 2h-12.2c-.3 0-.5.2-.5.5s.2.5.5.5h12l-.7 3h-11.3c-.3 0-.5.2-.5.5s.2.5.5.5h11.1l-.5 2h-11.2z" fill="#2b2b37"/><path d="m25 36c4.4 0 8 3.6 8 8s-3.6 8-8 8-8-3.6-8-8c0-.8.1-1.6.4-2.4.9-3.1 3.6-5.3 6.8-5.6z" fill="#2b2b37"/><circle cx="25" cy="44" fill="#ff6161" r="7"/><circle cx="27" cy="47" fill="#fbfbfb" r="1"/><circle cx="23" cy="41" fill="#fbfbfb" r="1"/><path d="m21 48.5c-.1 0-.3-.1-.4-.2-.2-.2-.2-.5 0-.7l8-8c.2-.2.5-.2.7 0s.2.5 0 .7l-8 8c0 .1-.2.2-.3.2z" fill="#fbfbfb"/><path d="m3.9 23-.6 2h9.7 12 1 16 .6l.6-2z" fill="#e69e2d"/><path d="m43.2 23-.6 2h20.4v-.9l-3.8-1.1z" fill="#c23b54"/><path d="m42.5 23.7.5-1.7 1 .3-.6 1.7z" fill="#222430"/><path d="m43.5 20.3.5-1.7 1 .3-.5 1.7z" fill="#222430"/><path d="m32.5 17.6-2.6-.8c-.2-.1-.4 0-.6.2l-1.2 2-14-4c-.1 0-.3 0-.4.1s-.2.2-.2.4l-1 9.5h1l.9-8.8 13.1 3.7-.9 1.4-10.7-3c-.3-.1-.6.1-.6.4-.1.3.1.6.4.6l10.4 3-1.2 1.8-10.1-2.6c-.3-.1-.6.1-.6.4-.1.3.1.6.4.6l9.4 2.5h1.6l4.3-7.1 2.3.6c.3.1.6-.1.6-.4s0-.5-.3-.5z" fill="#222430"/></svg>

Before

Width:  |  Height:  |  Size: 2.8 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,44 +0,0 @@
/**
* WooCommerce Smart Coupons JavaScript
*
* @package WooCommerce Smart Coupons/Assets/JS
*/
jQuery(
function(){
tinymce.create(
'tinymce.plugins.smart_coupons_shortcode_plugin',
{
init : function(ed, url) {
var assetsUrl = url.substr( 0, url.lastIndexOf( "/js" ) );
// Register command for when button is clicked.
ed.addCommand(
'smart_coupons_insert_shortcode',
function() {
ed.windowManager.open(
{
id : 'sc_coupons_attributes',
width : "auto",
height : "auto",
wpDialog : true
},
{
plugin_url : url // Plugin absolute URL.
}
);
}
);
// Register buttons - trigger above command when clicked.
ed.addButton( 'sc_shortcode_button', {title : 'Insert Smart Coupons shortcode', cmd : 'smart_coupons_insert_shortcode', classes: 'smart-coupon-shortcode btn' } );
},
}
);
// Register our TinyMCE plugin.
// first parameter is the button ID1.
// second parameter must match the first parameter of the tinymce.create() function above.
tinymce.PluginManager.add( 'sc_shortcode_button', tinymce.plugins.smart_coupons_shortcode_plugin );
}
);

File diff suppressed because it is too large Load Diff

View File

@@ -1,156 +0,0 @@
<?php
/**
* Functions to register client-side assets (scripts and stylesheets) for the
* Gutenberg block.
*
* @author StoreApps
* @since 4.0.0
* @version 1.0
*
* @package woocommerce-smart-coupons/includes/blocks
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'WC_SC_Gutenberg_Coupon_Block' ) ) {
/**
* Class for handling Smart Coupons Shortcode
*/
class WC_SC_Gutenberg_Coupon_Block {
/**
* Variable to hold instance of WC_SC_Gutenberg_Coupon_Block
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
private function __construct() {
global $wp_version;
if ( ! function_exists( 'is_plugin_active' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
if ( is_plugin_active( 'gutenberg/gutenberg.php' ) || version_compare( $wp_version, '5.0', '>=' ) ) {
add_action( 'init', array( $this, 'gutenberg_coupon_block_init' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'gutenberg_coupon_add_inline_css' ) );
}
}
/**
* Get single instance of WC_SC_Gutenberg_Coupon_Block
*
* @return WC_SC_Gutenberg_Coupon_Block Singleton object of WC_SC_Gutenberg_Coupon_Block
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Registers all block assets so that they can be enqueued through Gutenberg in
* the corresponding context.
*
* @see https://wordpress.org/gutenberg/handbook/blocks/writing-your-first-block-type/#enqueuing-block-scripts
*/
public function gutenberg_coupon_block_init() {
// Skip block registration if Gutenberg is not enabled/merged.
if ( ! function_exists( 'register_block_type' ) ) {
return;
}
$dir = dirname( __FILE__ );
$index_js = 'sc-gutenberg-block.js';
wp_register_script(
'coupon-block-editor-js',
plugins_url( $index_js, __FILE__ ),
array(
'wp-blocks',
'wp-i18n',
'wp-element',
'wp-components',
),
filemtime( "$dir/$index_js" ),
true
);
if ( shortcode_exists( 'smart_coupons' ) ) {
register_block_type(
'woocommerce-smart-coupons/coupon',
array(
'editor_script' => 'coupon-block-editor-js',
'attributes' => array(
'coupon_code' => array( 'type' => 'string' ),
),
'render_callback' => array( WC_SC_Shortcode::get_instance(), 'execute_smart_coupons_shortcode' ),
)
);
}
}
/**
* Our componenet is referring to smart-coupon.css as main css file.
* We cannot add register/enqueue a new CSS file to render coupon design in Gutenberg.
* And hence we are adding necessary files via wp_add_inline_style.
*/
public function gutenberg_coupon_add_inline_css() {
if ( ! wp_style_is( 'smart-coupon' ) ) {
wp_enqueue_style( 'smart-coupon' );
}
$coupon_style_attributes = WC_Smart_Coupons::get_instance()->get_coupon_style_attributes();
$gutenberg_active_coupon_style = '
.gb-active-coupon {
' . $coupon_style_attributes . '
}
';
// Add the above custom CSS via wp_add_inline_style.
wp_add_inline_style( 'smart-coupon', $gutenberg_active_coupon_style );
}
}
}
WC_SC_Gutenberg_Coupon_Block::get_instance();

View File

@@ -1,120 +0,0 @@
/**
* WooCommerce Smart Coupons Gutenberg
*
* @author StoreApps
* @since 4.0.0
* @version 1.0
*
* @package woocommerce-smart-coupons/includes/blocks
*/
( function( wp ) {
/**
* Registers a new block provided a unique name and an object defining its behavior.
*
* @see https://github.com/WordPress/gutenberg/tree/master/blocks#api
*/
const {registerBlockType} = wp.blocks;
/**
* Returns a new element of given type. Element is an abstraction layer atop React.
*
* @see https://github.com/WordPress/gutenberg/tree/master/element#element
*/
const createElement = wp.element.createElement;
/**
* Retrieves the translation of text.
*
* @see https://github.com/WordPress/gutenberg/tree/master/i18n#api
*/
const {__} = wp.i18n;
/**
* Every block starts by registering a new block type definition.
*
* @see https://wordpress.org/gutenberg/handbook/block-api/
*/
registerBlockType(
'woocommerce-smart-coupons/coupon',
{
/**
* This is the display title for our block, which can be translated with `i18n` functions.
* The block inserter will show this name.
*/
title: __( 'Smart Coupons', 'woocommerce-smart-coupons' ),
/**
* This is the block description for our block, which can be translated with `il8n` functions.
*/
description: __( 'Show any WooCommerce coupon with Smart Coupons.' ),
/**
* Blocks are grouped into categories to help users browse and discover them.
* The categories provided by core are `common`, `embed`, `formatting`, `layout` and `widgets`.
*/
category: 'embed',
/**
* Define block icon for our block.
*/
icon: 'heart',
/**
* This are the block keywords using which our block can be searched.
*/
keywords: [
__( 'Smart' ),
__( 'Coupons' ),
__( 'Store Credit' ),
],
/**
* Optional block extended support features.
*/
supports: {
// Removes support for an HTML mode.
html: false,
// align: [ 'wide', 'full' ],.
},
attributes: {
coupon_code: {
type: 'string',
},
},
/**
* The edit function describes the structure of your block in the context of the editor.
* This represents what the editor will render when the block is used.
*
* @see https://wordpress.org/gutenberg/handbook/block-edit-save/#edit
*
* @param {Object} [props] Properties passed from the editor.
* @return {Element} Element to render.
*/
edit: function( props ){
return createElement(
wp.editor.RichText,
{
className: 'coupon-container gb-active-coupon',
value: props.attributes.coupon_code,
onChange: function( coupon_code ) {
props.setAttributes( { coupon_code: coupon_code } );
}
}
);
},
/**
* The save function defines the way in which the different attributes should be combined
* into the final markup, which is then serialized by Gutenberg into `post_content`.
*
* @see https://wordpress.org/gutenberg/handbook/block-edit-save/#save
*
* @return {Element} Element to render.
*/
save:function( props ){
return null;
}
}
);
} )( window.wp );

View File

@@ -1,250 +0,0 @@
<?php
/**
* Smart Coupons Initialize
*
* @author StoreApps
* @since 3.3.0
* @version 1.2.0
* @package WooCommerce Smart Coupons
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Act_Deact' ) ) {
/**
* Class for handling actions to be performed during initialization
*/
class WC_SC_Act_Deact {
/**
* Database changes required for Smart Coupons
*
* Add option 'smart_coupon_email_subject' if not exists
* Enable 'Auto Generation' for Store Credit (discount_type: 'smart_coupon') not having any customer_email
* Disable 'apply_before_tax' for all Store Credit (discount_type: 'smart_coupon')
*/
public static function smart_coupon_activate() {
set_transient( '_smart_coupons_process_activation', 1, 30 );
if ( ! is_network_admin() && ! isset( $_GET['activate-multi'] ) ) { // phpcs:ignore
set_transient( '_smart_coupons_activation_redirect', 1, 30 );
}
}
/**
* Process activation
*/
public static function process_activation() {
global $wpdb, $blog_id, $woocommerce_smart_coupon;
$is_migrate_site_options = get_site_option( 'wc_sc_migrate_site_options', 'yes' );
if ( 'yes' === $is_migrate_site_options ) {
// phpcs:disable
$default_options = array(
'all_tasks_count_woo_sc', // => '',.
'bulk_coupon_action_woo_sc', // => '',.
'current_time_woo_sc', // => '',.
'remaining_tasks_count_woo_sc', // => '',.
'smart_coupons_combine_emails', // => 'no',.
'smart_coupons_is_send_email', // => 'yes',.
'start_time_woo_sc', // => '',.
'wc_sc_auto_apply_coupon_ids', // => maybe_serialize( array() ),.
'wc_sc_is_show_terms_notice', // => 'yes',.
'wc_sc_terms_page_id', // => '',.
'woocommerce_wc_sc_combined_email_coupon_settings', // => maybe_serialize( array() ),.
'woocommerce_wc_sc_email_coupon_settings', // => maybe_serialize( array() ),.
'woo_sc_action_data', // => '',.
'woo_sc_generate_coupon_posted_data', // => '',.
);
// phpcs:enable
$existing_options = array();
foreach ( $default_options as $option_name ) {
$site_option = get_site_option( $option_name );
if ( ! empty( $site_option ) ) {
$existing_options[ $option_name ] = $site_option;
}
}
}
if ( is_multisite() ) {
$blog_ids = $wpdb->get_col( "SELECT blog_id FROM {$wpdb->blogs}", 0 ); // WPCS: cache ok, db call ok.
} else {
$blog_ids = array( $blog_id );
}
if ( ! get_option( 'smart_coupon_email_subject' ) ) {
add_option( 'smart_coupon_email_subject' );
}
if ( ! is_object( $woocommerce_smart_coupon ) || ! is_a( $woocommerce_smart_coupon, 'WC_Smart_Coupons' ) || ! is_callable( array( $woocommerce_smart_coupon, 'update_post_meta' ) ) ) {
if ( ! class_exists( 'WC_Smart_Coupons' ) ) {
if ( file_exists( WP_PLUGIN_DIR . '/woocommerce-smart-coupons/includes/class-wc-smart-coupons.php' ) ) {
include_once WP_PLUGIN_DIR . '/woocommerce-smart-coupons/includes/class-wc-smart-coupons.php';
}
if ( class_exists( 'WC_Smart_Coupons' ) && is_callable( array( 'WC_Smart_Coupons', 'get_instance' ) ) ) {
$woocommerce_smart_coupon = WC_Smart_Coupons::get_instance();
}
}
}
foreach ( $blog_ids as $blogid ) {
if ( ( file_exists( WP_PLUGIN_DIR . '/woocommerce/woocommerce.php' ) ) && ( is_plugin_active( 'woocommerce/woocommerce.php' ) ) ) {
$wpdb_obj = clone $wpdb;
$wpdb->blogid = $blogid;
$wpdb->set_prefix( $wpdb->base_prefix );
$results = $wpdb->get_col(
$wpdb->prepare(
"SELECT postmeta.post_id FROM {$wpdb->prefix}postmeta as postmeta WHERE postmeta.meta_key = %s AND postmeta.meta_value = %s AND postmeta.post_id IN
(SELECT p.post_id FROM {$wpdb->prefix}postmeta AS p WHERE p.meta_key = %s AND p.meta_value = %s) ",
'discount_type',
'smart_coupon',
'customer_email',
'a:0:{}'
)
); // WPCS: cache ok, db call ok.
foreach ( $results as $result ) {
if ( is_object( $woocommerce_smart_coupon ) && is_callable( array( $woocommerce_smart_coupon, 'update_post_meta' ) ) ) {
$woocommerce_smart_coupon->update_post_meta( $result, 'auto_generate_coupon', 'yes' );
} else {
update_post_meta( $result, 'auto_generate_coupon', 'yes' );
}
}
// To disable apply_before_tax option for Gift Certificates / Store Credit.
$tax_post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT post_id FROM {$wpdb->prefix}postmeta WHERE meta_key = %s AND meta_value = %s", 'discount_type', 'smart_coupon' ) ); // WPCS: cache ok, db call ok.
foreach ( $tax_post_ids as $tax_post_id ) {
if ( is_object( $woocommerce_smart_coupon ) && is_callable( array( $woocommerce_smart_coupon, 'update_post_meta' ) ) ) {
$woocommerce_smart_coupon->update_post_meta( $tax_post_id, 'apply_before_tax', 'no' );
} else {
update_post_meta( $tax_post_id, 'apply_before_tax', 'no' );
}
}
if ( 'yes' === $is_migrate_site_options ) {
$results = $wpdb->get_results( // phpcs:ignore
$wpdb->prepare(
"SELECT option_id,
option_name,
option_value
FROM {$wpdb->prefix}options
WHERE option_name IN (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)",
'smart_coupons_is_send_email',
'smart_coupons_combine_emails',
'woocommerce_wc_sc_combined_email_coupon_settings',
'woocommerce_wc_sc_email_coupon_settings',
'wc_sc_is_show_terms_notice',
'wc_sc_terms_page_id',
'woo_sc_generate_coupon_posted_data',
'start_time_woo_sc',
'current_time_woo_sc',
'all_tasks_count_woo_sc',
'remaining_tasks_count_woo_sc',
'bulk_coupon_action_woo_sc',
'woo_sc_action_data',
'wc_sc_auto_apply_coupon_ids'
),
ARRAY_A
);
if ( ! empty( $results ) ) {
foreach ( $results as $result ) {
$option_value = ( ! empty( $existing_options[ $result['option_name'] ] ) ) ? $existing_options[ $result['option_name'] ] : '';
if ( ! empty( $option_value ) ) {
if ( is_array( $option_value ) ) {
$option_value = maybe_serialize( $option_value );
}
$wpdb->query( // phpcs:ignore
$wpdb->prepare(
"INSERT INTO {$wpdb->prefix}options (option_id, option_name, option_value, autoload)
VALUES (%d,%s,%s,%s)
ON DUPLICATE KEY UPDATE option_value = %s",
$result['option_id'],
$result['option_name'],
$option_value,
'no',
$option_value
)
);
}
}
}
}
$wpdb = clone $wpdb_obj; // phpcs:ignore
}
}
if ( 'yes' === $is_migrate_site_options ) {
update_site_option( 'wc_sc_migrate_site_options', 'no' );
}
}
/**
* Database changes required for Smart Coupons
*
* Delete option 'sc_display_global_coupons' if exists
*/
public static function smart_coupon_deactivate() {
if ( get_option( 'sc_display_global_coupons' ) !== false ) {
delete_option( 'sc_display_global_coupons' );
}
if ( false === ( get_option( 'sc_flushed_rules' ) ) || 'found' === ( get_option( 'sc_flushed_rules' ) ) ) {
delete_option( 'sc_flushed_rules' );
}
self::clear_cache();
}
/**
* Clear cache
*
* @return string $message
*/
public static function clear_cache() {
$all_cache_key = get_option( 'wc_sc_all_cache_key' );
if ( ! empty( $all_cache_key ) ) {
$cleared_cache = array();
foreach ( $all_cache_key as $key ) {
$is_cleared = wp_cache_delete( $key );
if ( true === $is_cleared ) {
$cleared_cache[] = $key;
}
}
// phpcs:disable
// if ( count( $all_cache_key ) === count( $cleared_cache ) ) {
// update_option( 'wc_sc_all_cache_key', array(), 'no' );
// /* translators: Number of all cache key */
// $message = sprintf( __( 'Successfully cleared %d cache!', 'woocommerce-smart-coupons' ), count( $all_cache_key ) );
// } else {
// $remaining = array_diff( $all_cache_key, $cleared_cache );
// update_option( 'wc_sc_all_cache_key', $remaining, 'no' );
// /* translators: 1. Number of cache not deleted 2. Number of all cache key */
// $message = sprintf( __( 'Failed! Could not clear %1$d out of %2$d cache', 'woocommerce-smart-coupons' ), count( $remaining ), count( $all_cache_key ) );
// }
// phpcs:enable
// There's no method in WordPress to detect if the cache is added successfully.
// Therefore it's not possible to know whether it is deleted or not.
// Hence returning a success message always.
// Enable above block of code when we can detect saving & deleting of cache.
}
return __( 'Successfully cleared WooCommerce Smart Coupons cache!', 'woocommerce-smart-coupons' );
}
}
}

View File

@@ -1,418 +0,0 @@
<?php
/**
* Actions for coupons dashboard
*
* @author StoreApps
* @since 4.4.0
* @version 1.4.0
* @package WooCommerce Smart Coupons
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Admin_Coupons_Dashboard_Actions' ) ) {
/**
* Class for actions on coupons dashboard
*/
class WC_SC_Admin_Coupons_Dashboard_Actions {
/**
* Variable to hold instance of WC_SC_Admin_Coupons_Dashboard_Actions
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
private function __construct() {
add_filter( 'post_row_actions', array( $this, 'woocommerce_sc_add_custom_actions' ), 1, 2 );
add_action( 'admin_action_duplicate_coupon', array( $this, 'woocommerce_duplicate_coupon_action' ) );
add_action( 'admin_footer', array( $this, 'add_post_row_script' ) );
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name Function to call.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return mixed Result of function call.
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Get single instance of WC_SC_Admin_Coupons_Dashboard_Actions
*
* @return WC_SC_Admin_Coupons_Dashboard_Actions Singleton object of WC_SC_Admin_Coupons_Dashboard_Actions
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Add Smart Coupons actions on WC Coupons dashboard
*
* @param array $actions Array of existing actions.
* @param WP_Post $post Post object.
* @return array $actions including duplicate action of coupons
*/
public function woocommerce_sc_add_custom_actions( $actions, $post ) {
if ( 'shop_coupon' !== $post->post_type ) {
return $actions;
}
if ( ! current_user_can( 'manage_woocommerce' ) ) {
return $actions;
}
$coupon_code = ( ! empty( $post->post_title ) ) ? $post->post_title : '';
$coupon_id = ( ! empty( $post->ID ) ) ? $post->ID : 0;
$shop_page_id = get_option( 'woocommerce_shop_page_id', 0 );
if ( ! empty( $shop_page_id ) ) {
$shop_page_id = 'shop';
} else {
$home_url = home_url();
$shop_page_id = ( function_exists( 'wpcom_vip_url_to_postid' ) ) ? wpcom_vip_url_to_postid( $home_url ) : url_to_postid( $home_url ); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.url_to_postid_url_to_postid
}
if ( empty( $shop_page_id ) ) {
$shop_page_id = 'cart';
}
$coupon_share_url = add_query_arg(
array(
'coupon-code' => $coupon_code,
'sc-page' => $shop_page_id,
),
home_url( '/' )
);
$actions['copy'] = '<a href="#" id="sc-click-to-copy-' . esc_attr( $coupon_id ) . '" onclick="sc_copy_to_clipboard(' . "'" . esc_js( $coupon_code ) . "'" . ')" data-clipboard-action="copy" data-clipboard-target=".row-title" title="' . __( 'Copy this coupon code', 'woocommerce-smart-coupons' ) . '" rel="permalink">' . __( 'Copy', 'woocommerce-smart-coupons' ) . '</a>';
$actions['share-link'] = '<a href="#" id="sc-click-to-share-' . esc_attr( $coupon_id ) . '" onclick="sc_copy_to_clipboard(' . "'" . esc_js( $coupon_share_url ) . "'" . ')" data-clipboard-action="copy" data-clipboard-target=".row-title" title="' . __( 'Copy coupon shareable link and apply via URL', 'woocommerce-smart-coupons' ) . '" rel="permalink">' . __( 'Get shareable link', 'woocommerce-smart-coupons' ) . '</a>';
if ( function_exists( 'duplicate_post_plugin_activation' ) ) {
return $actions;
} else {
$actions['duplicate'] = '<a href="' . esc_url( wp_nonce_url( admin_url( 'admin.php?action=duplicate_coupon&amp;post=' . $coupon_id ), 'woocommerce-duplicate-coupon_' . $coupon_id ) ) . '" title="' . __( 'Make a duplicate from this coupon', 'woocommerce-smart-coupons' ) . '" rel="permalink">' . __( 'Duplicate', 'woocommerce-smart-coupons' ) . '</a>';
}
return $actions;
}
/**
* Function to insert post meta values for duplicate coupon
*
* @param int $id ID of parent coupon.
* @param int $new_id ID of duplicated coupon.
*/
public function woocommerce_duplicate_coupon_post_meta( $id, $new_id ) {
global $wpdb;
$meta_keys = array( 'expiry_date', 'usage_count', '_used_by', 'date_expires' );
$how_many = count( $meta_keys );
$placeholders = array_fill( 0, $how_many, '%s' );
$post_meta_infos = $wpdb->get_results( $wpdb->prepare( "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=%d AND meta_key NOT IN ( " . implode( ',', $placeholders ) . ' )', array_merge( array( $id ), $meta_keys ) ) ); // phpcs:ignore
if ( 0 !== count( $post_meta_infos ) ) {
$sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
foreach ( $post_meta_infos as $meta_info ) {
$meta_key = $meta_info->meta_key;
$meta_value = $meta_info->meta_value;
$sql_query_sel[] = $wpdb->prepare( 'SELECT %d, %s, %s', $new_id, $meta_key, $meta_value );
}
$sql_query .= implode( ' UNION ALL ', $sql_query_sel );
$wpdb->query( $sql_query ); // phpcs:ignore
}
}
/**
* Function to duplicate post taxonomies for the duplicate coupon
*
* @param int $id ID of parent coupon.
* @param int $new_id ID of duplicated coupon.
* @param string $post_type Post type being duplicated.
*/
public function woocommerce_duplicate_coupon_post_taxonomies( $id, $new_id, $post_type ) {
global $wpdb;
$taxonomies = get_object_taxonomies( $post_type );
foreach ( $taxonomies as $taxonomy ) {
$post_terms = wp_get_object_terms( $id, $taxonomy );
$post_terms_count = count( $post_terms );
for ( $i = 0; $i < $post_terms_count; $i++ ) {
wp_set_object_terms( $new_id, $post_terms[ $i ]->slug, $taxonomy, true );
}
}
}
/**
* Function to create duplicate coupon and copy all properties of the coupon to duplicate coupon
*
* @param WP_Post $post Post object.
* @param int $parent Post parent ID.
* @param string $post_status Post status.
* @return int $new_post_id
*/
public function woocommerce_create_duplicate_from_coupon( $post, $parent = 0, $post_status = '' ) {
global $wpdb;
$new_post_author = wp_get_current_user();
$new_post_date = current_time( 'mysql' );
$new_post_date_gmt = get_gmt_from_date( $new_post_date );
if ( $parent > 0 ) {
$post_parent = $parent;
$post_status = $post_status ? $post_status : 'publish';
$suffix = '';
} else {
$post_parent = $post->post_parent;
$post_status = $post_status ? $post_status : 'draft';
$suffix = __( '(Copy)', 'woocommerce-smart-coupons' );
}
$new_post_type = $post->post_type;
$post_content = str_replace( "'", "''", $post->post_content );
$post_content_filtered = str_replace( "'", "''", $post->post_content_filtered );
$post_excerpt = str_replace( "'", "''", $post->post_excerpt );
$post_title = strtolower( str_replace( "'", "''", $post->post_title ) . $suffix );
$post_name = str_replace( "'", "''", $post->post_name );
$comment_status = str_replace( "'", "''", $post->comment_status );
$ping_status = str_replace( "'", "''", $post->ping_status );
$wpdb->insert(
$wpdb->posts,
array(
'post_author' => $new_post_author->ID,
'post_date' => $new_post_date,
'post_date_gmt' => $new_post_date_gmt,
'post_content' => $post_content,
'post_content_filtered' => $post_content_filtered,
'post_title' => $post_title,
'post_excerpt' => $post_excerpt,
'post_status' => $post_status,
'post_type' => $new_post_type,
'comment_status' => $comment_status,
'ping_status' => $ping_status,
'post_password' => $post->post_password,
'to_ping' => $post->to_ping,
'pinged' => $post->pinged,
'post_modified' => $new_post_date,
'post_modified_gmt' => $new_post_date_gmt,
'post_parent' => 0, // No need to link it with any other coupon.
'menu_order' => $post->menu_order,
'post_mime_type' => $post->post_mime_type,
)
); // WPCS: db call ok.
$new_post_id = $wpdb->insert_id;
$this->woocommerce_duplicate_coupon_post_taxonomies( $post->ID, $new_post_id, $post->post_type );
$this->woocommerce_duplicate_coupon_post_meta( $post->ID, $new_post_id );
return $new_post_id;
}
/**
* Function to return post id of the duplicate coupon to be created
*
* @param int $id ID of the coupon to duplicate.
* @return object $post Duplicated post object.
*/
public function woocommerce_get_coupon_to_duplicate( $id ) {
global $wpdb;
$post = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE ID=%d", $id ) ); // WPCS: cache ok, db call ok.
if ( isset( $post->post_type ) && 'revision' === $post->post_type ) {
$id = $post->post_parent;
$post = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE ID=%d", $id ) ); // WPCS: cache ok, db call ok.
}
return $post[0];
}
/**
* Function to validate condition and create duplicate coupon
*/
public function woocommerce_duplicate_coupon() {
if ( empty( $_REQUEST['post'] ) || ( isset( $_REQUEST['action'] ) && 'duplicate_post_save_as_new_page' === $_REQUEST['action'] ) ) { // phpcs:ignore
wp_die( esc_html__( 'No coupon to duplicate has been supplied!', 'woocommerce-smart-coupons' ) );
}
// Get the original page.
$id = absint( $_REQUEST['post'] ); // WPCS: input var ok.
check_admin_referer( 'woocommerce-duplicate-coupon_' . $id );
$post = $this->woocommerce_get_coupon_to_duplicate( $id );
if ( isset( $post ) && null !== $post ) {
$new_id = $this->woocommerce_create_duplicate_from_coupon( $post );
// If you have written a plugin which uses non-WP database tables to save
// information about a page you can hook this action to dupe that data.
do_action( 'woocommerce_duplicate_coupon', $new_id, $post );
// Redirect to the edit screen for the new draft page.
wp_safe_redirect( admin_url( 'post.php?action=edit&post=' . $new_id ) );
exit;
} else {
/* translators: %d: Post ID */
wp_die( sprintf( esc_html__( 'Coupon creation failed, could not find original coupon: %d', 'woocommerce-smart-coupons' ), esc_html( $id ) ) );
}
}
/**
* Function to call function to create duplicate coupon
*/
public function woocommerce_duplicate_coupon_action() {
$coupon_id = ( ! empty( $_REQUEST['post'] ) ) ? absint( $_REQUEST['post'] ) : 0;
check_admin_referer( 'woocommerce-duplicate-coupon_' . $coupon_id );
$action = ( ! empty( $_REQUEST['action'] ) ) ? wc_clean( wp_unslash( $_REQUEST['action'] ) ) : ''; // phpcs:ignore
if ( 'duplicate_coupon' !== $action ) {
return;
}
if ( $this->is_wc_gte_30() ) {
$coupon = new WC_Coupon( $coupon_id );
if ( false === $coupon ) {
/* translators: %s: coupon id */
wp_die( sprintf( esc_html__( 'Coupon creation failed, could not find original coupon: %s', 'woocommerce-smart-coupons' ), esc_html( $coupon_id ) ) );
}
$duplicate = $this->coupon_duplicate( $coupon );
// Hook rename to match other woocommerce_coupon_* hooks, and to move away from depending on a response from the wp_posts table.
do_action( 'wc_sc_duplicate_coupon', $duplicate, $coupon );
// Redirect to the edit screen for the new draft page.
wp_safe_redirect( admin_url( 'post.php?action=edit&post=' . $duplicate->get_id() ) );
exit;
} else {
$this->woocommerce_duplicate_coupon();
}
}
/**
* Duplicate coupon
*
* @param WC_Coupon $coupon The coupon object to duplicate.
* @return WC_Coupon $duplicate The duplicated coupon.
*/
public function coupon_duplicate( $coupon = null ) {
/**
* Filter to allow us to exclude meta keys from coupon duplication..
*
* @param array $exclude_meta The keys to exclude from the duplicate.
* @param array $existing_meta_keys The meta keys that the coupon already has.
* @since 7.2.0
*/
$meta_to_exclude = array_filter(
apply_filters(
'wc_sc_duplicate_coupon_exclude_meta',
array(),
array_map(
function ( $meta ) {
return $meta->key;
},
$coupon->get_meta_data()
)
)
);
$duplicate = clone $coupon;
$duplicate->set_id( 0 );
/* translators: %s contains the code of the original coupon. */
$duplicate->set_code( sprintf( '%s-copy', $duplicate->get_code() ) );
$duplicate->set_status( 'draft' );
$duplicate->set_date_created( null );
$duplicate->set_usage_count( 0 );
$duplicate->set_used_by( array() );
$duplicate->set_date_expires( null );
foreach ( $meta_to_exclude as $meta_key ) {
$duplicate->delete_meta_data( $meta_key );
}
/**
* This action can be used to modify the object further before it is created - it will be passed by reference.
*
* @since 3.0
*/
do_action( 'wc_sc_coupon_duplicate_before_save', $duplicate, $coupon );
// Save parent coupon.
$duplicate_id = $duplicate->save();
$duplicate = new WC_Coupon( $duplicate_id );
$this->woocommerce_duplicate_coupon_post_taxonomies( $coupon->get_id(), $duplicate_id, 'shop_coupon' );
if ( ! empty( $duplicate_id ) && 'draft' !== $duplicate->get_status() ) {
$args = array(
'ID' => $duplicate_id,
'post_status' => 'draft',
);
wp_update_post( $args ); // Because $coupon->set_status( 'draft' ) not working.
}
return new WC_Coupon( $duplicate_id );
}
/**
* Function to copy and share coupon via jQuery.
*/
public function add_post_row_script() {
$screen = get_current_screen();
if ( 'edit-shop_coupon' === $screen->id ) {
?>
<script type="text/javascript" class="sc-copy-share">
function sc_copy_to_clipboard(copyElement) {
var copyText = copyElement;
var temp = jQuery('<input>');
jQuery("body").append(temp);
temp.val(copyText).select();
document.execCommand("copy");
temp.remove();
}
</script>
<?php
}
}
}
}
WC_SC_Admin_Coupons_Dashboard_Actions::get_instance();

View File

@@ -1,485 +0,0 @@
<?php
/**
* Smart Coupons Admin Notifications
*
* @author StoreApps
* @since 4.0.0
* @version 1.4.0
*
* @package woocommerce-smart-coupons/includes/
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'WC_SC_Admin_Notifications' ) ) {
/**
* Class for handling admin pages of Smart Coupons
*/
class WC_SC_Admin_Notifications {
/**
* Variable to hold instance of WC_SC_Admin_Notifications
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
private function __construct() {
add_filter( 'plugin_action_links_' . plugin_basename( WC_SC_PLUGIN_FILE ), array( $this, 'plugin_action_links' ) );
add_action( 'wp_ajax_wc_sc_review_notice_action', array( $this, 'wc_sc_review_notice_action' ) );
add_action( 'wp_ajax_wc_sc_40_notice_action', array( $this, 'wc_sc_40_notice_action' ) );
add_action( 'admin_notices', array( $this, 'show_plugin_notice' ) );
// To update footer text on SC screens.
add_filter( 'admin_footer_text', array( $this, 'wc_sc_footer_text' ) );
add_filter( 'update_footer', array( $this, 'wc_sc_update_footer_text' ), 99 );
// To show 'Connect your store' notice of WC Helper on SC pages.
add_filter( 'woocommerce_screen_ids', array( $this, 'add_wc_connect_store_notice_on_sc_pages' ) );
// Show Database update notices.
add_action( 'admin_notices', array( $this, 'admin_db_update_notices' ) );
}
/**
* Get single instance of WC_SC_Admin_Pages
*
* @return WC_SC_Admin_Pages Singleton object of WC_SC_Admin_Pages
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Function to add more action on plugins page
*
* @param array $links Existing links.
* @return array $links
*/
public function plugin_action_links( $links ) {
$action_links = array(
'settings' => '<a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=wc-smart-coupons' ) ) . '">' . esc_html__( 'Settings', 'woocommerce-smart-coupons' ) . '</a>',
'faqs' => '<a href="' . esc_url( admin_url( 'admin.php?page=sc-faqs' ) ) . '">' . esc_html__( 'FAQ\'s', 'woocommerce-smart-coupons' ) . '</a>',
'docs' => '<a target="_blank" href="' . esc_url( 'https://woocommerce.com/document/smart-coupons/' ) . '">' . __( 'Docs', 'woocommerce-smart-coupons' ) . '</a>',
'support' => '<a target="_blank" href="' . esc_url( 'https://woocommerce.com/my-account/create-a-ticket/' ) . '">' . __( 'Support', 'woocommerce-smart-coupons' ) . '</a>',
'review' => '<a target="_blank" href="' . esc_url( 'https://woocommerce.com/products/smart-coupons/?review' ) . '">' . __( 'Review', 'woocommerce-smart-coupons' ) . '</a>',
);
return array_merge( $action_links, $links );
}
/**
* Handle Smart Coupons review notice action
*/
public function wc_sc_review_notice_action() {
check_ajax_referer( 'wc-sc-review-notice-action', 'security' );
$post_do = ( ! empty( $_POST['do'] ) ) ? wc_clean( wp_unslash( $_POST['do'] ) ) : ''; // phpcs:ignore
$option = strtotime( '+1 month' );
if ( 'remove' === $post_do ) {
$option = 'no';
}
update_option( 'wc_sc_is_show_review_notice', $option, 'no' );
wp_send_json( array( 'success' => 'yes' ) );
}
/**
* Handle Smart Coupons version 4.0.0 notice action
*/
public function wc_sc_40_notice_action() {
check_ajax_referer( 'wc-sc-40-notice-action', 'security' );
update_option( 'wc_sc_is_show_40_notice', 'no', 'no' );
wp_send_json( array( 'success' => 'yes' ) );
}
/**
* Show plugin review notice
*/
public function show_plugin_notice() {
global $pagenow, $post;
$valid_post_types = array( 'shop_coupon', 'shop_order', 'product' );
$valid_pagenow = array( 'edit.php', 'post.php', 'plugins.php' );
$is_show_review_notice = get_option( 'wc_sc_is_show_review_notice' );
$is_coupon_enabled = get_option( 'woocommerce_enable_coupons' );
$get_post_type = ( ! empty( $post->post_type ) ) ? $post->post_type : '';
$get_page = ( ! empty( $_GET['page'] ) ) ? wc_clean( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore
$get_tab = ( ! empty( $_GET['tab'] ) ) ? wc_clean( wp_unslash( $_GET['tab'] ) ) : ''; // phpcs:ignore
$design = get_option( 'wc_sc_setting_coupon_design', 'basic' );
$is_page = ( in_array( $pagenow, $valid_pagenow, true ) || in_array( $get_post_type, $valid_post_types, true ) || ( 'admin.php' === $pagenow && ( 'wc-smart-coupons' === $get_page || 'wc-smart-coupons' === $get_tab ) ) );
if ( $is_page && 'yes' !== $is_coupon_enabled ) {
?>
<div id="wc_sc_coupon_disabled" class="updated fade error">
<p>
<?php
echo '<strong>' . esc_html__( 'Important', 'woocommerce-smart-coupons' ) . ':</strong> ' . esc_html__( 'Setting "Enable the use of coupon codes" is disabled.', 'woocommerce-smart-coupons' ) . ' ' . sprintf(
'<a href="%s">%s</a>',
esc_url(
add_query_arg(
array(
'page' => 'wc-settings',
'tab' => 'general',
),
admin_url( 'admin.php' )
)
),
esc_html__( 'Enable', 'woocommerce-smart-coupons' )
) . ' ' . esc_html__( 'it to use', 'woocommerce-smart-coupons' ) . ' <strong>' . esc_html__( 'WooCommerce Smart Coupons', 'woocommerce-smart-coupons' ) . '</strong> ' . esc_html__( 'features.', 'woocommerce-smart-coupons' );
?>
</p>
</div>
<?php
}
// Review Notice.
if ( $is_page && ! empty( $is_show_review_notice ) && 'no' !== $is_show_review_notice && time() >= absint( $is_show_review_notice ) ) {
if ( ! wp_script_is( 'jquery' ) ) {
wp_enqueue_script( 'jquery' );
}
?>
<style type="text/css" media="screen">
#wc_sc_review_notice .wc_sc_review_notice_action {
float: right;
padding: 0.5em 0;
text-align: right;
}
</style>
<script type="text/javascript">
jQuery(function(){
jQuery('body').on('click', '#wc_sc_review_notice .wc_sc_review_notice_action a.wc_sc_review_notice_remind', function( e ){
jQuery.ajax({
url: '<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>',
type: 'post',
dataType: 'json',
data: {
action: 'wc_sc_review_notice_action',
security: '<?php echo esc_html( wp_create_nonce( 'wc-sc-review-notice-action' ) ); ?>',
do: 'remind'
},
success: function( response ){
if ( response.success != undefined && response.success != '' && response.success == 'yes' ) {
jQuery('#wc_sc_review_notice').fadeOut(500, function(){ jQuery('#wc_sc_review_notice').remove(); });
}
}
});
return false;
});
jQuery('body').on('click', '#wc_sc_review_notice .wc_sc_review_notice_action a.wc_sc_review_notice_remove', function(){
jQuery.ajax({
url: '<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>',
type: 'post',
dataType: 'json',
data: {
action: 'wc_sc_review_notice_action',
security: '<?php echo esc_html( wp_create_nonce( 'wc-sc-review-notice-action' ) ); ?>',
do: 'remove'
},
success: function( response ){
if ( response.success != undefined && response.success != '' && response.success == 'yes' ) {
jQuery('#wc_sc_review_notice').fadeOut(500, function(){ jQuery('#wc_sc_review_notice').remove(); });
}
}
});
return false;
});
});
</script>
<div id="wc_sc_review_notice" class="updated fade">
<div class="wc_sc_review_notice_action">
<a href="javascript:void(0)" class="wc_sc_review_notice_remind"><?php echo esc_html__( 'Remind me after a month', 'woocommerce-smart-coupons' ); ?></a><br>
<a href="javascript:void(0)" class="wc_sc_review_notice_remove"><?php echo esc_html__( 'Never show again', 'woocommerce-smart-coupons' ); ?></a>
</div>
<p>
<?php echo esc_html__( 'Awesome, you successfully auto-generated a coupon! Are you having a great experience with', 'woocommerce-smart-coupons' ) . ' <strong>' . esc_html__( 'WooCommerce Smart Coupons', 'woocommerce-smart-coupons' ) . '</strong> ' . esc_html__( 'so far?', 'woocommerce-smart-coupons' ) . '<br>' . esc_html__( 'Please consider', 'woocommerce-smart-coupons' ) . ' <a href="' . esc_url( 'https://woocommerce.com/products/smart-coupons/#reviews' ) . '">' . esc_html__( 'leaving a review', 'woocommerce-smart-coupons' ) . '</a> ' . esc_html__( '! If things aren\'t going quite as expected, we\'re happy to help -- please reach out to', 'woocommerce-smart-coupons' ) . ' <a href="' . esc_url( 'https://woocommerce.com/my-account/create-a-ticket/' ) . '">' . esc_html__( 'our support team', 'woocommerce-smart-coupons' ) . '</a>.'; ?>
</p>
</div>
<?php
}
if ( $is_page && 'custom-design' === $design ) {
?>
<div class="updated fade error" style="background-color: #f0fff0;">
<p>
<?php
echo sprintf(
/* translators: 1: WooCommerce Smart Coupons 2: Link for the Smart Coupons settings */
esc_html__( '%1$s: You are using a custom coupon style which is planned to be removed from the plugin in upcoming versions. New, improved styles & colors are added in the version 4.9.0. We would request you to choose a color scheme & a style for coupon from the newly added colors & styles. You can do this from %2$s.', 'woocommerce-smart-coupons' ),
'<strong>' . esc_html__( 'WooCommerce Smart Coupons', 'woocommerce-smart-coupons' ) . '</strong>',
'<a href="' . esc_url(
add_query_arg(
array(
'page' => 'wc-settings',
'tab' => 'wc-smart-coupons',
),
admin_url( 'admin.php' )
)
) . '" target="_blank">' . esc_html__(
'Smart Coupons settings',
'woocommerce-smart-coupons'
) . '</a>'
);
?>
</p>
</div>
<?php
}
}
/**
* Function to 'Connect your store' notice on Smart Coupons pages in admin
*
* @param string $sc_rating_text Text in footer (left).
* @return string $sc_rating_text
*/
public function wc_sc_footer_text( $sc_rating_text ) {
global $post, $pagenow;
if ( ! empty( $pagenow ) ) {
$get_post_type = ( ! empty( $post->post_type ) ) ? $post->post_type : '';
$get_page = ( ! empty( $_GET['page'] ) ) ? wc_clean( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore
$get_tab = ( ! empty( $_GET['tab'] ) ) ? wc_clean( wp_unslash( $_GET['tab'] ) ) : ''; // phpcs:ignore
$sc_pages = array( 'wc-smart-coupons', 'sc-about', 'sc-faqs' );
if ( in_array( $get_page, $sc_pages, true ) || 'shop_coupon' === $get_post_type || 'wc-smart-coupons' === $get_tab ) {
?>
<style type="text/css">
#wpfooter {
display: block !important;
}
</style>
<?php
/* translators: %s: link to review WooCommerce Smart Coupons */
$sc_rating_text = wp_kses_post( sprintf( __( 'Liked WooCommerce Smart Coupons? Leave us a %s. A huge thank you from WooCommerce & StoreApps in advance!', 'woocommerce-smart-coupons' ), '<a target="_blank" href="' . esc_url( 'https://woocommerce.com/products/smart-coupons/?review' ) . '" style="color: #5850EC;">5-star rating here</a>' ) );
}
}
return $sc_rating_text;
}
/**
* Function to 'Connect your store' notice on Smart Coupons pages in admin
*
* @param string $sc_text Text in footer (right).
* @return string $sc_text
*/
public function wc_sc_update_footer_text( $sc_text ) {
global $post, $pagenow;
if ( ! empty( $pagenow ) ) {
$get_post_type = ( ! empty( $post->post_type ) ) ? $post->post_type : '';
$get_page = ( ! empty( $_GET['page'] ) ) ? wc_clean( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore
$get_tab = ( ! empty( $_GET['tab'] ) ) ? wc_clean( wp_unslash( $_GET['tab'] ) ) : ''; // phpcs:ignore
$sc_pages = array( 'wc-smart-coupons', 'sc-about', 'sc-faqs' );
if ( in_array( $get_page, $sc_pages, true ) || 'shop_coupon' === $get_post_type || 'wc-smart-coupons' === $get_tab ) {
/* translators: %s: link to submit idea for Smart Coupons on WooCommerce idea board */
$sc_text = sprintf( __( 'Have a feature request? Submit it %s.', 'woocommerce-smart-coupons' ), '<a href="' . esc_url( 'https://woocommerce.com/feature-requests/smart-coupons/' ) . '" target="_blank" style="color: #5850EC;">' . __( 'here', 'woocommerce-smart-coupons' ) . '</a>' );
}
}
return $sc_text;
}
/**
* Function to 'Connect your store' notice on Smart Coupons pages in admin
*
* @param array $screen_ids List of existing screen ids.
* @return array $screen_ids
*/
public function add_wc_connect_store_notice_on_sc_pages( $screen_ids ) {
array_push( $screen_ids, 'woocommerce_page_wc-smart-coupons' );
return $screen_ids;
}
/**
* Function to render admin notice
*
* @param string $type Notice type.
* @param string $title Notice title.
* @param string $message Notice message.
* @param string $action Notice actions.
* @param bool $dismissible Notice dismissible.
* @return void.
*/
public function show_notice( $type = 'info', $title = '', $message = '', $action = '', $dismissible = false ) {
$css_classes = array(
'notice',
'notice-' . $type,
);
if ( true === $dismissible ) {
$css_classes[] = 'is-dismissible';
}
?>
<div class="<?php echo esc_attr( implode( ' ', $css_classes ) ); ?>">
<?php
if ( ! empty( $title ) ) {
printf( '<p><strong>%s</strong></p>', esc_html( $title ) );
}
if ( ! empty( $message ) ) {
printf( '<p>%s</p>', esc_html( $message ) );
}
if ( ! empty( $action ) ) {
printf( '<p class="submit">%s</p>', wp_kses_post( $action ) );
}
?>
</div>
<?php
}
/**
* Function to show database update notice
*/
public function admin_db_update_notices() {
if ( ! class_exists( 'WC_SC_Background_Upgrade' ) ) {
include_once 'class-wc-sc-background-upgrade.php';
}
$wcsc_db = WC_SC_Background_Upgrade::get_instance();
$update_status = $wcsc_db->get_status( '4.28.0' );
if ( 'pending' === $update_status ) {
// Notice for pending update.
$this->db_update_pending_notice();
} elseif ( 'processing' === $update_status ) {
// Notice for processing update.
$this->db_update_processing_notice();
} elseif ( 'completed' === $update_status ) {
// Notice for completed update.
$this->db_update_completed_notice();
$wcsc_db->set_status( '4.28.0', 'done' );
}
}
/**
* Function to show pending database update notice
*/
public function db_update_pending_notice() {
global $woocommerce_smart_coupon;
$plugin_version = $woocommerce_smart_coupon->get_smart_coupons_version();
/* translators: %s: Plugin name */
$title = sprintf( __( '%s database update required', 'woocommerce-smart-coupons' ), 'WooCommerce Smart Coupons' );
$message = __( 'The database update process runs in the background and may take a little while, so please be patient.', 'woocommerce-smart-coupons' );
$update_url = wp_nonce_url(
add_query_arg(
array(
'page' => 'wc-settings',
'tab' => 'wc-smart-coupons',
'wc_sc_update' => '4.28.0',
),
admin_url( 'admin.php' )
),
'wc_sc_db_process',
'wc_sc_db_update_nonce'
);
$action_button = sprintf( '<a href="%1$s" class="button button-primary">%2$s</a>', esc_url( $update_url ), __( 'Update database', 'woocommerce-smart-coupons' ) );
$this->show_notice( 'warning', $title, $message, $action_button );
}
/**
* Function to show database update processing notice.
*/
public function db_update_processing_notice() {
if ( 'woocommerce_page_wc-status' === $this->get_current_screen_id() && isset( $_GET['tab'] ) && 'action-scheduler' === wc_clean( wp_unslash( $_GET['tab'] ) ) ) { // phpcs:ignore
return;
}
$actions_url = add_query_arg(
array(
'page' => 'wc-status',
'tab' => 'action-scheduler',
's' => 'move_applied_coupon_options_to_transient',
'status' => 'pending',
),
admin_url( 'admin.php' )
);
$cron_disabled = defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON;
/* translators: %s: Plugin name */
$message = sprintf( __( '%s is updating the database in the background. The database update process may take a little while, so please be patient.', 'woocommerce-smart-coupons' ), 'WooCommerce Smart Coupons' );
if ( true === $cron_disabled ) {
$message .= '<br>' . __( 'Note: WP CRON has been disabled on your install which may prevent this update from completing.', 'woocommerce-smart-coupons' );
}
$action_button = sprintf( '<a href="%1$s" class="button button-secondary">%2$s</a>', esc_url( $actions_url ), __( 'View status', 'woocommerce-smart-coupons' ) );
$this->show_notice( 'info', '', $message, $action_button );
}
/**
* Function to show database update completed notice.
*/
public function db_update_completed_notice() {
/* translators: %s: Plugin name */
$message = sprintf( __( '%s database update completed. Thank you for updating to the latest version!', 'woocommerce-smart-coupons' ), 'WooCommerce Smart Coupons' );
$this->show_notice( 'success', '', $message, '', true );
}
/**
* Function to get current screen id.
*
* @return string.
*/
public function get_current_screen_id() {
$screen = get_current_screen();
return $screen ? $screen->id : '';
}
}
}
WC_SC_Admin_Notifications::get_instance();

View File

@@ -1,504 +0,0 @@
<?php
/**
* A Welcome page for store admin
*
* @author StoreApps
* @since 3.3.0
* @version 1.3.0
*
* @package woocommerce-smart-coupons/includes/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Admin_Welcome' ) ) {
/**
* WC_SC_Admin_Welcome class
*/
class WC_SC_Admin_Welcome {
/**
* Variable to hold instance of WC_SC_Admin_Welcome
*
* @var $instance
*/
private static $instance = null;
/**
* Hook in tabs.
*/
private function __construct() {
add_action( 'admin_menu', array( $this, 'admin_menus' ) );
add_action( 'admin_head', array( $this, 'admin_head' ) );
add_action( 'admin_init', array( $this, 'sc_welcome' ) );
}
/**
* Get single instance of WC_SC_Admin_Welcome
*
* @return WC_SC_Admin_Welcome Singleton object of WC_SC_Admin_Welcome
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Add admin menus/screens.
*/
public function admin_menus() {
$get_page = ( ! empty( $_GET['page'] ) ) ? wc_clean( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore
if ( empty( $get_page ) ) {
return;
}
$welcome_page_name = __( 'About Smart Coupons', 'woocommerce-smart-coupons' );
$welcome_page_title = __( 'Welcome to Smart Coupons', 'woocommerce-smart-coupons' );
$parent_slug = ( $this->is_wc_gte_44() ) ? 'woocommerce-marketing' : 'woocommerce';
switch ( $get_page ) {
case 'sc-about':
add_submenu_page( $parent_slug, $welcome_page_title, $welcome_page_name, 'manage_options', 'sc-about', array( $this, 'about_screen' ) );
break;
case 'sc-faqs':
add_submenu_page( $parent_slug, $welcome_page_title, $welcome_page_name, 'manage_options', 'sc-faqs', array( $this, 'faqs_screen' ) );
break;
}
}
/**
* Add styles just for this page, and remove dashboard page links.
*/
public function admin_head() {
$parent_slug = ( $this->is_wc_gte_44() ) ? 'woocommerce-marketing' : 'woocommerce';
remove_submenu_page( $parent_slug, 'sc-about' );
remove_submenu_page( $parent_slug, 'sc-faqs' );
$get_page = ( ! empty( $_GET['page'] ) ) ? wc_clean( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore
if ( ! empty( $get_page ) && ( 'sc-faqs' === $get_page || 'sc-about' === $get_page ) ) {
?>
<style type="text/css">
/*<![CDATA[*/
.about-wrap h3 {
margin-top: 1em;
margin-right: 0em;
margin-bottom: 0.1em;
}
.about-wrap .button-primary {
margin-top: 18px;
}
.about-wrap .button-hero {
color: #FFF!important;
border-color: #03a025!important;
background: #03a025 !important;
box-shadow: 0 1px 0 #03a025;
font-size: 1em;
font-weight: bold;
}
.about-wrap .button-hero:hover {
color: #FFF!important;
background: #0AAB2E!important;
border-color: #0AAB2E!important;
}
.about-wrap p {
margin-top: 0.6em;
margin-bottom: 0.8em;
}
.about-wrap .feature-section {
padding-bottom: 5px;
}
.about-wrap .aligncenter {
text-align: center;
}
.about-wrap,
.about-wrap .has-2-columns,
.about-wrap .has-3-columns {
max-width: unset !important;
}
ul.sc-top-features {
list-style-type: disc !important;
padding-left: 1.5em !important;
}
/*]]>*/
</style>
<?php
}
}
/**
* Intro text/links shown on all about pages.
*/
private function intro() {
if ( is_callable( 'WC_Smart_Coupons::get_smart_coupons_plugin_data' ) ) {
$plugin_data = WC_Smart_Coupons::get_smart_coupons_plugin_data();
$version = $plugin_data['Version'];
} else {
$version = '';
}
?>
<h1><?php echo esc_html__( 'Thank you for installing WooCommerce Smart Coupons', 'woocommerce-smart-coupons' ) . ' ' . esc_html( $version ) . '!'; ?></h1>
<p class="about-text"><?php echo esc_html__( 'Glad to have you onboard. We hope WooCommerce Smart Coupons adds to your desired success 🏆', 'woocommerce-smart-coupons' ); ?></p>
<div class="has-2-columns feature-section col two-col" style="margin-bottom: 30px !important;">
<div class="is-vertically-aligned-center column col">
<a href="<?php echo esc_url( admin_url( 'edit.php?post_type=shop_coupon' ) ); ?>" class="button button-hero"><?php echo esc_html__( 'Go To Coupons', 'woocommerce-smart-coupons' ); ?></a>
</div>
<div class="is-vertically-aligned-center column col last-feature">
<p class="alignright">
<?php
$settings_tab_url = add_query_arg(
array(
'page' => 'wc-settings',
'tab' => 'wc-smart-coupons',
),
admin_url( 'admin.php' )
);
?>
<a href="<?php echo esc_url( $settings_tab_url ); ?>" class="button button-primary" target="_blank"><?php echo esc_html__( 'Settings', 'woocommerce-smart-coupons' ); ?></a>
<a href="<?php echo esc_url( apply_filters( 'smart_coupons_docs_url', 'https://woocommerce.com/document/smart-coupons/', 'woocommerce-smart-coupons' ) ); ?>" class="docs button button-primary" target="_blank"><?php echo esc_html__( 'Docs', 'woocommerce-smart-coupons' ); ?></a>
</p>
</div>
</div>
<h2 class="nav-tab-wrapper">
<a class="nav-tab
<?php
$get_page = ( ! empty( $_GET['page'] ) ) ? wc_clean( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore
if ( 'sc-about' === $get_page ) {
echo 'nav-tab-active';
}
?>
" href="<?php echo esc_url( admin_url( add_query_arg( array( 'page' => 'sc-about' ), 'admin.php' ) ) ); ?>">
<?php echo esc_html__( 'Know Smart Coupons', 'woocommerce-smart-coupons' ); ?>
</a>
<a class="nav-tab
<?php
if ( 'sc-faqs' === $get_page ) {
echo 'nav-tab-active';
}
?>
" href="<?php echo esc_url( admin_url( add_query_arg( array( 'page' => 'sc-faqs' ), 'admin.php' ) ) ); ?>">
<?php echo esc_html__( "FAQ's", 'woocommerce-smart-coupons' ); ?>
</a>
</h2>
<?php
}
/**
* Output the about screen.
*/
public function about_screen() {
if ( ! wp_script_is( 'jquery' ) ) {
wp_enqueue_script( 'jquery' );
}
?>
<script type="text/javascript">
jQuery(function(){
jQuery('#toplevel_page_woocommerce').find('a[href$=shop_coupon]').addClass('current');
jQuery('#toplevel_page_woocommerce').find('a[href$=shop_coupon]').parent().addClass('current');
});
</script>
<div class="wrap about-wrap">
<?php $this->intro(); ?>
<div>
<div class="has-3-columns feature-section col three-col">
<div class="column col">
<h4><?php echo esc_html__( 'What is Smart Coupons?', 'woocommerce-smart-coupons' ); ?></h4>
<p>
<?php echo esc_html__( 'Smart Coupons is a powerful extension, built on top of WooCommerce coupons. It adds a new discount type - Store Credit - and advanced functionality to the default coupons.', 'woocommerce-smart-coupons' ); ?>
<?php echo esc_html__( 'Smart Coupons enable coupons to become an automatic/interactive system.', 'woocommerce-smart-coupons' ); ?>
</p>
</div>
<div class="column col">
<h4><?php echo esc_html__( 'Top Smart Coupons features', 'woocommerce-smart-coupons' ); ?></h4>
<ul class="sc-top-features">
<li><?php echo esc_html__( 'Create and gift Store Credit / Gift Cards', 'woocommerce-smart-coupons' ); ?></li>
<li><?php echo esc_html__( 'Bulk generate coupons', 'woocommerce-smart-coupons' ); ?></li>
<li><?php echo esc_html__( 'Apply multiple coupons via URL', 'woocommerce-smart-coupons' ); ?></li>
<li><?php echo esc_html__( 'Advanced restrictions - payment, shipping, location, user roles, product attributes', 'woocommerce-smart-coupons' ); ?></li>
</ul>
<p>
<?php echo esc_html__( 'and a lot more…', 'woocommerce-smart-coupons' ); ?>
</p>
</div>
<div class="column col last-feature">
<h4><?php echo esc_html__( 'Automatic payment for subscription renewals', 'woocommerce-smart-coupons' ); ?></h4>
<p>
<?php
/* translators: WooCommerce Subscriptions product link */
echo sprintf( esc_html__( 'If your store is using %s and your customer has purchased a subscription using a Store Credit. If that store credit has balance left in it, store will automatically use it for renewing that subscription.', 'woocommerce-smart-coupons' ), '<a href="https://woocommerce.com/products/woocommerce-subscriptions/?aff=5475">' . esc_html__( 'WooCommerce Subscriptions', 'woocommerce-smart-coupons' ) . '</a>' );
?>
</p>
</div>
</div>
<center><h3><?php echo esc_html__( 'How to use Smart Coupons the best way', 'woocommerce-smart-coupons' ); ?></h3></center>
<div class="has-3-columns feature-section col three-col">
<div class="column col">
<h4><?php echo esc_html__( 'Sell or issue store credit / gift cards', 'woocommerce-smart-coupons' ); ?></h4>
<p>
<?php
/* translators: 1: Affiliate For WooCommerce 2: Smart Manager 3: Smart Offers */
echo sprintf( esc_html__( 'Let customers purchase gift cards from you or you issue store credit that your users can redeem on the current or next purchase. See how: %1$s or %2$s', 'woocommerce-smart-coupons' ), ' <a href="https://woocommerce.com/document/smart-coupons/how-to-sell-gift-card-of-any-amount/" target="_blank">' . esc_html__( 'any amount', 'woocommerce-smart-coupons' ) . '</a>', '<a href="https://woocommerce.com/document/smart-coupons/how-to-sell-gift-card-of-variable-but-a-fixed-amount/" target="_blank">' . esc_html__( 'variable but fixed amount', 'woocommerce-smart-coupons' ) . '</a>.' );
?>
</p>
</div>
<div class="column col">
<h4><?php echo esc_html__( 'Bulk create unique coupons & email them', 'woocommerce-smart-coupons' ); ?></h4>
<p>
<?php echo esc_html__( 'Import and export unique coupons in bulk via CSV. Share coupon codes to deal sites or email them to your customers.', 'woocommerce-smart-coupons' ) . ' <a href="https://woocommerce.com/document/smart-coupons/how-to-bulk-generate-coupons/" target="_blank">' . esc_html__( 'See how', 'woocommerce-smart-coupons' ) . '</a>.'; ?>
</p>
</div>
<div class="column col last-feature">
<h4><?php echo esc_html__( 'Gift a product via coupon', 'woocommerce-smart-coupons' ); ?></h4>
<p>
<?php echo esc_html__( 'Attach a gift of any value (free or paid product) to a particular coupon. Here, instead of a discount, a product is redeemed for the coupon code.', 'woocommerce-smart-coupons' ) . ' <a href="https://woocommerce.com/document/smart-coupons/how-to-gift-a-product-via-coupon/" target="_blank">' . esc_html__( 'See how', 'woocommerce-smart-coupons' ) . '</a>.'; ?>
</p>
</div>
</div>
<div class="has-3-columns feature-section col three-col">
<div class="column col">
<h4><?php echo esc_html__( 'Give discounts to customers for next purchase', 'woocommerce-smart-coupons' ); ?></h4>
<p>
<?php echo esc_html__( 'You can give a coupon to your customer after every purchase, which can encourage them to purchase again from you.', 'woocommerce-smart-coupons' ) . ' <a href="https://woocommerce.com/document/smart-coupons/how-to-give-coupons-with-products-for-next-order/" target="_blank">' . esc_html__( 'See how', 'woocommerce-smart-coupons' ) . '</a>.'; ?>
</p>
</div>
<div class="column col">
<h4><?php echo esc_html__( 'Set a maximum discount limit', 'woocommerce-smart-coupons' ); ?></h4>
<p>
<?php echo esc_html__( 'Give bigger discounts without hurting your profits. Offer a percentage off coupon upto a particular value. Example - Flat 50% off upto $100.', 'woocommerce-smart-coupons' ); ?>
</p>
</div>
<div class="column col last-feature">
<h4><?php echo esc_html__( 'Make customer\'s coupon usage, easy & simple', 'woocommerce-smart-coupons' ); ?></h4>
<p>
<?php echo esc_html__( 'Show only valid coupons to your customer (if logged in) on cart, checkout & My Account page. Coupons can be applied with single click. So, no need to remember the coupon code or copy-pasting.', 'woocommerce-smart-coupons' ); ?>
</p>
</div>
</div>
</div>
</div>
<?php
}
/**
* Output the FAQ's screen.
*/
public function faqs_screen() {
if ( ! wp_script_is( 'jquery' ) ) {
wp_enqueue_script( 'jquery' );
}
?>
<script type="text/javascript">
jQuery(function(){
jQuery('#toplevel_page_woocommerce').find('a[href$=shop_coupon]').addClass('current');
jQuery('#toplevel_page_woocommerce').find('a[href$=shop_coupon]').parent().addClass('current');
});
</script>
<div class="wrap about-wrap">
<?php $this->intro(); ?>
<h3 class="aligncenter"><?php echo esc_html__( 'FAQ / Common Problems', 'woocommerce-smart-coupons' ); ?></h3>
<?php
$faqs = array(
array(
'que' => esc_html__( 'When trying to add coupon/Smart Coupon, I get "Invalid post type" message.', 'woocommerce-smart-coupons' ),
'ans' => esc_html__( 'Make sure use of coupon is enabled in your store. You can find this setting', 'woocommerce-smart-coupons' ) . ' <a href="' . add_query_arg(
array(
'page' => 'wc-settings',
'tab' => 'general',
),
admin_url( 'admin.php' )
) . '" target="_blank">' . __( 'here', 'woocommerce-smart-coupons' ) . '</a>.',
),
array(
'que' => esc_html__( 'Smart Coupon\'s fields are broken?', 'woocommerce-smart-coupons' ),
'ans' => esc_html__( 'Make sure you are using the ', 'woocommerce-smart-coupons' ) . '<a target="_blank" href="http://dzv365zjfbd8v.cloudfront.net/changelogs/woocommerce-smart-coupons/changelog.txt">' . __( 'latest version of Smart Coupons', 'woocommerce-smart-coupons' ) . '</a>' . esc_html__( '. If still the issue persist, temporarily de-activate all plugins except WooCommerce & Smart Coupons. Re-check the issue, if the issue still persists, contact us (from the link at the end of this page). If the issue goes away, re-activate other plugins one-by-one & re-checking the fields, to find out which plugin is conflicting.', 'woocommerce-smart-coupons' ),
),
array(
'que' => esc_html__( 'How to translate texts from Smart Coupons?', 'woocommerce-smart-coupons' ),
'ans' => esc_html__( 'Simplest method is by installing', 'woocommerce-smart-coupons' ) . ' <a href="https://wordpress.org/plugins/loco-translate/" target="_blank">' . esc_html__( 'Loco Translate', 'woocommerce-smart-coupons' ) . '</a> ' . esc_html__( 'plugin and then following steps listed ', 'woocommerce-smart-coupons' ) . ' <a href="https://woocommerce.com/document/smart-coupons/how-to-translate-smart-coupons/" target="_blank">' . __( 'here', 'woocommerce-smart-coupons' ) . '</a>.',
),
array(
'que' => esc_html__( 'How to change texts of the emails sent from Smart Coupons?', 'woocommerce-smart-coupons' ),
'ans' => esc_html__( 'You can do this by overriding the email template.', 'woocommerce-smart-coupons' ) . ' <a href="https://woocommerce.com/document/smart-coupons/how-to-change-replace-and-override-email-template/" target="_blank">' . esc_html__( 'How to override email template', 'woocommerce-smart-coupons' ) . '</a>.',
),
array(
'que' => esc_html__( 'Can coupon code have any spaces in the name? / My Store Credit/Gift Certificate is not working (not generating new coupon code).', 'woocommerce-smart-coupons' ),
'ans' => esc_html__( 'No. Coupon code should not have any spaces in the name, Eg, Coupon code should be “gift-certificate” & not “gift certificate”.', 'woocommerce-smart-coupons' ),
),
array(
'que' => esc_html__( 'What\'s the URL to a coupon, so it\'s automatically inserted when visiting?', 'woocommerce-smart-coupons' ),
/* translators: Documentation link for 'How to Apply Single or Multiple Coupons on Click of a Link' */
'ans' => esc_html__( 'URL of coupon should be like this:', 'woocommerce-smart-coupons' ) . ' <code>https://www.mysite.com/?coupon-code=discount5&sc-page=shop</code> ' . esc_html__( '. Replace www.mysite.com with your own site URL and replace discount5 with the your coupon code.', 'woocommerce-smart-coupons' ) . ' ' . sprintf( esc_html__( 'For more details you can refer to this article: %s', 'woocommerce-smart-coupons' ), '<a href="https://woocommerce.com/document/smart-coupons/how-to-apply-single-or-multiple-coupons-on-click-of-a-link/" target="_blank">' . esc_html__( 'How to Apply Single or Multiple Coupons on Click of a Link', 'woocommerce-smart-coupons' ) . '</a>' ),
),
array(
'que' => esc_html__( 'Do not want to tie store credit to be used by only one customer? / Can a customer send a gift certificate to themselves to pass on to someone else?', 'woocommerce-smart-coupons' ),
'ans' => esc_html__( 'Edit the main coupon which is entered in "Coupons" field of the product edit page, then go to "Usage Restrictions" > "Disable Email Restriction" and disable this setting and save the coupon.', 'woocommerce-smart-coupons' ),
),
array(
'que' => esc_html__( 'Getting \'Page Not Found Error\' when accessing Coupons tab from My Account Page?', 'woocommerce-smart-coupons' ),
'ans' => esc_html__( 'Go to WordPress -> Settings -> Permalinks and click on Save Settings once.', 'woocommerce-smart-coupons' ),
),
array(
'que' => esc_html__( 'Is there any reference file for creating an import file for coupons?', 'woocommerce-smart-coupons' ),
/* translators: 1. File name 2. File download link */
'ans' => sprintf( esc_html__( 'There is one file which is located inside the plugin. You can download the %1$s file from %2$s.', 'woocommerce-smart-coupons' ), '<code>sample.csv</code>', '<a href="' . esc_url( plugins_url( dirname( dirname( plugin_basename( __FILE__ ) ) ) . '/sample.csv' ) ) . '">' . esc_html__( 'here', 'woocommerce-smart-coupons' ) . '</a>' ) . ' ' . esc_html__( 'If you want to import coupon through file, the file should be like', 'woocommerce-smart-coupons' ) . ' <code>sample.csv</code>',
),
array(
'que' => esc_html__( 'Available coupons are not visible on Cart, Checkout & My Account page?', 'woocommerce-smart-coupons' ),
'ans' => esc_html__( 'Smart Coupons uses hooks of Cart, Checkout & My Account page to display available coupons. If your theme is not using those hooks in cart, checkout & my-account template, coupons will not be displayed.', 'woocommerce-smart-coupons' ),
),
array(
'que' => esc_html__( 'How can I resend gift card coupon bought by customers?', 'woocommerce-smart-coupons' ),
'ans' => esc_html__( 'You can resend them from order admin edit page.', 'woocommerce-smart-coupons' ) . ' <a href="https://woocommerce.com/document/smart-coupons/how-to-resend-coupons-generated-from-an-order-to-the-buyer/" target="_blank">' . __( 'See how', 'woocommerce-smart-coupons' ) . '</a>.',
),
array(
'que' => esc_html__( 'Uncheck "Auto-generate" option in Store Credit is not saving? Is it always checked?', 'woocommerce-smart-coupons' ),
'ans' => esc_html__( 'Store Credit\'s default behavior is auto-generate because, when using a store credit, it\'s balance keeps reducing. Therefore it should be uniquely created for every user automatically.', 'woocommerce-smart-coupons' ),
),
array(
'que' => esc_html__( 'Smart Coupons is not sending emails.', 'woocommerce-smart-coupons' ),
'ans' => esc_html__( 'Smart Coupons sends email only after order completion. So make sure that order complete email is enabled and sending. If enabled, then make sure all settings of coupons, products are in place. Also check by switching your theme.', 'woocommerce-smart-coupons' ),
),
array(
'que' => esc_html__( '"Store Credit Receiver detail" form not appearing on checkout page?', 'woocommerce-smart-coupons' ),
'ans' => esc_html__( 'This form is displayed using a hook which is available in My Account template. Make sure your theme\'s my-account template contains all hooks required for that template. Update your theme if it is not updated.', 'woocommerce-smart-coupons' ),
),
array(
'que' => esc_html__( 'Does Smart Coupons allow printing of coupon as Gift Card?', 'woocommerce-smart-coupons' ),
/* translators: Documentation link for 'How to Print Coupons' */
'ans' => sprintf( esc_html__( 'Yes, Smart Coupons does provide a feature for printing coupons. For more details, check this article: %s', 'woocommerce-smart-coupons' ), '<a href="https://woocommerce.com/document/smart-coupons/how-to-print-coupons/" target="_blank">' . esc_html__( 'How to Print Coupons', 'woocommerce-smart-coupons' ) . '</a>' ),
),
array(
'que' => esc_html__( 'Is it possible to have a coupon for each variation of the variable product?', 'woocommerce-smart-coupons' ),
'ans' => esc_html__( 'From version 4.11.0, you can add/link coupons to product variations as well. This feature is not available in a version lower than 4.11.0.', 'woocommerce-smart-coupons' ),
),
array(
'que' => esc_html__( 'Is Smart Coupons compatible with WooCommerce Subscriptions?', 'woocommerce-smart-coupons' ),
'ans' => esc_html__( 'Yes, Smart Coupons does work with WooCommerce Subscriptions.', 'woocommerce-smart-coupons' ),
),
array(
'que' => esc_html__( 'Which features of Smart Coupons work with Subscriptions?', 'woocommerce-smart-coupons' ),
'ans' => esc_html__( 'Give away a discount or credit on signing up a subscription, give away recurring discount or credits, apply credit during sign up, automatic payment for renewals from credit (Note: When using PayPal Standard Gateway, store credit can be applied only during sign up. Automatic payment for renewals by credit will not work for PayPal Standard Gateway).', 'woocommerce-smart-coupons' ),
),
array(
'que' => esc_html__( 'How does automatic payment by store credit work with Subscriptions?', 'woocommerce-smart-coupons' ),
'ans' => esc_html__( 'Customers can apply store credit on a subscription during purchase of subscription. If the same store credit has sufficient balance, it\'ll keep applying it to renewals till the remainder in store credit is higher than renewal price. Customers will be able to apply store credit only during signup. They will not get an option to apply store credit in renewals. But if the store credit will not have sufficient balance to pay for the renewals, then the order will go into pending mode. Now when the customer will go to pay for this renewal order, they\'ll get an option to apply store credit again. To activate the subscription again, the customer will have to pay for the renewals. When the customer is paying for the renewals from their account, then in that process they can use the same store credit which didn\'t have the sufficient balance, again & pay for the remaining amount.', 'woocommerce-smart-coupons' ),
),
array(
'que' => esc_html__( 'Is it possible to partially pay for a subscription with store credit and the remainder by another method?', 'woocommerce-smart-coupons' ),
'ans' => esc_html__( 'No, this is possible only in those cases where subscription amount is more than store credit\'s balance. If store credit\'s balance is more than subscription\'s total then your bank account or credit card will not be charged.', 'woocommerce-smart-coupons' ),
),
array(
'que' => esc_html__( 'Is Smart Coupons WPML compatible?', 'woocommerce-smart-coupons' ),
'ans' => esc_html__( 'Not yet, but this is being worked on. You will find this in later versions.', 'woocommerce-smart-coupons' ),
),
array(
'que' => esc_html__( 'I\'m using WPML & WPML provides support for multi-currency, but Smart Coupons only changes currency symbol & the price value remains same. Can Smart Coupons change the currency symbol and the price value associated with it?', 'woocommerce-smart-coupons' ),
/* translators: Link for the plugin 'Aelia Currency Switcher for WooCommerce' */
'ans' => sprintf( esc_html__( 'Currently, Smart Coupons is compatible with %s. But it is not compatible with any other multi-currency plugin or with WPML.', 'woocommerce-smart-coupons' ), '<a href="https://aelia.co/shop/currency-switcher-woocommerce/" target="_blank">' . esc_html__( 'Aelia Currency Switcher for WooCommerce', 'woocommerce-smart-coupons' ) . '</a>' ),
),
);
$faqs = array_chunk( $faqs, 2 );
$right_faq_numbering = 1;
$left_faq_numbering = 0;
echo '<div>';
foreach ( $faqs as $fqs ) {
echo '<div class="has-2-columns two-col">';
foreach ( $fqs as $index => $faq ) {
echo '<div' . ( ( 1 === absint( $index ) ) ? ' class="column col last-feature"' : ' class="column col"' ) . '>';
echo '<h4>' . ( ( 1 === absint( $index ) ) ? $right_faq_numbering : ( $left_faq_numbering + 1 ) ) . '. ' . $faq['que'] . '</h4>'; // phpcs:ignore
echo '<p>' . $faq['ans'] . '</p>'; // phpcs:ignore
echo '</div>';
$right_faq_numbering++;
$left_faq_numbering++;
}
echo '</div>';
}
echo '</div>';
?>
<div class="aligncenter">
<h3>
<?php
/* translators: WooCommerce My Account support link */
echo sprintf( __( 'If you are facing any issues, please %s from your WooCommerce account.', 'woocommerce-smart-coupons' ), '<a target="_blank" href="https://woocommerce.com/my-account/create-a-ticket/">' . esc_html__( 'submit a ticket', 'woocommerce-smart-coupons' ) . '</a>' ); // phpcs:ignore
?>
</h3>
</div>
</div>
<?php
}
/**
* Sends user to the welcome page on first activation.
*/
public function sc_welcome() {
if ( ! get_transient( '_smart_coupons_activation_redirect' ) ) {
return;
}
// Delete the redirect transient.
delete_transient( '_smart_coupons_activation_redirect' );
wp_safe_redirect( admin_url( 'admin.php?page=sc-about' ) );
exit;
}
}
}
WC_SC_Admin_Welcome::get_instance();

View File

@@ -1,402 +0,0 @@
<?php
/**
* Smart Coupons Ajax Actions
*
* @author StoreApps
* @since 3.3.0
* @version 1.5.0
*
* @package woocommerce-smart-coupons/includes/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Ajax' ) ) {
/**
* Class for handling ajax actions for Smart Coupons
*/
class WC_SC_Ajax {
/**
* Variable to hold instance of WC_SC_Ajax
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
private function __construct() {
add_action( 'wp_ajax_sc_json_search_coupons', array( $this, 'sc_json_search_coupons' ) );
add_action( 'wp_ajax_sc_json_search_storewide_coupons', array( $this, 'sc_json_search_storewide_coupons' ) );
add_action( 'wp_ajax_smart_coupons_json_search', array( $this, 'smart_coupons_json_search' ) );
add_action( 'wp_ajax_hide_notice_delete_after_usage', array( $this, 'hide_notice_delete_after_usage' ) );
}
/**
* Get single instance of WC_SC_Ajax
*
* @return WC_SC_Ajax Singleton object of WC_SC_Ajax
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Function to search coupons
*
* @param string $x Search term.
* @param array $post_types Post types.
*/
public function sc_json_search_coupons( $x = '', $post_types = array( 'shop_coupon' ) ) {
global $wpdb;
check_ajax_referer( 'search-coupons', 'security' );
$term = (string) wc_clean( wp_unslash( $_GET['term'] ) ); // phpcs:ignore
if ( empty( $term ) ) {
die();
}
$args = array(
'post_type' => $post_types,
'post_status' => 'publish',
'posts_per_page' => -1,
's' => $term,
'fields' => 'all',
);
$posts = wp_cache_get( 'wc_sc_search_coupon_by_code_' . sanitize_title( $term ), 'woocommerce_smart_coupons' );
if ( false === $posts ) {
$posts = $wpdb->get_results( // phpcs:ignore
$wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}posts
WHERE post_type = %s
AND post_title LIKE %s
AND post_status = %s",
'shop_coupon',
$wpdb->esc_like( $term ) . '%',
'publish'
)
);
wp_cache_set( 'wc_sc_search_coupon_by_code_' . sanitize_title( $term ), $posts, 'woocommerce_smart_coupons' );
$this->maybe_add_cache_key( 'wc_sc_search_coupon_by_code_' . sanitize_title( $term ) );
}
$found_products = array();
$all_discount_types = wc_get_coupon_types();
if ( $posts ) {
foreach ( $posts as $post ) {
$discount_type = $this->get_post_meta( $post->ID, 'discount_type', true );
if ( ! empty( $all_discount_types[ $discount_type ] ) ) {
$discount_type = ' (' . __( 'Type', 'woocommerce-smart-coupons' ) . ': ' . $all_discount_types[ $discount_type ] . ')';
$found_products[ $post->post_title ] = $post->post_title . $discount_type;
}
}
}
wp_send_json( $found_products );
}
/**
* Function to search storewide coupons
*
* @param string $x Search term.
* @param array $post_types Post types.
*/
public function sc_json_search_storewide_coupons( $x = '', $post_types = array( 'shop_coupon' ) ) {
global $wpdb;
check_ajax_referer( 'search-coupons', 'security' );
$term = (string) wc_clean( wp_unslash( $_GET['term'] ) ); // phpcs:ignore
if ( empty( $term ) ) {
die();
}
$found_coupons = array();
$coupon_posts = array();
$posts = wp_cache_get( 'wc_sc_search_storewide_coupon_by_code_' . sanitize_title( $term ), 'woocommerce_smart_coupons' );
if ( false === $posts ) {
$posts = $wpdb->get_results( // phpcs:ignore
$wpdb->prepare(
"SELECT p.ID,
p.post_title,
pm.meta_key,
pm.meta_value
FROM {$wpdb->posts} AS p
JOIN {$wpdb->postmeta} AS pm
ON (p.ID = pm.post_id AND pm.meta_key IN (%s,%s,%s,%s,%s,%s))
WHERE p.post_type = %s
AND p.post_title LIKE %s
AND p.post_status = %s",
'discount_type',
'coupon_amount',
'date_expires',
'auto_generate_coupon',
'customer_email',
'wc_sc_expiry_time',
'shop_coupon',
$wpdb->esc_like( $term ) . '%',
'publish'
),
ARRAY_A
);
wp_cache_set( 'wc_sc_search_storewide_coupon_by_code_' . sanitize_title( $term ), $posts, 'woocommerce_smart_coupons' );
$this->maybe_add_cache_key( 'wc_sc_search_storewide_coupon_by_code_' . sanitize_title( $term ) );
}
if ( ! empty( $posts ) ) {
foreach ( $posts as $post ) {
$post_id = ( ! empty( $post['ID'] ) ) ? absint( $post['ID'] ) : 0;
$post_title = ( ! empty( $post['post_title'] ) ) ? $post['post_title'] : '';
if ( empty( $post_id ) || empty( $post_title ) ) {
continue;
}
if ( empty( $coupon_posts[ $post_id ] ) || ! is_array( $coupon_posts[ $post_id ] ) ) {
$coupon_posts[ $post_id ] = array();
}
$coupon_posts[ $post_id ]['post_id'] = $post_id;
$coupon_posts[ $post_id ]['post_title'] = $post_title;
switch ( $post['meta_key'] ) {
case 'discount_type':
case 'coupon_amount':
case 'date_expires':
case 'auto_generate_coupon':
case 'wc_sc_expiry_time':
$coupon_posts[ $post_id ][ $post['meta_key'] ] = $post['meta_value']; // phpcs:ignore
break;
case 'customer_email':
$coupon_posts[ $post_id ][ $post['meta_key'] ] = maybe_unserialize( $post['meta_value'] ); // phpcs:ignore
break;
}
}
}
$all_discount_types = wc_get_coupon_types();
if ( ! empty( $coupon_posts ) ) {
foreach ( $coupon_posts as $post_id => $coupon_post ) {
$discount_type = ( ! empty( $coupon_post['discount_type'] ) ) ? $coupon_post['discount_type'] : '';
$coupon_amount = ( ! empty( $coupon_post['coupon_amount'] ) ) ? $coupon_post['coupon_amount'] : 0;
$date_expires = ( ! empty( $coupon_post['date_expires'] ) ) ? absint( $coupon_post['date_expires'] ) : 0;
$wc_sc_expiry_time = ( ! empty( $coupon_post['wc_sc_expiry_time'] ) ) ? absint( $coupon_post['wc_sc_expiry_time'] ) : 0;
$auto_generate_coupon = ( ! empty( $coupon_post['auto_generate_coupon'] ) ) ? $coupon_post['auto_generate_coupon'] : '';
$customer_email = ( ! empty( $coupon_post['customer_email'] ) ) ? $coupon_post['customer_email'] : array();
if ( empty( $discount_type ) || 'smart_coupon' === $discount_type ) {
continue;
}
if ( empty( $coupon_amount ) ) {
continue;
}
if ( ! empty( $date_expires ) ) {
$date_expires += $wc_sc_expiry_time;
if ( time() >= $date_expires ) {
continue;
}
}
if ( 'yes' === $auto_generate_coupon ) {
continue;
}
if ( ! empty( $customer_email ) ) {
continue;
}
if ( ! empty( $all_discount_types[ $discount_type ] ) ) {
/* translators: 1. The coupon code, 2. The discount type */
$found_coupons[ $coupon_post['post_title'] ] = sprintf( __( '%1$s (Type: %2$s)', 'woocommerce-smart-coupons' ), $coupon_post['post_title'], $all_discount_types[ $discount_type ] );
}
}
$found_coupons = apply_filters(
'wc_sc_json_search_storewide_coupons',
$found_coupons,
array(
'source' => $this,
'search_text' => $term,
'posts' => $posts,
'coupon_posts' => $coupon_posts,
)
);
}
wp_send_json( $found_coupons );
}
/**
* JSON Search coupon via ajax
*
* @param string $x Search text.
* @param array $post_types Post types.
*/
public function smart_coupons_json_search( $x = '', $post_types = array( 'shop_coupon' ) ) {
global $wpdb, $store_credit_label;
check_ajax_referer( 'search-coupons', 'security' );
$term = (string) wc_clean( wp_unslash( $_GET['term'] ) ); // phpcs:ignore
if ( empty( $term ) ) {
die();
}
$posts = wp_cache_get( 'wc_sc_shortcode_search_coupon_by_code_' . sanitize_title( $term ), 'woocommerce_smart_coupons' );
if ( false === $posts ) {
$posts = $wpdb->get_results( // phpcs:ignore
$wpdb->prepare(
"SELECT *
FROM {$wpdb->prefix}posts
WHERE post_type = %s
AND post_title LIKE %s
AND post_status = %s",
'shop_coupon',
$wpdb->esc_like( $term ) . '%',
'publish'
)
);
wp_cache_set( 'wc_sc_shortcode_search_coupon_by_code_' . sanitize_title( $term ), $posts, 'woocommerce_smart_coupons' );
$this->maybe_add_cache_key( 'wc_sc_shortcode_search_coupon_by_code_' . sanitize_title( $term ) );
}
$found_products = array();
$all_discount_types = wc_get_coupon_types();
if ( $posts ) {
foreach ( $posts as $post ) {
$discount_type = $this->get_post_meta( $post->ID, 'discount_type', true );
if ( ! empty( $all_discount_types[ $discount_type ] ) ) {
$coupon = new WC_Coupon( $post->post_title );
if ( $this->is_wc_gte_30() ) {
$discount_type = $coupon->get_discount_type();
} else {
$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
}
$coupon_amount = $this->get_amount( $coupon );
switch ( $discount_type ) {
case 'smart_coupon':
$coupon_type = ! empty( $store_credit_label['singular'] ) ? ucwords( $store_credit_label['singular'] ) : __( 'Store Credit', 'woocommerce-smart-coupons' );
$coupon_amount = wc_price( $coupon_amount );
break;
case 'fixed_cart':
$coupon_type = __( 'Cart Discount', 'woocommerce-smart-coupons' );
$coupon_amount = wc_price( $coupon_amount );
break;
case 'fixed_product':
$coupon_type = __( 'Product Discount', 'woocommerce-smart-coupons' );
$coupon_amount = wc_price( $coupon_amount );
break;
case 'percent_product':
$coupon_type = __( 'Product Discount', 'woocommerce-smart-coupons' );
$coupon_amount = $coupon_amount . '%';
break;
case 'percent':
$coupon_type = ( $this->is_wc_gte_30() ) ? __( 'Discount', 'woocommerce-smart-coupons' ) : __( 'Cart Discount', 'woocommerce-smart-coupons' );
$coupon_amount = $coupon_amount . '%';
$max_discount = $this->get_post_meta( $post->ID, 'wc_sc_max_discount', true );
if ( ! empty( $max_discount ) && is_numeric( $max_discount ) ) {
/* translators: %s: Maximum coupon discount amount */
$coupon_type .= ' ' . sprintf( __( 'upto %s', 'woocommerce-smart-coupons' ), wc_price( $max_discount ) );
}
break;
default:
$default_coupon_type = ( ! empty( $all_discount_types[ $discount_type ] ) ) ? $all_discount_types[ $discount_type ] : ucwords( str_replace( array( '_', '-' ), ' ', $discount_type ) );
$coupon_type = apply_filters( 'wc_sc_coupon_type', $default_coupon_type, $coupon, $all_discount_types );
$coupon_amount = apply_filters( 'wc_sc_coupon_amount', $coupon_amount, $coupon );
break;
}
$discount_type = ' ( ' . $coupon_amount . ' ' . $coupon_type . ' )';
$discount_type = wp_strip_all_tags( $discount_type );
$found_products[ $post->post_title ] = $post->post_title . ' ' . $discount_type;
}
}
}
if ( ! empty( $found_products ) ) {
echo wp_json_encode( $found_products );
}
die();
}
/**
* Function to Hide Notice Delete After Usage
*/
public function hide_notice_delete_after_usage() {
check_ajax_referer( 'hide-smart-coupons-notice', 'security' );
$current_user_id = get_current_user_id();
update_user_meta( $current_user_id, 'hide_delete_credit_after_usage_notice', 'yes' );
wp_send_json( array( 'message' => 'success' ) );
}
}
}
WC_SC_Ajax::get_instance();

View File

@@ -1,634 +0,0 @@
<?php
/**
* Processing of coupons
*
* @author StoreApps
* @since 3.3.0
* @version 1.7.0
* @package WooCommerce Smart Coupons
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Apply_Before_Tax' ) ) {
/**
* Class for applying store credit before tax calculation
*/
class WC_SC_Apply_Before_Tax {
/**
* Variable to hold instance of WC_SC_Apply_Before_Tax
*
* @var $instance
*/
private static $instance = null;
/**
* Store credit left after application on each cart item
*
* @var $sc_credit_left
*/
private $sc_credit_left = array();
/**
* Store credit left after application on each cart item in REST API
*
* @var $sc_api_credit_left
*/
private $sc_api_credit_left = array();
/**
* Remaining total to apply credit
*
* @var $remaining_total_to_apply_credit
*/
private $remaining_total_to_apply_credit = array();
/**
* Constructor
*/
private function __construct() {
add_action( 'woocommerce_order_before_calculate_totals', array( $this, 'order_calculate_discount_amount_before_tax' ), 10, 2 );
add_action( 'woocommerce_order_after_calculate_totals', array( $this, 'order_set_discount_total' ), 10, 2 );
add_action( 'woocommerce_checkout_create_order', array( $this, 'cart_set_discount_total' ), 10, 1 );
add_action( 'wp_loaded', array( $this, 'cart_calculate_discount_amount' ), 20 );
add_filter( 'woocommerce_coupon_get_discount_amount', array( $this, 'cart_return_discount_amount' ), 20, 5 );
add_filter( 'woocommerce_coupon_custom_discounts_array', array( $this, 'store_credit_discounts_array' ), 10, 2 );
add_filter( 'woocommerce_add_cart_item', array( $this, 'sc_mnm_compat' ), 20, 2 );
add_action( 'woocommerce_after_calculate_totals', array( $this, 'cart_set_total_credit_used' ), 10, 1 );
add_action( 'woocommerce_before_calculate_totals', array( $this, 'cart_reset_credit_left' ), 15 );
}
/**
* Get single instance of WC_SC_Apply_Before_Tax
*
* @return WC_SC_Apply_Before_Tax Singleton object of WC_SC_Apply_Before_Tax
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name Function to call.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return mixed Result of function call.
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Function to apply store credit before tax calculation for orders that are manually created and updated from backend
*
* @param bool $and_taxes Calc taxes if true.
* @param WC_Order $order Order object.
*/
public function order_calculate_discount_amount_before_tax( $and_taxes, $order ) {
$order_actions = array( 'woocommerce_add_coupon_discount', 'woocommerce_calc_line_taxes', 'woocommerce_save_order_items' );
if ( $order instanceof WC_Order && ! empty( $_POST['action'] ) && ( in_array( wp_unslash( $_POST['action'] ), $order_actions, true ) || ( ! empty( $_POST['post_type'] ) && 'shop_order' === wp_unslash( $_POST['post_type'] ) && 'editpost' === wp_unslash( $_POST['action'] ) ) ) ) { // phpcs:ignore
if ( ! is_object( $order ) || ! is_callable( array( $order, 'get_id' ) ) ) {
return;
}
$order_id = $order->get_id();
if ( empty( $order_id ) ) {
return;
}
$coupons = $order->get_items( 'coupon' );
$order_items = $order->get_items( 'line_item' );
if ( empty( $order_items ) && empty( $coupons ) ) {
return;
}
foreach ( $coupons as $item_id => $item ) {
$coupon_code = ( is_object( $item ) && is_callable( array( $item, 'get_name' ) ) ) ? $item->get_name() : $item['name'];
if ( empty( $coupon_code ) ) {
continue;
}
$coupon = new WC_Coupon( $coupon_code );
$discount_type = $coupon->get_discount_type();
if ( 'smart_coupon' === $discount_type ) {
$sc_include_tax = $this->is_store_credit_include_tax();
$smart_coupons_contribution = $this->get_post_meta( $order_id, 'smart_coupons_contribution', true, true );
$smart_coupons_contribution = ( ! empty( $smart_coupons_contribution ) ) ? $smart_coupons_contribution : array();
$discount_amount = ( is_object( $item ) && is_callable( array( $item, 'get_discount' ) ) ) ? $item->get_discount() : $this->get_order_item_meta( $item_id, 'discount_amount', true, true );
$discount_amount_tax = ( is_object( $item ) && is_callable( array( $item, 'get_discount_tax' ) ) ) ? $item->get_discount_tax() : $this->get_order_item_meta( $item_id, 'discount_amount_tax', true, true );
if ( is_array( $smart_coupons_contribution ) && count( $smart_coupons_contribution ) > 0 && array_key_exists( $coupon_code, $smart_coupons_contribution ) ) {
// If store credit discount is inclusive of tax then remove discount given tax from Smart Coupons' contribution.
if ( 'yes' === $sc_include_tax && ! empty( $discount_amount_tax ) ) {
$new_discount = $smart_coupons_contribution[ $coupon_code ] - $discount_amount_tax;
} else {
$new_discount = $smart_coupons_contribution[ $coupon_code ];
}
if ( is_object( $item ) && is_callable( array( $item, 'set_discount' ) ) ) {
$item->set_discount( $new_discount );
} else {
$item['discount_amount'] = $new_discount;
}
} elseif ( ! empty( $discount_amount ) ) {
if ( is_object( $item ) && is_callable( array( $item, 'set_discount' ) ) ) {
$item->set_discount( $discount_amount );
} else {
$item['discount_amount'] = $discount_amount;
}
// If discount includes tax then Smart Coupons contribution is sum of discount on product price and discount on tax.
if ( 'yes' === $sc_include_tax && ! empty( $discount_amount_tax ) ) {
$smart_coupons_contribution[ $coupon_code ] = $discount_amount + $discount_amount_tax;
} else {
$smart_coupons_contribution[ $coupon_code ] = $discount_amount;
}
} else {
$coupon_amount = $this->get_amount( $coupon, true, $order );
$coupon_product_ids = $coupon->get_product_ids();
$coupon_category_ids = $coupon->get_product_categories();
$subtotal = 0;
$items_to_apply_credit = array();
if ( count( $coupon_product_ids ) > 0 || count( $coupon_category_ids ) > 0 ) {
foreach ( $order_items as $order_item_id => $order_item ) {
$product_category_ids = wc_get_product_cat_ids( $order_item['product_id'] );
if ( count( $coupon_product_ids ) > 0 && count( $coupon_category_ids ) > 0 ) {
if ( ( in_array( $order_item['product_id'], $coupon_product_ids, true ) || in_array( $order_item['variation_id'], $coupon_product_ids, true ) ) && count( array_intersect( $product_category_ids, $coupon_category_ids ) ) > 0 ) {
$items_to_apply_credit[] = $order_item_id;
}
} else {
if ( in_array( $order_item['product_id'], $coupon_product_ids, true ) || in_array( $order_item['variation_id'], $coupon_product_ids, true ) || count( array_intersect( $product_category_ids, $coupon_category_ids ) ) > 0 ) {
$items_to_apply_credit[] = $order_item_id;
}
}
}
} else {
$items_to_apply_credit = array_keys( $order_items );
}
$subtotal = array_sum( array_map( array( $this, 'sc_get_order_subtotal' ), $items_to_apply_credit ) );
if ( $subtotal <= 0 ) {
continue;
}
$store_credit_used = 0;
foreach ( $items_to_apply_credit as $order_item_id ) {
$order_item = $order_items[ $order_item_id ];
$discounting_amount = $order_item->get_total();
// If discount include tax then add item tax to discounting amount to allow discount calculation on tax also.
if ( 'yes' === $sc_include_tax ) {
$item_tax = ( is_callable( array( $order, 'get_line_tax' ) ) ) ? $order->get_line_tax( $order_item ) : 0;
$discounting_amount += $item_tax;
}
$quantity = $order_item->get_quantity();
$discount = $this->sc_get_discounted_price( $discounting_amount, $quantity, $subtotal, $coupon_amount );
$discount *= $quantity;
$order_item->set_total( $discounting_amount - $discount );
$store_credit_used += $discount;
}
if ( is_object( $item ) && is_callable( array( $item, 'set_discount' ) ) ) {
$item->set_discount( $store_credit_used );
} else {
$item['discount_amount'] = $store_credit_used;
}
$smart_coupons_contribution[ $coupon_code ] = $store_credit_used;
$this->update_post_meta( $order_id, 'smart_coupons_contribution', $smart_coupons_contribution, true );
}
$order->sc_total_credit_used = $smart_coupons_contribution;
}
}
}
}
/**
* Function to calculate subtotal of items in order which is necessary for applying store credit before tax calculation
*
* @param int $order_item_id Item ID.
* @return float $subtotal
*/
private function sc_get_order_subtotal( $order_item_id ) {
$order_item = WC_Order_Factory::get_order_item( $order_item_id );
$subtotal = $order_item->get_total();
$prices_include_tax = wc_prices_include_tax();
// Get global setting for whether store credit discount is inclusive of tax or not.
$sc_include_tax = get_option( 'woocommerce_smart_coupon_include_tax', 'no' );
// If prices are inclusive of tax and discount amount is also inclusive of tax then add item tax in subtotal to handle discount calculation correctly.
if ( true === $prices_include_tax && 'yes' === $sc_include_tax ) {
$subtotal += $order_item->get_total_tax();
}
return $subtotal;
}
/**
* Function to update_discount_total for an order
*
* @param WC_Order $order Order object.
* @param float $total_credit_used Total store credit used.
*/
public function update_discount_total( $order = '', $total_credit_used = 0 ) {
if ( $order instanceof WC_Order ) {
$discount_total = $order->get_discount_total();
$sc_credit_used = min( $discount_total, $total_credit_used );
$order->set_discount_total( $discount_total - $sc_credit_used );
}
}
/**
* Function to set discount total for orders that are created manually
*
* @param bool $and_taxes Calc taxes if true.
* @param WC_Order $order Order object.
*/
public function order_set_discount_total( $and_taxes, $order ) {
if ( isset( $order->sc_total_credit_used ) && is_array( $order->sc_total_credit_used ) && count( $order->sc_total_credit_used ) > 0 ) {
$total_credit_used = array_sum( $order->sc_total_credit_used );
$this->update_discount_total( $order, $total_credit_used );
$pending_statuses = $this->get_pending_statuses();
if ( ! empty( $_POST['action'] ) && 'woocommerce_add_coupon_discount' === wp_unslash( $_POST['action'] ) && $order->has_status( $pending_statuses ) && did_action( 'sc_after_order_calculate_discount_amount' ) <= 0 ) { // phpcs:ignore
do_action( 'sc_after_order_calculate_discount_amount', $order->get_id() );
}
}
}
/**
* Function to set discount total for a new order
*
* @param WC_Order $order Order object.
*/
public function cart_set_discount_total( $order ) {
if ( isset( WC()->cart->smart_coupon_credit_used ) && is_array( WC()->cart->smart_coupon_credit_used ) && count( WC()->cart->smart_coupon_credit_used ) > 0 ) {
$total_credit_used = array_sum( WC()->cart->smart_coupon_credit_used );
$this->update_discount_total( $order, $total_credit_used );
}
}
/**
* Function to apply store credit before tax calculation for cart items
*/
public function cart_calculate_discount_amount() {
$cart = ( isset( WC()->cart ) ) ? WC()->cart : '';
if ( $cart instanceof WC_Cart ) {
$cart_contents = WC()->cart->get_cart();
$coupons = $cart->get_coupons();
if ( ! empty( $coupons ) ) {
$items_to_apply_credit = array();
foreach ( $coupons as $coupon_code => $coupon ) {
$discount_type = $coupon->get_discount_type();
if ( 'smart_coupon' === $discount_type ) {
$coupon_product_ids = $coupon->get_product_ids();
$coupon_category_ids = $coupon->get_product_categories();
if ( count( $coupon_product_ids ) > 0 || count( $coupon_category_ids ) > 0 ) {
foreach ( $cart_contents as $cart_item_key => $cart_item ) {
$product_category_ids = wc_get_product_cat_ids( $cart_item['product_id'] );
if ( count( $coupon_product_ids ) > 0 && count( $coupon_category_ids ) > 0 ) {
if ( ( in_array( $cart_item['product_id'], $coupon_product_ids, true ) || in_array( $cart_item['variation_id'], $coupon_product_ids, true ) ) && count( array_intersect( $product_category_ids, $coupon_category_ids ) ) > 0 ) {
$items_to_apply_credit[ $coupon_code ][] = $cart_item_key;
}
} else {
if ( in_array( $cart_item['product_id'], $coupon_product_ids, true ) || in_array( $cart_item['variation_id'], $coupon_product_ids, true ) || count( array_intersect( $product_category_ids, $coupon_category_ids ) ) > 0 ) {
$items_to_apply_credit[ $coupon_code ][] = $cart_item_key;
}
}
}
} else {
$items_to_apply_credit[ $coupon_code ] = array_keys( $cart_contents );
}
}
}
if ( ! empty( $items_to_apply_credit ) ) {
WC()->cart->sc_items_to_apply_credit = $items_to_apply_credit;
}
}
}
}
/**
* Get discount amount for a cart item.
*
* @param float $discount Amount this coupon has discounted.
* @param float $discounting_amount Amount the coupon is being applied to.
* @param array|null $cart_item Cart item being discounted if applicable.
* @param bool $single True if discounting a single qty item, false if its the line.
* @param WC_Coupon $coupon Coupon object.
* @return float $discount
*/
public function cart_return_discount_amount( $discount, $discounting_amount, $cart_item, $single, $coupon ) {
if ( ! is_object( $coupon ) || ! is_a( $coupon, 'WC_Coupon' ) ) {
return $discount;
}
$discount_type = is_callable( array( $coupon, 'get_discount_type' ) ) ? $coupon->get_discount_type() : '';
if ( 'smart_coupon' !== $discount_type ) {
return $discount;
}
$coupon_code = is_callable( array( $coupon, 'get_code' ) ) ? $coupon->get_code() : '';
if ( is_object( $cart_item ) && is_a( $cart_item, 'WC_Order_Item_Product' ) ) {
return $this->calculate_discount_amount_for_rest_api( $discount, $discounting_amount, $cart_item, $single, $coupon );
}
$coupon_amount = $this->get_amount( $coupon, true );
$product = isset( $cart_item['data'] ) ? $cart_item['data'] : array();
$quantity = $cart_item['quantity'];
// Compatibility for WC version < 3.2.0.
if ( ! isset( $cart_item['key'] ) ) {
$product_id = ( ! empty( $cart_item['variation_id'] ) ) ? $cart_item['variation_id'] : $cart_item['product_id'];
foreach ( WC()->cart->cart_contents as $key => $cart_data ) {
$cart_data_product_id = ( ! empty( $cart_data['variation_id'] ) ) ? $cart_data['variation_id'] : $cart_data['product_id'];
if ( $product_id === $cart_data_product_id ) {
$cart_item['key'] = $key;
}
}
}
$prices_include_tax = ( 'incl' === get_option( 'woocommerce_tax_display_cart' ) ) ? true : false;
if ( true === $prices_include_tax ) {
$sc_include_tax = get_option( 'woocommerce_smart_coupon_include_tax', 'no' );
if ( 'no' === $sc_include_tax ) {
$discounting_amount = $cart_item['line_subtotal'] / $quantity;
}
}
$items_to_apply_credit = isset( WC()->cart->sc_items_to_apply_credit ) ? WC()->cart->sc_items_to_apply_credit : array();
if ( ! empty( $items_to_apply_credit ) && is_array( $items_to_apply_credit ) && array_key_exists( $coupon_code, $items_to_apply_credit ) && in_array( $cart_item['key'], $items_to_apply_credit[ $coupon_code ], true ) ) {
$credit_left = isset( $this->sc_credit_left[ $coupon_code ] ) ? $this->sc_credit_left[ $coupon_code ] : $coupon_amount;
$total_discounting_amount = $discounting_amount * $quantity;
if ( isset( $this->remaining_total_to_apply_credit[ $cart_item['key'] ] ) ) {
$total_discounting_amount = wc_remove_number_precision( $this->remaining_total_to_apply_credit[ $cart_item['key'] ] );
}
$applied_discount = min( $total_discounting_amount, $credit_left );
$this->sc_credit_left[ $coupon_code ] = ( $total_discounting_amount < $credit_left ) ? $credit_left - $total_discounting_amount : 0;
$discount = $applied_discount / $quantity;
}
return $discount;
}
/**
* Calculate discount amount for REST API.
*
* @param float $discount Amount this coupon has discounted.
* @param float $discounting_amount Amount the coupon is being applied to.
* @param WC_Order_Item_Product $cart_item Object.
* @param bool $single True if discounting a single qty item, false if its the line.
* @param WC_Coupon $coupon Object.
* @return float|int|mixed
*/
public function calculate_discount_amount_for_rest_api( $discount = 0, $discounting_amount = 0, $cart_item = object, $single = false, $coupon = object ) {
if ( ! is_object( $coupon ) || ! is_a( $coupon, 'WC_Coupon' ) ) {
return $discount;
}
if ( ! is_object( $cart_item ) || ! is_a( $cart_item, 'WC_Order_Item_Product' ) ) {
return $discount;
}
$product_id = ( is_callable( array( $cart_item, 'get_product_id' ) ) ) ? $cart_item->get_product_id() : 0;
$variation_id = ( is_callable( array( $cart_item, 'get_variation_id' ) ) ) ? $cart_item->get_variation_id() : 0;
$quantity = ( is_callable( array( $cart_item, 'get_quantity' ) ) ) ? $cart_item->get_quantity() : 1;
$item_id = ( is_callable( array( $cart_item, 'get_id' ) ) ) ? $cart_item->get_id() : 0;
$product_subtotal = ( is_callable( array( $cart_item, 'get_subtotal' ) ) ) ? $cart_item->get_subtotal() : 0;
$product_subtotal_tax = ( is_callable( array( $cart_item, 'get_subtotal_tax' ) ) ) ? $cart_item->get_subtotal_tax() : 0;
$order = ( is_callable( array( $cart_item, 'get_order' ) ) ) ? $cart_item->get_order() : null;
$coupon_code = ( is_callable( array( $coupon, 'get_code' ) ) ) ? $coupon->get_code() : '';
$discount_type = ( is_callable( array( $coupon, 'get_discount_type' ) ) ) ? $coupon->get_discount_type() : '';
if ( 'smart_coupon' !== $discount_type ) {
return $discount;
}
$coupon_amount = $this->get_amount( $coupon, true, $order );
if ( ! empty( $this->sc_api_credit_left[ $item_id ][ $variation_id ] ) ) {
return $this->sc_api_credit_left[ $item_id ][ $variation_id ] / $quantity;
} elseif ( ! empty( $this->sc_api_credit_left[ $item_id ][ $product_id ] ) ) {
return $this->sc_api_credit_left[ $item_id ][ $product_id ] / $quantity;
}
if ( isset( $this->sc_api_credit_left[ $coupon_code ] ) && empty( $this->sc_api_credit_left[ $coupon_code ] ) ) {
return $discount;
}
$prices_include_tax = ( 'yes' === get_option( 'woocommerce_prices_include_tax' ) ) ? true : false;
if ( true === $prices_include_tax ) {
$sc_include_tax = get_option( 'woocommerce_smart_coupon_include_tax', 'no' );
if ( 'no' === $sc_include_tax ) {
$discounting_amount = $product_subtotal / $quantity;
}
}
$credit_left = ( ! empty( $this->sc_api_credit_left ) && isset( $this->sc_api_credit_left[ $coupon_code ] ) ) ? $this->sc_api_credit_left[ $coupon_code ] : $coupon_amount;
if ( $credit_left > 0 ) {
$discount = $discounting_amount * $quantity;
if ( $credit_left >= $discount ) {
$credit_left = $credit_left - $discount;
$this->sc_api_credit_left[ $coupon_code ] = $credit_left;
} else {
$discount = $credit_left;
$this->sc_api_credit_left[ $coupon_code ] = 0;
}
}
if ( ! empty( $variation_id ) ) {
$this->sc_api_credit_left[ $item_id ][ $variation_id ] = $discount;
} else {
$this->sc_api_credit_left[ $item_id ][ $product_id ] = $discount;
}
return $discount;
}
/**
* Discount details for store credit
*
* @param array $discounts The discount details.
* @param WC_Coupon $coupon The coupon object.
* @return array
*/
public function store_credit_discounts_array( $discounts = array(), $coupon = null ) {
$cart = ( isset( WC()->cart ) ) ? WC()->cart : '';
if ( $cart instanceof WC_Cart ) {
$cart_contents = ( is_object( WC()->cart ) && is_callable( array( WC()->cart, 'get_cart' ) ) ) ? WC()->cart->get_cart() : array();
if ( ! empty( $cart_contents ) ) {
$discount_type = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_discount_type' ) ) ) ? $coupon->get_discount_type() : '';
if ( 'smart_coupon' === $discount_type ) {
$prices_include_tax = ( 'incl' === get_option( 'woocommerce_tax_display_cart' ) ) ? true : false;
if ( true === $prices_include_tax ) {
$sc_include_tax = get_option( 'woocommerce_smart_coupon_include_tax', 'no' );
if ( 'no' === $sc_include_tax ) {
if ( ! empty( $discounts ) ) {
foreach ( $discounts as $item_key => $discount ) {
$line_subtotal = wc_round_discount( wc_add_number_precision( $cart_contents[ $item_key ]['line_subtotal'] ), 0 );
$line_subtotal = ( isset( $this->remaining_total_to_apply_credit[ $item_key ] ) ) ? min( $this->remaining_total_to_apply_credit[ $item_key ], $line_subtotal ) : $line_subtotal;
$discount = min( $discount, $line_subtotal );
$discounts [ $item_key ] = $discount;
$this->remaining_total_to_apply_credit[ $item_key ] = $line_subtotal - $discount;
}
}
}
}
}
}
}
return $discounts;
}
/**
* Set smart coupon credit used
*/
public function cart_set_total_credit_used() {
$coupon_discount_totals = ( is_callable( array( 'WC_Cart', 'get_coupon_discount_totals' ) ) ) ? WC()->cart->get_coupon_discount_totals() : WC()->cart->coupon_discount_amounts;
$coupon_discount_tax_totals = ( is_callable( array( 'WC_Cart', 'get_coupon_discount_tax_totals' ) ) ) ? WC()->cart->get_coupon_discount_tax_totals() : WC()->cart->coupon_discount_tax_amounts;
$sc_total_credit_used = array();
if ( ! empty( $coupon_discount_totals ) && is_array( $coupon_discount_totals ) && count( $coupon_discount_totals ) > 0 ) {
foreach ( $coupon_discount_totals as $coupon_code => $total ) {
$coupon = new WC_Coupon( $coupon_code );
$discount_type = $coupon->get_discount_type();
if ( 'smart_coupon' === $discount_type ) {
$sc_total_credit_used[ $coupon_code ] = $total;
if ( ! empty( $coupon_discount_tax_totals[ $coupon_code ] ) ) {
$sc_include_tax = $this->is_store_credit_include_tax();
if ( 'yes' === $sc_include_tax ) {
$sc_total_credit_used[ $coupon_code ] += $coupon_discount_tax_totals[ $coupon_code ];
} else {
$prices_include_tax = ( 'incl' === get_option( 'woocommerce_tax_display_cart' ) ) ? true : false;
if ( true === $prices_include_tax ) {
$apply_before_tax = get_option( 'woocommerce_smart_coupon_apply_before_tax', 'no' );
if ( 'yes' === $apply_before_tax ) {
$_sc_include_tax = get_option( 'woocommerce_smart_coupon_include_tax', 'no' );
if ( 'no' === $_sc_include_tax ) {
$sc_total_credit_used[ $coupon_code ] += $coupon_discount_tax_totals[ $coupon_code ];
}
}
}
}
}
}
}
}
if ( ! empty( $sc_total_credit_used ) ) {
WC()->cart->smart_coupon_credit_used = $sc_total_credit_used;
}
}
/**
* Function to calculate discount amount for an item
*
* @param float $discounting_amount Amount the coupon is being applied to.
* @param int $quantity Item quantity.
* @param float $subtotal Cart/Order subtotal.
* @param float $coupon_amount Coupon amount.
* @return float $discount
*/
public function sc_get_discounted_price( $discounting_amount = 0, $quantity = 1, $subtotal = 0, $coupon_amount = 0 ) {
$discount = 0;
$discounting_amount = $discounting_amount / $quantity;
$discount_percent = ( $discounting_amount * $quantity ) / $subtotal;
$discount = ( $coupon_amount * $discount_percent ) / $quantity;
$discount = min( $discount, $discounting_amount );
return $discount;
}
/**
* Function to add cart item key for MNM child items.
* This was need because MNM child items didn't had cart item key inside $cart_item_data array and the
* function WC_SC_Apply_Before_Tax::cart_return_discount_amount() uses cart item key to set discount amount.
*
* @param array $cart_item_data Cart item data.
* @param string $cart_item_key Cart item key.
* @return float $cart_item_data
*/
public function sc_mnm_compat( $cart_item_data, $cart_item_key ) {
if ( ! empty( $cart_item_data['mnm_container'] ) ) {
$cart_item_data['key'] = $cart_item_key;
}
return $cart_item_data;
}
/**
* Reset credit left to the defaults.
*/
public function cart_reset_credit_left() {
$this->sc_credit_left = array();
$this->sc_api_credit_left = array();
$this->remaining_total_to_apply_credit = array();
}
}
}
WC_SC_Apply_Before_Tax::get_instance();

View File

@@ -1,562 +0,0 @@
<?php
/**
* Auto apply coupon
*
* @author StoreApps
* @since 4.6.0
* @version 1.8.0
*
* @package woocommerce-smart-coupons/includes/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Auto_Apply_Coupon' ) ) {
/**
* Class for handling coupons applied via URL
*/
class WC_SC_Auto_Apply_Coupon {
/**
* Variable to hold instance of WC_SC_Auto_Apply_Coupon
*
* @var $instance
*/
private static $instance = null;
/**
* Variable to hold coupon notices
*
* @var $coupon_notices
*/
private $coupon_notices = array();
/**
* Constructor
*/
private function __construct() {
add_action( 'woocommerce_coupon_options', array( $this, 'usage_restriction' ), 10, 2 );
add_action( 'woocommerce_coupon_options_save', array( $this, 'process_meta' ), 10, 2 );
add_filter( 'wc_smart_coupons_export_headers', array( $this, 'export_headers' ) );
add_filter( 'smart_coupons_parser_postmeta_defaults', array( $this, 'postmeta_defaults' ) );
add_filter( 'sc_generate_coupon_meta', array( $this, 'generate_coupon_meta' ), 10, 2 );
add_filter( 'wc_sc_process_coupon_meta_value_for_import', array( $this, 'process_coupon_meta_value_for_import' ), 10, 2 );
add_filter( 'is_protected_meta', array( $this, 'make_action_meta_protected' ), 10, 3 );
// Action to auto apply coupons.
add_action( 'wp_loaded', array( $this, 'auto_apply_coupons' ) );
add_action( 'woocommerce_cart_emptied', array( $this, 'reset_auto_applied_coupons_session' ) );
add_action( 'woocommerce_removed_coupon', array( $this, 'wc_sc_removed_coupon' ) );
}
/**
* Get single instance of WC_SC_Auto_Apply_Coupon
*
* @return WC_SC_Auto_Apply_Coupon Singleton object of WC_SC_Auto_Apply_Coupon
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Display field for auto apply coupon
*
* @param integer $coupon_id The coupon id.
* @param WC_Coupon $coupon The coupon object.
*/
public function usage_restriction( $coupon_id = 0, $coupon = null ) {
?>
<script type="text/javascript">
jQuery(function() {
let show_hide_auto_apply_field = function() {
let discount_type = jQuery('select#discount_type').val();
if ('smart_coupon' === discount_type) {
jQuery('.wc_sc_auto_apply_coupon_field').hide();
} else {
jQuery('.wc_sc_auto_apply_coupon_field').show();
}
}
show_hide_auto_apply_field();
jQuery('select#discount_type').on('change', function() {
show_hide_auto_apply_field();
});
});
</script>
<div class="options_group smart-coupons-field">
<?php
woocommerce_wp_checkbox(
array(
'id' => 'wc_sc_auto_apply_coupon',
'label' => __( 'Auto apply?', 'woocommerce-smart-coupons' ),
'description' => __( 'When checked, this coupon will be applied automatically, if it is valid. If enabled in more than 5 coupons, only 5 coupons will be applied automatically, rest will be ignored.', 'woocommerce-smart-coupons' ),
)
);
?>
</div>
<?php
}
/**
* Save auto apply coupon in meta
*
* @param Integer $post_id The coupon post ID.
* @param WC_Coupon $coupon The coupon object.
*/
public function process_meta( $post_id = 0, $coupon = null ) {
if ( empty( $post_id ) ) {
return;
}
if ( is_null( $coupon ) || ! is_a( $coupon, 'WC_Coupon' ) ) {
$coupon = new WC_Coupon( $post_id );
}
$is_callable_coupon_update_meta = $this->is_callable( $coupon, 'update_meta_data' ) && $this->is_callable( $coupon, 'save' );
// Get list of ids of coupons to auto apply.
$auto_apply_coupon_ids = get_option( 'wc_sc_auto_apply_coupon_ids', array() );
$auto_apply_coupon_ids = array_map( 'absint', $auto_apply_coupon_ids );
$post_id = absint( $post_id );
if ( isset( $_POST['wc_sc_auto_apply_coupon'] ) && isset( $_POST['discount_type'] ) && 'smart_coupon' !== wc_clean( wp_unslash( $_POST['discount_type'] ) ) ) { // phpcs:ignore
$auto_apply_coupon = wc_clean( wp_unslash( $_POST['wc_sc_auto_apply_coupon'] ) ); // phpcs:ignore
if ( true === $is_callable_coupon_update_meta ) {
$coupon->update_meta_data( 'wc_sc_auto_apply_coupon', $auto_apply_coupon );
$coupon->save();
} else {
$this->update_post_meta( $post_id, 'wc_sc_auto_apply_coupon', $auto_apply_coupon );
}
// Add coupon id to auto apply coupon list if haven't added already.
if ( is_array( $auto_apply_coupon_ids ) && ! in_array( $post_id, $auto_apply_coupon_ids, true ) ) {
$auto_apply_coupon_ids[] = $post_id;
}
} else {
if ( true === $is_callable_coupon_update_meta ) {
$coupon->update_meta_data( 'wc_sc_auto_apply_coupon', 'no' );
$coupon->save();
} else {
$this->update_post_meta( $post_id, 'wc_sc_auto_apply_coupon', 'no' );
}
// Remove coupon id from auto apply coupon list if auto apply is disabled.
if ( is_array( $auto_apply_coupon_ids ) && in_array( $post_id, $auto_apply_coupon_ids, true ) ) {
$auto_apply_coupon_ids = array_diff( $auto_apply_coupon_ids, array( $post_id ) );
}
}
update_option( 'wc_sc_auto_apply_coupon_ids', $auto_apply_coupon_ids, 'no' );
}
/**
* Add meta in export headers
*
* @param array $headers Existing headers.
* @return array
*/
public function export_headers( $headers = array() ) {
$headers['wc_sc_auto_apply_coupon'] = __( 'Auto apply?', 'woocommerce-smart-coupons' );
return $headers;
}
/**
* Post meta defaults for auto apply coupon meta
*
* @param array $defaults Existing postmeta defaults.
* @return array $defaults Modified postmeta defaults
*/
public function postmeta_defaults( $defaults = array() ) {
$defaults['wc_sc_auto_apply_coupon'] = '';
return $defaults;
}
/**
* Add auto apply coupon's meta with value in coupon meta
*
* @param array $data The row data.
* @param array $post The POST values.
* @return array $data Modified row data
*/
public function generate_coupon_meta( $data = array(), $post = array() ) {
if ( isset( $post['discount_type'] ) && 'smart_coupon' !== $post['discount_type'] ) {
$data['wc_sc_auto_apply_coupon'] = ( isset( $post['wc_sc_auto_apply_coupon'] ) ) ? $post['wc_sc_auto_apply_coupon'] : '';
}
return $data;
}
/**
* Process coupon meta value for import
*
* @param mixed $meta_value The meta value.
* @param array $args Additional Arguments.
* @return mixed $meta_value
*/
public function process_coupon_meta_value_for_import( $meta_value = null, $args = array() ) {
$discount_type = isset( $args['discount_type'] ) ? $args['discount_type'] : '';
if ( 'smart_coupon' !== $discount_type && ! empty( $args['meta_key'] ) && 'wc_sc_auto_apply_coupon' === $args['meta_key'] ) {
$auto_apply_coupon = $meta_value;
if ( 'yes' === $auto_apply_coupon ) {
$auto_apply_coupon_ids = get_option( 'wc_sc_auto_apply_coupon_ids', array() );
$auto_apply_coupon_ids = array_map( 'absint', $auto_apply_coupon_ids );
$coupon_id = ( isset( $args['post']['post_id'] ) ) ? absint( $args['post']['post_id'] ) : 0;
if ( ! empty( $coupon_id ) && ! in_array( $coupon_id, $auto_apply_coupon_ids, true ) ) {
$auto_apply_coupon_ids[] = $coupon_id;
update_option( 'wc_sc_auto_apply_coupon_ids', $auto_apply_coupon_ids, 'no' );
}
}
}
return $meta_value;
}
/**
* Make meta data of auto apply coupon meta protected
*
* @param bool $protected Is protected.
* @param string $meta_key The meta key.
* @param string $meta_type The meta type.
* @return bool $protected
*/
public function make_action_meta_protected( $protected = false, $meta_key = '', $meta_type = '' ) {
if ( 'wc_sc_auto_apply_coupon' === $meta_key ) {
return true;
}
return $protected;
}
/**
* Get auto applied coupons
*
* @since 4.27.0
* @return array
*/
public function get_auto_applied_coupons() {
$coupons = ( is_object( WC()->session ) && is_callable( array( WC()->session, 'get' ) ) ) ? WC()->session->get( 'wc_sc_auto_applied_coupons' ) : array();
return apply_filters( 'wc_sc_' . __FUNCTION__, ( ! empty( $coupons ) && is_array( $coupons ) ? $coupons : array() ), array( 'source' => $this ) );
}
/**
* Add auto applied coupon to WC session
*
* @since 4.27.0
* @param string $coupon_code Coupon Code.
*/
public function set_auto_applied_coupon( $coupon_code = '' ) {
if ( ! empty( $coupon_code ) ) {
$coupons = $this->get_auto_applied_coupons();
// Check if auto applied coupons are not empty.
if ( ! empty( $coupons ) && is_array( $coupons ) ) {
$coupons[] = $coupon_code;
} else {
$coupons = array( $coupon_code );
}
if ( is_object( WC()->session ) && is_callable( array( WC()->session, 'set' ) ) ) {
WC()->session->set( 'wc_sc_auto_applied_coupons', $coupons );
}
}
}
/**
* Remove an auto applied coupon from WC session
*
* @since 4.31.0
* @param string $coupon_code Coupon Code.
*/
public function unset_auto_applied_coupon( $coupon_code = '' ) {
if ( ! empty( $coupon_code ) ) {
$update = false;
$coupons = $this->get_auto_applied_coupons();
// Check if auto applied coupons are not empty.
if ( ! empty( $coupons ) && in_array( $coupon_code, $coupons, true ) ) {
$coupons = array_diff( $coupons, array( $coupon_code ) );
$update = true;
}
if ( true === $update && is_object( WC()->session ) && is_callable( array( WC()->session, 'set' ) ) ) {
$coupons = array_values( array_filter( $coupons ) );
WC()->session->set( 'wc_sc_auto_applied_coupons', $coupons );
}
}
}
/**
* Reset cart session data.
*
* @since 4.27.0
*/
public function reset_auto_applied_coupons_session() {
if ( is_object( WC()->session ) && is_callable( array( WC()->session, 'set' ) ) ) {
WC()->session->set( 'wc_sc_auto_applied_coupons', null );
}
}
/**
* Runs after a coupon is removed
*
* @since 4.31.0
* @param string $coupon_code The coupon code.
* @return void
*/
public function wc_sc_removed_coupon( $coupon_code = '' ) {
$backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore
if ( ! empty( $coupon_code ) && ! empty( $backtrace ) ) {
foreach ( $backtrace as $trace ) {
if ( ! empty( $trace['function'] ) && 'check_cart_coupons' === $trace['function'] && ! empty( $trace['class'] ) && 'WC_Cart' === $trace['class'] ) { // This condition will make sure that the coupon is removed automatically.
$this->unset_auto_applied_coupon( $coupon_code );
}
}
}
}
/**
* Check if auto apply coupon allowed in the cart
*
* @since 4.27.0
* @return bool.
*/
public function is_allow_auto_apply_coupons() {
$auto_applied_coupons = $this->get_auto_applied_coupons();
$auto_applied_coupons_count = ! empty( $auto_applied_coupons ) && is_array( $auto_applied_coupons ) ? count( $auto_applied_coupons ) : 0;
$max_auto_apply_coupons_limit = apply_filters( 'wc_sc_max_auto_apply_coupons_limit', get_option( 'wc_sc_max_auto_apply_coupons_limit', 5 ), array( 'source' => $this ) );
return apply_filters(
'wc_sc_' . __FUNCTION__,
$auto_applied_coupons_count < $max_auto_apply_coupons_limit,
array(
'source' => $this,
'auto_applied_coupons' => $auto_applied_coupons,
)
);
}
/**
* Check if the auto apply removable
*
* @since 4.27.0
* @param string $coupon_code Coupon Code.
* @return bool.
*/
public function is_auto_apply_coupon_removable( $coupon_code = '' ) {
return apply_filters(
'wc_sc_' . __FUNCTION__,
get_option( 'wc_sc_auto_apply_coupon_removable', 'yes' ),
array(
'source' => $this,
'coupon_code' => $coupon_code,
)
);
}
/**
* Check if the coupon is applied through auto apply
*
* @since 4.27.0
* @param string $coupon_code Coupon Code.
* @return bool.
*/
public function is_coupon_applied_by_auto_apply( $coupon_code = '' ) {
if ( ! empty( $coupon_code ) ) {
$applied_coupons = $this->get_auto_applied_coupons();
if ( ! empty( $applied_coupons ) && is_array( $applied_coupons ) && in_array( $coupon_code, $applied_coupons, true ) ) {
return true;
}
}
return false;
}
/**
* Check if coupon is applicable for auto apply
*
* @since 4.26.0
* @param WC_Coupon $coupon WooCommerce coupon object.
* @return bool
*/
public function is_coupon_valid_for_auto_apply( $coupon = null ) {
$valid = false;
if ( is_object( $coupon ) && $coupon instanceof WC_Coupon ) {
if ( $this->is_wc_gte_30() ) {
$coupon_code = is_callable( array( $coupon, 'get_code' ) ) ? $coupon->get_code() : '';
$discount_type = is_callable( array( $coupon, 'get_discount_type' ) ) ? $coupon->get_discount_type() : '';
$is_auto_generate_coupon = is_callable( array( $coupon, 'get_meta' ) ) ? $coupon->get_meta( 'auto_generate_coupon' ) : 'no';
$is_disable_email_restrict = is_callable( array( $coupon, 'get_meta' ) ) ? $coupon->get_meta( 'sc_disable_email_restriction' ) : 'no';
} else {
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
$coupon_code = ( ! empty( $coupon->code ) ) ? $coupon->code : '';
$discount_type = get_post_meta( $coupon_id, 'discount_type', true );
$is_auto_generate_coupon = get_post_meta( $coupon_id, 'auto_generate_coupon', true );
$is_disable_email_restrict = get_post_meta( $coupon_id, 'sc_disable_email_restriction', true );
}
$is_removable = $this->is_auto_apply_coupon_removable( $coupon_code );
$is_auto_applied = $this->is_coupon_applied_by_auto_apply( $coupon_code );
/**
* Validate coupon for auto apply if
*
* Discount type is not smart_coupon.
* Auto generate is not enabled.
* Coupon should not be auto applied OR auto applied coupon should not be removable.
* Coupon code is valid.
*/
$valid = 'smart_coupon' !== $discount_type
&& 'yes' !== $is_auto_generate_coupon
&& ( ! $is_auto_applied || 'yes' !== $is_removable )
&& $coupon->is_valid();
}
return apply_filters(
'wc_sc_' . __FUNCTION__,
$valid,
array(
'coupon_obj' => $coupon,
'source' => $this,
)
);
}
/**
* Function to apply coupons automatically.
*
* TODO: IF we need another variable for removed coupons;
* There will be 2 session variables: wc_sc_auto_applied_coupons and wc_sc_removed_auto_applied_coupons.
* Whenever a coupon will be auto-applied, it'll be stored in wc_sc_auto_applied_coupons.
* Whenever a coupon will be removed, it'll be moved from wc_sc_auto_applied_coupons to wc_sc_removed_auto_applied_coupons.
* And before applying an auto-apply coupon, it'll be made sure that the coupon doesn't exist in wc_sc_removed_auto_applied_coupons
* And sum of counts of both session variable will be considered before auto applying coupons. It will be made sure that the sum of counts in not exceeding option `wc_sc_max_auto_apply_coupons_limit`
* Reference: issues/234#note_27085
*/
public function auto_apply_coupons() {
$cart = ( is_object( WC() ) && isset( WC()->cart ) ) ? WC()->cart : null;
if ( is_object( $cart ) && is_callable( array( $cart, 'is_empty' ) ) && ! $cart->is_empty() && $this->is_allow_auto_apply_coupons() ) {
global $wpdb;
$user_role = '';
$email = '';
if ( ! is_admin() ) {
$current_user = wp_get_current_user();
if ( ! empty( $current_user->ID ) ) {
$user_role = ( ! empty( $current_user->roles[0] ) ) ? $current_user->roles[0] : '';
$email = get_user_meta( $current_user->ID, 'billing_email', true );
$email = ( ! empty( $email ) ) ? $email : $current_user->user_email;
}
}
$query = $wpdb->prepare(
"SELECT DISTINCT p.ID
FROM {$wpdb->posts} AS p
JOIN {$wpdb->postmeta} AS pm1
ON (p.ID = pm1.post_id
AND p.post_type = %s
AND p.post_status = %s
AND pm1.meta_key = %s
AND pm1.meta_value = %s)
JOIN {$wpdb->postmeta} AS pm2
ON (p.ID = pm2.post_id
AND pm2.meta_key IN ('wc_sc_user_role_ids', 'customer_email')
AND (pm2.meta_value = ''
OR pm2.meta_value = 'a:0:{}'",
'shop_coupon',
'publish',
'wc_sc_auto_apply_coupon',
'yes'
);
if ( ! empty( $user_role ) ) {
$query .= $wpdb->prepare(
' OR pm2.meta_value LIKE %s',
'%' . $wpdb->esc_like( $user_role ) . '%'
);
}
if ( ! empty( $email ) ) {
$query .= $wpdb->prepare(
' OR pm2.meta_value LIKE %s',
'%' . $wpdb->esc_like( $email ) . '%'
);
}
$query .= '))';
$auto_apply_coupon_ids = $wpdb->get_col( $query ); // phpcs:ignore
$auto_apply_coupon_ids = array_filter( array_map( 'absint', $auto_apply_coupon_ids ) );
if ( ! empty( $auto_apply_coupon_ids ) && is_array( $auto_apply_coupon_ids ) ) {
$valid_coupon_counter = 0;
$max_auto_apply_coupons_limit = apply_filters( 'wc_sc_max_auto_apply_coupons_limit', get_option( 'wc_sc_max_auto_apply_coupons_limit', 5 ), array( 'source' => $this ) );
foreach ( $auto_apply_coupon_ids as $apply_coupon_id ) {
// Process only five coupons.
if ( absint( $max_auto_apply_coupons_limit ) === $valid_coupon_counter ) {
break;
}
$coupon = new WC_Coupon( absint( $apply_coupon_id ) );
if ( $this->is_wc_gte_30() ) {
$coupon_id = ( ! empty( $coupon ) && is_callable( array( $coupon, 'get_id' ) ) ) ? $coupon->get_id() : 0;
$coupon_code = ( ! empty( $coupon ) && is_callable( array( $coupon, 'get_code' ) ) ) ? $coupon->get_code() : '';
} else {
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
$coupon_code = ( ! empty( $coupon->code ) ) ? $coupon->code : '';
}
// Check if it is a valid coupon object.
if ( $apply_coupon_id === $coupon_id && ! empty( $coupon_code ) && $this->is_coupon_valid_for_auto_apply( $coupon ) ) {
$cart_total = ( $this->is_wc_greater_than( '3.1.2' ) ) ? $cart->get_cart_contents_total() : $cart->cart_contents_total;
$is_auto_apply = apply_filters(
'wc_sc_is_auto_apply',
( $cart_total > 0 ),
array(
'source' => $this,
'cart_obj' => $cart,
'coupon_obj' => $coupon,
'cart_total' => $cart_total,
)
);
// Check if cart still requires a coupon discount and does not have coupon already applied.
if ( true === $is_auto_apply && ! $cart->has_discount( $coupon_code ) ) {
$cart->add_discount( $coupon_code );
$this->set_auto_applied_coupon( $coupon_code );
}
$valid_coupon_counter++;
} // End if to check valid coupon.
}
}
}
}
}
}
WC_SC_Auto_Apply_Coupon::get_instance();

View File

@@ -1,433 +0,0 @@
<?php
/**
* WooCommerce Smart Coupon DB update.
*
* @author StoreApps
* @since 4.28.0
* @version 1.1.0
* @package woocommerce-smart-coupons/includes/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Background_Upgrade' ) ) {
/**
* Class for WooCommerce Smart Coupons database update.
*/
class WC_SC_Background_Upgrade {
/**
* Number of row to fetch once a query run.
*
* (default value: 100)
*
* @var int
* @access protected
*/
protected $row_limit = 100;
/**
* Action name.
*
* @var string
* @access protected
*/
protected $action = '';
/**
* Variable to hold instance of WC_SC_Background_Upgrade
*
* @var $instance
*/
private static $instance = null;
/**
* Get single instance of WC_SC_Background_Upgrade
*
* @return WC_SC_Background_Upgrade Singleton object of WC_SC_Background_Upgrade
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Example_Background_Processing constructor.
*/
private function __construct() {
$this->action = 'wc_db_upgrade';
add_action( 'plugins_loaded', array( $this, 'init' ) );
add_action( 'init', array( $this, 'process_handler' ) );
add_action( 'init', array( $this, 'clear_all_process' ) );
add_action( 'action_scheduler_failed_action', array( $this, 'restart_failed_action' ) );
}
/**
* Init
*/
public function init() {
global $woocommerce_smart_coupon;
// Get list of db updates.
$updates = $this->get_updates();
if ( ! empty( $updates ) ) {
foreach ( $updates as $update ) {
// Break if version is empty.
if ( empty( $update['version'] ) ) {
break;
}
$version = $update['version'];
$update_status = $this->get_status( $version );
if ( version_compare( $woocommerce_smart_coupon->get_smart_coupons_version(), $version, '>=' ) && ( false === $update_status ) ) {
// Set db update status to pending.
$this->set_status( $version, 'pending' );
}
$handler = isset( $update['cron_handler'] ) ? $update['cron_handler'] : '';
$this->register_scheduler( $handler );
}
}
}
/**
* Process handler
*/
public function process_handler() {
if ( ! isset( $_GET['wc_sc_update'] ) || ! isset( $_GET['wc_sc_db_update_nonce'] ) ) {
return;
}
if ( ! wp_verify_nonce( wc_clean( wp_unslash( $_GET['wc_sc_db_update_nonce'] ) ), 'wc_sc_db_process' ) ) { // phpcs:ignore
return;
}
$this->handle_all( wc_clean( wp_unslash( $_GET['wc_sc_update'] ) ) ); // phpcs:ignore
}
/**
* Get list of db updates.
*/
public function get_updates() {
return array(
array(
'version' => '4.28.0', // Minimum plugin version to do the action.
'get_row_handler' => array( __CLASS__, 'get_applied_coupon_profile_options' ), // get data.
'cron_handler' => 'wcsc_move_applied_coupon_options_to_transient', // define crone handler which should be in this class.
),
);
}
/**
* Register action schedulers for db update.
*
* @param string $handler Handler name.
*/
public function register_scheduler( $handler = '' ) {
if ( ! empty( $handler ) && is_callable( array( $this, $handler ) ) ) {
add_action( $handler, array( $this, $handler ) );
}
}
/**
* Handle all updates.
*
* @param string $current_version Plugin version.
*/
protected function handle_all( $current_version = '0' ) {
if ( empty( $current_version ) ) {
return;
}
do_action( 'wc_sc_start_background_update', $current_version );
$updates = $this->get_updates();
if ( is_array( $updates ) && ! empty( $updates ) ) {
foreach ( $updates as $update ) {
// Compare version for db updates.
if ( ! empty( $update['version'] ) && version_compare( $current_version, $update['version'], '>=' ) ) {
$cron_handler = isset( $update['cron_handler'] ) ? $update['cron_handler'] : '';
if ( ! empty( $cron_handler ) && is_callable( array( $this, $cron_handler ) ) ) {
$row_handler = isset( $update['get_row_handler'] ) ? $update['get_row_handler'] : '';
$this->process( $update['version'], $cron_handler, $row_handler );
}
}
}
}
}
/**
* Handle the process.
*
* @param string $version Version number.
* @param string $cron_handler Cron handler action name.
* @param string $row_handler Fetch data handler name.
*/
private function process( $version = '', $cron_handler = '', $row_handler = '' ) {
$rows = ! empty( $row_handler ) && is_callable( $row_handler ) ? call_user_func( $row_handler ) : '';
if ( ! empty( $rows ) && is_array( $rows ) ) {
// Start the process if the status is pending.
if ( 'pending' === $this->get_status( $version ) ) {
if ( function_exists( 'as_enqueue_async_action' ) ) {
$this->set_status( $version, 'processing' );
as_enqueue_async_action( $cron_handler );
}
}
} else {
// Set status to `completed` if the data is empty.
$this->set_status( $version, 'completed' );
}
}
/**
* Clear all update process.
*/
public function clear_all_process() {
$updates = $this->get_updates();
foreach ( $updates as $update ) {
$version = isset( $update['version'] ) ? $update['version'] : '';
$row_handler = isset( $update['get_row_handler'] ) ? $update['get_row_handler'] : '';
$status = $this->get_status( $version );
if ( false === $status || 'done' === $status ) {
return;
}
$rows = ! empty( $row_handler ) && is_callable( $row_handler ) ? call_user_func( $row_handler ) : '';
if ( 'processing' === $status && empty( $rows ) ) {
do_action( 'wc_sc_background_update_completed', $version );
$this->set_status( $version, 'completed' );
}
}
}
/**
* Callback Method for move options to transient.
*
* @return void
*/
public function wcsc_move_applied_coupon_options_to_transient() {
$options = $this->get_applied_coupon_profile_options();
// Check if coupons are not empty.
if ( ! empty( $options ) && is_array( $options ) ) {
$start_time = time();
$loop = 1;
foreach ( $options as $option ) {
// disable auto apply.
$this->move_option_to_transient( $option );
if ( $this->loop_exceeded( $loop ) || $this->time_exceeded( $start_time ) || $this->memory_exceeded() ) {
// Update auto apply coupon id list.
if ( function_exists( 'as_enqueue_async_action' ) ) {
as_enqueue_async_action( __FUNCTION__ );
}
break;
}
$loop++;
}
}
}
/**
* Restart scheduler after one minute if it fails
*
* @param array $action_id id of failed action.
*/
public function restart_failed_action( $action_id = 0 ) {
if ( empty( $action_id ) || ! class_exists( 'ActionScheduler' ) || ! is_callable( array( 'ActionScheduler', 'store' ) ) || ! function_exists( 'as_enqueue_async_action' ) ) {
return;
}
$action = ActionScheduler::store()->fetch_action( $action_id );
$action_hook = $action->get_hook();
$updates = $this->get_updates();
if ( ! empty( $updates ) ) {
foreach ( $updates as $update ) {
if ( ! empty( $update['version'] ) && ! empty( $update['cron_handler'] ) ) {
if ( $action_hook === $update['cron_handler'] ) {
$this->set_status( $update['version'], 'processing' );
as_enqueue_async_action( $update['cron_handler'] );
}
}
}
}
}
/**
* Method to update the status of db upgrade.
*
* @param string $version wcsc db version.
* @param string $status status.
*
* @return bool.
*/
public function set_status( $version = '', $status = '' ) {
if ( ! empty( $version ) && ! empty( $status ) ) {
$db_status = get_option( 'sc_wc_db_update_status', array() );
$db_status[ $version ] = $status;
return update_option( 'sc_wc_db_update_status', $db_status, 'no' );
}
return false;
}
/**
* Method to get the status of db upgrade.
*
* @param string $version wcsc db version.
*
* @return bool.
*/
public function get_status( $version = '' ) {
if ( ! empty( $version ) ) {
$db_status = get_option( 'sc_wc_db_update_status', array() );
return ( ! empty( $db_status ) && isset( $db_status[ $version ] ) ) ? $db_status[ $version ] : false;
}
return false;
}
/**
* Loop exceeded
*
* Ensures the batch process never exceeds to handle the given limit of row.
*
* @param int $loop Number of loop done.
* @return bool
*/
public function loop_exceeded( $loop = 0 ) {
return $loop > apply_filters( $this->action . '_default_row_limit', $this->row_limit );
}
/**
* Memory exceeded
*
* Ensures the batch process never exceeds 90%
* of the maximum WordPress memory.
*
* @return bool
*/
protected function memory_exceeded() {
$memory_limit = $this->get_memory_limit() * 0.9; // 90% of max memory
$current_memory = memory_get_usage( true );
if ( $current_memory >= $memory_limit ) {
return true;
}
return false;
}
/**
* Get memory limit.
*
* @return int
*/
protected function get_memory_limit() {
if ( function_exists( 'ini_get' ) ) {
$memory_limit = ini_get( 'memory_limit' );
} else {
// Sensible default.
$memory_limit = '128M';
}
if ( ! $memory_limit || -1 === intval( $memory_limit ) ) {
// Unlimited, set to 32GB.
$memory_limit = '32G';
}
return wp_convert_hr_to_bytes( $memory_limit );
}
/**
* Time exceeded.
*
* Ensures the batch never exceeds a sensible time limit.
* A timeout limit of 30s is common on shared hosting.
*
* @param string $start_time start timestamp.
* @return bool
*/
protected function time_exceeded( $start_time = '' ) {
$finish = $start_time + apply_filters( $this->action . '_default_time_limit', 20 ); // 20 seconds
$return = false;
if ( time() >= $finish ) {
$return = true;
}
return apply_filters( $this->action . '_time_exceeded', $return );
}
/**
* Get `applied_coupon_profile` options names and values
*
* @return array
*/
public function get_applied_coupon_profile_options() {
global $wpdb;
$option_name = 'sc_applied_coupon_profile_%';
$options = $wpdb->get_results( // @codingStandardsIgnoreLine
$wpdb->prepare(
"SELECT option_name, option_value
FROM $wpdb->options
WHERE option_name LIKE %s",
$option_name
),
ARRAY_A
);
return $options;
}
/**
* Method to transfer single options to transient.
*
* @param array $option Array of option name and value.
* @return void
*/
protected function move_option_to_transient( $option = array() ) {
if ( isset( $option['option_name'] ) && isset( $option['option_value'] ) ) {
// Add new transient with option name.
$move = set_transient(
$option['option_name'],
maybe_unserialize( $option['option_value'] ),
apply_filters( 'wc_sc_applied_coupon_by_url_expire_time', MONTH_IN_SECONDS )
);
if ( true === $move ) {
// Delete the option if option is successfully moved.
delete_option( $option['option_name'] );
}
}
}
} // End class
} // End class exists check
WC_SC_Background_Upgrade::get_instance();

View File

@@ -1,773 +0,0 @@
<?php
/**
* Handle coupon actions
*
* @author StoreApps
* @since 3.5.0
* @version 1.5.0
*
* @package woocommerce-smart-coupons/includes/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Coupon_Actions' ) ) {
/**
* Class for handling processes of coupons
*/
class WC_SC_Coupon_Actions {
/**
* Variable to hold instance of WC_SC_Coupon_Actions
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
private function __construct() {
add_filter( 'woocommerce_add_cart_item', array( $this, 'modify_cart_item_data_in_add_to_cart' ), 15, 2 );
add_filter( 'woocommerce_get_cart_item_from_session', array( $this, 'modify_cart_item_in_session' ), 15, 3 );
add_filter( 'woocommerce_cart_item_quantity', array( $this, 'modify_cart_item_quantity' ), 5, 3 );
add_filter( 'woocommerce_cart_item_price', array( $this, 'modify_cart_item_price' ), 10, 3 );
add_filter( 'woocommerce_cart_item_subtotal', array( $this, 'modify_cart_item_price' ), 10, 3 );
add_filter( 'woocommerce_order_formatted_line_subtotal', array( $this, 'modify_cart_item_price' ), 10, 3 );
add_filter( 'woocommerce_coupon_get_items_to_validate', array( $this, 'remove_products_from_validation' ), 10, 2 );
add_action( 'woocommerce_applied_coupon', array( $this, 'coupon_action' ) );
add_action( 'woocommerce_removed_coupon', array( $this, 'remove_product_from_cart' ) );
add_action( 'woocommerce_check_cart_items', array( $this, 'review_cart_items' ) );
add_action( 'woocommerce_checkout_create_order_line_item', array( $this, 'add_product_source_in_order_item_meta' ), 10, 4 );
add_filter( 'wc_smart_coupons_export_headers', array( $this, 'export_headers' ) );
add_filter( 'wc_sc_export_coupon_meta_data', array( $this, 'export_coupon_meta_data' ), 10, 2 );
add_filter( 'smart_coupons_parser_postmeta_defaults', array( $this, 'postmeta_defaults' ) );
add_filter( 'sc_generate_coupon_meta', array( $this, 'generate_coupon_meta' ), 10, 2 );
add_filter( 'is_protected_meta', array( $this, 'make_action_meta_protected' ), 10, 3 );
add_action( 'wc_sc_new_coupon_generated', array( $this, 'copy_coupon_action_meta' ) );
add_filter( 'show_zero_amount_coupon', array( $this, 'show_coupon_with_actions' ), 10, 2 );
add_filter( 'wc_sc_is_auto_generate', array( $this, 'auto_generate_coupon_with_actions' ), 10, 2 );
add_filter( 'wc_sc_validate_coupon_amount', array( $this, 'validate_coupon_amount' ), 10, 2 );
add_filter( 'wc_sc_hold_applied_coupons', array( $this, 'maybe_run_coupon_actions' ), 10, 2 );
add_action( 'woocommerce_after_cart_item_quantity_update', array( $this, 'stop_cart_item_quantity_update' ), 99, 4 );
}
/**
* Get single instance of WC_SC_Coupon_Actions
*
* @return WC_SC_Coupon_Actions Singleton object of WC_SC_Coupon_Actions
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Get coupon actions
*
* @param string $coupon_code The coupon code.
* @return array Coupon actions
*/
public function get_coupon_actions( $coupon_code = '' ) {
if ( empty( $coupon_code ) ) {
return array();
}
$coupon_code = wc_format_coupon_code( $coupon_code );
$coupon = new WC_Coupon( $coupon_code );
if ( ! is_wp_error( $coupon ) ) {
if ( $this->is_wc_gte_30() ) {
$actions = $coupon->get_meta( 'wc_sc_add_product_details' );
} else {
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
$actions = get_post_meta( $coupon_id, 'wc_sc_add_product_details', true );
}
return apply_filters( 'wc_sc_coupon_actions', $actions, array( 'coupon_code' => $coupon_code ) );
}
return array();
}
/**
* Modify cart item data
*
* @param array $cart_item_data The cart item data.
* @param integer $product_id The product id.
* @param integer $variation_id The variation id.
* @param integer $quantity The quantity of product.
* @return array $cart_item_data
*/
public function modify_cart_item_data( $cart_item_data = array(), $product_id = 0, $variation_id = 0, $quantity = 0 ) {
if ( empty( $cart_item_data ) || empty( $product_id ) || empty( $quantity ) ) {
return $cart_item_data;
}
if ( ! empty( $cart_item_data['wc_sc_product_source'] ) ) {
$coupon_code = $cart_item_data['wc_sc_product_source'];
$coupon_actions = $this->get_coupon_actions( $coupon_code );
if ( ! empty( $coupon_actions ) ) {
foreach ( $coupon_actions as $product_data ) {
if ( ! empty( $product_data['product_id'] ) && in_array( absint( $product_data['product_id'] ), array_map( 'absint', array( $product_id, $variation_id ) ), true ) ) {
$discount_amount = ( '' !== $product_data['discount_amount'] ) ? $product_data['discount_amount'] : '';
if ( '' !== $discount_amount ) {
if ( ! empty( $variation_id ) ) {
$product = wc_get_product( $variation_id );
} else {
$product = wc_get_product( $product_id );
}
$product_price = $product->get_price();
$regular_price = $product->get_regular_price();
$discount_type = ( ! empty( $product_data['discount_type'] ) ) ? $product_data['discount_type'] : 'percent';
switch ( $discount_type ) {
case 'flat':
$discount = $this->convert_price( $discount_amount );
break;
case 'percent':
$discount = ( $product_price * $discount_amount ) / 100;
break;
}
$discount = wc_cart_round_discount( min( $product_price, $discount ), 2 );
$discounted_price = $product_price - $discount;
$cart_item_data['data']->set_price( $discounted_price );
$cart_item_data['data']->set_regular_price( $regular_price );
$cart_item_data['data']->set_sale_price( $discounted_price );
}
break;
}
}
}
}
return $cart_item_data;
}
/**
* Modify cart item in WC_Cart::add_to_cart()
*
* @param array $cart_item_data The cart item data as passed by filter 'woocommerce_add_cart_item'.
* @param string $cart_item_key The cart item key.
* @return array $cart_item_data
*/
public function modify_cart_item_data_in_add_to_cart( $cart_item_data = array(), $cart_item_key = '' ) {
if ( ! empty( $cart_item_data['wc_sc_product_source'] ) ) {
$cart_item_data = $this->modify_cart_item_data( $cart_item_data, $cart_item_data['product_id'], $cart_item_data['variation_id'], $cart_item_data['quantity'] );
}
return $cart_item_data;
}
/**
* Modify cart item in session
*
* @param array $session_data The session data.
* @param array $values The cart item.
* @param string $key The cart item key.
* @return array $session_data
*/
public function modify_cart_item_in_session( $session_data = array(), $values = array(), $key = '' ) {
if ( ! empty( $values['wc_sc_product_source'] ) ) {
$session_data['wc_sc_product_source'] = $values['wc_sc_product_source'];
$qty = ( ! empty( $session_data['quantity'] ) ) ? absint( $session_data['quantity'] ) : ( ( ! empty( $values['quantity'] ) ) ? absint( $values['quantity'] ) : 1 );
$session_data = $this->modify_cart_item_data( $session_data, $session_data['product_id'], $session_data['variation_id'], $qty );
}
return $session_data;
}
/**
* Modify cart item quantity
*
* @param string $product_quantity The product quantity.
* @param string $cart_item_key The cart item key.
* @param array $cart_item The cart item.
* @return string $product_quantity
*/
public function modify_cart_item_quantity( $product_quantity = '', $cart_item_key = '', $cart_item = array() ) {
if ( ! empty( $cart_item['wc_sc_product_source'] ) ) {
$product_quantity = sprintf( '%s <input type="hidden" name="cart[%s][qty]" value="%s" />', $cart_item['quantity'], $cart_item_key, $cart_item['quantity'] );
}
return $product_quantity;
}
/**
* Modify cart item price
*
* @param string $product_price The product price.
* @param array $cart_item The cart item.
* @param string $cart_item_key The cart item key.
* @return string $product_price
*/
public function modify_cart_item_price( $product_price = '', $cart_item = array(), $cart_item_key = '' ) {
if ( ( is_array( $cart_item ) && isset( $cart_item['wc_sc_product_source'] ) ) || ( is_object( $cart_item ) && is_callable( array( $cart_item, 'get_meta' ) ) && $cart_item->get_meta( '_wc_sc_product_source' ) ) ) {
if ( wc_price( 0 ) === $product_price ) {
$product_price = apply_filters(
'wc_sc_price_zero_text',
$product_price,
array(
'cart_item' => $cart_item,
'cart_item_key' => $cart_item_key,
)
);
}
}
return $product_price;
}
/**
* Remove products added by the coupon from validation
*
* Since the filter 'woocommerce_coupon_get_items_to_validate' is added in WooCommerce 3.4.0, this function will work only in WC 3.4.0+
* Otherwise, the products added by coupon might get double discounts applied
*
* @param array $items The cart/order items.
* @param WC_Discounts $discounts The discounts object.
* @return mixed $items
*/
public function remove_products_from_validation( $items = array(), $discounts = null ) {
if ( ! empty( $items ) ) {
foreach ( $items as $index => $item ) {
$coupon_code = '';
if ( is_array( $item->object ) && isset( $item->object['wc_sc_product_source'] ) ) {
$coupon_code = $item->object['wc_sc_product_source'];
} elseif ( is_a( $item->object, 'WC_Order_Item' ) && is_callable( array( $item->object, 'get_meta' ) ) && $item->object->get_meta( '_wc_sc_product_source' ) ) {
$coupon_code = $item->object->get_meta( '_wc_sc_product_source' );
}
if ( ! empty( $coupon_code ) ) {
$item_product_id = ( is_a( $item->product, 'WC_Product' ) && is_callable( array( $item->product, 'get_id' ) ) ) ? $item->product->get_id() : 0;
$coupon_actions = $this->get_coupon_actions( $coupon_code );
if ( ! empty( $coupon_actions ) ) {
foreach ( $coupon_actions as $product_data ) {
if ( ! empty( $product_data['product_id'] ) && absint( $product_data['product_id'] ) === absint( $item_product_id ) ) {
$discount_amount = ( '' !== $product_data['discount_amount'] ) ? $product_data['discount_amount'] : '';
if ( '' !== $discount_amount ) {
unset( $items[ $index ] );
}
}
}
}
}
}
}
return $items;
}
/**
* Apply coupons actions
*
* @param string $coupon_code The coupon code.
*/
public function coupon_action( $coupon_code = '' ) {
if ( empty( $coupon_code ) ) {
return;
}
$coupon_actions = $this->get_coupon_actions( $coupon_code );
if ( ! empty( $coupon_actions ) && ! is_scalar( $coupon_actions ) ) {
$product_names = array();
foreach ( $coupon_actions as $coupon_action ) {
if ( empty( $coupon_action['product_id'] ) ) {
continue;
}
$id = absint( $coupon_action['product_id'] );
$product = wc_get_product( $id );
$product_data = $this->get_product_data( $product );
$product_id = ( ! empty( $product_data['product_id'] ) ) ? absint( $product_data['product_id'] ) : 0;
$variation_id = ( ! empty( $product_data['variation_id'] ) ) ? absint( $product_data['variation_id'] ) : 0;
$variation = array();
if ( ! empty( $variation_id ) ) {
$variation = $product->get_variation_attributes();
}
$quantity = absint( $coupon_action['quantity'] );
$cart_item_data = array(
'wc_sc_product_source' => $coupon_code,
);
$cart_item_key = WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variation, $cart_item_data );
if ( ! empty( $cart_item_key ) ) {
if ( $this->is_wc_gte_30() ) {
$product_names[] = ( is_object( $product ) && is_callable( array( $product, 'get_name' ) ) ) ? $product->get_name() : '';
} else {
$product_names[] = ( is_object( $product ) && is_callable( array( $product, 'get_title' ) ) ) ? $product->get_title() : '';
}
}
}
if ( ! empty( $product_names ) ) {
/* translators: 1. Product title */
wc_add_notice( sprintf( __( '%s has been added to your cart!', 'woocommerce-smart-coupons' ), implode( ', ', $product_names ) ) );
}
}
}
/**
* Remove products from cart if the coupon, which added the product, is removed
*
* @param string $coupon_code The coupon code.
*/
public function remove_product_from_cart( $coupon_code = '' ) {
if ( is_admin() ) {
return;
}
if ( ! empty( $coupon_code ) ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if ( isset( $cart_item['wc_sc_product_source'] ) && $cart_item['wc_sc_product_source'] === $coupon_code ) {
// Action 'woocommerce_before_calculate_totals' is hooked by WooCommerce Subscription while removing coupons in local WooCommerce Cart variable in which we don't need to remove added cart item.
if ( ! doing_action( 'woocommerce_before_calculate_totals' ) ) {
WC()->cart->set_quantity( $cart_item_key, 0 );
}
}
}
}
}
/**
* Review cart items
*/
public function review_cart_items() {
$applied_coupons = (array) WC()->cart->applied_coupons;
$products = array();
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if ( ! empty( $cart_item['wc_sc_product_source'] ) && ! in_array( $cart_item['wc_sc_product_source'], $applied_coupons, true ) ) {
WC()->cart->set_quantity( $cart_item_key, 0 );
$coupon_code = $cart_item['wc_sc_product_source'];
if ( empty( $products[ $coupon_code ] ) || ! is_array( $products[ $coupon_code ] ) ) {
$products[ $coupon_code ] = array();
}
$products[ $coupon_code ][] = ( is_object( $cart_item['data'] ) && is_callable( array( $cart_item['data'], 'get_name' ) ) ) ? $cart_item['data']->get_name() : '';
$products[ $coupon_code ] = array_filter( $products[ $coupon_code ] );
}
}
if ( ! empty( $products ) ) {
foreach ( $products as $coupon_code => $product_names ) {
/* translators: 1. Product/s 2. Product names 3. is/are 4. Coupons code */
wc_add_notice( sprintf( __( '%1$s %2$s %3$s removed because coupon %4$s is removed.', 'woocommerce-smart-coupons' ), _n( 'Product', 'Products', count( $products[ $coupon_code ] ), 'woocommerce-smart-coupons' ), '<strong>' . implode( ', ', $products[ $coupon_code ] ) . '</strong>', _n( 'is', 'are', count( $products[ $coupon_code ] ), 'woocommerce-smart-coupons' ), '<code>' . $coupon_code . '</code>' ), 'error' );
}
}
}
/**
* Add product source in order item meta
*
* @param mixed $item The item.
* @param string $cart_item_key The cart item key.
* @param array $values The cart item.
* @param WC_Order $order The order.
*/
public function add_product_source_in_order_item_meta( $item = null, $cart_item_key = '', $values = array(), $order = null ) {
if ( isset( $values['wc_sc_product_source'] ) ) {
$item->add_meta_data( '_wc_sc_product_source', $values['wc_sc_product_source'], true );
}
}
/**
* Get product data
*
* @param mixed $product The product object.
* @return array
*/
public function get_product_data( $product = null ) {
if ( empty( $product ) ) {
return array();
}
if ( $this->is_wc_gte_30() ) {
$product_id = ( is_object( $product ) && is_callable( array( $product, 'get_id' ) ) ) ? $product->get_id() : 0;
} else {
$product_id = ( ! empty( $product->id ) ) ? $product->id : 0;
}
$product_type = ( is_object( $product ) && is_callable( array( $product, 'get_type' ) ) ) ? $product->get_type() : '';
if ( 'variation' === $product_type ) {
$variation_id = $product_id;
if ( $this->is_wc_gte_30() ) {
$parent_id = ( is_object( $product ) && is_callable( array( $product, 'get_parent_id' ) ) ) ? $product->get_parent_id() : 0;
$variation_data = wc_get_product_variation_attributes( $variation_id );
} else {
$parent_id = ( is_object( $product ) && is_callable( array( $product, 'get_parent' ) ) ) ? $product->get_parent() : 0;
$variation_data = ( ! empty( $product->variation_data ) ) ? $product->variation_data : array();
}
$product_id = $parent_id;
} else {
$variation_id = 0;
$variation_data = array();
}
$product_data = array(
'product_id' => $product_id,
'variation_id' => $variation_id,
'variation_data' => $variation_data,
);
return apply_filters( 'wc_sc_product_data', $product_data, array( 'product_obj' => $product ) );
}
/**
* Add action's meta in export headers
*
* @param array $headers Existing headers.
* @return array
*/
public function export_headers( $headers = array() ) {
$action_headers = array(
'wc_sc_add_product_details' => __( 'Add product details', 'woocommerce-smart-coupons' ),
);
return array_merge( $headers, $action_headers );
}
/**
* Function to handle coupon meta data during export of existing coupons
*
* @param mixed $meta_value The meta value.
* @param array $args Additional arguments.
* @return string Processed meta value
*/
public function export_coupon_meta_data( $meta_value = '', $args = array() ) {
$index = ( ! empty( $args['index'] ) ) ? $args['index'] : -1;
$meta_keys = ( ! empty( $args['meta_keys'] ) ) ? $args['meta_keys'] : array();
$meta_values = ( ! empty( $args['meta_values'] ) ) ? $args['meta_values'] : array();
if ( $index >= 0 && ! empty( $meta_keys[ $index ] ) && 'wc_sc_add_product_details' === $meta_keys[ $index ] ) {
if ( ! empty( $meta_value ) && is_array( $meta_value ) ) {
$product_details = array();
foreach ( $meta_value as $value ) {
$product_details[] = implode( ',', $value );
}
$meta_value = implode( '|', $product_details );
}
}
return $meta_value;
}
/**
* Post meta defaults for action's meta
*
* @param array $defaults Existing postmeta defaults.
* @return array
*/
public function postmeta_defaults( $defaults = array() ) {
$actions_defaults = array(
'wc_sc_add_product_details' => '',
);
return array_merge( $defaults, $actions_defaults );
}
/**
* Add action's meta with value in coupon meta
*
* @param array $data The row data.
* @param array $post The POST values.
* @return array Modified data
*/
public function generate_coupon_meta( $data = array(), $post = array() ) {
if ( isset( $post['wc_sc_add_product_ids'] ) ) {
if ( $this->is_wc_gte_30() ) {
$product_ids = wc_clean( wp_unslash( $post['wc_sc_add_product_ids'] ) ); // phpcs:ignore
} else {
$product_ids = array_filter( array_map( 'trim', explode( ',', sanitize_text_field( wp_unslash( $post['wc_sc_add_product_ids'] ) ) ) ) ); // phpcs:ignore
}
$add_product_details = array();
if ( ! empty( $product_ids ) ) {
$quantity = ( isset( $post['wc_sc_add_product_qty'] ) ) ? wc_clean( wp_unslash( $post['wc_sc_add_product_qty'] ) ) : 1;
$discount_amount = ( isset( $post['wc_sc_product_discount_amount'] ) ) ? wc_clean( wp_unslash( $post['wc_sc_product_discount_amount'] ) ) : '';
$discount_type = ( isset( $post['wc_sc_product_discount_type'] ) ) ? wc_clean( wp_unslash( $post['wc_sc_product_discount_type'] ) ) : '';
foreach ( $product_ids as $id ) {
$product_data = array();
$product_data['product_id'] = $id;
$product_data['quantity'] = $quantity;
$product_data['discount_amount'] = $discount_amount;
$product_data['discount_type'] = $discount_type;
$add_product_details[] = implode( ',', $product_data );
}
}
$data['wc_sc_add_product_details'] = implode( '|', $add_product_details );
}
return $data;
}
/**
* Make meta data of SC actions, protected
*
* @param bool $protected Is protected.
* @param string $meta_key The meta key.
* @param string $meta_type The meta type.
* @return bool $protected
*/
public function make_action_meta_protected( $protected, $meta_key, $meta_type ) {
$sc_meta = array(
'wc_sc_add_product_details',
);
if ( in_array( $meta_key, $sc_meta, true ) ) {
return true;
}
return $protected;
}
/**
* Function to copy coupon action meta in newly generated coupon
*
* @param array $args The arguments.
*/
public function copy_coupon_action_meta( $args = array() ) {
$new_coupon_id = ( ! empty( $args['new_coupon_id'] ) ) ? absint( $args['new_coupon_id'] ) : 0;
$coupon = ( ! empty( $args['ref_coupon'] ) ) ? $args['ref_coupon'] : false;
if ( empty( $new_coupon_id ) || empty( $coupon ) ) {
return;
}
$add_product_details = array();
if ( $this->is_wc_gte_30() ) {
$add_product_details = $coupon->get_meta( 'wc_sc_add_product_details' );
} else {
$old_coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
$add_product_details = get_post_meta( $old_coupon_id, 'wc_sc_add_product_details', true );
}
$this->update_post_meta( $new_coupon_id, 'wc_sc_add_product_details', $add_product_details );
}
/**
* Function to validate whether to show the coupon or not
*
* @param boolean $is_show Show or not.
* @param array $args Additional arguments.
* @return boolean
*/
public function show_coupon_with_actions( $is_show = false, $args = array() ) {
$coupon = ( ! empty( $args['coupon'] ) ) ? $args['coupon'] : null;
if ( empty( $coupon ) ) {
return $is_show;
}
if ( $this->is_wc_gte_30() ) {
$coupon_code = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_code' ) ) ) ? $coupon->get_code() : '';
} else {
$coupon_code = ( ! empty( $coupon->code ) ) ? $coupon->code : '';
}
$coupon_actions = $this->get_coupon_actions( $coupon_code );
if ( ! empty( $coupon_actions ) ) {
return true;
}
return $is_show;
}
/**
* Allow auto-generate of coupon with coupon action
*
* @param boolean $is_auto_generate Whether to auto-generate or not.
* @param array $args Additional parameters.
* @return boolean $is_auto_generate
*/
public function auto_generate_coupon_with_actions( $is_auto_generate = false, $args = array() ) {
$coupon = ( ! empty( $args['coupon_obj'] ) && $args['coupon_obj'] instanceof WC_Coupon ) ? $args['coupon_obj'] : false;
$coupon_id = ( ! empty( $args['coupon_id'] ) ) ? $args['coupon_id'] : false;
if ( ! empty( $coupon ) && ! empty( $coupon_id ) ) {
if ( $this->is_wc_gte_30() ) {
$coupon_code = $coupon->get_code();
} else {
$coupon_code = ( ! empty( $coupon->code ) ) ? $coupon->code : '';
}
if ( ! empty( $coupon_code ) ) {
$actions = ( $this->is_callable( $coupon, 'get_meta' ) ) ? $coupon->get_meta( 'wc_sc_add_product_details' ) : get_post_meta( $coupon_id, 'wc_sc_add_product_details', true );
$coupon_actions = apply_filters(
'wc_sc_coupon_actions',
$actions,
array(
'coupon_code' => $coupon_code,
'source' => $this,
)
);
if ( ! empty( $coupon_actions ) ) {
return true;
}
}
}
return $is_auto_generate;
}
/**
* Validate coupon having actions but without an amount
*
* @param boolean $is_valid_coupon_amount Whether the amount is validate or not.
* @param array $args Additional parameters.
* @return boolean
*/
public function validate_coupon_amount( $is_valid_coupon_amount = true, $args = array() ) {
if ( ! $is_valid_coupon_amount ) {
$coupon_amount = ( ! empty( $args['coupon_amount'] ) ) ? $args['coupon_amount'] : 0;
$discount_type = ( ! empty( $args['discount_type'] ) ) ? $args['discount_type'] : '';
$coupon_code = ( ! empty( $args['coupon_code'] ) ) ? $args['coupon_code'] : '';
$coupon_actions = ( ! empty( $coupon_code ) ) ? $this->get_coupon_actions( $coupon_code ) : array();
if ( 'smart_coupon' === $discount_type && $coupon_amount <= 0 && ! empty( $coupon_actions ) ) {
return true;
}
}
return $is_valid_coupon_amount;
}
/**
* Handle coupon actions when the cart is empty
*
* @param boolean $is_hold Whether to hold the coupon in cookie.
* @param array $args Additional arguments.
* @return boolean
*/
public function maybe_run_coupon_actions( $is_hold = true, $args = array() ) {
$cart = ( is_object( WC() ) && isset( WC()->cart ) ) ? WC()->cart : null;
if ( empty( $cart ) || WC()->cart->is_empty() ) {
$coupons_data = ( ! empty( $args['coupons_data'] ) ) ? $args['coupons_data'] : array();
if ( ! empty( $coupons_data ) ) {
foreach ( $coupons_data as $coupon_data ) {
$coupon_code = ( ! empty( $coupon_data['coupon-code'] ) ) ? $coupon_data['coupon-code'] : '';
if ( ! empty( $coupon_code ) ) {
$coupon_actions = $this->get_coupon_actions( $coupon_code );
$coupon_products = ( ! empty( $coupon_actions ) ) ? wp_list_pluck( $coupon_actions, 'product_id' ) : array();
if ( ! empty( $coupon_products ) ) {
if ( ! WC()->cart->has_discount( $coupon_code ) ) {
WC()->cart->add_discount( trim( $coupon_code ) );
$is_hold = false;
}
}
}
}
}
}
return $is_hold;
}
/**
* Stop product update option for action tab products.
*
* @param string $cart_item_key contains the id of the cart item.
* @param int $quantity Current quantity of the item.
* @param int $old_quantity Old quantity of the item.
* @param WC_Cart $cart Cart object.
* @return void
*/
public function stop_cart_item_quantity_update( $cart_item_key = '', $quantity = 1, $old_quantity = 1, $cart = object ) {
if ( empty( $cart_item_key ) || ! is_object( $cart ) || ! is_a( $cart, 'WC_Cart' ) ) {
return;
}
$cart_data = is_callable( array( $cart, 'get_cart' ) ) ? $cart->get_cart() : array();
$cart_item = ( ! empty( $cart_data[ $cart_item_key ] ) ) ? $cart_data[ $cart_item_key ] : array();
if ( empty( $cart_item ) ) {
return;
}
$applied_coupons = is_callable( array( $cart, 'get_applied_coupons' ) ) ? $cart->get_applied_coupons() : array();
if ( ! empty( $cart_item['wc_sc_product_source'] ) && in_array( $cart_item['wc_sc_product_source'], $applied_coupons, true ) ) {
$cart->cart_contents[ $cart_item_key ]['quantity'] = $old_quantity;
}
}
}
}
WC_SC_Coupon_Actions::get_instance();

View File

@@ -1,216 +0,0 @@
<?php
/**
* Smart Coupons category fields in coupons
*
* @author StoreApps
* @since 4.8.0
* @version 1.2.0
*
* @package woocommerce-smart-coupons/includes/
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'WC_SC_Coupon_Categories' ) ) {
/**
* Class for handling Smart Coupons' field in coupons
*/
class WC_SC_Coupon_Categories {
/**
* Variable to hold instance of WC_SC_Coupon_Categories
*
* @var $instance
*/
private static $instance = null;
/**
* Get single instance of WC_SC_Coupon_Categories
*
* @return WC_SC_Coupon_Categories Singleton object of WC_SC_Coupon_Categories
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor
*/
private function __construct() {
add_action( 'init', array( $this, 'wc_sc_coupons_add_category' ) );
add_filter( 'parent_file', array( $this, 'wc_sc_make_menu_active' ) );
add_action( 'admin_footer', array( $this, 'add_footer_script' ) );
add_filter( 'manage_edit-sc_coupon_category_columns', array( $this, 'wc_sc_coupon_category_id_column' ) );
add_filter( 'manage_sc_coupon_category_custom_column', array( $this, 'wc_sc_coupon_category_id_column_content' ), 10, 3 );
add_filter( 'manage_edit-sc_coupon_category_sortable_columns', array( $this, 'wc_sc_define_sortable_id_columns' ) );
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Register custom taxonomy called sc_coupon_category.
*/
public function wc_sc_coupons_add_category() {
$labels = array(
'name' => __( 'Coupon categories', 'woocommerce-smart-coupons' ),
'singular_name' => __( 'Category', 'woocommerce-smart-coupons' ),
'menu_name' => _x( 'Categories', 'Admin menu name', 'woocommerce-smart-coupons' ),
'search_items' => __( 'Search coupon categories', 'woocommerce-smart-coupons' ),
'all_items' => __( 'All coupon categories', 'woocommerce-smart-coupons' ),
'parent_item' => __( 'Parent coupon category', 'woocommerce-smart-coupons' ),
'parent_item_colon' => __( 'Parent coupon category:', 'woocommerce-smart-coupons' ),
'edit_item' => __( 'Edit coupon category', 'woocommerce-smart-coupons' ),
'update_item' => __( 'Update coupon category', 'woocommerce-smart-coupons' ),
'add_new_item' => __( 'Add new coupon category', 'woocommerce-smart-coupons' ),
'new_item_name' => __( 'New coupon category name', 'woocommerce-smart-coupons' ),
'not_found' => __( 'No coupon categories found', 'woocommerce-smart-coupons' ),
);
register_taxonomy(
'sc_coupon_category', // Taxonomy name.
array( 'shop_coupon' ), // object for which the taxonomy is created.
array(
'labels' => $labels,
'description' => __( 'Manage coupon categories', 'woocommerce-smart-coupons' ),
'public' => true,
'hierarchical' => true,
'show_ui' => true,
'show_in_menu' => false,
'show_in_rest' => true,
'show_admin_column' => true,
'rewrite' => array( 'slug' => 'sc_coupon_category' ),
'query_var' => true,
)
);
register_taxonomy_for_object_type( 'sc_coupon_category', 'shop_coupon' );
}
/**
* Function to render coupon category column on coupons dashboard.
*
* @param int $post_id The coupon ID.
*/
public function render_coupon_category_column( $post_id ) {
$terms = get_the_terms( $post_id, 'sc_coupon_category' );
if ( ! empty( $terms ) ) {
foreach ( $terms as $term ) {
$content[] = '<a href="' . esc_url( admin_url( 'edit.php?sc_coupon_category=' . $term->slug . '&post_type=shop_coupon' ) ) . '">' . esc_html( $term->name ) . '</a>';
}
echo join( ', ', $content ); // phpcs:ignore
} else {
echo '<span class="na">&ndash;</span>';
}
}
/**
* Function to set woocommerce menu active
*
* @param string $parent_file file reference for menu.
*/
public function wc_sc_make_menu_active( $parent_file ) {
global $current_screen;
$taxonomy = $current_screen->taxonomy;
if ( 'sc_coupon_category' === $taxonomy ) {
if ( $this->is_wc_gte_44() ) {
$parent_file = 'woocommerce-marketing';
} else {
$parent_file = 'woocommerce';
}
}
return $parent_file;
}
/**
* Function to add custom script in admin footer.
*/
public function add_footer_script() {
global $pagenow, $post;
$get_post_type = ( ! empty( $post->post_type ) ) ? $post->post_type : ( ( ! empty( $_GET['post_type'] ) ) ? wc_clean( wp_unslash( $_GET['post_type'] ) ) : '' ); // phpcs:ignore
if ( 'shop_coupon' === $get_post_type ) {
if ( 'post.php' === $pagenow || 'post-new.php' === $pagenow ) {
$manage_category_string = __( 'Manage coupon categories', 'woocommerce-smart-coupons' );
?>
<script type="text/javascript">
jQuery(function() {
jQuery('#sc_coupon_category-tabs').before('<div class="sc-manage-category"><a target="_blank" href="<?php echo esc_url( admin_url( 'edit-tags.php?taxonomy=sc_coupon_category&post_type=shop_coupon' ) ); ?> "><?php echo esc_html( $manage_category_string ); ?></a></div>');
});
</script>
<?php
}
}
}
/**
* Function for add id column in coupon category taxonomy page.
*
* @param array $columns - Existing headers.
* @return array
*/
public function wc_sc_coupon_category_id_column( $columns = array() ) {
if ( ! empty( $columns ) ) {
return array_slice( $columns, 0, 1, true ) + array( 'id' => 'ID' ) + array_slice( $columns, 1, count( $columns ) - 1, true );
}
return $columns;
}
/**
* Function for add content to ID column of coupon category taxonomy page.
*
* @param string $content - column content.
* @param string $column_name - column_name.
* @param string $term_id - id.
* @return string
*/
public function wc_sc_coupon_category_id_column_content( $content = '', $column_name = '', $term_id = 0 ) {
return $term_id;
}
/**
* Function for change ID column to sortable.
*
* @param array $columns - Existing columns.
* @return array
*/
public function wc_sc_define_sortable_id_columns( $columns = array() ) {
$columns['id'] = 'id';
return $columns;
}
}
}
WC_SC_Coupon_Categories::get_instance();

View File

@@ -1,196 +0,0 @@
<?php
/**
* Handle coupon columns
*
* @author StoreApps
* @since 4.5.2
* @version 1.1.0
*
* @package woocommerce-smart-coupons/includes/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Coupon_Columns' ) ) {
/**
* Class for handling coupon columns
*/
class WC_SC_Coupon_Columns {
/**
* Variable to hold instance of WC_SC_Coupon_Columns
*
* @var $instance
*/
private static $instance = null;
/**
* Post type.
*
* @var string
*/
protected $list_table_type = 'shop_coupon';
/**
* Object being shown on the row.
*
* @var object|null
*/
protected $object = null;
/**
* Constructor
*/
private function __construct() {
add_filter( 'manage_' . $this->list_table_type . '_posts_columns', array( $this, 'define_columns' ), 11 );
add_action( 'manage_' . $this->list_table_type . '_posts_custom_column', array( $this, 'render_columns' ), 10, 2 );
}
/**
* Get single instance of WC_SC_Coupon_Columns
*
* @return WC_SC_Coupon_Columns Singleton object of WC_SC_Coupon_Columns
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Pre-fetch any data for the row each column has access to it.
*
* @param int $post_id Post ID being shown.
*/
protected function prepare_row_data( $post_id = 0 ) {
if ( empty( $post_id ) ) {
return;
}
$coupon_id = 0;
if ( ! empty( $this->object ) ) {
$coupon = $this->object;
if ( $this->is_wc_gte_30() ) {
$coupon_id = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_id' ) ) ) ? $coupon->get_id() : 0;
} else {
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
}
}
if ( empty( $this->object ) || $coupon_id !== $post_id ) {
$this->object = new WC_Coupon( $post_id );
}
}
/**
* Define which columns to show on this screen.
*
* @param array $columns Existing columns.
* @return array
*/
public function define_columns( $columns = array() ) {
if ( ! is_array( $columns ) || empty( $columns ) ) {
$columns = array();
}
$columns['wc_sc_view_orders'] = __( 'Used in orders', 'woocommerce-smart-coupons' );
$columns['wc_sc_coupon_category'] = __( 'Coupon categories', 'woocommerce-smart-coupons' );
return $columns;
}
/**
* Render individual columns.
*
* @param string $column Column ID to render.
* @param int $post_id Post ID being shown.
*/
public function render_columns( $column = '', $post_id = 0 ) {
$this->prepare_row_data( $post_id );
if ( ! $this->object ) {
return;
}
if ( ! empty( $column ) ) {
switch ( $column ) {
case 'wc_sc_view_orders':
$this->render_view_orders_column();
break;
case 'wc_sc_coupon_category':
WC_SC_Coupon_Categories::get_instance()->render_coupon_category_column( $post_id );
break;
}
}
}
/**
* Render column: view_orders.
*/
public function render_view_orders_column() {
$coupon = $this->object;
if ( $this->is_wc_gte_30() ) {
$usage_count = ( ! empty( $coupon ) && is_callable( array( $coupon, 'get_usage_count' ) ) ) ? $coupon->get_usage_count() : 0;
} else {
$usage_count = ( ! empty( $coupon->usage_count ) ) ? $coupon->usage_count : 0;
}
$column_content = '';
if ( ! empty( $usage_count ) ) {
if ( $this->is_wc_gte_30() ) {
$coupon_code = ( ! empty( $coupon ) && is_callable( array( $coupon, 'get_code' ) ) ) ? $coupon->get_code() : '';
} else {
$coupon_code = ( ! empty( $coupon->code ) ) ? $coupon->code : '';
}
$coupon_usage_url = esc_url( admin_url( sprintf( 'edit.php?s=%s&post_status=all&post_type=shop_order&trigger=woocommerce-smart-coupons', esc_html( $coupon_code ) ) ) );
$column_content = sprintf( '<a href="%s" target="_blank"><span class="dashicons dashicons-external"></span></a>', $coupon_usage_url );
} else {
$column_content = '&ndash;';
}
$column_content = apply_filters( 'wc_sc_view_orders_column_content', $column_content, array( 'coupon' => $coupon ) );
echo $column_content; // phpcs:ignore
}
}
}
WC_SC_Coupon_Columns::get_instance();

View File

@@ -1,463 +0,0 @@
<?php
/**
* Class to handle feature Coupon Message
*
* @author Ratnakar
* @category Admin
* @package wocommerce-smart-coupons/includes
* @version 1.9.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Coupon_Message' ) ) {
/**
* Class WC_SC_Coupon_Message
*/
class WC_SC_Coupon_Message {
/**
* Variable to hold instance of this class
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*
* @since 1.0
*/
private function __construct() {
add_action( 'wc_smart_coupons_actions', array( $this, 'wc_coupon_message_options' ), 10, 2 );
add_action( 'woocommerce_coupon_options_save', array( $this, 'wc_process_coupon_message_meta' ), 10, 2 );
add_action( 'wp_ajax_get_wc_coupon_message', array( $this, 'get_wc_coupon_message' ) );
add_action( 'wp_ajax_nopriv_get_wc_coupon_message', array( $this, 'get_wc_coupon_message' ) );
add_action( 'woocommerce_before_cart_table', array( $this, 'wc_coupon_message_display' ) );
add_action( 'woocommerce_checkout_before_customer_details', array( $this, 'wc_coupon_message_display' ) );
add_action( 'woocommerce_email_after_order_table', array( $this, 'wc_add_coupons_message_in_email' ), null, 3 );
add_filter( 'wc_smart_coupons_export_headers', array( $this, 'export_headers' ) );
add_filter( 'smart_coupons_parser_postmeta_defaults', array( $this, 'postmeta_defaults' ) );
add_filter( 'sc_generate_coupon_meta', array( $this, 'generate_coupon_meta' ), 10, 2 );
add_filter( 'is_protected_meta', array( $this, 'make_action_meta_protected' ), 10, 3 );
add_action( 'wc_sc_new_coupon_generated', array( $this, 'copy_coupon_action_meta' ) );
}
/**
* Get single instance of this class
*
* @return this class Singleton object of this class
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Function to add additional fields for coupon
*
* @param integer $coupon_id The coupon id.
* @param WC_Coupon $coupon The coupon object.
* @since 1.0
*/
public function wc_coupon_message_options( $coupon_id = 0, $coupon = null ) {
global $post;
?>
<style type="text/css">
#wc_coupon_message_options #wc_coupon_message_ifr {
height: 100% !important;
}
#wp-wc_coupon_message-wrap {
display: inline-block;
width: 70%;
margin: -3em 0 0 12.5em;
}
.wp_editor_coupon_message {
width: 100%;
}
</style>
<?php
$editor_args = array(
'textarea_name' => 'wc_coupon_message',
'textarea_rows' => 10,
'editor_class' => 'wp_editor_coupon_message',
'media_buttons' => true,
'tinymce' => true,
);
echo '<div id="wc_coupon_message_options" class="options_group smart-coupons-field">';
?>
<p class="form-field wc_coupon_message_row">
<label for="wc_coupon_message"><?php echo esc_html__( 'Display message', 'woocommerce-smart-coupons' ); ?></label>
<?php $wc_coupon_message = $this->get_post_meta( $post->ID, 'wc_coupon_message', true ); ?>
<?php wp_editor( $wc_coupon_message, 'wc_coupon_message', $editor_args ); ?>
</p>
<?php
woocommerce_wp_checkbox(
array(
'id' => 'wc_email_message',
'label' => __( 'Email message?', 'woocommerce-smart-coupons' ),
'description' => __(
'Check this box to include above message in order confirmation email',
'woocommerce-smart-coupons'
),
)
);
echo '</div>';
}
/**
* Function to save coupon plus data in coupon's meta
*
* @since 1.0
*
* @param integer $post_id Coupon's id.
* @param WC_Coupon $coupon Current coupon object.
*/
public function wc_process_coupon_message_meta( $post_id = 0, $coupon = null ) {
if ( empty( $post_id ) ) {
return;
}
if ( is_null( $coupon ) || ! is_a( $coupon, 'WC_Coupon' ) ) {
$coupon = new WC_Coupon( $post_id );
}
if ( $this->is_callable( $coupon, 'update_meta_data' ) && $this->is_callable( $coupon, 'save' ) ) {
if ( isset( $_POST['wc_coupon_message'] ) ) { // phpcs:ignore
$coupon->update_meta_data( 'wc_coupon_message', wp_filter_post_kses( $_POST['wc_coupon_message'] ) ); // phpcs:ignore
}
if ( isset( $_POST['wc_email_message'] ) ) { // phpcs:ignore
$coupon->update_meta_data( 'wc_email_message', wc_clean( wp_unslash( $_POST['wc_email_message'] ) ) ); // phpcs:ignore
} else {
$coupon->update_meta_data( 'wc_email_message', 'no' );
}
$coupon->save();
} else {
if ( isset( $_POST['wc_coupon_message'] ) ) { // phpcs:ignore
update_post_meta( $post_id, 'wc_coupon_message', wp_filter_post_kses( $_POST['wc_coupon_message'] ) ); // phpcs:ignore
}
if ( isset( $_POST['wc_email_message'] ) ) { // phpcs:ignore
update_post_meta( $post_id, 'wc_email_message', wc_clean( wp_unslash( $_POST['wc_email_message'] ) ) ); // phpcs:ignore
} else {
update_post_meta( $post_id, 'wc_email_message', 'no' );
}
}
}
/**
* Function to print coupon message
*
* @param array $applied_coupons Applied coupons.
*/
public function print_coupon_message( $applied_coupons = array() ) {
if ( empty( $applied_coupons ) ) {
echo '<div class="no_wc_coupon_message"></div>';
return;
}
foreach ( $applied_coupons as $coupon_code ) {
$coupon = new WC_Coupon( $coupon_code );
if ( ! $coupon->is_valid() ) {
continue;
}
if ( $this->is_wc_gte_30() ) {
$coupon_id = ( ! empty( $coupon ) && is_callable( array( $coupon, 'get_id' ) ) ) ? $coupon->get_id() : 0;
} else {
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
}
$wc_coupon_message = ( $this->is_callable( $coupon, 'get_meta' ) ) ? $coupon->get_meta( 'wc_coupon_message' ) : get_post_meta( $coupon_id, 'wc_coupon_message', true );
if ( empty( $wc_coupon_message ) ) {
continue;
}
?>
<div id="wc_coupon_message_<?php echo esc_attr( $coupon_id ); ?>" class="wc_coupon_message_container">
<div class="wc_coupon_message_body">
<?php
$is_filter_content = apply_filters(
'wc_sc_is_filter_content_coupon_message',
true,
array(
'source' => $this,
'called_by' => current_filter(),
'coupon_object' => $coupon,
)
);
if ( true === $is_filter_content ) {
$wc_coupon_message = apply_filters( 'the_content', $wc_coupon_message );
}
?>
<?php echo wp_kses_post( $wc_coupon_message ); // phpcs:ignore ?>
</div>
</div>
<?php
}
}
/**
* Function to validate applied coupon's additional field which comes from this plugin
*
* @since 1.0
*/
public function wc_coupon_message_display() {
if ( ! is_object( WC() ) || ! is_object( WC()->cart ) || WC()->cart->is_empty() ) {
return;
}
$applied_coupons = WC()->cart->get_applied_coupons();
?>
<div class="wc_coupon_message_wrap" style="padding: 10px 0 10px;">
<?php $this->print_coupon_message( $applied_coupons ); ?>
</div>
<?php
if ( is_cart() || is_checkout() ) {
$js = "
if (typeof sc_coupon_message_ajax === 'undefined') {
var sc_coupon_message_ajax = null;
}
jQuery('body').on('applied_coupon removed_coupon updated_checkout', function(){
clearTimeout( sc_coupon_message_ajax );
sc_coupon_message_ajax = setTimeout(function(){
jQuery.ajax({
url: '" . admin_url( 'admin-ajax.php' ) . "',
type: 'POST',
dataType: 'html',
data: {
action: 'get_wc_coupon_message',
security: '" . wp_create_nonce( 'wc_coupon_message' ) . "'
},
success: function( response ) {
jQuery('.wc_coupon_message_wrap').html('');
if ( response != undefined && response != '' ) {
jQuery('.wc_coupon_message_wrap').html( response );
}
}
});
}, 200);
});
";
wc_enqueue_js( $js );
}
}
/**
* Function to get coupon messages via ajax
*/
public function get_wc_coupon_message() {
check_ajax_referer( 'wc_coupon_message', 'security' );
$applied_coupons = WC()->cart->get_applied_coupons();
$this->print_coupon_message( $applied_coupons );
die();
}
/**
* Function to add coupon's message in email
*
* @since 1.0
*
* @param WC_Order $order Order's object.
* @param boolean $bool Not used in this function.
* @param boolean $plain_text Not used in this function.
*/
public function wc_add_coupons_message_in_email( $order = null, $bool = false, $plain_text = false ) {
$used_coupons = $this->get_coupon_codes( $order );
if ( count( $used_coupons ) <= 0 ) {
return;
}
$show_coupon_message_title = false;
$coupon_messages = '';
foreach ( $used_coupons as $coupon_code ) {
$coupon = new WC_Coupon( $coupon_code );
if ( $this->is_wc_gte_30() ) {
$coupon_id = ( ! empty( $coupon ) && is_callable( array( $coupon, 'get_id' ) ) ) ? $coupon->get_id() : 0;
} else {
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
}
$is_callable_coupon_get_meta = $this->is_callable( $coupon, 'get_meta' );
if ( true === $is_callable_coupon_get_meta ) {
$coupon_message = $coupon->get_meta( 'wc_coupon_message' );
$include_in_email = $coupon->get_meta( 'wc_email_message' );
} else {
$coupon_message = get_post_meta( $coupon_id, 'wc_coupon_message', true );
$include_in_email = get_post_meta( $coupon_id, 'wc_email_message', true );
}
if ( ! empty( $coupon_message ) && 'yes' === $include_in_email ) {
$is_filter_content = apply_filters(
'wc_sc_is_filter_content_coupon_message',
true,
array(
'source' => $this,
'called_by' => current_filter(),
'coupon_object' => $coupon,
'order_object' => $order,
)
);
if ( true === $is_filter_content ) {
$coupon_messages .= apply_filters( 'the_content', $coupon_message );
} else {
$coupon_messages .= $coupon_message;
}
$show_coupon_message_title = true;
}
}
if ( $show_coupon_message_title ) {
?>
<h2><?php echo esc_html__( 'Coupon Message', 'woocommerce-smart-coupons' ); ?></h2>
<?php
echo '<div class="wc_coupon_message_wrap" style="padding: 10px 0 10px;">';
echo wp_kses_post( $coupon_messages ); // phpcs:ignore
echo '</div>';
}
}
/**
* Add meta in export headers
*
* @param array $headers Existing headers.
* @return array
*/
public function export_headers( $headers = array() ) {
$cm_headers = array(
'wc_coupon_message' => __( 'Coupon Message', 'woocommerce-smart-coupons' ),
'wc_email_message' => __( 'Is Email Coupon Message', 'woocommerce-smart-coupons' ),
);
return array_merge( $headers, $cm_headers );
}
/**
* Post meta defaults for CM's meta
*
* @param array $defaults Existing postmeta defaults.
* @return array
*/
public function postmeta_defaults( $defaults = array() ) {
$cm_defaults = array(
'wc_coupon_message' => '',
'wc_email_message' => '',
);
return array_merge( $defaults, $cm_defaults );
}
/**
* Add CM's meta with value in coupon meta
*
* @param array $data The row data.
* @param array $post The POST values.
* @return array Modified data
*/
public function generate_coupon_meta( $data = array(), $post = array() ) {
$data['wc_coupon_message'] = ( ! empty( $post['wc_coupon_message'] ) ) ? wp_kses_post( $post['wc_coupon_message'] ) : '';
$data['wc_email_message'] = ( ! empty( $post['wc_email_message'] ) ) ? wc_clean( wp_unslash( $post['wc_email_message'] ) ) : 'no';
return $data;
}
/**
* Make meta data of SC CM, protected
*
* @param bool $protected Is protected.
* @param string $meta_key The meta key.
* @param string $meta_type The meta type.
* @return bool $protected
*/
public function make_action_meta_protected( $protected, $meta_key, $meta_type ) {
$sc_meta = array(
'wc_coupon_message' => '',
'wc_email_message' => '',
);
if ( in_array( $meta_key, $sc_meta, true ) ) {
return true;
}
return $protected;
}
/**
* Function to copy CM meta in newly generated coupon
*
* @param array $args The arguments.
*/
public function copy_coupon_action_meta( $args = array() ) {
$new_coupon_id = ( ! empty( $args['new_coupon_id'] ) ) ? absint( $args['new_coupon_id'] ) : 0;
$coupon = ( ! empty( $args['ref_coupon'] ) ) ? $args['ref_coupon'] : false;
if ( empty( $new_coupon_id ) || empty( $coupon ) ) {
return;
}
$new_coupon = new WC_Coupon( $new_coupon_id );
if ( $this->is_callable( $new_coupon, 'get_meta' ) && $this->is_callable( $new_coupon, 'update_meta_data' ) && $this->is_callable( $new_coupon, 'save' ) ) {
$coupon_message = $coupon->get_meta( 'wc_coupon_message' );
$email_message = $coupon->get_meta( 'wc_email_message' );
$new_coupon->update_meta_data( 'wc_coupon_message', wp_filter_post_kses( $coupon_message ) );
$new_coupon->update_meta_data( 'wc_email_message', $email_message );
} else {
$old_coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
$coupon_message = get_post_meta( $old_coupon_id, 'wc_coupon_message', true );
$email_message = get_post_meta( $old_coupon_id, 'wc_email_message', true );
update_post_meta( $new_coupon_id, 'wc_coupon_message', wp_filter_post_kses( $coupon_message ) );
update_post_meta( $new_coupon_id, 'wc_email_message', $email_message );
}
}
}
}
WC_SC_Coupon_Message::get_instance();

View File

@@ -1,450 +0,0 @@
<?php
/**
* Coupon parser during import & export
*
* @author StoreApps
* @since 3.3.0
* @version 1.3.0
*
* @package woocommerce-smart-coupons/includes/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Coupon_Parser' ) ) {
/**
* Class to parse values for WC_Coupon for importing
*/
class WC_SC_Coupon_Parser {
/**
* The post type
*
* @var string $post_type
*/
public $post_type;
/**
* Reserved fields
*
* @var array $reserved_fields
*/
public $reserved_fields; // Fields we map/handle (not custom fields).
/**
* POst defaults
*
* @var array $post_defaults
*/
public $post_defaults; // Default post data.
/**
* Postmeta defaults
*
* @var array $postmeta_defaults
*/
public $postmeta_defaults; // default post meta.
/**
* Term defaults
*
* @var array $term_defaults
*/
public $term_defaults; // default term data.
/**
* Row number
*
* @var int $row
*/
public $row;
/**
* Constructor
*
* @param string $post_type The post type.
*/
public function __construct( $post_type = 'shop_coupon' ) {
$this->post_type = $post_type;
$this->reserved_fields = array(
'id',
'post_id',
'post_type',
'menu_order',
'postmeta',
'post_status',
'post_title',
'post_name',
'comment_status',
'post_date',
'post_date_gmt',
'post_content',
'post_excerpt',
'post_parent',
'post_password',
'discount_type',
'coupon_amount',
'free_shipping',
'expiry_date',
'minimum_amount',
'maximum_amount',
'individual_use',
'exclude_sale_items',
'product_ids',
'exclude_product_ids',
'product_categories',
'exclude_product_categories',
'customer_email',
'usage_limit',
'usage_limit_per_user',
'limit_usage_to_x_items',
'usage_count',
'_used_by',
);
$this->post_defaults = array(
'post_type' => $this->post_type,
'menu_order' => '',
'postmeta' => array(),
'post_status' => 'publish',
'post_title' => '',
'post_name' => '',
'comment_status' => 'closed',
'post_date' => '',
'post_date_gmt' => '',
'post_content' => '',
'post_excerpt' => '',
'post_parent' => 0,
'post_password' => '',
'post_author' => get_current_user_id(),
);
$this->postmeta_defaults = apply_filters(
'smart_coupons_parser_postmeta_defaults',
array(
'discount_type' => 'fixed_cart',
'coupon_amount' => '',
'free_shipping' => '',
'expiry_date' => '',
'sc_coupon_validity' => '',
'validity_suffix' => '',
'auto_generate_coupon' => '',
'coupon_title_prefix' => '',
'coupon_title_suffix' => '',
'is_pick_price_of_product' => '',
'minimum_amount' => '',
'maximum_amount' => '',
'individual_use' => '',
'exclude_sale_items' => '',
'product_ids' => '',
'exclude_product_ids' => '',
'product_categories' => '',
'exclude_product_categories' => '',
'customer_email' => '',
'sc_disable_email_restriction' => '',
'usage_limit' => '',
'usage_limit_per_user' => '',
'limit_usage_to_x_items' => '',
'sc_is_visible_storewide' => '',
'usage_count' => '',
'_used_by' => '',
'sc_restrict_to_new_user' => '',
'wc_sc_max_discount' => '',
)
);
$this->term_defaults = array(
'sc_coupon_category' => '',
);
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Format data passed from CSV
*
* @param array $data The data to format.
* @param string $enc encoding The encoding.
*/
public function format_data_from_csv( $data, $enc ) {
return ( 'UTF-8' === $enc ) ? $data : utf8_encode( $data );
}
/**
* Parse data
*
* @param string $file Imported file.
* @return array parsed data with headers
*/
public function parse_data( $file ) {
// Set locale.
$enc = $this->mb_detect_encoding( $file, 'UTF-8, ISO-8859-1', true );
if ( $enc ) {
setlocale( LC_ALL, 'en_US.' . $enc );
}
ini_set( 'auto_detect_line_endings', true ); // phpcs:ignore
$parsed_data = array();
$handle = fopen( $file, 'r' ); // phpcs:ignore
// Put all CSV data into an associative array.
if ( false !== $handle ) {
$header = fgetcsv( $handle, 0 );
while ( false !== ( $postmeta = fgetcsv( $handle, 0 ) ) ) { // phpcs:ignore
$row = array();
foreach ( $header as $key => $heading ) {
$s_heading = strtolower( $heading );
$row[ $s_heading ] = ( isset( $postmeta[ $key ] ) ) ? $this->format_data_from_csv( stripslashes( $postmeta[ $key ] ), $enc ) : '';
$raw_headers[ $s_heading ] = $heading;
}
$parsed_data[] = $row;
unset( $postmeta, $row );
}
fclose( $handle ); // phpcs:ignore
}
return array( $parsed_data, $raw_headers );
}
/**
* Parse data one row at a time
*
* @param boolean $file_handler CSV file handler.
* @param array $header CSV header meta column name.
* @param integer $file_position file pointer posistion to read from.
* @param string $encoding Character encoding.
* @return array $result parsed data with current file pointer position
*/
public function parse_data_by_row( $file_handler = false, $header = array(), $file_position = 0, $encoding = '' ) {
$parsed_csv_data = array();
$reading_completed = false;
if ( false !== $file_handler ) {
if ( $file_position > 0 ) {
fseek( $file_handler, (int) $file_position );
}
if ( false !== ( $postmeta = fgetcsv( $file_handler, 0 ) ) ) { // phpcs:ignore
$row = array();
foreach ( $header as $key => $heading ) {
$s_heading = strtolower( $heading );
// Put all CSV data into an associative array by row.
$row[ $s_heading ] = ( isset( $postmeta[ $key ] ) ) ? $this->format_data_from_csv( stripslashes( $postmeta[ $key ] ), $encoding ) : '';
}
$parsed_csv_data = $row;
unset( $postmeta, $row );
} else {
$reading_completed = true;
}
$file_position = ftell( $file_handler );
}
$result = array(
'parsed_csv_data' => $parsed_csv_data,
'file_position' => $file_position,
'reading_completed' => $reading_completed,
);
return $result;
}
/**
* Parse coupon
*
* @param array $item The imported item.
* @return array $coupon
*/
public function parse_coupon( $item ) {
global $wc_csv_coupon_import, $wpdb;
$this->row++;
$postmeta = array();
$term_data = array();
$coupon = array();
$post_id = ( ! empty( $item['id'] ) ) ? absint( $item['id'] ) : 0;
$post_id = ( ! empty( $item['post_id'] ) ) ? absint( $item['post_id'] ) : $post_id;
$product['post_id'] = $post_id;
// Get post fields.
foreach ( $this->post_defaults as $column => $default ) {
if ( isset( $item[ $column ] ) ) {
$product[ $column ] = $item[ $column ];
}
}
// Get custom fields.
foreach ( $this->postmeta_defaults as $column => $default ) {
if ( isset( $item[ $column ] ) ) {
$postmeta[ $column ] = (string) $item[ $column ];
} elseif ( isset( $item[ '_' . $column ] ) ) {
$postmeta[ $column ] = (string) $item[ '_' . $column ];
}
}
// Get term fields.
foreach ( $this->term_defaults as $column => $default ) {
if ( isset( $item[ $column ] ) ) {
$term_data[ $column ] = $item[ $column ];
}
}
// Merge post meta with defaults.
$coupon = wp_parse_args( $product, $this->post_defaults );
$postmeta = wp_parse_args( $postmeta, $this->postmeta_defaults );
$term_data = wp_parse_args( $term_data, $this->term_defaults );
if ( ! empty( $postmeta['discount_type'] ) ) {
$discount_type = $postmeta['discount_type'];
} else {
if ( $this->is_wc_gte_30() ) {
$discount_type = 'Percentage discount';
} else {
$discount_type = 'Cart % Discount';
}
}
$all_discount_types = wc_get_coupon_types();
// discount types.
if ( ! empty( $discount_type ) ) {
if ( in_array( $discount_type, $all_discount_types, true ) ) {
$postmeta['discount_type'] = array_search( $discount_type, $all_discount_types, true );
}
if ( empty( $postmeta['discount_type'] ) ) {
$postmeta['discount_type'] = 'percent';
}
}
// product_ids.
if ( isset( $postmeta['product_ids'] ) && ! is_array( $postmeta['product_ids'] ) ) {
$ids = array_filter( array_map( 'trim', explode( '|', $postmeta['product_ids'] ) ) );
$ids = implode( ',', $ids );
$postmeta['product_ids'] = $ids;
}
// exclude_product_ids.
if ( isset( $postmeta['exclude_product_ids'] ) && ! is_array( $postmeta['exclude_product_ids'] ) ) {
$ids = array_filter( array_map( 'trim', explode( '|', $postmeta['exclude_product_ids'] ) ) );
$ids = implode( ',', $ids );
$postmeta['exclude_product_ids'] = $ids;
}
// product_categories.
if ( isset( $postmeta['product_categories'] ) && ! is_array( $postmeta['product_categories'] ) ) {
$ids = array_filter( array_map( 'trim', explode( '|', $postmeta['product_categories'] ) ) );
$postmeta['product_categories'] = $ids;
}
// exclude_product_categories.
if ( isset( $postmeta['exclude_product_categories'] ) && ! is_array( $postmeta['exclude_product_categories'] ) ) {
$ids = array_filter( array_map( 'trim', explode( '|', $postmeta['exclude_product_categories'] ) ) );
$postmeta['exclude_product_categories'] = $ids;
}
// customer_email.
if ( isset( $postmeta['customer_email'] ) && ! is_array( $postmeta['customer_email'] ) ) {
$email_ids = array_filter( array_map( 'trim', explode( ',', $postmeta['customer_email'] ) ) );
$postmeta['customer_email'] = $email_ids;
}
// expiry date.
if ( isset( $postmeta['expiry_date'] ) ) {
$timestamp_expiry_date = '';
if ( ! empty( $postmeta['expiry_date'] ) ) {
$timestamp_expiry_date = ( function_exists( 'wc_string_to_timestamp' ) ) ? wc_string_to_timestamp( $postmeta['expiry_date'] ) : 0;
}
if ( ! empty( $postmeta['expiry_date'] ) && empty( $timestamp_expiry_date ) ) {
/* translators: 1. Coupon code 2. Expiry date */
$this->log( 'error', sprintf( __( 'Incorrect format for expiry date of coupon "%1$s". Entered date is %2$s. Expected date format: YYYY-MM-DD', 'woocommerce-smart-coupons' ), $coupon['post_title'], $postmeta['expiry_date'] ) );
}
$postmeta['expiry_date'] = ( ! empty( $timestamp_expiry_date ) ) ? gmdate( 'Y-m-d', $timestamp_expiry_date ) : '';
}
// usage count.
if ( isset( $postmeta['usage_count'] ) ) {
$postmeta['usage_count'] = ( ! empty( $postmeta['usage_count'] ) ) ? $postmeta['usage_count'] : 0;
}
// used_by.
if ( isset( $postmeta['_used_by'] ) ) {
$postmeta['_used_by'] = ( ! empty( $postmeta['_used_by'] ) ) ? $postmeta['_used_by'] : '';
}
// Put set core product postmeta into product array.
foreach ( $postmeta as $key => $value ) {
$coupon['postmeta'][] = array(
'key' => esc_attr( $key ),
'value' => $value,
);
}
// term data.
foreach ( $term_data as $key => $value ) {
$coupon['term_data'][] = array(
'key' => esc_attr( $key ),
'value' => $value,
);
}
unset( $item, $postmeta );
return $coupon;
}
}
}

View File

@@ -1,713 +0,0 @@
<?php
/**
* Processing of smart coupons refund
*
* @author StoreApps
* @since 5.2.0
* @version 1.6.0
*
* @package woocommerce-smart-coupons/includes/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Coupon_Refund_Process' ) ) {
/**
* Class for handling processes of smart coupons refund
*/
class WC_SC_Coupon_Refund_Process {
/**
* Variable to hold instance of WC_SC_Coupon_Refund_Process
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
private function __construct() {
add_action( 'woocommerce_admin_order_items_after_shipping', array( $this, 'render_used_store_credits_details' ) );
add_action( 'woocommerce_admin_order_items_after_refunds', array( $this, 'render_refunded_store_credits_details' ) );
add_filter( 'woocommerce_order_fully_refunded_status', array( $this, 'update_fully_refunded_status' ), 10, 3 );
add_action( 'wp_ajax_wc_sc_refund_store_credit', array( $this, 'wc_sc_refund_store_credit' ) );
add_action( 'wp_ajax_wc_sc_revoke_refunded_store_credit', array( $this, 'wc_sc_revoke_refunded_store_credit' ) );
}
/**
* Get single instance of WC_SC_Coupon_Process
*
* @return WC_SC_Coupon_Process Singleton object of WC_SC_Coupon_Process
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Render smart coupon UI in order page
*
* @param int $order_id order id.
* @return void html of smart coupon UI
*/
public function render_used_store_credits_details( $order_id ) {
?>
<style type="text/css">
#order_sc_store_credit_line_items tbody tr:first-child td {
border-top: 8px solid #f8f8f8;
}
</style>
<script type="text/javascript">
jQuery(function ($) {
/**
* Auto fill and remove - refund store credit coupon amount
*/
$(document).on('change', '.sc_auto_fill_refund', function () {
if ($(this).prop("checked") === true) {
$('.sc_store_credit').each(function (index, element) {
let used_sc = $(element).data("order_used_sc");
let order_used_sc_tax = $(element).data("order_used_sc_tax");
$(this).find('.refund_used_sc').val(used_sc);
$(this).find('.refund_used_sc_tax').val(order_used_sc_tax);
});
} else {
$('.refund_used_sc').val(0);
$('.refund_used_sc_tax').val(0);
}
});
/**
* Process store credit refund
*/
$('#woocommerce-order-items').on('click', 'button.do-api-refund, button.do-manual-refund', function () {
var sc_line_item = {};
$('.sc_store_credit').each(function (index, element) {
let sc_line_item_data = {};
let used_coupon_id = $(this).data("used_sc_id");
let order_id = $(this).data("used_sc_order_id");
let sc_refund_amount = $(this).find('.refund_used_sc').val();
let sc_refund_tax_amount = $(this).find('.refund_used_sc_tax').val();
let order_used_total_amount = $(this).find('.order_used_total_sc_amount').val();
let order_sc_item_id = $(this).find('.order_sc_item_id').val();
if (order_sc_item_id !== 0 || order_sc_item_id !== null || order_sc_item_id !== undefined) {
sc_line_item_data['coupon_id'] = used_coupon_id;
sc_line_item_data['refund_amount'] = sc_refund_amount;
sc_line_item_data['order_used_total_amount'] = order_used_total_amount;
sc_line_item_data['order_sc_item_id'] = order_sc_item_id;
sc_line_item_data['sc_order_id'] = order_id;
sc_line_item_data['order_sc_refund_tax_amount'] = sc_refund_tax_amount;
sc_line_item [order_sc_item_id] = sc_line_item_data;
}
});
let sc_refund_nonce = $('#sc_refund_nonce').val();
var data = {
action: 'wc_sc_refund_store_credit',
line_items: JSON.stringify(sc_line_item, null, ''),
security: sc_refund_nonce
};
$.ajax({
url: '<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>',
type: 'POST',
data: data
})
})
});
</script>
<tbody id="order_sc_store_credit_line_items">
<?php
$order = ( function_exists( 'wc_get_order' ) ) ? wc_get_order( $order_id ) : null;
$tax_data = ( function_exists( 'wc_tax_enabled' ) && wc_tax_enabled() && is_object( $order ) && is_callable( array( $order, 'get_taxes' ) ) ) ? $order->get_taxes() : array();
$order_items = ( is_object( $order ) && is_callable( array( $order, 'get_items' ) ) ) ? $order->get_items( 'coupon' ) : array();
$i = 1;
if ( ! empty( $order_items ) ) {
foreach ( $order_items as $item_id => $item ) {
$order_discount_amount = $sc_refunded_discount = $sc_refunded_discount_tax = $order_discount_tax_amount = 0; // phpcs:ignore
$coupon_post_obj = ( function_exists( 'wpcom_vip_get_page_by_title' ) ) ? wpcom_vip_get_page_by_title( $item->get_name(), OBJECT, 'shop_coupon' ) : get_page_by_title( $item->get_name(), OBJECT, 'shop_coupon' );// phpcs:ignore
$coupon_id = isset( $coupon_post_obj->ID ) ? $coupon_post_obj->ID : '';
$coupon_title = isset( $coupon_post_obj->post_title ) ? $coupon_post_obj->post_title : '';
$coupon = new WC_Coupon( $coupon_id );
if ( is_a( $coupon, 'WC_Coupon' ) ) {
if ( $coupon->is_type( 'smart_coupon' ) ) {
if ( 1 === $i ) {
?>
<tr class="sc_store_credit_head refund">
<td class="">
<div class="refund" style="display: none; padding-top: 15px;">
<svg xmlns="http://www.w3.org/2000/svg" style="color: #b5b5b5;" fill="none" viewBox="0 0 40 40" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1" d="M15 5v2m0 4v2m0 4v2M5 5a2 2 0 00-2 2v3a2 2 0 110 4v3a2 2 0 002 2h14a2 2 0 002-2v-3a2 2 0 110-4V7a2 2 0 00-2-2H5z">
</path>
</svg>
</div>
</td>
<td>
<div class="refund" style="display: none; padding-top: 15px;">
<div class="view"><?php echo esc_html__( 'Refund to Store Credit', 'woocommerce-smart-coupons' ); ?></div>
</div>
</td>
<td>
</td>
<td>
<input type="hidden" name="sc_refund_nonce" id="sc_refund_nonce" value="<?php echo esc_attr( wp_create_nonce( 'sc_refund_nonce' ) ); ?>">
</td>
<td colspan="2">
<div class="refund" style="display: none; padding-top: 15px;">
<input type="checkbox" name="sc_auto_fill_refund" class="sc_auto_fill_refund" id="sc_auto_fill_refund">
<label for="sc_auto_fill_refund"><?php echo esc_html_e( 'Auto-fill refund amount', 'woocommerce-smart-coupons' ); ?></label>
</div>
</td>
<?php
if ( ! empty( $tax_data ) ) {
?>
<td>
</td>
<?php
}
?>
</tr>
<?php
}
$i++;
if ( is_callable( array( $this, 'get_order_item_meta' ) ) ) {
$order_discount_amount = $this->get_order_item_meta( $item_id, 'discount_amount', true );
$sc_refunded_discount = $this->get_order_item_meta( $item_id, 'sc_refunded_discount', true );
$sc_refunded_discount_tax = $this->get_order_item_meta( $item_id, 'sc_refunded_discount_tax', true );
$order_discount_tax_amount = $this->get_order_item_meta( $item_id, 'discount_amount_tax', true );
}
?>
<tr class="sc_store_credit" data-order_used_sc="<?php echo esc_attr( $order_discount_amount ); ?>"
data-used_sc_id="<?php echo esc_attr( $coupon_id ); ?>"
data-used_sc_order_id="<?php echo esc_attr( $order_id ); ?>"
data-order_used_sc_tax="<?php echo esc_attr( $order_discount_tax_amount ); ?>">
<td class="thumb">
<div>
<svg xmlns="http://www.w3.org/2000/svg" style="color: #b5b5b5;" fill="none" viewBox="0 0 40 40" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1" d="M15 5v2m0 4v2m0 4v2M5 5a2 2 0 00-2 2v3a2 2 0 110 4v3a2 2 0 002 2h14a2 2 0 002-2v-3a2 2 0 110-4V7a2 2 0 00-2-2H5z">
</path>
</svg>
</div>
</td>
<td class="name">
<div class="view">
<?php
echo esc_html( $coupon_title ); // phpcs:ignore
?>
</div>
</td>
<td class="item_cost" width="1%">&nbsp;</td>
<td class="quantity" width="1%">&nbsp;</td>
<td class="line_cost" width="1%">
<div class="view">
<?php
echo wp_kses_post(
wc_price( $order_discount_amount )
);
if ( ! empty( $sc_refunded_discount ) ) {
?>
<small class="refunded"><?php echo esc_html( $sc_refunded_discount ); ?></small>
<?php
}
?>
</div>
<div class="edit" style="display: none;">
<input type="text" name="sc_store_credit_cost[<?php echo esc_attr( $coupon_id ); ?>]" placeholder="0" value="<?php echo esc_attr( $order_discount_amount ); ?>" class="sc_line_total wc_input_price">
</div>
<div class="refund" style="display: none;">
<input type="text" name="refund_sc_store_credit_line_total[<?php echo esc_attr( $coupon_id ); ?>]" placeholder="0" class="refund_used_sc wc_input_price">
<input type="hidden" name="order_used_total_sc_amount[<?php echo esc_attr( $coupon_id ); ?>]" value="<?php echo esc_attr( $order_discount_amount ); ?>" class="order_used_total_sc_amount">
<input type="hidden" name="order_used_item_id[<?php echo esc_attr( $item_id ); ?>]" value="<?php echo esc_attr( $item_id ); ?>" class="order_sc_item_id">
</div>
</td>
<?php
if ( ! empty( $tax_data ) ) {
?>
<td class="line_tax" width="1%">
<div class="view">
<?php
echo wp_kses_post(
wc_price( $order_discount_tax_amount )
);
if ( ! empty( $sc_refunded_discount_tax ) ) {
?>
<small class="refunded"><?php echo esc_html( $sc_refunded_discount_tax ); ?></small>
<?php
}
?>
</div>
<div class="edit" style="display: none;">
<input type="text" name="sc_store_credit_cost[<?php echo esc_attr( $coupon_id ); ?>]" placeholder="0" value="<?php echo esc_attr( $order_discount_tax_amount ); ?>" class="sc_line_total wc_input_price">
</div>
<div class="refund" style="display: none;">
<input type="text" name="refund_sc_store_credit_line_total[<?php echo esc_attr( $coupon_id ); ?>]" placeholder="0" class="refund_used_sc_tax wc_input_price">
</div>
</td>
<?php } ?>
<td class="wc-order-edit-line-item">
</td>
</tr>
<?php
}
}
}
}
?>
</tbody>
<?php
}
/**
* Refund store credit coupon
*
* @return void add refund store credit to the coupon
*/
public function wc_sc_refund_store_credit() {
global $woocommerce_smart_coupon;
$nonce_token = ! empty( $_POST['security'] ) ? $_POST['security'] : ''; // phpcs:ignore
if ( wp_verify_nonce( wp_unslash( $nonce_token ), 'sc_refund_nonce' ) ) {
$response = array();
$line_items = isset( $_POST['line_items'] ) ? json_decode( sanitize_text_field( wp_unslash( $_POST['line_items'] ) ), true ) : array();
if ( ! empty( $line_items ) ) {
$order = null;
foreach ( $line_items as $line_item ) {
$total_refunded = $total_refunded_tax = $order_discount_amount = $refunded_amount = $refunded_tax_amount = $order_discount_tax_amount = 0; // phpcs:ignore
$smart_coupon_id = ( ! empty( $line_item['coupon_id'] ) ) ? $line_item['coupon_id'] : 0;
$refund_amount = ( ! empty( $line_item['refund_amount'] ) ) ? $line_item['refund_amount'] : 0;
$item_id = ( ! empty( $line_item['order_sc_item_id'] ) ) ? $line_item['order_sc_item_id'] : 0;
$order_sc_refund_tax_amount = ( ! empty( $line_item['order_sc_refund_tax_amount'] ) ) ? $line_item['order_sc_refund_tax_amount'] : 0;
$order_id = ( ! empty( $line_item['sc_order_id'] ) ) ? $line_item['sc_order_id'] : 0;
$order = ( ! is_a( $order, 'WC_Order' ) ) ? wc_get_order( $order_id ) : $order;
if ( is_callable( array( $this, 'get_order_item_meta' ) ) ) {
$order_discount_amount = $this->get_order_item_meta( $item_id, 'discount_amount', true );
$refunded_amount = $this->get_order_item_meta( $item_id, 'sc_refunded_discount', true );
$refunded_tax_amount = $this->get_order_item_meta( $item_id, 'sc_refunded_discount_tax', true );
$order_discount_tax_amount = $this->get_order_item_meta( $item_id, 'discount_amount_tax', true );
}
if ( floatval( $order_discount_amount ) === floatval( $refunded_amount ) && floatval( $order_discount_tax_amount ) === floatval( $refunded_tax_amount ) ) {
continue;
}
if ( $refunded_amount ) {
$total_refunded = $refund_amount + $refunded_amount;
}
if ( $refunded_tax_amount ) {
$total_refunded_tax = $order_sc_refund_tax_amount + $refunded_tax_amount;
}
if ( $order_discount_amount >= $refund_amount && $order_discount_amount >= $total_refunded && $order_discount_tax_amount >= $order_sc_refund_tax_amount && $order_discount_tax_amount >= $total_refunded_tax && ! empty( $smart_coupon_id ) ) {
$coupon = new WC_Coupon( $smart_coupon_id );
if ( is_a( $coupon, 'WC_Coupon' ) ) {
if ( $this->is_wc_gte_30() ) {
$discount_type = ( is_callable( array( $coupon, 'get_discount_type' ) ) ) ? $coupon->get_discount_type() : '';
} else {
$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
}
$coupon_amount = $this->get_amount( $coupon, true, $order );
if ( 'smart_coupon' === $discount_type && is_numeric( $refund_amount ) && is_numeric( $order_sc_refund_tax_amount ) ) {
$amount = $coupon_amount + $refund_amount + $order_sc_refund_tax_amount;
$this->update_post_meta( $smart_coupon_id, 'coupon_amount', $amount, true, $order );
$user = ( function_exists( 'get_current_user_id' ) ) ? get_current_user_id() : 0;
$local_time = ( function_exists( 'current_datetime' ) ) ? current_datetime() : '';
$get_timestamp = ( is_object( $local_time ) && is_callable( array( $local_time, 'getTimestamp' ) ) ) ? $local_time->getTimestamp() : '';
$get_offset = ( is_object( $local_time ) && is_callable( array( $local_time, 'getOffset' ) ) ) ? $local_time->getOffset() : '';
$current_time_stamp = $get_timestamp + $get_offset;
if ( 0 < $total_refunded ) {
$refund_amount = $total_refunded;
}
if ( 0 < $total_refunded_tax ) {
$order_sc_refund_tax_amount = $total_refunded_tax;
}
if ( is_callable( array( $this, 'update_order_item_meta' ) ) ) {
$this->update_order_item_meta( $item_id, 'sc_refunded_discount_tax', $order_sc_refund_tax_amount );
$this->update_order_item_meta( $item_id, 'sc_refunded_discount', $refund_amount );
$this->update_order_item_meta( $item_id, 'sc_refunded_user_id', $user );
$this->update_order_item_meta( $item_id, 'sc_refunded_timestamp', $current_time_stamp );
$this->update_order_item_meta( $item_id, 'sc_refunded_coupon_id', $smart_coupon_id );
$message = __( 'Successfully updated store credit refund details.', 'woocommerce-smart-coupons' );
} else {
$message = __( 'Failed to update store credit refund details.', 'woocommerce-smart-coupons' );
$woocommerce_smart_coupon->log( 'notice', $message . ' ' . __FILE__ . ' ' . __LINE__ );
}
$response['message'] = $message;
}
}
}
}
}
wp_send_json_success( $response );
} else {
$response['message'] = __( 'Nonce verification failed for action "wc_sc_refund_store_credit".', 'woocommerce-smart-coupons' );
wp_send_json_error( $response );
}
}
/**
* Render refund store credit UI in order page
*
* @param int $order_id order id.
* @return void revoke refund html
*/
public function render_refunded_store_credits_details( $order_id ) {
?>
<style type="text/css">
#woocommerce-order-items .wc-order-edit-line-item-actions .delete_wc_sc_refund::before {
font-family: Dashicons;
font-weight: 400;
text-transform: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
text-indent: 0px;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
text-align: center;
content: "";
position: relative;
font-variant: normal;
margin: 0px;
color: #a00;
}
</style>
<script type="text/javascript">
jQuery(function ($) {
/**
* Process store credit revoke refund
*/
var wc_sc_meta_boxes_order_items = {
block: function () {
$('#woocommerce-order-items').block({
message: null,
overlayCSS: {
background: '#fff',
opacity: 0.6
}
});
},
};
$('#woocommerce-order-items').on('click', '.delete_wc_sc_refund', function () {
var confirm_message = '<?php esc_html_e( 'Are you sure you wish to delete this refund? This action cannot be undone.', 'woocommerce-smart-coupons' ); ?>';
if (confirm(confirm_message)) {
let sc_line_item_data = {};
let wc_sc_refunded_id = $(this).parents('.wc_sc_refunded').data("wc_sc_refunded_id");
let order_id = $(this).parents('.wc_sc_refunded').data("wc_sc_order_id");
let wc_sc_id = $(this).parents('.wc_sc_refunded').data("wc_sc_coupon_id");
let wc_sc_refunded_amount = $(this).parents('.wc_sc_refunded').data("wc_sc_refunded_amount");
let wc_sc_refunded_amount_tax = $(this).parents('.wc_sc_refunded').data("wc_sc_refunded_amount_tax");
if (wc_sc_refunded_id !== 0 || wc_sc_refunded_id !== null || wc_sc_refunded_id !== undefined) {
sc_line_item_data['coupon_id'] = wc_sc_id;
sc_line_item_data['refund_amount'] = wc_sc_refunded_amount;
sc_line_item_data['refund_amount_tax'] = wc_sc_refunded_amount_tax;
sc_line_item_data['wc_sc_refunded_id'] = wc_sc_refunded_id;
sc_line_item_data['wc_sc_order_id'] = order_id;
}
let sc_revoke_refund_nonce = $('#sc_revoke_refund_nonce').val();
var data = {
action: 'wc_sc_revoke_refunded_store_credit',
line_items: JSON.stringify(sc_line_item_data, null, ''),
security: sc_revoke_refund_nonce
};
wc_sc_meta_boxes_order_items.block();
$.ajax({
url: '<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>',
type: 'POST',
data: data,
success: function (response) {
if (true === response.success) {
// Redirect to same page for show the refunded status
window.location.reload();
} else {
console.log(response.data.error);
}
}
});
}
})
});
</script>
<?php
$order = wc_get_order( $order_id );
$order_items = ( is_object( $order ) && is_callable( array( $order, 'get_items' ) ) ) ? $order->get_items( 'coupon' ) : array();
if ( ! empty( $order_items ) ) {
foreach ( $order_items as $item_id => $item ) {
$sc_refunded_discount = $sc_refunded_discount_tax = $sc_refunded_user = $sc_refunded_timestamp = 0; // phpcs:ignore
$coupon_post_obj = ( function_exists( 'wpcom_vip_get_page_by_title' ) ) ? wpcom_vip_get_page_by_title( $item->get_name(), OBJECT, 'shop_coupon' ) : get_page_by_title( $item->get_name(), OBJECT, 'shop_coupon' );// phpcs:ignore
$coupon_id = isset( $coupon_post_obj->ID ) ? $coupon_post_obj->ID : '';
$coupon_title = isset( $coupon_post_obj->post_title ) ? $coupon_post_obj->post_title : '';
$coupon = new WC_Coupon( $coupon_id );
if ( is_callable( array( $this, 'get_order_item_meta' ) ) ) {
$sc_refunded_discount = $this->get_order_item_meta( $item_id, 'sc_refunded_discount', true );
$sc_refunded_discount_tax = $this->get_order_item_meta( $item_id, 'sc_refunded_discount_tax', true );
$sc_refunded_user = $this->get_order_item_meta( $item_id, 'sc_refunded_user_id', true );
$sc_refunded_timestamp = $this->get_order_item_meta( $item_id, 'sc_refunded_timestamp', true );
}
if ( empty( $sc_refunded_timestamp ) ) {
$sc_refunded_timestamp = time() + $this->wc_timezone_offset();
}
$sc_refunded_discount = empty( $sc_refunded_discount ) ? 0 : $sc_refunded_discount;
$sc_refunded_discount_tax = empty( $sc_refunded_discount_tax ) ? 0 : $sc_refunded_discount_tax;
if ( is_a( $coupon, 'WC_Coupon' ) ) {
if ( $coupon->is_type( 'smart_coupon' ) && ( ! empty( $sc_refunded_discount ) || ! empty( $sc_refunded_discount_tax ) ) ) {
$who_refunded = new WP_User( $sc_refunded_user );
$refunder_id = isset( $who_refunded->ID ) ? $who_refunded->ID : 0;
$refunder_name = isset( $who_refunded->display_name ) ? $who_refunded->display_name : '';
?>
<input type="hidden" name="sc_revoke_refund_nonce" id="sc_revoke_refund_nonce" value="<?php echo esc_attr( wp_create_nonce( 'sc_revoke_refund_nonce' ) ); ?>">
<tr class="refund wc_sc_refunded" data-wc_sc_refunded_id="<?php echo esc_attr( $item_id ); ?>"
data-wc_sc_coupon_id="<?php echo esc_attr( $coupon_id ); ?>"
data-wc_sc_order_id="<?php echo esc_attr( $order_id ); ?>"
data-wc_sc_refunded_amount_tax="<?php echo esc_attr( $sc_refunded_discount_tax ); ?>"
data-wc_sc_refunded_amount="<?php echo esc_attr( $sc_refunded_discount ); ?>">
<td class="thumb">
<div></div>
</td>
<td class="name">
<?php
if ( $who_refunded->exists() ) {
printf(
/* translators: 1: refund id 2: refund date 3: username */
esc_html__( 'Refund %1$s - %2$s by %3$s', 'woocommerce-smart-coupons' ),
esc_html( 'Store Credit Coupon - ' . $coupon_title ),
esc_html( $this->format_date( $sc_refunded_timestamp ) ),
sprintf(
'<abbr class="refund_by" title="%1$s">%2$s</abbr>',
/* translators: 1: ID who refunded */
sprintf( esc_attr__( 'ID: %d', 'woocommerce-smart-coupons' ), absint( $refunder_id ) ),
esc_html( $refunder_name )
)
);
} else {
printf(
/* translators: 1: refund id 2: refund date */
esc_html__( 'Refund %1$s - %2$s', 'woocommerce-smart-coupons' ),
esc_html( 'Store Credit Coupon -' . $coupon_title ),
esc_html( $this->format_date( $sc_refunded_timestamp ) )
);
}
?>
</td>
<td class="item_cost" width="1%">&nbsp;</td>
<td class="quantity" width="1%">&nbsp;</td>
<td class="line_cost" width="1%">
<div class="view">
<?php
$total = $sc_refunded_discount + $sc_refunded_discount_tax;
echo wp_kses_post(
wc_price( '-' . $total )
);
?>
</div>
</td>
<?php if ( wc_tax_enabled() ) : ?>
<td class="line_tax" width="1%"></td>
<?php endif; ?>
<td class="wc-order-edit-line-item">
<div class="wc-order-edit-line-item-actions">
<a class="delete_wc_sc_refund" href="#" style=""></a>
</div>
</td>
</tr>
<?php
}
}
}
}
}
/**
* Formatting the date
*
* @param timestamp $date timestamp for date.
* @param string $format date format.
* @return string date format string
*/
protected function format_date( $date, $format = '' ) {
if ( ! is_int( $date ) ) {
$date = intval( $date );
}
if ( empty( $format ) ) {
$format = get_option( 'date_format', 'F j, Y' ) . ' ' . get_option( 'time_format', 'g:i a' );
}
return gmdate( $format, $date );
}
/**
* Revoke refund store credit
*
* @return void remove refund store credit amount to the coupon
*/
public function wc_sc_revoke_refunded_store_credit() {
$nonce_token = ! empty( $_POST['security'] ) ? $_POST['security'] : ''; // phpcs:ignore
if ( wp_verify_nonce( wp_unslash( $nonce_token ), 'sc_revoke_refund_nonce' ) ) {
$line_item = ! empty( $_POST['line_items'] ) ? json_decode( sanitize_text_field( wp_unslash( $_POST['line_items'] ) ), true ) : array();
if ( ! empty( $line_item ) ) {
$smart_coupon_id = ! empty( $line_item['coupon_id'] ) ? $line_item['coupon_id'] : 0;
$refunded_amount = ! empty( $line_item['refund_amount'] ) ? $line_item['refund_amount'] : 0;
$refunded_amount_tax = ! empty( $line_item['refund_amount_tax'] ) ? $line_item['refund_amount_tax'] : 0;
$wc_sc_refunded_id = ! empty( $line_item['wc_sc_refunded_id'] ) ? $line_item['wc_sc_refunded_id'] : 0;
$order_id = ! empty( $line_item['wc_sc_order_id'] ) ? $line_item['wc_sc_order_id'] : 0;
$order = ( ! is_a( $order, 'WC_Order' ) ) ? wc_get_order( $order_id ) : $order;
$order_discount_amount = $this->get_order_item_meta( $wc_sc_refunded_id, 'discount_amount', true );
$order_discount_tax_amount = $this->get_order_item_meta( $wc_sc_refunded_id, 'discount_amount_tax', true );
if ( $order_discount_amount >= $refunded_amount && $order_discount_tax_amount >= $refunded_amount_tax && ! empty( $smart_coupon_id ) ) {
$coupon = new WC_Coupon( $smart_coupon_id );
if ( is_a( $coupon, 'WC_Coupon' ) ) {
if ( $this->is_wc_gte_30() ) {
$discount_type = ( is_callable( array( $coupon, 'get_discount_type' ) ) ) ? $coupon->get_discount_type() : '';
} else {
$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
}
$coupon_amount = $this->get_amount( $coupon, true, $order );
if ( 'smart_coupon' === $discount_type ) {
if ( ! is_numeric( $refunded_amount ) ) {
$refunded_amount = 0;
}
if ( ! is_numeric( $refunded_amount_tax ) ) {
$refunded_amount_tax = 0;
}
$refund_amount = $refunded_amount + $refunded_amount_tax;
$amount = $coupon_amount - $refund_amount;
$this->update_post_meta( $smart_coupon_id, 'coupon_amount', $amount, true, $order );
$user = ( function_exists( 'get_current_user_id' ) ) ? get_current_user_id() : 0;
$local_time = ( function_exists( 'current_datetime' ) ) ? current_datetime() : '';
$get_timestamp = ( is_object( $local_time ) && is_callable( array( $local_time, 'getTimestamp' ) ) ) ? $local_time->getTimestamp() : 0;
$get_offset = ( is_object( $local_time ) && is_callable( array( $local_time, 'getOffset' ) ) ) ? $local_time->getOffset() : 0;
$current_time_stamp = $get_timestamp + $get_offset;
if ( is_callable( array( $this, 'update_order_item_meta' ) ) ) {
$this->update_order_item_meta( $wc_sc_refunded_id, 'sc_revoke_refunded_discount', $refunded_amount, true );
$this->update_order_item_meta( $wc_sc_refunded_id, 'sc_revoke_refunded_discount_tax', $refunded_amount_tax, true );
$this->update_order_item_meta( $wc_sc_refunded_id, 'sc_revoke_refunded_user_id', $user );
$this->update_order_item_meta( $wc_sc_refunded_id, 'sc_revoke_refunded_timestamp', $current_time_stamp );
$this->update_order_item_meta( $wc_sc_refunded_id, 'sc_revoke_refunded_coupon_id', $smart_coupon_id );
$this->update_order_item_meta( $wc_sc_refunded_id, 'sc_refunded_discount', 0 );
$this->update_order_item_meta( $wc_sc_refunded_id, 'sc_refunded_discount_tax', 0 );
}
}
}
}
}
wp_send_json_success();
} else {
wp_send_json_error();
}
}
/**
* Change order status when fully refunded.
*
* @param string $status order status.
* @param number $order_id order id.
* @param number $refund_id refund id.
* @return false|mixed order status
*/
public function update_fully_refunded_status( $status, $order_id, $refund_id ) {
$order = wc_get_order( $order_id );
$order_items = ( is_object( $order ) && is_callable( array( $order, 'get_items' ) ) ) ? $order->get_items( 'coupon' ) : array();
if ( ! empty( $order_items ) ) {
foreach ( $order_items as $item_id => $item ) {
$sc_refunded_discount = $sc_refunded_discount_tax = $order_discount_amount = $order_discount_tax_amount = 0; // phpcs:ignore
$coupon_post_obj = ( function_exists( 'wpcom_vip_get_page_by_title' ) ) ? wpcom_vip_get_page_by_title( $item->get_name(), OBJECT, 'shop_coupon' ) : get_page_by_title( $item->get_name(), OBJECT, 'shop_coupon' );// phpcs:ignore
$coupon_id = isset( $coupon_post_obj->ID ) ? $coupon_post_obj->ID : '';
$coupon = new WC_Coupon( $coupon_id );
if ( is_callable( array( $this, 'get_order_item_meta' ) ) ) {
$sc_refunded_discount = $this->get_order_item_meta( $item_id, 'sc_refunded_discount', true );
$sc_refunded_discount_tax = $this->get_order_item_meta( $item_id, 'sc_refunded_discount_tax', true );
$order_discount_amount = $this->get_order_item_meta( $item_id, 'discount_amount', true );
$order_discount_tax_amount = $this->get_order_item_meta( $item_id, 'discount_amount_tax', true );
}
if ( is_a( $coupon, 'WC_Coupon' ) ) {
if ( $coupon->is_type( 'smart_coupon' ) ) {
$get_order_total = ( is_object( $order ) && is_callable( array( $order, 'get_total' ) ) ) ? $order->get_total() : 0;
$refunded_order_total = ( is_object( $order ) && is_callable( array( $order, 'get_total_refunded' ) ) ) ? $order->get_total_refunded() : 0;
if ( empty( $get_order_total ) && empty( $sc_refunded_discount_tax ) && empty( $order_discount_tax_amount ) && $order_discount_amount !== $sc_refunded_discount ) {
return false;
} elseif ( empty( $get_order_total ) && ! empty( $sc_refunded_discount_tax ) && ! empty( $order_discount_tax_amount ) && $order_discount_amount !== $sc_refunded_discount && $sc_refunded_discount_tax !== $order_discount_tax_amount ) {
return false;
} elseif ( ! empty( $get_order_total ) && empty( $sc_refunded_discount_tax ) && empty( $order_discount_tax_amount ) && $get_order_total === $refunded_order_total && $order_discount_amount !== $sc_refunded_discount ) {
return false;
} elseif ( ! empty( $get_order_total ) && ! empty( $sc_refunded_discount_tax ) && ! empty( $order_discount_tax_amount ) && $get_order_total === $refunded_order_total && $order_discount_amount !== $sc_refunded_discount && $sc_refunded_discount_tax !== $order_discount_tax_amount ) {
return false;
} elseif ( empty( $sc_refunded_discount_tax ) && ! empty( $order_discount_tax_amount ) ) {
return false;
}
}
}
}
}
return $status;
}
}
}
WC_SC_Coupon_Refund_Process::get_instance();

View File

@@ -1,343 +0,0 @@
<?php
/**
* Class to handle feature Coupons By Excluded Email
*
* @author StoreApps
* @category Admin
* @package wocommerce-smart-coupons/includes
* @since 6.7.0
* @version 1.2.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Coupons_By_Excluded_Email' ) ) {
/**
* Class WC_SC_Coupons_By_Excluded_Email
*/
class WC_SC_Coupons_By_Excluded_Email {
/**
* Variable to hold instance of this class
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
private function __construct() {
add_action( 'wc_sc_start_coupon_options_email_restriction', array( $this, 'usage_restriction' ) );
add_action( 'woocommerce_coupon_options_save', array( $this, 'process_meta' ), 10, 2 );
add_action( 'woocommerce_after_checkout_validation', array( $this, 'check_customer_coupons' ), 99, 2 );
add_filter( 'wc_smart_coupons_export_headers', array( $this, 'export_headers' ) );
add_filter( 'smart_coupons_parser_postmeta_defaults', array( $this, 'postmeta_defaults' ) );
add_filter( 'is_protected_meta', array( $this, 'make_action_meta_protected' ), 10, 3 );
add_filter( 'sc_generate_coupon_meta', array( $this, 'generate_coupon_meta' ), 10, 2 );
add_filter( 'wc_sc_process_coupon_meta_value_for_import', array( $this, 'import_coupon_meta' ), 10, 2 );
add_action( 'wc_sc_new_coupon_generated', array( $this, 'copy_coupon_meta' ) );
}
/**
* Get single instance of this class
*
* @return this class Singleton object of this class
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name = '', $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Display field for coupon by excluded email
*
* @param array $args Arguments.
*/
public function usage_restriction( $args = array() ) {
$coupon_id = ( ! empty( $args['coupon_id'] ) ) ? absint( $args['coupon_id'] ) : 0;
$coupon = ( ! empty( $args['coupon_obj'] ) ) ? $args['coupon_obj'] : null;
$excluded_emails = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_meta' ) ) ) ? $coupon->get_meta( 'wc_sc_excluded_customer_email' ) : get_post_meta( $coupon_id, 'wc_sc_excluded_customer_email', true );
if ( ! is_array( $excluded_emails ) || empty( $excluded_emails ) ) {
$excluded_emails = array();
}
woocommerce_wp_text_input(
array(
'id' => 'wc_sc_excluded_customer_email',
'label' => __( 'Excluded emails', 'woocommerce-smart-coupons' ),
'placeholder' => __( 'No restrictions', 'woocommerce-smart-coupons' ),
'description' => __( 'List of excluded billing emails to check against when an order is placed. Separate email addresses with commas. You can also use an asterisk (*) to match parts of an email. For example "*@gmail.com" would match all gmail addresses.', 'woocommerce-smart-coupons' ),
'value' => implode( ', ', $excluded_emails ),
'desc_tip' => true,
'type' => 'email',
'class' => '',
'custom_attributes' => array(
'multiple' => 'multiple',
),
)
);
}
/**
* Save coupon by excluded email data in meta
*
* @param Integer $post_id The coupon post ID.
* @param WC_Coupon $coupon The coupon object.
*/
public function process_meta( $post_id = 0, $coupon = null ) {
if ( empty( $post_id ) ) {
return;
}
if ( is_null( $coupon ) || ! is_a( $coupon, 'WC_Coupon' ) ) {
$coupon = new WC_Coupon( $post_id );
}
$excluded_emails = ( isset( $_POST['wc_sc_excluded_customer_email'] ) ) ? wc_clean( wp_unslash( $_POST['wc_sc_excluded_customer_email'] ) ) : ''; // phpcs:ignore
$excluded_emails = explode( ',', $excluded_emails );
$excluded_emails = array_map( 'trim', $excluded_emails );
$excluded_emails = array_filter( $excluded_emails, 'is_email' );
$excluded_emails = array_filter( $excluded_emails );
if ( $this->is_callable( $coupon, 'update_meta_data' ) && $this->is_callable( $coupon, 'save' ) ) {
$coupon->update_meta_data( 'wc_sc_excluded_customer_email', $excluded_emails );
$coupon->save();
} else {
update_post_meta( $post_id, 'wc_sc_excluded_customer_email', $excluded_emails );
}
}
/**
* Now that we have billing email, check if the coupon is excluded to be used for the user or billing email
*
* Credit: WooCommerce
*
* @param array $posted Post data.
*/
public function check_customer_coupons( $posted = array() ) {
$cart = ( function_exists( 'WC' ) && isset( WC()->cart ) ) ? WC()->cart : null;
if ( is_a( $cart, 'WC_Cart' ) ) {
$is_cart_empty = is_callable( array( $cart, 'is_empty' ) ) && $cart->is_empty();
if ( false === $is_cart_empty ) {
$applied_coupons = ( is_callable( array( $cart, 'get_applied_coupons' ) ) ) ? $cart->get_applied_coupons() : array();
if ( ! empty( $applied_coupons ) ) {
foreach ( $applied_coupons as $code ) {
$coupon = new WC_Coupon( $code );
if ( is_object( $coupon ) && is_callable( array( $coupon, 'is_valid' ) ) && $coupon->is_valid() ) {
// Get user and posted emails to compare.
$current_user = wp_get_current_user();
$billing_email = isset( $posted['billing_email'] ) ? $posted['billing_email'] : '';
$check_emails = array_unique(
array_filter(
array_map(
'strtolower',
array_map(
'sanitize_email',
array(
$billing_email,
$current_user->user_email,
)
)
)
)
);
if ( is_object( $coupon ) && is_callable( array( $coupon, 'get_meta' ) ) ) {
$exclude_restrictions = $coupon->get_meta( 'wc_sc_excluded_customer_email' );
} else {
if ( is_object( $coupon ) && is_callable( array( $coupon, 'get_id' ) ) ) {
$coupon_id = $coupon->get_id();
} else {
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
}
$exclude_restrictions = ( ! empty( $coupon_id ) ) ? get_post_meta( $coupon_id, 'wc_sc_excluded_customer_email', true ) : array();
}
if ( is_array( $exclude_restrictions ) && 0 < count( $exclude_restrictions ) && is_callable( array( $coupon, 'add_coupon_message' ) ) && is_callable( array( $cart, 'remove_coupon' ) ) && is_callable( array( $cart, 'is_coupon_emails_allowed' ) ) && $cart->is_coupon_emails_allowed( $check_emails, $exclude_restrictions ) ) {
$coupon->add_coupon_message( WC_Coupon::E_WC_COUPON_NOT_YOURS_REMOVED );
$cart->remove_coupon( $code );
}
/*
|===========================================================================================================================================================================|
| |
| Before this method, WooCommerce checks for Allowed emails. |
| And in that method, it already checks for the usage limit whether it is allowed to apply the coupon or not. |
| 1. If it's allowed, it means the usage limit is within reach & we can proceed with checking for excluded email. |
| Because the main purpose of excluded email is to prevent application of coupon. And since the usage limit is already checked, it's not needed to check it again |
| 2. If it's not allowed, the process will not reach in this method, as it's already invalidated. |
| |
|===========================================================================================================================================================================|
*/
}
}
}
}
}
}
/**
* Add meta in export headers
*
* @param array $headers Existing headers.
* @return array
*/
public function export_headers( $headers = array() ) {
$headers['wc_sc_excluded_customer_email'] = __( 'Excluded emails', 'woocommerce-smart-coupons' );
return $headers;
}
/**
* Post meta defaults for excluded email ids meta
*
* @param array $defaults Existing postmeta defaults.
* @return array $defaults Modified postmeta defaults
*/
public function postmeta_defaults( $defaults = array() ) {
$defaults['wc_sc_excluded_customer_email'] = '';
return $defaults;
}
/**
* Make meta data of excluded email ids protected
*
* @param bool $protected Is protected.
* @param string $meta_key The meta key.
* @param string $meta_type The meta type.
* @return bool $protected
*/
public function make_action_meta_protected( $protected = false, $meta_key = '', $meta_type = '' ) {
$sc_excluded_email_keys = array(
'wc_sc_excluded_customer_email',
);
if ( in_array( $meta_key, $sc_excluded_email_keys, true ) ) {
return true;
}
return $protected;
}
/**
* Add excluded email in coupon meta
*
* @param array $data The row data.
* @param array $post The POST values.
* @return array Modified data
*/
public function generate_coupon_meta( $data = array(), $post = array() ) {
$excluded_emails = ( isset( $post['wc_sc_excluded_customer_email'] ) ) ? wc_clean( wp_unslash( $post['wc_sc_excluded_customer_email'] ) ) : ''; // phpcs:ignore
$excluded_emails = explode( ',', $excluded_emails );
$excluded_emails = array_map( 'trim', $excluded_emails );
$excluded_emails = array_filter( $excluded_emails, 'is_email' );
$excluded_emails = array_filter( $excluded_emails );
$excluded_emails = implode( ',', $excluded_emails );
$data['wc_sc_excluded_customer_email'] = $excluded_emails;
return $data;
}
/**
* Process coupon meta value for import
*
* @param mixed $meta_value The meta value.
* @param array $args Additional Arguments.
* @return mixed $meta_value
*/
public function import_coupon_meta( $meta_value = null, $args = array() ) {
if ( ! empty( $args['meta_key'] ) && 'wc_sc_excluded_customer_email' === $args['meta_key'] ) {
$excluded_emails = ( isset( $args['postmeta']['wc_sc_excluded_customer_email'] ) ) ? wc_clean( wp_unslash( $args['postmeta']['wc_sc_excluded_customer_email'] ) ) : ''; // phpcs:ignore
$excluded_emails = explode( ',', $excluded_emails );
$excluded_emails = array_map( 'trim', $excluded_emails );
$excluded_emails = array_filter( $excluded_emails, 'is_email' );
$meta_value = array_filter( $excluded_emails );
}
return $meta_value;
}
/**
* Function to copy excluded email meta in newly generated coupon
*
* @param array $args The arguments.
*/
public function copy_coupon_meta( $args = array() ) {
$new_coupon_id = ( ! empty( $args['new_coupon_id'] ) ) ? absint( $args['new_coupon_id'] ) : 0;
$coupon = ( ! empty( $args['ref_coupon'] ) ) ? $args['ref_coupon'] : false;
if ( empty( $new_coupon_id ) || empty( $coupon ) ) {
return;
}
if ( $this->is_wc_gte_30() && is_object( $coupon ) && is_callable( array( $coupon, 'get_meta' ) ) ) {
$excluded_emails = $coupon->get_meta( 'wc_sc_excluded_customer_email' );
} else {
$old_coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
$excluded_emails = get_post_meta( $old_coupon_id, 'wc_sc_excluded_customer_email', true );
}
if ( ! is_array( $excluded_emails ) || empty( $excluded_emails ) ) {
$excluded_emails = array();
}
$new_coupon = new WC_Coupon( $new_coupon_id );
if ( is_object( $new_coupon ) && is_callable( array( $new_coupon, 'update_meta_data' ) ) && is_callable( array( $new_coupon, 'save' ) ) ) {
$new_coupon->update_meta_data( 'wc_sc_excluded_customer_email', $excluded_emails );
$new_coupon->save();
} else {
update_post_meta( $new_coupon_id, 'wc_sc_excluded_customer_email', $excluded_emails );
}
}
}
}
WC_SC_Coupons_By_Excluded_Email::get_instance();

View File

@@ -1,642 +0,0 @@
<?php
/**
* Class to handle feature Coupons By Location
*
* @author StoreApps
* @category Admin
* @package wocommerce-smart-coupons/includes
* @version 1.7.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Coupons_By_Location' ) ) {
/**
* Class WC_SC_Coupons_By_Location
*/
class WC_SC_Coupons_By_Location {
/**
* Variable to hold instance of this class
*
* @var $instance
*/
private static $instance = null;
/**
* Additional Locations
*
* @var $additional_locations
*/
public $additional_locations = array();
/**
* Countries
*
* @var $countries
*/
public $countries;
/**
* Global Additional Locations
*
* @var $global_additional_locations
*/
public $global_additional_locations = array();
/**
* Custom Locations
*
* @var $custom_locations
*/
public $custom_locations = array();
/**
* Locations Lookup In
*
* @var $locations_lookup_in
*/
public $locations_lookup_in;
/**
* Address
*
* @var $address
*/
public $address;
/**
* Constructor
*/
private function __construct() {
add_action( 'init', array( $this, 'initialize_cbl_additional_locations' ) );
add_filter( 'woocommerce_coupon_is_valid', array( $this, 'validate' ), 11, 2 );
if ( is_admin() ) {
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_javascript_css' ) );
add_action( 'woocommerce_coupon_options_usage_restriction', array( $this, 'usage_restriction' ) );
add_action( 'woocommerce_coupon_options_save', array( $this, 'process_meta' ), 10, 2 );
}
add_filter( 'wc_smart_coupons_export_headers', array( $this, 'export_headers' ) );
add_filter( 'wc_sc_export_coupon_meta_data', array( $this, 'export_coupon_meta_data' ), 10, 2 );
add_filter( 'smart_coupons_parser_postmeta_defaults', array( $this, 'postmeta_defaults' ) );
add_filter( 'sc_generate_coupon_meta', array( $this, 'generate_coupon_meta' ), 10, 2 );
add_filter( 'is_protected_meta', array( $this, 'make_action_meta_protected' ), 10, 3 );
add_filter( 'wc_sc_process_coupon_meta_value_for_import', array( $this, 'process_coupon_meta_value_for_import' ), 10, 2 );
add_action( 'wc_sc_new_coupon_generated', array( $this, 'copy_coupon_action_meta' ) );
}
/**
* Get single instance of this class
*
* @return this class Singleton object of this class
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Initialize additional locations
*/
public function initialize_cbl_additional_locations() {
if ( empty( $this->global_additional_locations ) ) {
$this->global_additional_locations = get_option( 'sa_cbl_additional_locations', array() );
}
}
/**
* Styles & scripts
*/
public function enqueue_admin_javascript_css() {
global $woocommerce_smart_coupon;
$post_type = get_post_type();
$get_page = ( ! empty( $_GET['page'] ) ) ? wc_clean( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore
if ( 'shop_coupon' !== $post_type && 'wc-smart-coupons' !== $get_page ) {
return;
}
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
// Add customized chosen javascript library for adding new location from same field.
wp_register_script( 'sa_coupons_by_location_chosen', plugins_url( '/', dirname( __FILE__ ) ) . 'assets/js/chosen.jquery' . $suffix . '.js', array( 'jquery' ), $woocommerce_smart_coupon->plugin_data['Version'], true );
wp_enqueue_style( 'sa_coupons_by_location_css', plugins_url( '/', dirname( __FILE__ ) ) . 'assets/css/cbl-admin' . $suffix . '.css', array(), $woocommerce_smart_coupon->plugin_data['Version'] );
}
/**
* Display field for coupon by location
*/
public function usage_restriction() {
global $post;
if ( ! wp_script_is( 'sa_coupons_by_location_chosen' ) ) {
wp_enqueue_script( 'sa_coupons_by_location_chosen' );
}
$coupon = ( ! empty( $post->ID ) ) ? new WC_Coupon( $post->ID ) : null;
$is_callable_coupon_get_meta = $this->is_callable( $coupon, 'get_meta' );
$this->locations_lookup_in = ( true === $is_callable_coupon_get_meta ) ? $coupon->get_meta( 'sa_cbl_locations_lookup_in' ) : get_post_meta( $post->ID, 'sa_cbl_locations_lookup_in', true );
if ( ! is_array( $this->locations_lookup_in ) || empty( $this->locations_lookup_in ) ) {
$this->locations_lookup_in = array( 'address' => 'billing' );
$this->update_post_meta( $post->ID, 'sa_cbl_locations_lookup_in', $this->locations_lookup_in );
}
$this->address = $this->locations_lookup_in['address'];
?>
<div class="options_group smart-coupons-field" id="locations">
<p class="form-field">
<span class='search_in'><label><?php echo esc_html__( 'Address to look in', 'woocommerce-smart-coupons' ); ?></label></span>
<label for="billing" class="billing">
<input type="radio" name="sa_cbl_search_in[address]" value="billing" <?php ( ! empty( $this->address ) && 'billing' === $this->address ) ? checked( $this->address, 'billing' ) : ''; ?> />
<?php echo esc_html__( 'Billing', 'woocommerce-smart-coupons' ); ?>
</label> &nbsp;
<label for="shipping" class="shipping">
<input type="radio" name="sa_cbl_search_in[address]" value="shipping" <?php ( ! empty( $this->address ) && 'shipping' === $this->address ) ? checked( $this->address, 'shipping' ) : ''; ?> />
<?php echo esc_html__( 'Shipping', 'woocommerce-smart-coupons' ); ?>
</label>
</p>
<p class="form-field">
<label class="options_header"><?php echo esc_html__( 'Locations', 'woocommerce-smart-coupons' ); ?></label>
<?php
$locations = ( true === $is_callable_coupon_get_meta ) ? $coupon->get_meta( 'sa_cbl_' . $this->address . '_locations' ) : get_post_meta( $post->ID, 'sa_cbl_' . $this->address . '_locations', true );
if ( empty( $locations ) || ! is_array( $locations ) ) {
$locations = array();
}
if ( ! array_key_exists( 'additional_locations', $locations ) || ! is_array( $locations['additional_locations'] ) ) {
$locations['additional_locations'] = array();
}
$this->additional_locations = array_map( 'html_entity_decode', array_map( 'strtolower', $locations['additional_locations'] ) );
$this->countries = array_map( 'strtolower', WC()->countries->countries );
echo '<select name="locations[additional_locations][]" id="cc_list" data-placeholder="' . esc_html__( 'Select location', 'woocommerce-smart-coupons' ) . '..." class="sa_cbl_search_location sa_cbl_add_location" multiple>';
// Countries.
echo ' <optgroup label="' . esc_html__( 'Select Country', 'woocommerce-smart-coupons' ) . '"> ';
foreach ( $this->countries as $country ) {
echo '<option value="' . esc_attr( $country ) . '"';
if ( ! empty( $this->additional_locations ) ) {
$encoding = $this->mb_detect_encoding( $country, 'UTF-8, ISO-8859-1', true );
$decoded_country = ( false !== $encoding ) ? html_entity_decode( $country, ENT_COMPAT, $encoding ) : $country;
echo esc_attr( selected( in_array( $decoded_country, $this->additional_locations, true ) ) );
}
echo '>' . esc_html( ucwords( strtolower( $country ) ) ) . '</option>';
}
echo ' </optgroup> ';
// others.
echo ' <optgroup label="' . esc_html__( 'Select Additional Locations', 'woocommerce-smart-coupons' ) . '"> ';
if ( ! empty( $this->global_additional_locations ) ) {
foreach ( $this->global_additional_locations as $list ) {
echo '<option value="' . esc_attr( $list ) . '"';
if ( ! empty( $this->additional_locations ) ) {
$encoding = $this->mb_detect_encoding( $list, 'UTF-8, ISO-8859-1', true );
$decoded_list = ( false !== $encoding ) ? html_entity_decode( $list, ENT_COMPAT, $encoding ) : $list;
echo esc_attr( selected( in_array( $decoded_list, $this->additional_locations, true ) ) );
}
echo '>' . esc_html( ucwords( strtolower( $list ) ) ) . '</option>';
}
}
echo ' </optgroup> ';
echo '</select>';
?>
</p>
</div>
<?php
$js = "jQuery('select.sa_cbl_search_location').chosen({
disable_search_threshold: 10,
width: '50%'
});";
$js .= "jQuery('#cc_list_chosen').on('click', function(){
var cc_height = jQuery('#cc_list_chosen').height();
jQuery('#cc_list_chosen .chosen-drop').attr('style', 'bottom: '+cc_height+'px !important; border-bottom: 0 !important; border-top: 1px solid #aaa !important; top: auto !important;');
});
";
wc_enqueue_js( $js );
}
/**
* Save coupon by location data in meta
*
* @param Integer $post_id The coupon post ID.
* @param WC_Coupon $coupon The coupon object.
*/
public function process_meta( $post_id = 0, $coupon = null ) {
if ( empty( $post_id ) ) {
return;
}
if ( is_null( $coupon ) || ! is_a( $coupon, 'WC_Coupon' ) ) {
$coupon = new WC_Coupon( $post_id );
}
$locations = ( ! empty( $_POST['locations'] ) ) ? wc_clean( wp_unslash( $_POST['locations'] ) ) : array(); // phpcs:ignore
$this->locations_lookup_in['address'] = ( ! empty( $_POST['sa_cbl_search_in']['address'] ) ) ? wc_clean( wp_unslash( $_POST['sa_cbl_search_in']['address'] ) ) : ''; // phpcs:ignore
if ( $this->is_callable( $coupon, 'update_meta_data' ) && $this->is_callable( $coupon, 'save' ) ) {
$coupon->update_meta_data( 'sa_cbl_' . $this->locations_lookup_in['address'] . '_locations', $locations );
if ( isset( $this->locations_lookup_in['address'] ) && ! empty( $this->locations_lookup_in['address'] ) ) {
$coupon->update_meta_data( 'sa_cbl_locations_lookup_in', $this->locations_lookup_in );
}
$coupon->save();
} else {
update_post_meta( $post_id, 'sa_cbl_' . $this->locations_lookup_in['address'] . '_locations', $locations );
if ( isset( $this->locations_lookup_in['address'] ) && ! empty( $this->locations_lookup_in['address'] ) ) {
update_post_meta( $post_id, 'sa_cbl_locations_lookup_in', $this->locations_lookup_in );
}
}
$this->countries = array_map( 'strtolower', WC()->countries->countries );
if ( ! empty( $locations['additional_locations'] ) ) {
$this->additional_locations = array_map( 'strtolower', $locations['additional_locations'] );
}
if ( count( $this->additional_locations ) > 0 ) {
// Loop through all location entered in Billing location of coupons.
// and collect those location which is not available in WooCommerce countries.
foreach ( $this->additional_locations as $location ) {
if ( ! in_array( $location, $this->countries, true ) ) {
$this->custom_locations[] = strtolower( $location );
}
}
// Add new location with already saved locations.
if ( false !== $this->global_additional_locations && ! empty( $this->global_additional_locations ) ) {
$this->global_additional_locations = array_merge( $this->global_additional_locations, $this->custom_locations );
} else {
$this->global_additional_locations = $this->custom_locations;
}
// Discard duplicate values, arrange alphabetically & save.
$this->global_additional_locations = array_unique( $this->global_additional_locations );
sort( $this->global_additional_locations );
update_option( 'sa_cbl_additional_locations', $this->global_additional_locations, 'no' );
}
}
/**
* Validate the coupon based on location
*
* @param boolean $valid Is valid or not.
* @param WC_Coupon $coupon The coupon object.
*
* @throws Exception If the coupon is invalid.
* @return boolean Is valid or not
*/
public function validate( $valid, $coupon ) {
global $checkout;
// If coupon is invalid already, no need for further checks.
if ( ! $valid ) {
return $valid;
}
$coupon_id = ( $this->is_wc_gte_30() ) ? $coupon->get_id() : $coupon->id;
$is_callable_coupon_get_meta = $this->is_callable( $coupon, 'get_meta' );
$this->locations_lookup_in = ( true === $is_callable_coupon_get_meta ) ? $coupon->get_meta( 'sa_cbl_locations_lookup_in' ) : get_post_meta( $coupon_id, 'sa_cbl_locations_lookup_in', true );
if ( empty( $this->locations_lookup_in ) || empty( $this->locations_lookup_in['address'] ) ) {
return $valid;
}
$locations = ( true === $is_callable_coupon_get_meta ) ? $coupon->get_meta( 'sa_cbl_' . $this->locations_lookup_in['address'] . '_locations' ) : get_post_meta( $coupon_id, 'sa_cbl_' . $this->locations_lookup_in['address'] . '_locations', true );
if ( ! empty( $locations ) && is_array( $locations ) && ! empty( $locations['additional_locations'] ) && is_array( $locations['additional_locations'] ) && array_key_exists( 'additional_locations', $locations ) ) {
$wc_customer = WC()->customer;
$wc_countries = WC()->countries;
// Collect country, state & city.
if ( 'billing' === $this->locations_lookup_in['address'] ) {
if ( $this->is_wc_gte_30() ) {
$customer_billing_country = $wc_customer->get_billing_country();
$customer_billing_state = $wc_customer->get_billing_state();
$customer_billing_city = $wc_customer->get_billing_city();
$customer_billing_postcode = $wc_customer->get_billing_postcode();
$current_country = ( ! empty( $customer_billing_country ) ) ? $customer_billing_country : '';
$current_state = ( ! empty( $customer_billing_state ) ) ? $customer_billing_state : '';
$current_city = ( ! empty( $customer_billing_city ) ) ? $customer_billing_city : '';
$current_post_code = ( ! empty( $customer_billing_postcode ) ) ? $customer_billing_postcode : '';
} else {
$current_country = ( ! empty( $wc_customer->country ) ) ? $wc_customer->country : '';
$current_state = ( ! empty( $wc_customer->state ) ) ? $wc_customer->state : '';
$current_city = ( ! empty( $wc_customer->city ) ) ? $wc_customer->city : '';
$current_post_code = ( ! empty( $wc_customer->postcode ) ) ? $wc_customer->postcode : '';
}
} else {
if ( $this->is_wc_gte_30() ) {
$customer_shipping_country = $wc_customer->get_shipping_country();
$customer_shipping_state = $wc_customer->get_shipping_state();
$customer_shipping_city = $wc_customer->get_shipping_city();
$customer_shipping_postcode = $wc_customer->get_shipping_postcode();
$current_country = ( ! empty( $customer_shipping_country ) ) ? $customer_shipping_country : '';
$current_state = ( ! empty( $customer_shipping_state ) ) ? $customer_shipping_state : '';
$current_city = ( ! empty( $customer_shipping_city ) ) ? $customer_shipping_city : '';
$current_post_code = ( ! empty( $customer_shipping_postcode ) ) ? $customer_shipping_postcode : '';
} else {
$current_country = ( ! empty( $wc_customer->shipping_country ) ) ? $wc_customer->shipping_country : '';
$current_state = ( ! empty( $wc_customer->shipping_state ) ) ? $wc_customer->shipping_state : '';
$current_city = ( ! empty( $wc_customer->shipping_city ) ) ? $wc_customer->shipping_city : '';
$current_post_code = ( ! empty( $wc_customer->shipping_postcode ) ) ? $wc_customer->shipping_postcode : '';
}
}
// Convert country code or state code to actual country & state.
$country = ( ! empty( $wc_countries->countries[ $current_country ] ) ) ? strtolower( $wc_countries->countries[ $current_country ] ) : '';
$state = ( ! empty( $wc_countries->states[ $current_country ][ $current_state ] ) ) ? strtolower( $wc_countries->states[ $current_country ][ $current_state ] ) : strtolower( $current_state );
$city = ( ! empty( $current_city ) ) ? strtolower( $current_city ) : '';
$post_code = ( ! empty( $current_post_code ) ) ? strtolower( $current_post_code ) : '';
// Loop through additional_locations and return true on matching with either country, state or city.
// Return false otherwise.
foreach ( $locations['additional_locations'] as $additional_location ) {
if ( $country === $additional_location || $state === $additional_location || $city === $additional_location || $post_code === $additional_location ) {
return true;
}
}
throw new Exception( __( 'Coupon is not valid for the', 'woocommerce-smart-coupons' ) . ' ' . ( ( 'billing' === $this->locations_lookup_in['address'] ) ? __( 'billing address', 'woocommerce-smart-coupons' ) : __( 'shipping address', 'woocommerce-smart-coupons' ) ) );
}
return $valid;
}
/**
* Add meta in export headers
*
* @param array $headers Existing headers.
* @return array
*/
public function export_headers( $headers = array() ) {
$cbl_headers = array(
'sa_cbl_locations_lookup_in' => __( 'Locations lookup in', 'woocommerce-smart-coupons' ),
'sa_cbl_billing_locations' => __( 'Billing Locations', 'woocommerce-smart-coupons' ),
'sa_cbl_shipping_locations' => __( 'Shipping Locations', 'woocommerce-smart-coupons' ),
);
return array_merge( $headers, $cbl_headers );
}
/**
* Function to handle coupon meta data during export of existing coupons
*
* @param mixed $meta_value The meta value.
* @param array $args Additional arguments.
* @return string Processed meta value
*/
public function export_coupon_meta_data( $meta_value = '', $args = array() ) {
if ( ! empty( $args['meta_key'] ) && in_array( $args['meta_key'], array( 'sa_cbl_billing_locations', 'sa_cbl_shipping_locations' ), true ) ) {
switch ( $args['meta_key'] ) {
case 'sa_cbl_billing_locations':
case 'sa_cbl_shipping_locations':
$meta_value = ( ! empty( $meta_value['additional_locations'] ) ) ? implode( '|', wc_clean( wp_unslash( $meta_value['additional_locations'] ) ) ) : '';
break;
}
}
return $meta_value;
}
/**
* Post meta defaults for CBL's meta
*
* @param array $defaults Existing postmeta defaults.
* @return array
*/
public function postmeta_defaults( $defaults = array() ) {
$cbl_defaults = array(
'sa_cbl_locations_lookup_in' => '',
'sa_cbl_billing_locations' => '',
'sa_cbl_shipping_locations' => '',
);
return array_merge( $defaults, $cbl_defaults );
}
/**
* Add CBL's meta with value in coupon meta
*
* @param array $data The row data.
* @param array $post The POST values.
* @return array Modified data
*/
public function generate_coupon_meta( $data = array(), $post = array() ) {
$data['sa_cbl_locations_lookup_in'] = ( ! empty( $post['sa_cbl_search_in']['address'] ) ) ? wc_clean( wp_unslash( $post['sa_cbl_search_in']['address'] ) ) : '';
$data['sa_cbl_billing_locations'] = ( ! empty( $data['sa_cbl_locations_lookup_in'] ) && 'billing' === $data['sa_cbl_locations_lookup_in'] && ! empty( $post['locations']['additional_locations'] ) && is_array( $post['locations']['additional_locations'] ) ) ? implode( '|', wc_clean( wp_unslash( $post['locations']['additional_locations'] ) ) ) : '';
$data['sa_cbl_shipping_locations'] = ( ! empty( $data['sa_cbl_locations_lookup_in'] ) && 'shipping' === $data['sa_cbl_locations_lookup_in'] && ! empty( $post['locations']['additional_locations'] ) && is_array( $post['locations']['additional_locations'] ) ) ? implode( '|', wc_clean( wp_unslash( $post['locations']['additional_locations'] ) ) ) : '';
if ( ! empty( $post['locations']['additional_locations'] ) ) {
$additional_locations = wc_clean( wp_unslash( $post['locations']['additional_locations'] ) );
$this->update_global_additional_locations( $additional_locations );
}
return $data;
}
/**
* Make meta data of SC CBL, protected
*
* @param bool $protected Is protected.
* @param string $meta_key The meta key.
* @param string $meta_type The meta type.
* @return bool $protected
*/
public function make_action_meta_protected( $protected, $meta_key, $meta_type ) {
$sc_meta = array(
'sa_cbl_locations_lookup_in' => '',
'sa_cbl_billing_locations' => '',
'sa_cbl_shipping_locations' => '',
);
if ( in_array( $meta_key, $sc_meta, true ) ) {
return true;
}
return $protected;
}
/**
* Function to copy CBL meta in newly generated coupon
*
* @param array $args The arguments.
*/
public function copy_coupon_action_meta( $args = array() ) {
$new_coupon_id = ( ! empty( $args['new_coupon_id'] ) ) ? absint( $args['new_coupon_id'] ) : 0;
$coupon = ( ! empty( $args['ref_coupon'] ) ) ? $args['ref_coupon'] : false;
if ( empty( $new_coupon_id ) || empty( $coupon ) ) {
return;
}
if ( $this->is_wc_gte_30() ) {
$locations_lookup_in = $coupon->get_meta( 'sa_cbl_locations_lookup_in' );
$billing_locations = $coupon->get_meta( 'sa_cbl_billing_locations' );
$shipping_locations = $coupon->get_meta( 'sa_cbl_shipping_locations' );
} else {
$old_coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
$locations_lookup_in = get_post_meta( $old_coupon_id, 'sa_cbl_locations_lookup_in', true );
$billing_locations = get_post_meta( $old_coupon_id, 'sa_cbl_billing_locations', true );
$shipping_locations = get_post_meta( $old_coupon_id, 'sa_cbl_shipping_locations', true );
}
$new_coupon = new WC_Coupon( $new_coupon_id );
if ( $this->is_callable( $new_coupon, 'update_meta_data' ) && $this->is_callable( $new_coupon, 'save' ) ) {
$new_coupon->update_meta_data( 'sa_cbl_locations_lookup_in', $locations_lookup_in );
$new_coupon->update_meta_data( 'sa_cbl_billing_locations', $billing_locations );
$new_coupon->update_meta_data( 'sa_cbl_shipping_locations', $shipping_locations );
$new_coupon->save();
} else {
update_post_meta( $new_coupon_id, 'sa_cbl_locations_lookup_in', $locations_lookup_in );
update_post_meta( $new_coupon_id, 'sa_cbl_billing_locations', $billing_locations );
update_post_meta( $new_coupon_id, 'sa_cbl_shipping_locations', $shipping_locations );
}
if ( ! empty( $billing_locations['additional_locations'] ) ) {
$this->update_global_additional_locations( $billing_locations['additional_locations'] );
}
if ( ! empty( $shipping_locations['additional_locations'] ) ) {
$this->update_global_additional_locations( $shipping_locations['additional_locations'] );
}
}
/**
* Process coupon meta value for import
*
* @param mixed $meta_value The meta value.
* @param array $args Additional Arguments.
* @return mixed $meta_value
*/
public function process_coupon_meta_value_for_import( $meta_value = null, $args = array() ) {
if ( ! empty( $args['meta_key'] ) && in_array( $args['meta_key'], array( 'sa_cbl_locations_lookup_in', 'sa_cbl_billing_locations', 'sa_cbl_shipping_locations' ), true ) ) {
switch ( $args['meta_key'] ) {
case 'sa_cbl_locations_lookup_in':
$meta_value = ( ! empty( $args['postmeta']['sa_cbl_locations_lookup_in'] ) ) ? array( 'address' => wc_clean( wp_unslash( $args['postmeta']['sa_cbl_locations_lookup_in'] ) ) ) : array();
break;
case 'sa_cbl_billing_locations':
$meta_value = ( ! empty( $args['postmeta']['sa_cbl_billing_locations'] ) ) ? array( 'additional_locations' => explode( '|', wc_clean( wp_unslash( $args['postmeta']['sa_cbl_billing_locations'] ) ) ) ) : array();
break;
case 'sa_cbl_shipping_locations':
$meta_value = ( ! empty( $args['postmeta']['sa_cbl_shipping_locations'] ) ) ? array( 'additional_locations' => explode( '|', wc_clean( wp_unslash( $args['postmeta']['sa_cbl_shipping_locations'] ) ) ) ) : array();
break;
}
if ( in_array( $args['meta_key'], array( 'sa_cbl_billing_locations', 'sa_cbl_shipping_locations' ), true ) && ! empty( $meta_value['additional_locations'] ) ) {
$this->update_global_additional_locations( $meta_value['additional_locations'] );
}
}
return $meta_value;
}
/**
* Update global additional locations
*
* @param array $additional_locations The locations.
*/
public function update_global_additional_locations( $additional_locations = array() ) {
if ( empty( $additional_locations ) ) {
return;
}
$additional_locations = array_map( 'strtolower', $additional_locations );
$wc_countries = array_map( 'strtolower', WC()->countries->countries );
foreach ( $wc_countries as $index => $country ) {
$encoding = $this->mb_detect_encoding( $country, 'UTF-8, ISO-8859-1', true );
$wc_countries[ $index ] = ( false !== $encoding ) ? html_entity_decode( $country, ENT_COMPAT, $encoding ) : $country;
}
if ( count( $additional_locations ) > 0 ) {
$custom_locations = array();
// Loop through all location entered in Billing location of coupons.
// and collect those location which is not available in WooCommerce countries.
foreach ( $additional_locations as $location ) {
if ( ! in_array( $location, $wc_countries, true ) ) {
$custom_locations[] = $location;
}
}
$global_additional_locations = ( ! empty( $this->global_additional_locations ) ) ? $this->global_additional_locations : get_option( 'sa_cbl_additional_locations', array() );
// Add new location with already saved locations.
if ( false !== $global_additional_locations && ! empty( $global_additional_locations ) ) {
$global_additional_locations = array_merge( $global_additional_locations, $custom_locations );
} else {
$global_additional_locations = $custom_locations;
}
// Discard duplicate values, arrange alphabetically & save.
$global_additional_locations = array_unique( $global_additional_locations );
sort( $global_additional_locations );
update_option( 'sa_cbl_additional_locations', $global_additional_locations, 'no' );
}
}
}
}
WC_SC_Coupons_By_Location::get_instance();

View File

@@ -1,378 +0,0 @@
<?php
/**
* Class to handle feature Coupons By Payment Method
*
* @author StoreApps
* @category Admin
* @package wocommerce-smart-coupons/includes
* @version 1.3.1
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Coupons_By_Payment_Method' ) ) {
/**
* Class WC_SC_Coupons_By_Payment_Method
*/
class WC_SC_Coupons_By_Payment_Method {
/**
* Variable to hold instance of this class
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
private function __construct() {
add_action( 'woocommerce_coupon_options_usage_restriction', array( $this, 'usage_restriction' ), 10, 2 );
add_action( 'woocommerce_coupon_options_save', array( $this, 'process_meta' ), 10, 2 );
add_filter( 'woocommerce_coupon_is_valid', array( $this, 'validate' ), 11, 3 );
add_filter( 'wc_smart_coupons_export_headers', array( $this, 'export_headers' ) );
add_filter( 'wc_sc_export_coupon_meta', array( $this, 'export_coupon_meta_data' ), 10, 2 );
add_filter( 'smart_coupons_parser_postmeta_defaults', array( $this, 'postmeta_defaults' ) );
add_filter( 'sc_generate_coupon_meta', array( $this, 'generate_coupon_meta' ), 10, 2 );
add_filter( 'wc_sc_process_coupon_meta_value_for_import', array( $this, 'process_coupon_meta_value_for_import' ), 10, 2 );
add_filter( 'is_protected_meta', array( $this, 'make_action_meta_protected' ), 10, 3 );
add_action( 'wc_sc_new_coupon_generated', array( $this, 'copy_coupon_payment_method_meta' ) );
}
/**
* Get single instance of this class
*
* @return this class Singleton object of this class
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name = '', $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Display field for coupon by payment method
*
* @param integer $coupon_id The coupon id.
* @param WC_Coupon $coupon The coupon object.
*/
public function usage_restriction( $coupon_id = 0, $coupon = null ) {
$payment_method_ids = array();
if ( ! empty( $coupon_id ) ) {
$payment_method_ids = $this->get_post_meta( $coupon_id, 'wc_sc_payment_method_ids', true );
if ( empty( $payment_method_ids ) || ! is_array( $payment_method_ids ) ) {
$payment_method_ids = array();
}
}
$available_payment_methods = WC()->payment_gateways->get_available_payment_gateways();
?>
<div class="options_group smart-coupons-field">
<p class="form-field">
<label for="wc_sc_payment_method_ids"><?php echo esc_html__( 'Payment methods', 'woocommerce-smart-coupons' ); ?></label>
<select id="wc_sc_payment_method_ids" name="wc_sc_payment_method_ids[]" style="width: 50%;" class="wc-enhanced-select" multiple="multiple" data-placeholder="<?php esc_attr_e( 'No payment methods', 'woocommerce-smart-coupons' ); ?>">
<?php
if ( is_array( $available_payment_methods ) && ! empty( $available_payment_methods ) ) {
foreach ( $available_payment_methods as $payment_method ) {
echo '<option value="' . esc_attr( $payment_method->id ) . '"' . esc_attr( selected( in_array( $payment_method->id, $payment_method_ids, true ), true, false ) ) . '>' . esc_html( $payment_method->get_title() ) . '</option>';
}
}
?>
</select>
<?php
$tooltip_text = esc_html__( 'Payment methods that must be selected during checkout for this coupon to be valid.', 'woocommerce-smart-coupons' );
echo wc_help_tip( $tooltip_text ); // phpcs:ignore
?>
</p>
</div>
<?php
}
/**
* Save coupon by payment method data in meta
*
* @param Integer $post_id The coupon post ID.
* @param WC_Coupon $coupon The coupon object.
*/
public function process_meta( $post_id = 0, $coupon = null ) {
if ( empty( $post_id ) ) {
return;
}
if ( is_null( $coupon ) || ! is_a( $coupon, 'WC_Coupon' ) ) {
$coupon = new WC_Coupon( $post_id );
}
$payment_method_ids = ( isset( $_POST['wc_sc_payment_method_ids'] ) ) ? wc_clean( wp_unslash( $_POST['wc_sc_payment_method_ids'] ) ) : array(); // phpcs:ignore
if ( $this->is_callable( $coupon, 'update_meta_data' ) && $this->is_callable( $coupon, 'save' ) ) {
$coupon->update_meta_data( 'wc_sc_payment_method_ids', $payment_method_ids );
$coupon->save();
} else {
$this->update_post_meta( $post_id, 'wc_sc_payment_method_ids', $payment_method_ids );
}
}
/**
* Validate the coupon based on payment method
*
* @param boolean $valid Is valid or not.
* @param WC_Coupon $coupon The coupon object.
* @param WC_Discounts $discounts The discount object.
*
* @throws Exception If the coupon is invalid.
* @return boolean Is valid or not
*/
public function validate( $valid = false, $coupon = object, $discounts = object ) {
// If coupon is already invalid, no need for further checks.
if ( false === $valid ) {
return $valid;
}
if ( ! is_a( $coupon, 'WC_Coupon' ) ) {
return $valid;
}
if ( ! is_a( $discounts, 'WC_Discounts' ) ) {
return $valid;
}
if ( $this->is_wc_gte_30() ) {
$coupon_id = ( ! empty( $coupon ) && is_callable( array( $coupon, 'get_id' ) ) ) ? $coupon->get_id() : 0;
$coupon_code = ( ! empty( $coupon ) && is_callable( array( $coupon, 'get_code' ) ) ) ? $coupon->get_code() : '';
} else {
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
$coupon_code = ( ! empty( $coupon->code ) ) ? $coupon->code : '';
}
if ( empty( $coupon_id ) ) {
return $valid;
}
$payment_method_ids = $this->get_post_meta( $coupon_id, 'wc_sc_payment_method_ids', true );
$cart_or_order_object = is_callable( array( $discounts, 'get_object' ) ) ? $discounts->get_object() : null;
$is_wc_session = is_a( $cart_or_order_object, 'WC_Cart' ) && function_exists( 'WC' ) && isset( WC()->session ) && is_object( WC()->session );
if ( is_array( $payment_method_ids ) && ! empty( $payment_method_ids ) ) {
$payment_titles = $this->get_payment_method_titles_by_ids( $payment_method_ids );
$chosen_payment_method = '';
if ( is_a( $cart_or_order_object, 'WC_Order' ) ) {
$chosen_payment_method = is_callable( array( $cart_or_order_object, 'get_payment_method' ) ) ? $cart_or_order_object->get_payment_method() : '';
} elseif ( true === $is_wc_session ) {
$chosen_payment_method = ( WC()->session->__isset( 'chosen_payment_method' ) ) ? WC()->session->get( 'chosen_payment_method' ) : '';
}
if ( ! in_array( $chosen_payment_method, $payment_method_ids, true ) ) {
if ( true === $is_wc_session && is_callable( array( WC()->session, 'set' ) ) ) {
WC()->session->set( 'wc_sc_reload_payment_method', 'yes' );
}
/* translators: 1. The coupon code 2. The text 'payment method/s' 3. List of payment method names 4. Link to the checkout page */
throw new Exception( sprintf( __( 'Coupon code %1$s is valid only for %2$s: %3$s. You can change payment method from the %4$s page.', 'woocommerce-smart-coupons' ), '<code>' . $coupon_code . '</code>', _n( 'payment method', 'payment methods', count( $payment_titles ), 'woocommerce-smart-coupons' ), '<strong>"' . implode( '", "', $payment_titles ) . '"</strong>', '<a href="' . esc_url( wc_get_checkout_url() ) . '"><strong>' . __( 'Checkout', 'woocommerce-smart-coupons' ) . '</strong></a>' ) );
}
if ( true === $is_wc_session && is_callable( array( WC()->session, 'set' ) ) ) {
WC()->session->set( 'wc_sc_reload_payment_method', 'no' );
}
}
return $valid;
}
/**
* Add meta in export headers
*
* @param array $headers Existing headers.
* @return array
*/
public function export_headers( $headers = array() ) {
$headers['wc_sc_payment_method_ids'] = __( 'Payment methods', 'woocommerce-smart-coupons' );
return $headers;
}
/**
* Function to handle coupon meta data during export of existing coupons
*
* @param mixed $meta_value The meta value.
* @param array $args Additional arguments.
* @return string Processed meta value
*/
public function export_coupon_meta_data( $meta_value = '', $args = array() ) {
if ( ! empty( $args['meta_key'] ) && 'wc_sc_payment_method_ids' === $args['meta_key'] ) {
if ( isset( $args['meta_value'] ) && ! empty( $args['meta_value'] ) ) {
$payment_method_ids = maybe_unserialize( stripslashes( $args['meta_value'] ) );
if ( is_array( $payment_method_ids ) && ! empty( $payment_method_ids ) ) {
$payment_method_titles = $this->get_payment_method_titles_by_ids( $payment_method_ids );
if ( is_array( $payment_method_titles ) && ! empty( $payment_method_titles ) ) {
$meta_value = implode( '|', wc_clean( wp_unslash( $payment_method_titles ) ) ); // Replace payment method ids with their respective method titles.
}
}
}
}
return $meta_value;
}
/**
* Post meta defaults for payment method ids meta
*
* @param array $defaults Existing postmeta defaults.
* @return array $defaults Modified postmeta defaults
*/
public function postmeta_defaults( $defaults = array() ) {
$defaults['wc_sc_payment_method_ids'] = '';
return $defaults;
}
/**
* Add payment method's meta with value in coupon meta
*
* @param array $data The row data.
* @param array $post The POST values.
* @return array $data Modified row data
*/
public function generate_coupon_meta( $data = array(), $post = array() ) {
$payment_method_titles = '';
if ( ! empty( $post['wc_sc_payment_method_ids'] ) && is_array( $post['wc_sc_payment_method_ids'] ) ) {
$payment_method_titles = $this->get_payment_method_titles_by_ids( $post['wc_sc_payment_method_ids'] );
if ( is_array( $payment_method_titles ) && ! empty( $payment_method_titles ) ) {
$payment_method_titles = implode( '|', wc_clean( wp_unslash( $payment_method_titles ) ) );
}
}
$data['wc_sc_payment_method_ids'] = $payment_method_titles; // Replace payment method ids with their respective method titles.
return $data;
}
/**
* Function to get payment method titles for given payment method ids
*
* @param array $payment_method_ids ids of payment methods.
* @return array $payment_method_titles titles of payment methods
*/
public function get_payment_method_titles_by_ids( $payment_method_ids = array() ) {
$payment_method_titles = array();
if ( is_array( $payment_method_ids ) && ! empty( $payment_method_ids ) ) {
$available_payment_methods = WC()->payment_gateways->get_available_payment_gateways();
foreach ( $payment_method_ids as $index => $payment_method_id ) {
$payment_method = ( isset( $available_payment_methods[ $payment_method_id ] ) && ! empty( $available_payment_methods[ $payment_method_id ] ) ) ? $available_payment_methods[ $payment_method_id ] : '';
if ( ! empty( $payment_method ) && is_a( $payment_method, 'WC_Payment_Gateway' ) ) {
$payment_method_title = is_callable( array( $payment_method, 'get_title' ) ) ? $payment_method->get_title() : '';
if ( ! empty( $payment_method_title ) ) {
$payment_method_titles[ $index ] = $payment_method_title; // Replace payment method id with it's repective title.
} else {
$payment_method_titles[ $index ] = $payment_method->id; // In case of empty payment method title replace it with method id.
}
}
}
}
return $payment_method_titles;
}
/**
* Process coupon meta value for import
*
* @param mixed $meta_value The meta value.
* @param array $args Additional Arguments.
* @return mixed $meta_value
*/
public function process_coupon_meta_value_for_import( $meta_value = null, $args = array() ) {
if ( ! empty( $args['meta_key'] ) && 'wc_sc_payment_method_ids' === $args['meta_key'] ) {
$meta_value = ( ! empty( $args['postmeta']['wc_sc_payment_method_ids'] ) ) ? explode( '|', wc_clean( wp_unslash( $args['postmeta']['wc_sc_payment_method_ids'] ) ) ) : array();
if ( is_array( $meta_value ) && ! empty( $meta_value ) ) {
$available_payment_methods = WC()->payment_gateways->get_available_payment_gateways();
if ( is_array( $available_payment_methods ) && ! empty( $available_payment_methods ) ) {
foreach ( $meta_value as $index => $payment_method_title ) {
foreach ( $available_payment_methods as $payment_method ) {
$method_title = is_callable( array( $payment_method, 'get_title' ) ) ? $payment_method->get_title() : '';
if ( $method_title === $payment_method_title && ! empty( $payment_method->id ) ) {
$meta_value[ $index ] = $payment_method->id; // Replace payment method title with it's respective id.
}
}
}
}
}
}
return $meta_value;
}
/**
* Function to copy payment method restriction meta in newly generated coupon
*
* @param array $args The arguments.
*/
public function copy_coupon_payment_method_meta( $args = array() ) {
// Copy meta data to new coupon.
$this->copy_coupon_meta_data(
$args,
array( 'wc_sc_payment_method_ids' )
);
}
/**
* Make meta data of payment method ids protected
*
* @param bool $protected Is protected.
* @param string $meta_key The meta key.
* @param string $meta_type The meta type.
* @return bool $protected
*/
public function make_action_meta_protected( $protected = false, $meta_key = '', $meta_type = '' ) {
if ( 'wc_sc_payment_method_ids' === $meta_key ) {
return true;
}
return $protected;
}
}
}
WC_SC_Coupons_By_Payment_Method::get_instance();

View File

@@ -1,642 +0,0 @@
<?php
/**
* Class to handle feature Coupons By Product Attribute
*
* @author StoreApps
* @category Admin
* @package wocommerce-smart-coupons/includes
* @version 1.6.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Coupons_By_Product_Attribute' ) ) {
/**
* Class WC_SC_Coupons_By_Product_Attribute
*/
class WC_SC_Coupons_By_Product_Attribute {
/**
* Variable to hold instance of this class
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
private function __construct() {
add_action( 'woocommerce_coupon_options_usage_restriction', array( $this, 'usage_restriction' ), 10, 2 );
add_action( 'woocommerce_coupon_options_save', array( $this, 'process_meta' ), 10, 2 );
add_filter( 'woocommerce_coupon_is_valid_for_product', array( $this, 'validate' ), 11, 4 );
add_filter( 'woocommerce_coupon_is_valid', array( $this, 'handle_non_product_type_coupons' ), 11, 3 );
add_filter( 'wc_smart_coupons_export_headers', array( $this, 'export_headers' ) );
add_filter( 'smart_coupons_parser_postmeta_defaults', array( $this, 'postmeta_defaults' ) );
add_filter( 'is_protected_meta', array( $this, 'make_action_meta_protected' ), 10, 3 );
add_filter( 'sc_generate_coupon_meta', array( $this, 'generate_coupon_attribute_meta' ), 10, 2 );
add_action( 'wc_sc_new_coupon_generated', array( $this, 'copy_coupon_attributes_meta' ) );
}
/**
* Get single instance of this class
*
* @return this class Singleton object of this class
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name = '', $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Display field for coupon by product attribute
*
* @param integer $coupon_id The coupon id.
* @param WC_Coupon $coupon The coupon object.
*/
public function usage_restriction( $coupon_id = 0, $coupon = null ) {
global $wp_version;
$product_attribute_ids = array();
$exclude_product_attribute_ids = array();
$coupon_types = wc_get_coupon_types();
$product_coupon_types = wc_get_product_coupon_types();
$non_product_coupon_types = array();
foreach ( $coupon_types as $coupon_type => $coupon_label ) {
if ( ! in_array( $coupon_type, $product_coupon_types, true ) ) {
$non_product_coupon_types[] = $coupon_label;
}
}
if ( ! empty( $non_product_coupon_types ) ) {
$non_product_coupon_types_label = '"' . implode( ', ', $non_product_coupon_types ) . '"';
} else {
$non_product_coupon_types_label = '';
}
if ( ! empty( $coupon_id ) ) {
$coupon = ( ! empty( $coupon_id ) ) ? new WC_Coupon( $coupon_id ) : null;
$is_callable_coupon_get_meta = $this->is_callable( $coupon, 'get_meta' );
$product_attribute_ids = ( true === $is_callable_coupon_get_meta ) ? $coupon->get_meta( 'wc_sc_product_attribute_ids' ) : get_post_meta( $coupon_id, 'wc_sc_product_attribute_ids', true );
if ( ! empty( $product_attribute_ids ) ) {
$product_attribute_ids = explode( '|', $product_attribute_ids );
} else {
$product_attribute_ids = array();
}
$exclude_product_attribute_ids = ( true === $is_callable_coupon_get_meta ) ? $coupon->get_meta( 'wc_sc_exclude_product_attribute_ids' ) : get_post_meta( $coupon_id, 'wc_sc_exclude_product_attribute_ids', true );
if ( ! empty( $exclude_product_attribute_ids ) ) {
$exclude_product_attribute_ids = explode( '|', $exclude_product_attribute_ids );
} else {
$exclude_product_attribute_ids = array();
}
}
$attribute_taxonomies = wc_get_attribute_taxonomies();
$attribute_options = array();
$attribute_taxonomies_label = array();
if ( ! empty( $attribute_taxonomies ) && is_array( $attribute_taxonomies ) ) {
$attribute_taxonomies_name = array();
foreach ( $attribute_taxonomies as $attribute_taxonomy ) {
$attribute_name = isset( $attribute_taxonomy->attribute_name ) ? $attribute_taxonomy->attribute_name : '';
$attribute_label = isset( $attribute_taxonomy->attribute_label ) ? $attribute_taxonomy->attribute_label : '';
if ( ! empty( $attribute_name ) && ! empty( $attribute_label ) ) {
$attribute_taxonomy_name = wc_attribute_taxonomy_name( $attribute_name );
$attribute_taxonomies_name[] = $attribute_taxonomy_name;
$attribute_taxonomies_label[ $attribute_taxonomy_name ] = $attribute_label;
}
}
if ( ! empty( $attribute_taxonomies_name ) ) {
$args = array(
'orderby' => 'name',
'hide_empty' => 0,
);
$args = apply_filters( 'woocommerce_product_attribute_terms', $args );
if ( version_compare( $wp_version, '4.5.0', '>=' ) ) {
$attribute_taxonomies_terms = get_terms(
array_merge(
array(
'taxonomy' => $attribute_taxonomies_name,
),
$args
)
);
} else {
$attribute_taxonomies_terms = get_terms( $attribute_taxonomies_name, $args );
}
if ( ! empty( $attribute_taxonomies_terms ) && is_array( $attribute_taxonomies_terms ) ) {
foreach ( $attribute_taxonomies_terms as $attribute_taxonomy_term ) {
$attribute_taxonomy = $attribute_taxonomy_term->taxonomy;
$attribute_taxonomy_label = isset( $attribute_taxonomies_label[ $attribute_taxonomy ] ) ? $attribute_taxonomies_label[ $attribute_taxonomy ] : '';
if ( empty( $attribute_taxonomy_label ) ) {
continue;
}
$attribute_term_id = $attribute_taxonomy_term->term_id;
$attribute_term_name = $attribute_taxonomy_term->name;
$attribute_title = __( 'Attribute=', 'woocommerce-smart-coupons' ) . $attribute_taxonomy_label . ':' . __( 'Value=', 'woocommerce-smart-coupons' ) . $attribute_term_name;
$attribute_label = $attribute_taxonomy_label . ': ' . $attribute_term_name;
$attribute_options[ $attribute_term_id ] = array(
'title' => $attribute_title,
'label' => $attribute_label,
);
}
}
}
}
?>
<div class="options_group smart-coupons-field">
<p class="form-field">
<label for="wc_sc_product_attribute_ids"><?php echo esc_html__( 'Product attributes', 'woocommerce-smart-coupons' ); ?></label>
<select id="wc_sc_product_attribute_ids" name="wc_sc_product_attribute_ids[]" style="width: 50%;" class="wc-enhanced-select" multiple="multiple" data-placeholder="<?php esc_attr_e( 'No product attributes', 'woocommerce-smart-coupons' ); ?>">
<?php
if ( ! empty( $attribute_options ) ) {
foreach ( $attribute_options as $attribute_id => $attribute_data ) {
echo '<option title="' . esc_attr( $attribute_data['title'] ) . '" value="' . esc_attr( $attribute_id ) . '"' . esc_attr( selected( in_array( (string) $attribute_id, $product_attribute_ids, true ), true, false ) ) . '>' . esc_html( $attribute_data['label'] ) . '</option>';
}
}
?>
</select>
<?php
/* translators: Non product type coupon labels */
$tooltip_text = sprintf( esc_html__( 'Product attributes that the coupon will be applied to, or that need to be in the cart in order for the %s to be applied.', 'woocommerce-smart-coupons' ), $non_product_coupon_types_label );
echo wc_help_tip( $tooltip_text ); // phpcs:ignore
?>
</p>
</div>
<div class="options_group smart-coupons-field">
<p class="form-field">
<label for="wc_sc_exclude_product_attribute_ids"><?php echo esc_html__( 'Exclude attributes', 'woocommerce-smart-coupons' ); ?></label>
<select id="wc_sc_exclude_product_attribute_ids" name="wc_sc_exclude_product_attribute_ids[]" style="width: 50%;" class="wc-enhanced-select" multiple="multiple" data-placeholder="<?php esc_attr_e( 'No product attributes', 'woocommerce-smart-coupons' ); ?>">
<?php
if ( ! empty( $attribute_options ) ) {
foreach ( $attribute_options as $attribute_id => $attribute_data ) {
echo '<option title="' . esc_attr( $attribute_data['title'] ) . '" value="' . esc_attr( $attribute_id ) . '"' . esc_attr( selected( in_array( (string) $attribute_id, $exclude_product_attribute_ids, true ), true, false ) ) . '>' . esc_html( $attribute_data['label'] ) . '</option>';
}
}
?>
</select>
<?php
/* translators: Non product type coupon labels */
$tooltip_text = sprintf( esc_html__( 'Product attributes that the coupon will not be applied to, or that cannot be in the cart in order for the %s to be applied.', 'woocommerce-smart-coupons' ), $non_product_coupon_types_label );
echo wc_help_tip( $tooltip_text ); // phpcs:ignore
?>
</p>
</div>
<?php
}
/**
* Save coupon by product attribute data in meta
*
* @param Integer $post_id The coupon post ID.
* @param WC_Coupon $coupon The coupon object.
*/
public function process_meta( $post_id = 0, $coupon = null ) {
if ( empty( $post_id ) ) {
return;
}
if ( is_null( $coupon ) || ! is_a( $coupon, 'WC_Coupon' ) ) {
$coupon = new WC_Coupon( $post_id );
}
$is_callable_coupon_update_meta = $this->is_callable( $coupon, 'update_meta_data' );
$product_attribute_ids = ( isset( $_POST['wc_sc_product_attribute_ids'] ) ) ? wc_clean( wp_unslash( $_POST['wc_sc_product_attribute_ids'] ) ) : array(); // phpcs:ignore
$product_attribute_ids = implode( '|', $product_attribute_ids ); // Store attribute ids as delimited data instead of serialized data.
if ( true === $is_callable_coupon_update_meta ) {
$coupon->update_meta_data( 'wc_sc_product_attribute_ids', $product_attribute_ids );
} else {
update_post_meta( $post_id, 'wc_sc_product_attribute_ids', $product_attribute_ids );
}
$exclude_product_attribute_ids = ( isset( $_POST['wc_sc_exclude_product_attribute_ids'] ) ) ? wc_clean( wp_unslash( $_POST['wc_sc_exclude_product_attribute_ids'] ) ) : array(); // phpcs:ignore
$exclude_product_attribute_ids = implode( '|', $exclude_product_attribute_ids ); // Store attribute ids as delimited data instead of serialized data.
if ( true === $is_callable_coupon_update_meta ) {
$coupon->update_meta_data( 'wc_sc_exclude_product_attribute_ids', $exclude_product_attribute_ids );
} else {
update_post_meta( $post_id, 'wc_sc_exclude_product_attribute_ids', $exclude_product_attribute_ids );
}
if ( $this->is_callable( $coupon, 'save' ) ) {
$coupon->save();
}
}
/**
* Function to validate coupons for against product attributes
*
* @param bool $valid Coupon validity.
* @param WC_Product|null $product Product object.
* @param WC_Coupon|null $coupon Coupon object.
* @param array|null $values Values.
* @return bool $valid
*/
public function validate( $valid = false, $product = null, $coupon = null, $values = null ) {
$backtrace = wp_list_pluck( debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ), 'function' ); // phpcs:ignore
// If coupon is already invalid, no need for further checks.
// Ignore this check if the discount type is a non-product-type discount.
if ( true !== $valid && ! in_array( 'handle_non_product_type_coupons', $backtrace, true ) ) {
return $valid;
}
if ( empty( $product ) || empty( $coupon ) ) {
return $valid;
}
if ( $this->is_wc_gte_30() ) {
$coupon_id = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_id' ) ) ) ? $coupon->get_id() : 0;
} else {
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
}
if ( ! empty( $coupon_id ) ) {
$coupon = ( ! empty( $coupon_id ) ) ? new WC_Coupon( $coupon_id ) : null;
if ( $this->is_callable( $coupon, 'get_meta' ) ) {
$product_attribute_ids = $coupon->get_meta( 'wc_sc_product_attribute_ids' );
$exclude_product_attribute_ids = $coupon->get_meta( 'wc_sc_exclude_product_attribute_ids' );
} else {
$product_attribute_ids = get_post_meta( $coupon_id, 'wc_sc_product_attribute_ids', true );
$exclude_product_attribute_ids = get_post_meta( $coupon_id, 'wc_sc_exclude_product_attribute_ids', true );
}
if ( ! empty( $product_attribute_ids ) || ! empty( $exclude_product_attribute_ids ) ) {
$current_product_attribute_ids = $this->get_product_attributes( $product );
if ( ! empty( $product_attribute_ids ) ) {
$product_attribute_ids = explode( '|', $product_attribute_ids );
}
$product_attribute_found = true;
if ( ! empty( $product_attribute_ids ) && is_array( $product_attribute_ids ) ) {
$common_attribute_ids = array_intersect( $product_attribute_ids, $current_product_attribute_ids );
if ( count( $common_attribute_ids ) > 0 ) {
$product_attribute_found = true;
} else {
$product_attribute_found = false;
}
}
if ( ! empty( $exclude_product_attribute_ids ) ) {
$exclude_product_attribute_ids = explode( '|', $exclude_product_attribute_ids );
}
$exclude_attribute_found = false;
if ( ! empty( $exclude_product_attribute_ids ) && is_array( $exclude_product_attribute_ids ) ) {
$common_exclude_attribute_ids = array_intersect( $exclude_product_attribute_ids, $current_product_attribute_ids );
if ( count( $common_exclude_attribute_ids ) > 0 ) {
$exclude_attribute_found = true;
} else {
$exclude_attribute_found = false;
}
}
if ( false === $product_attribute_found && false === $exclude_attribute_found ) {
$product_parent_id = is_callable( array( $product, 'get_parent_id' ) ) ? $product->get_parent_id() : 0;
if ( ! empty( $product_parent_id ) ) {
$parent_product = ( function_exists( 'wc_get_product' ) ) ? wc_get_product( $product_parent_id ) : null;
if ( ! empty( $parent_product ) ) {
$parent_product_attribute_ids = $this->get_product_attributes( $parent_product );
if ( apply_filters( 'wc_sc_check_parent_attributes', true, $product ) && ! empty( $product_attribute_ids ) && is_array( $product_attribute_ids ) ) {
$parent_product_attribute_id = array_intersect( $product_attribute_ids, $parent_product_attribute_ids );
if ( count( $parent_product_attribute_id ) > 0 ) {
$product_attribute_found = true;
} else {
$product_attribute_found = false;
}
}
if ( apply_filters( 'wc_sc_check_parent_attributes', true, $product ) && ! empty( $exclude_product_attribute_ids ) && is_array( $exclude_product_attribute_ids ) ) {
$exclude_parent_product_attribute_id = array_intersect( $exclude_product_attribute_ids, $parent_product_attribute_ids );
if ( count( $exclude_parent_product_attribute_id ) > 0 ) {
$exclude_attribute_found = true;
} else {
$exclude_attribute_found = false;
}
}
}
}
}
$valid = ( $product_attribute_found && ! $exclude_attribute_found ) ? true : false;
}
}
return $valid;
}
/**
* Function to get product attributes of a given product.
*
* @param WC_Product $product Product.
* @return array $product_attributes_ids IDs of product attributes
*/
public function get_product_attributes( $product = null ) {
$product_attributes_ids = array();
if ( ! is_a( $product, 'WC_Product' ) ) {
// Check if product id has been passed.
if ( is_numeric( $product ) ) {
$product = wc_get_product( $product );
}
}
if ( ! is_a( $product, 'WC_Product' ) ) {
return $product_attribute_ids;
}
$product_attributes = $product->get_attributes();
if ( ! empty( $product_attributes ) ) {
if ( true === $product->is_type( 'variation' ) ) {
foreach ( $product_attributes as $variation_taxonomy => $variation_slug ) {
$variation_attribute = get_term_by( 'slug', $variation_slug, $variation_taxonomy );
if ( is_object( $variation_attribute ) ) {
$product_attributes_ids[] = $variation_attribute->term_id;
}
}
} else {
$product_id = ( is_object( $product ) && is_callable( array( $product, 'get_id' ) ) ) ? $product->get_id() : 0;
if ( ! empty( $product_id ) ) {
foreach ( $product_attributes as $attribute ) {
if ( isset( $attribute['is_taxonomy'] ) && ! empty( $attribute['is_taxonomy'] ) ) {
$attribute_taxonomy_name = $attribute['name'];
$product_term_ids = wc_get_product_terms( $product_id, $attribute_taxonomy_name, array( 'fields' => 'ids' ) );
if ( ! empty( $product_term_ids ) && is_array( $product_term_ids ) ) {
foreach ( $product_term_ids as $product_term_id ) {
$product_attributes_ids[] = $product_term_id;
}
}
}
}
}
}
}
return $product_attributes_ids;
}
/**
* Function to validate non product type coupons against product attribute restriction
* We need to remove coupon if it does not pass attribute validation even for single cart item in case of non product type coupons e.g fixed_cart, smart_coupon since these coupon type require all products in the cart to be valid
*
* @param boolean $valid Coupon validity.
* @param WC_Coupon $coupon Coupon object.
* @param WC_Discounts $discounts Discounts object.
* @throws Exception Validation exception.
* @return boolean $valid Coupon validity
*/
public function handle_non_product_type_coupons( $valid = true, $coupon = null, $discounts = null ) {
// If coupon is already invalid, no need for further checks.
if ( true !== $valid ) {
return $valid;
}
if ( ! is_a( $coupon, 'WC_Coupon' ) ) {
return $valid;
}
if ( $this->is_wc_gte_30() ) {
$coupon_id = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_id' ) ) ) ? $coupon->get_id() : 0;
$discount_type = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_discount_type' ) ) ) ? $coupon->get_discount_type() : '';
} else {
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
}
if ( ! empty( $coupon_id ) ) {
if ( $this->is_callable( $coupon, 'get_meta' ) ) {
$product_attribute_ids = $coupon->get_meta( 'wc_sc_product_attribute_ids' );
$exclude_product_attribute_ids = $coupon->get_meta( 'wc_sc_exclude_product_attribute_ids' );
} else {
$product_attribute_ids = get_post_meta( $coupon_id, 'wc_sc_product_attribute_ids', true );
$exclude_product_attribute_ids = get_post_meta( $coupon_id, 'wc_sc_exclude_product_attribute_ids', true );
}
// If product attributes are not set in coupon, stop further processing and return from here.
if ( empty( $product_attribute_ids ) && empty( $exclude_product_attribute_ids ) ) {
return $valid;
}
} else {
return $valid;
}
$product_coupon_types = wc_get_product_coupon_types();
// Proceed if it is non product type coupon.
if ( ! in_array( $discount_type, $product_coupon_types, true ) ) {
if ( class_exists( 'WC_Discounts' ) && isset( WC()->cart ) ) {
$wc_cart = WC()->cart;
$wc_discounts = new WC_Discounts( $wc_cart );
$items_to_validate = array();
if ( is_callable( array( $wc_discounts, 'get_items_to_validate' ) ) ) {
$items_to_validate = $wc_discounts->get_items_to_validate();
} elseif ( is_callable( array( $wc_discounts, 'get_items' ) ) ) {
$items_to_validate = $wc_discounts->get_items();
} elseif ( isset( $wc_discounts->items ) && is_array( $wc_discounts->items ) ) {
$items_to_validate = $wc_discounts->items;
}
if ( ! empty( $items_to_validate ) && is_array( $items_to_validate ) ) {
$valid_products = array();
$invalid_products = array();
foreach ( $items_to_validate as $item ) {
$cart_item = clone $item; // Clone the item so changes to wc_discounts item do not affect the originals.
$item_product = isset( $cart_item->product ) ? $cart_item->product : null;
$item_object = isset( $cart_item->object ) ? $cart_item->object : null;
if ( ! is_null( $item_product ) && ! is_null( $item_object ) ) {
if ( $coupon->is_valid_for_product( $item_product, $item_object ) ) {
$valid_products[] = $item_product;
} else {
$invalid_products[] = $item_product;
}
}
}
// If cart does not have any valid product then throw Exception.
if ( 0 === count( $valid_products ) ) {
$error_message = __( 'Sorry, this coupon is not applicable to selected products.', 'woocommerce-smart-coupons' );
$error_code = defined( 'E_WC_COUPON_NOT_APPLICABLE' ) ? E_WC_COUPON_NOT_APPLICABLE : 0;
throw new Exception( $error_message, $error_code );
} elseif ( count( $invalid_products ) > 0 && ! empty( $exclude_product_attribute_ids ) ) {
$exclude_product_attribute_ids = explode( '|', $exclude_product_attribute_ids );
$excluded_products = array();
foreach ( $invalid_products as $invalid_product ) {
$product_attributes = $this->get_product_attributes( $invalid_product );
if ( ! empty( $product_attributes ) && is_array( $product_attributes ) ) {
$common_exclude_attribute_ids = array_intersect( $exclude_product_attribute_ids, $product_attributes );
if ( count( $common_exclude_attribute_ids ) > 0 ) {
$excluded_products[] = $invalid_product->get_name();
} else {
$product_parent_id = is_callable( array( $invalid_product, 'get_parent_id' ) ) ? $invalid_product->get_parent_id() : 0;
if ( ! empty( $product_parent_id ) ) {
$parent_product = ( function_exists( 'wc_get_product' ) ) ? wc_get_product( $product_parent_id ) : '';
if ( ! empty( $parent_product ) ) {
$parent_product_attribute_ids = $this->get_product_attributes( $parent_product );
if ( apply_filters( 'wc_sc_check_parent_attributes', true, $invalid_product ) && ! empty( $exclude_product_attribute_ids ) && is_array( $exclude_product_attribute_ids ) ) {
$exclude_parent_product_attribute_id = array_intersect( $exclude_product_attribute_ids, $parent_product_attribute_ids );
if ( count( $exclude_parent_product_attribute_id ) > 0 ) {
$excluded_products[] = $invalid_product->get_name();
}
}
}
}
}
}
}
if ( count( $excluded_products ) > 0 ) {
// If cart contains any excluded product and it is being excluded from our excluded product attributes then throw Exception.
/* translators: 1. Singular/plural label for product(s) 2. Excluded product names */
$error_message = sprintf( __( 'Sorry, this coupon is not applicable to the %1$s: %2$s.', 'woocommerce-smart-coupons' ), _n( 'product', 'products', count( $excluded_products ), 'woocommerce-smart-coupons' ), implode( ', ', $excluded_products ) );
$error_code = defined( 'E_WC_COUPON_EXCLUDED_PRODUCTS' ) ? E_WC_COUPON_EXCLUDED_PRODUCTS : 0;
throw new Exception( $error_message, $error_code );
}
}
}
}
}
return $valid;
}
/**
* Add meta in export headers
*
* @param array $headers Existing headers.
* @return array
*/
public function export_headers( $headers = array() ) {
$headers['wc_sc_product_attribute_ids'] = __( 'Product Attributes', 'woocommerce-smart-coupons' );
$headers['wc_sc_exclude_product_attribute_ids'] = __( 'Exclude Attributes', 'woocommerce-smart-coupons' );
return $headers;
}
/**
* Post meta defaults for product attribute ids meta
*
* @param array $defaults Existing postmeta defaults.
* @return array $defaults Modified postmeta defaults
*/
public function postmeta_defaults( $defaults = array() ) {
$defaults['wc_sc_product_attribute_ids'] = '';
$defaults['wc_sc_exclude_product_attribute_ids'] = '';
return $defaults;
}
/**
* Make meta data of product attribute ids protected
*
* @param bool $protected Is protected.
* @param string $meta_key The meta key.
* @param string $meta_type The meta type.
* @return bool $protected
*/
public function make_action_meta_protected( $protected = false, $meta_key = '', $meta_type = '' ) {
$sc_product_attribute_keys = array(
'wc_sc_product_attribute_ids',
'wc_sc_exclude_product_attribute_ids',
);
if ( in_array( $meta_key, $sc_product_attribute_keys, true ) ) {
return true;
}
return $protected;
}
/**
* Add product's attribute in coupon meta
*
* @param array $data The row data.
* @param array $post The POST values.
* @return array Modified data
*/
public function generate_coupon_attribute_meta( $data = array(), $post = array() ) {
$product_attribute_ids = ( isset( $post['wc_sc_product_attribute_ids'] ) ) ? wc_clean( wp_unslash( $post['wc_sc_product_attribute_ids'] ) ) : array(); // phpcs:ignore
$data['wc_sc_product_attribute_ids'] = implode( '|', $product_attribute_ids ); // Store attribute ids as delimited data instead of serialized data.
$exclude_product_attribute_ids = ( isset( $post['wc_sc_exclude_product_attribute_ids'] ) ) ? wc_clean( wp_unslash( $post['wc_sc_exclude_product_attribute_ids'] ) ) : array(); // phpcs:ignore
$data['wc_sc_exclude_product_attribute_ids'] = implode( '|', $exclude_product_attribute_ids ); // Store attribute ids as delimited data instead of serialized data.
return $data;
}
/**
* Function to copy product's attribute meta in newly generated coupon
*
* @param array $args The arguments.
*/
public function copy_coupon_attributes_meta( $args = array() ) {
$new_coupon_id = ( ! empty( $args['new_coupon_id'] ) ) ? absint( $args['new_coupon_id'] ) : 0;
$coupon = ( ! empty( $args['ref_coupon'] ) ) ? $args['ref_coupon'] : false;
if ( empty( $new_coupon_id ) || empty( $coupon ) ) {
return;
}
if ( $this->is_wc_gte_30() ) {
$product_attribute_ids = $coupon->get_meta( 'wc_sc_product_attribute_ids' );
$exclude_product_attribute_ids = $coupon->get_meta( 'wc_sc_exclude_product_attribute_ids' );
} else {
$old_coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
$product_attribute_ids = get_post_meta( $old_coupon_id, 'wc_sc_product_attribute_ids', true );
$exclude_product_attribute_ids = get_post_meta( $old_coupon_id, 'wc_sc_exclude_product_attribute_ids', true );
}
$new_coupon = new WC_Coupon( $new_coupon_id );
if ( $this->is_callable( $new_coupon, 'update_meta_data' ) && $this->is_callable( $new_coupon, 'save' ) ) {
$new_coupon->update_meta_data( 'wc_sc_product_attribute_ids', $product_attribute_ids );
$new_coupon->update_meta_data( 'wc_sc_exclude_product_attribute_ids', $exclude_product_attribute_ids );
$new_coupon->save();
} else {
update_post_meta( $new_coupon_id, 'wc_sc_product_attribute_ids', $product_attribute_ids );
update_post_meta( $new_coupon_id, 'wc_sc_exclude_product_attribute_ids', $exclude_product_attribute_ids );
}
}
}
}
WC_SC_Coupons_By_Product_Attribute::get_instance();

View File

@@ -1,759 +0,0 @@
<?php
/**
* Class to handle feature Coupons By Product Quantity
*
* @category Admin
* @author StoreApps
* @package woocommerce-smart-coupons/includes
* @since 5.0.0
* @version 1.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Coupons_By_Product_Quantity' ) ) {
/**
* Class WC_SC_Coupons_By_Product_Quantity
*/
class WC_SC_Coupons_By_Product_Quantity {
/**
* Variable to hold instance of this class
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
private function __construct() {
add_action( 'woocommerce_coupon_options_usage_restriction', array( $this, 'usage_restriction' ), 99, 2 );
add_action( 'admin_footer', array( $this, 'styles_and_scripts' ) );
add_action( 'woocommerce_coupon_options_save', array( $this, 'process_meta' ), 10, 2 );
add_filter( 'woocommerce_coupon_is_valid', array( $this, 'validate' ), 11, 3 );
}
/**
* Get single instance of this class
*
* @return this class Singleton object of this class
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name = '', $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Display field for coupon by product quantity
*
* @param integer $coupon_id The coupon id.
* @param WC_Coupon $coupon The coupon object.
*/
public function usage_restriction( $coupon_id = 0, $coupon = null ) {
if ( ! is_a( $coupon, 'WC_Coupon' ) || empty( $coupon_id ) ) {
return;
}
if ( ! is_a( $coupon, 'WC_Coupon' ) ) {
$coupon = ( ! empty( $coupon_id ) ) ? new WC_Coupon( $coupon_id ) : null;
}
if ( $this->is_callable( $coupon, 'get_meta' ) ) {
$product_quantity_restrictions = $coupon->get_meta( 'wc_sc_product_quantity_restrictions' );
} else {
$product_quantity_restrictions = $this->get_post_meta( $coupon_id, 'wc_sc_product_quantity_restrictions', true );
}
if ( ! is_array( $product_quantity_restrictions ) ) {
$product_quantity_restrictions = array();
}
$cart_min_quantity = ! empty( $product_quantity_restrictions['values']['cart']['min'] ) ? intval( $product_quantity_restrictions['values']['cart']['min'] ) : '';
$cart_max_quantity = ! empty( $product_quantity_restrictions['values']['cart']['max'] ) ? intval( $product_quantity_restrictions['values']['cart']['max'] ) : '';
$product_quantity_restrictions_type = ! empty( $product_quantity_restrictions['type'] ) ? $product_quantity_restrictions['type'] : 'cart';
?>
<div class="options_group smart-coupons-field">
<h3 class="smart-coupons-field" style="padding-left: 10px;"><?php echo esc_html__( 'Product quantity based restrictions', 'woocommerce-smart-coupons' ); ?></h3>
<p class="form-field">
<span class='left_column'><label><?php echo esc_html__( 'Validate quantity of', 'woocommerce-smart-coupons' ); ?></label></span>
<label for="wc_sc_product_quantity_type_cart" class="cart_quantity">
<input type="radio" name="wc_sc_product_quantity_restrictions[type]" id="wc_sc_product_quantity_type_cart" class="wc_sc_product_quantity_type wc_sc_product_quantity_type_cart" value="cart" <?php checked( 'cart', $product_quantity_restrictions_type, true ); ?> />
<?php echo esc_html__( 'Cart', 'woocommerce-smart-coupons' ); ?>
</label>
<label for="wc_sc_product_quantity_type_product" class="product_quantity">
<input type="radio" name="wc_sc_product_quantity_restrictions[type]" id="wc_sc_product_quantity_type_product" class="wc_sc_product_quantity_type wc_sc_product_quantity_type_product" value="product" <?php checked( 'product', $product_quantity_restrictions_type, true ); ?>>
<?php echo esc_html__( 'Product', 'woocommerce-smart-coupons' ); ?>
</label>
<?php
$tooltip_text = esc_html__( 'Choose whether to validate the quantity, cart-wise or product-wise', 'woocommerce-smart-coupons' );
echo wc_help_tip($tooltip_text); // phpcs:ignore ?>
</p>
<p class="form-field wc_sc_cart_quantity" style="<?php echo ( 'cart' === $product_quantity_restrictions_type ) ? '' : 'display: none;'; ?>">
<label for="wc_sc_min_product_quantity"><?php echo esc_html__( 'Minimum quantity', 'woocommerce-smart-coupons' ); ?></label>
<input type="number" name="wc_sc_product_quantity_restrictions[values][cart][min]" id="wc_sc_min_product_quantity" class="wc_sc_min_product_quantity" placeholder="<?php echo esc_attr__( 'No minimum', 'woocommerce-smart-coupons' ); ?>" value="<?php echo esc_attr( $cart_min_quantity ); ?>" min="0">
</p>
<p class="form-field wc_sc_cart_quantity" style="<?php echo ( 'cart' === $product_quantity_restrictions_type ) ? '' : 'display: none;'; ?>">
<label for="wc_sc_max_product_quantity"><?php echo esc_html__( 'Maximum quantity', 'woocommerce-smart-coupons' ); ?></label>
<input type="number" name="wc_sc_product_quantity_restrictions[values][cart][max]" id="wc_sc_max_product_quantity" class="wc_sc_max_product_quantity" placeholder="<?php echo esc_attr__( 'No maximum', 'woocommerce-smart-coupons' ); ?>" value="<?php echo esc_attr( $cart_max_quantity ); ?>" min="0">
</p>
<div class=" wc_sc_product_quantity" style="<?php echo isset( $product_quantity_restrictions['type'] ) && ( 'product' === $product_quantity_restrictions['type'] ) ? '' : 'display: none;'; ?>">
<?php
$product_quantities = ! empty( $product_quantity_restrictions['values']['product'] ) ? $product_quantity_restrictions['values']['product'] : array();
if ( ! empty( $product_quantities ) ) {
$display_label = true;
foreach ( $product_quantities as $product_id => $value ) {
if ( 0 !== $product_id ) {
$product = wc_get_product( $product_id );
if ( ! empty( $product ) && is_object( $product ) ) {
$product_name = is_callable( array( $product, 'get_name' ) ) ? $product->get_name() : '';
$product_max_quantity = ! empty( $value['max'] ) ? intval( $value['max'] ) : '';
$product_min_quantity = ! empty( $value['min'] ) ? intval( $value['min'] ) : '';
?>
<p class="form-field" data-index="<?php echo esc_attr( $product_id ); ?>">
<?php if ( true === $display_label ) { ?>
<label><?php echo esc_html__( 'Products', 'woocommerce-smart-coupons' ); ?></label>
<?php } ?>
<span>
<input type="text" name="wc_sc_product_quantity_restrictions[values][product][<?php echo esc_attr( $product_id ); ?>][product_id]" placeholder="<?php echo esc_attr( $product_id ); ?>" value="<?php echo esc_attr( $product_name ); ?>" disabled>
<input type="number" name="wc_sc_product_quantity_restrictions[values][product][<?php echo esc_attr( $product_id ); ?>][min]" class="product_min_quantity_field" placeholder="<?php echo esc_attr__( 'No minimum', 'woocommerce-smart-coupons' ); ?>" value="<?php echo esc_attr( $product_min_quantity ); ?>" min="0">
<input type="hidden" name="wc_sc_product_quantity_restrictions[values][product][<?php echo esc_attr( $product_id ); ?>][max]" class="product_max_quantity_field" placeholder="<?php echo esc_attr__( 'No maximum', 'woocommerce-smart-coupons' ); ?>" value="<?php echo esc_attr( $product_max_quantity ); ?>" min="0">
</span>
</p>
<?php
}
}
$display_label = false;
}
} else {
?>
<p class="form-field">
<span class='left_column'><label><?php echo esc_html__( 'Products', 'woocommerce-smart-coupons' ); ?></label></span>
<label class="hypertext_css wc_sc_click_select_product">
<?php echo esc_html__( 'Please select some products', 'woocommerce-smart-coupons' ); ?>
</label>
</p>
<?php
}
?>
</div>
<div class=" wc_sc_category_quantity" style="<?php echo isset( $product_quantity_restrictions['type'] ) && ( 'product' === $product_quantity_restrictions['type'] ) ? '' : 'display: none;'; ?>">
<?php
$product_category_quantities = ! empty( $product_quantity_restrictions['values']['product_category'] ) ? $product_quantity_restrictions['values']['product_category'] : array();
if ( ! empty( $product_category_quantities ) ) {
$i = 0;
foreach ( $product_category_quantities as $category_id => $value ) {
if ( 0 !== $category_id ) {
$term = get_term_by( 'id', $category_id, 'product_cat', ARRAY_A );
if ( ! empty( $term ) && is_array( $term ) ) {
$category_name = ! empty( $term['name'] ) ? $term['name'] : '';
?>
<p class="form-field" data-index="<?php echo esc_attr( $category_id ); ?>">
<?php if ( 0 === $i ) { ?>
<label><?php echo esc_html__( 'Categories', 'woocommerce-smart-coupons' ); ?></label>
<?php } ?>
<span>
<input type="text" name="wc_sc_product_quantity_restrictions[values][product_category][<?php echo esc_attr( $category_id ); ?>][category_id]" placeholder="<?php echo esc_attr( $category_id ); ?>" value="<?php echo esc_attr( $category_name ); ?>" disabled>
<input type="number" name="wc_sc_product_quantity_restrictions[values][product_category][<?php echo esc_attr( $category_id ); ?>][min]" class="product_min_quantity_field" placeholder="<?php echo esc_attr__( 'No minimum', 'woocommerce-smart-coupons' ); ?>" value="<?php echo esc_attr( ! empty( $value['min'] ) ? intval( $value['min'] ) : '' ); ?>" min="0">
<input type="hidden" name="wc_sc_product_quantity_restrictions[values][product_category][<?php echo esc_attr( $category_id ); ?>][max]" class="product_max_quantity_field" placeholder="<?php echo esc_attr__( 'No maximum', 'woocommerce-smart-coupons' ); ?>" value="<?php echo esc_attr( ! empty( $value['max'] ) ? intval( $value['max'] ) : '' ); ?>" min="0">
</span>
</p>
<?php
}
}
$i++;
}
} else {
?>
<p class="form-field">
<span class='left_column'><label><?php echo esc_html__( 'Categories', 'woocommerce-smart-coupons' ); ?></label></span>
<label for="product_categories" class="hypertext_css">
<?php echo esc_html__( 'Please select some categories', 'woocommerce-smart-coupons' ); ?>
</label>
</p>
<?php
}
?>
</div>
</div>
<div class="wc_sc_auto_generate_product_quantity" style="display: none;">
<p class="form-field" data-index="{i}">
<label>{p}</label>
<span>
<input type="text" name="wc_sc_product_quantity_restrictions[values][product][{i}][product_id]" placeholder="{i}" value="{n}" disabled>
<input type="number" name="wc_sc_product_quantity_restrictions[values][product][{i}][min]" class="product_min_quantity_field" placeholder="<?php echo esc_attr__( 'No minimum', 'woocommerce-smart-coupons' ); ?>" min="0">
<input type="hidden" name="wc_sc_product_quantity_restrictions[values][product][{i}][max]" class="product_max_quantity_field" placeholder="<?php echo esc_attr__( 'No maximum', 'woocommerce-smart-coupons' ); ?>" min="0">
</span>
</p>
</div>
<div class="wc_sc_auto_generate_category_quantity" style="display: none;">
<p class="form-field" data-index="{i}">
<label>{c}</label>
<span>
<input type="text" name="wc_sc_product_quantity_restrictions[values][product_category][{i}][category_id]" placeholder="{i}" value="{n}" disabled>
<input type="number" name="wc_sc_product_quantity_restrictions[values][product_category][{i}][min]" class="product_min_quantity_field" placeholder="<?php echo esc_attr__( 'No minimum', 'woocommerce-smart-coupons' ); ?>" min="0">
<input type="hidden" name="wc_sc_product_quantity_restrictions[values][product_category][{i}][max]" class="product_max_quantity_field" placeholder="<?php echo esc_attr__( 'No maximum', 'woocommerce-smart-coupons' ); ?>" min="0">
</span>
</p>
</div>
<div class="wc_sc_empty_products" style="display: none;">
<p class="form-field">
<span class='left_column'><label><?php echo esc_html__( 'Products', 'woocommerce-smart-coupons' ); ?></label></span>
<label class="hypertext_css wc_sc_click_select_product">
<?php echo esc_html__( 'Please select some products', 'woocommerce-smart-coupons' ); ?>
</label>
</p>
</div>
<div class="wc_sc_empty_categories" style="display: none;">
<p class="form-field">
<span class='left_column'><label><?php echo esc_html__( 'Categories', 'woocommerce-smart-coupons' ); ?></label></span>
<label for="product_categories" class="hypertext_css">
<?php echo esc_html__( 'Please select some categories', 'woocommerce-smart-coupons' ); ?>
</label>
</p>
</div>
<div class="wc_sc_product_section_title" style="display: none;">
<?php echo esc_html__( 'Products', 'woocommerce-smart-coupons' ); ?>
</div>
<div class="wc_sc_category_section_title" style="display: none;">
<?php echo esc_html__( 'Categories', 'woocommerce-smart-coupons' ); ?>
</div>
<?php
}
/**
* Styles and scripts
*/
public function styles_and_scripts() {
if ( ! wp_script_is( 'jquery' ) ) {
wp_enqueue_script( 'jquery' );
}
?>
<style type="text/css">
.wc_sc_product_quantity_type_product {
margin-left: 10px !important;
}
.product_min_quantity_field {
width: 15% !important;
margin-left: 10px !important;
}
.hypertext_css {
width: 50% !important;
color: #1870f0 !important;
text-decoration: underline !important;
width: 275px !important;
margin-left: 1px !important;
}
.width_32{
width: 32% !important;
}
.padding_left_3{
padding-left: 3px;
}
label.cart_quantity{
width: 75px !important;
margin-left: 1px !important;
}
label.product_quantity {
margin-left: 0px !important;
}
</style>
<script type="text/javascript">
jQuery(document).ready(function ($) {
/**
*Change quantity type cart or product.
*/
$(document).on('change', '.wc_sc_product_quantity_type', function () {
let value = $('input[name="wc_sc_product_quantity_restrictions[type]"]:checked').val();
if ("product" === value) {
$('.wc_sc_cart_quantity').hide();
$('.wc_sc_product_quantity, .wc_sc_category_quantity').show();
} else {
$('.wc_sc_cart_quantity').show();
$('.wc_sc_product_quantity, .wc_sc_category_quantity').hide();
}
});
/**
*Auto add product field.
*/
$(document).on('change', 'select[name="product_ids[]"]', function () {
var product_element_count = 0;
$('.wc_sc_product_quantity').empty();
let options = $("select[name='product_ids[]'] option:selected").val();
if( options === undefined ){
let product_empty = $('.wc_sc_empty_products').html();
$('.wc_sc_product_quantity').append(product_empty);
}
$("select[name='product_ids[]'] option:selected").each(function () {
var $this = $(this);
if ($this.length) {
product_element_count = parseInt(product_element_count) + parseInt(1);
let product_name = $this.text();
let product_id = $this.val();
let section_title = $('.wc_sc_product_section_title').text();
let wc_sc_product_quantity = $('.wc_sc_auto_generate_product_quantity').html();
wc_sc_product_quantity = wc_sc_product_quantity.replace(new RegExp('{i}', 'g'), product_id);
wc_sc_product_quantity = wc_sc_product_quantity.replace(new RegExp('{n}', 'g'), product_name);
if (product_element_count >= 2) {
wc_sc_product_quantity = wc_sc_product_quantity.replace(new RegExp('{p}', 'g'), '');
} else {
wc_sc_product_quantity = wc_sc_product_quantity.replace(new RegExp('{p}', 'g'), section_title);
}
$('.wc_sc_product_quantity').append(wc_sc_product_quantity);
}
});
});
/**
*Auto add category field.
*/
$(document).on('change', 'select[name="product_categories[]"]', function () {
var category_element_count = 0;
$('.wc_sc_category_quantity').empty();
let options = $("#product_categories option:selected").val();
if( options === undefined ){
let category_empty = $('.wc_sc_empty_categories').html();
$('.wc_sc_category_quantity').append(category_empty);
}
$("#product_categories option:selected").each(function () {
var $this = $(this);
if ($this.length) {
category_element_count = parseInt(category_element_count) + parseInt(1);
let category_name = $this.text();
let category_id = $this.val();
let section_title = $('.wc_sc_category_section_title').text();
let wc_sc_category_quantity = $('.wc_sc_auto_generate_category_quantity').html();
wc_sc_category_quantity = wc_sc_category_quantity.replace(new RegExp('{i}', 'g'), category_id);
wc_sc_category_quantity = wc_sc_category_quantity.replace(new RegExp('{n}', 'g'), category_name);
if (category_element_count >= 2) {
wc_sc_category_quantity = wc_sc_category_quantity.replace(new RegExp('{c}', 'g'), '');
} else {
wc_sc_category_quantity = wc_sc_category_quantity.replace(new RegExp('{c}', 'g'), section_title);
}
$('.wc_sc_category_quantity').append(wc_sc_category_quantity);
}
});
});
$("body").on('click', '.wc_sc_click_select_product', function() {
$(".wc-product-search").parent('p:nth-child(1)').css('background-color', '#ffffcc').animate({
backgroundColor: 'transparent'
}, 2000);
$('html, body').animate({
'scrollTop' : $(".wc-product-search").parent('p:nth-child(1)').position().top,
});
});
});
</script>
<?php
}
/**
* Save coupon by product quantity data in meta
*
* @param Integer $post_id The coupon post ID.
* @param WC_Coupon $coupon The coupon object.
*/
public function process_meta( $post_id = 0, $coupon = null ) {
if ( empty( $post_id ) ) {
return;
}
if ( is_null( $coupon ) || ! is_a( $coupon, 'WC_Coupon' ) ) {
$coupon = new WC_Coupon( $post_id );
}
$product_quantity_restrictions = (isset($_POST['wc_sc_product_quantity_restrictions'])) ? wc_clean(wp_unslash($_POST['wc_sc_product_quantity_restrictions'])) : array(); // phpcs:ignore
if ( ! isset( $product_quantity_restrictions['condition'] ) ) {
$product_quantity_restrictions['condition'] = 'any'; // Values: any, all.
}
if ( isset( $product_quantity_restrictions['values']['product']['{i}'] ) ) {
unset( $product_quantity_restrictions['values']['product']['{i}'] );
}
if ( isset( $product_quantity_restrictions['values']['product_category']['{i}'] ) ) {
unset( $product_quantity_restrictions['values']['product_category']['{i}'] );
}
if ( ! empty( $product_quantity_restrictions ) ) {
foreach ( $product_quantity_restrictions as $restriction_key => $restrictions ) {
if ( 'values' === $restriction_key ) {
// Max quantity feature not included for product quantity.
foreach ( $restrictions['product'] as $id => $restriction ) {
$id = absint( $id );
if ( 0 !== $id && isset( $product_quantity_restrictions['values']['product'][ $id ]['max'] ) ) {
$product_quantity_restrictions['values']['product'][ $id ]['max'] = ! empty( $restriction['min'] ) ? intval( $restriction['min'] ) : '';
}
}
// Max quantity feature not included for product category quantity.
foreach ( $restrictions['product_category'] as $id => $restriction ) {
$id = absint( $id );
if ( 0 !== $id && isset( $product_quantity_restrictions['values']['product_category'][ $id ]['max'] ) ) {
$product_quantity_restrictions['values']['product_category'][ $id ]['max'] = ! empty( $restriction['min'] ) ? intval( $restriction['min'] ) : '';
}
}
}
}
}
if ( $this->is_callable( $coupon, 'update_meta_data' ) && $this->is_callable( $coupon, 'save' ) ) {
$coupon->update_meta_data( 'wc_sc_product_quantity_restrictions', $product_quantity_restrictions );
$coupon->save();
} else {
$this->update_post_meta( $post_id, 'wc_sc_product_quantity_restrictions', $product_quantity_restrictions );
}
}
/**
* Validate the coupon based on product quantity
*
* @param boolean $valid Is valid or not.
* @param WC_Coupon $coupon The coupon object.
* @param WC_Discounts $wc_discounts The discounts object.
*
* @return boolean Is valid or not
* @throws Exception If the coupon is invalid.
*/
public function validate( $valid = false, $coupon = null, $wc_discounts = null ) {
// If coupon is invalid already, no need for further checks.
if ( false === $valid ) {
return $valid;
}
if ( ! is_a( $coupon, 'WC_Coupon' ) ) {
return $valid;
}
if ( ! is_a( $wc_discounts, 'WC_Discounts' ) ) {
return $valid;
}
$items_to_validate = array();
$cart_quantity = 0;
if ( is_callable( array( $wc_discounts, 'get_items_to_validate' ) ) ) {
$items_to_validate = $wc_discounts->get_items_to_validate();
} else {
return $valid;
}
if ( ! empty( $items_to_validate ) ) {
foreach ( $items_to_validate as $key => $cart_content ) {
$cart_item = ! empty( $cart_content->object ) ? $cart_content->object : array();
$cart_quantity += ! empty( $cart_item['quantity'] ) ? intval( $cart_item['quantity'] ) : 0;
}
} else {
return $valid;
}
// If the cart quantity is empty the rule will not work.
if ( $cart_quantity <= 0 ) {
return $valid;
}
$coupon_id = is_callable( array( $coupon, 'get_id' ) ) ? $coupon->get_id() : 0;
if ( $this->is_callable( $coupon, 'get_meta' ) ) {
$product_quantity_restrictions = $coupon->get_meta( 'wc_sc_product_quantity_restrictions' );
} else {
$product_quantity_restrictions = get_post_meta( $coupon_id, 'wc_sc_product_quantity_restrictions', true );
}
if ( is_array( $product_quantity_restrictions ) && ! empty( $product_quantity_restrictions ) ) {
$type = ! empty( $product_quantity_restrictions['type'] ) ? $product_quantity_restrictions['type'] : '';
$values = ! empty( $product_quantity_restrictions['values'] ) ? $product_quantity_restrictions['values'] : '';
$condition = ! empty( $product_quantity_restrictions['condition'] ) ? $product_quantity_restrictions['condition'] : 'any';
switch ( $type ) {
case 'cart':
$min = ! empty( $product_quantity_restrictions['values']['cart']['min'] ) ? intval( $product_quantity_restrictions['values']['cart']['min'] ) : 0;
$max = ! empty( $product_quantity_restrictions['values']['cart']['max'] ) ? intval( $product_quantity_restrictions['values']['cart']['max'] ) : 0;
$messages = array(
__( 'Your cart does not meet the quantity requirement.', 'woocommerce-smart-coupons' ),
);
if ( empty( $min ) && empty( $max ) ) {
return $valid;
} elseif ( empty( $min ) && ! empty( $max ) && $cart_quantity <= $max ) {
return $valid;
} elseif ( empty( $max ) && ! empty( $min ) && $cart_quantity >= $min ) {
return $valid;
} elseif ( ! empty( $min ) && ! empty( $max ) && $cart_quantity >= $min && $cart_quantity <= $max ) {
return $valid;
} else {
if ( $cart_quantity > $max ) {
/* translators: 1. Number of quantity 2. Singular or plural text based on number of quantities */
$messages[] = sprintf( __( 'Your cart should have a maximum of %1$d %2$s in total.', 'woocommerce-smart-coupons' ), $max, _n( 'quantity', 'quantities', $max ) );
}
if ( $cart_quantity < $min ) {
/* translators: 1. Number of quantity 2. Singular or plural text based on number of quantities */
$messages[] = sprintf( __( 'Your cart should have a minimum of %1$d %2$s in total.', 'woocommerce-smart-coupons' ), $min, _n( 'quantity', 'quantities', $min ) );
}
throw new Exception( implode( ' ', $messages ) );
}
break;
default:
case 'product':
$product_quantity_restrictions = ! empty( $values['product'] ) ? $values['product'] : array();
$product_category_quantity_restrictions = ! empty( $values['product_category'] ) ? $values['product_category'] : array();
$params = array(
'condition' => $condition,
'items_to_validate' => $items_to_validate,
);
$product_condition = $this->process_product_quantities( $product_quantity_restrictions, $params );
$product_category_condition = $this->process_category_quantities( $product_category_quantity_restrictions, $params );
if ( false === $product_condition && false === $product_category_condition ) {
throw new Exception( __( 'Your cart does not meet the product quantity requirement.', 'woocommerce-smart-coupons' ) );
} elseif ( 'empty' === $product_condition && false === $product_category_condition ) {
throw new Exception( __( 'Your cart does not meet the product quantity requirement.', 'woocommerce-smart-coupons' ) );
} elseif ( false === $product_condition && 'empty' === $product_category_condition ) {
throw new Exception( __( 'Your cart does not meet the product quantity requirement.', 'woocommerce-smart-coupons' ) );
}
break;
}
}
return $valid;
}
/**
* Process cart product quantities
*
* @param array $product_quantity_restrictions values.
* @param array $params condition and cart contents.
* @return bool
* @throws Exception If empty product quantities.
*/
public function process_product_quantities( $product_quantity_restrictions = array(), $params = array() ) {
if ( ! empty( $product_quantity_restrictions ) ) {
$status = array();
$condition = ! empty( $params['condition'] ) ? $params['condition'] : 'any';
$items_to_validate = ! empty( $params['items_to_validate'] ) ? $params['items_to_validate'] : array();
foreach ( $product_quantity_restrictions as $id => $restriction ) {
if ( 0 === $id ) {
continue;
}
$min_quantity = ! empty( $restriction['min'] ) ? intval( $restriction['min'] ) : 0;
$max_quantity = ! empty( $restriction['max'] ) ? intval( $restriction['max'] ) : 0;
$cart_product_quantities = $this->cart_product_quantities( $items_to_validate );
$product_quantity = ! empty( $cart_product_quantities[ $id ] ) ? intval( $cart_product_quantities[ $id ] ) : 1;
if ( empty( $min_quantity ) && empty( $max_quantity ) ) {
$status[] = 'empty';
} elseif ( empty( $min_quantity ) && ! empty( $max_quantity ) && $product_quantity <= $max_quantity ) {
$status[] = 'true';
} elseif ( empty( $max_quantity ) && ! empty( $min_quantity ) && $product_quantity >= $min_quantity ) {
$status[] = 'true';
} elseif ( ! empty( $min_quantity ) && ! empty( $max_quantity ) && $product_quantity >= $min_quantity && $product_quantity <= $max_quantity ) {
$status[] = 'true';
} else {
$status[] = 'false';
}
}
switch ( $condition ) {
case 'all':
if ( in_array( 'false', $status, true ) ) {
return false;
} elseif ( in_array( 'true', $status, true ) ) {
return true;
} else {
return 'empty';
}
default:
case 'any':
if ( in_array( 'true', $status, true ) ) {
return true;
} elseif ( in_array( 'false', $status, true ) ) {
return false;
} else {
return 'empty';
}
}
}
return 'empty';
}
/**
* Process cart category quantities
*
* @param array $product_category_quantity_restrictions values.
* @param array $params condition and cart contents.
* @return bool
* @throws Exception If empty cart category quantities.
*/
public function process_category_quantities( $product_category_quantity_restrictions = array(), $params = array() ) {
if ( ! empty( $product_category_quantity_restrictions ) ) {
$status = array();
$condition = ! empty( $params['condition'] ) ? $params['condition'] : 'any';
$items_to_validate = ! empty( $params['items_to_validate'] ) ? $params['items_to_validate'] : array();
$cart_product_categories_quantities = $this->cart_product_categories_quantities( $items_to_validate );
foreach ( $product_category_quantity_restrictions as $id => $restriction ) {
$min_quantity = ! empty( $restriction['min'] ) ? intval( $restriction['min'] ) : '';
$max_quantity = ! empty( $restriction['max'] ) ? intval( $restriction['max'] ) : '';
if ( 0 === $id ) {
continue;
}
$category_quantity = ! empty( $cart_product_categories_quantities[ $id ] ) ? intval( $cart_product_categories_quantities[ $id ] ) : 0;
if ( empty( $min_quantity ) && empty( $max_quantity ) ) {
$status[] = 'empty';
} elseif ( empty( $min_quantity ) && ! empty( $max_quantity ) && $category_quantity <= $max_quantity ) {
$status[] = 'true';
} elseif ( empty( $max_quantity ) && ! empty( $min_quantity ) && $category_quantity >= $min_quantity ) {
$status[] = 'true';
} elseif ( ! empty( $min_quantity ) && ! empty( $max_quantity ) && $category_quantity >= $min_quantity && $category_quantity <= $max_quantity ) {
$status[] = 'true';
} else {
$status[] = 'false';
}
}
switch ( $condition ) {
case 'all':
if ( in_array( 'false', $status, true ) ) {
return false;
} elseif ( in_array( 'true', $status, true ) ) {
return true;
} else {
return 'empty';
}
default:
case 'any':
if ( in_array( 'true', $status, true ) ) {
return true;
} elseif ( in_array( 'false', $status, true ) ) {
return false;
} else {
return 'empty';
}
}
}
return 'empty';
}
/**
* Calculate product quantities
*
* @param array $cart_contents cart contents.
* @return array
*/
public function cart_product_quantities( $cart_contents = array() ) {
if ( empty( $cart_contents ) ) {
return $cart_contents;
}
$cart_product_quantities = array();
foreach ( $cart_contents as $key => $cart_content ) {
$cart_item = ! empty( $cart_content->object ) ? $cart_content->object : array();
$quantity = ! empty( $cart_item['quantity'] ) ? intval( $cart_item['quantity'] ) : 1;
$product_id = ! empty( $cart_item['product_id'] ) ? intval( $cart_item['product_id'] ) : 0;
$variation_id = ! empty( $cart_item['variation_id'] ) ? intval( $cart_item['variation_id'] ) : 0;
if ( ! empty( $variation_id ) ) {
if ( isset( $cart_product_quantities[ $variation_id ] ) ) {
$cart_product_quantities[ $variation_id ] = $cart_product_quantities[ $variation_id ] + $quantity;
} else {
$cart_product_quantities[ $variation_id ] = $quantity;
}
}
if ( isset( $cart_product_quantities[ $product_id ] ) ) {
$cart_product_quantities[ $product_id ] = $cart_product_quantities[ $product_id ] + $quantity;
} else {
$cart_product_quantities[ $product_id ] = $quantity;
}
}
return $cart_product_quantities;
}
/**
* Calculate category quantities
*
* @param array $cart_contents cart contents.
* @return array
*/
public function cart_product_categories_quantities( $cart_contents = array() ) {
if ( empty( $cart_contents ) ) {
return $cart_contents;
}
$categories_quantities = array();
foreach ( $cart_contents as $key => $cart_content ) {
$cart_item = ! empty( $cart_content->object ) ? $cart_content->object : array();
$product = ! empty( $cart_item['data'] ) ? $cart_item['data'] : array();
$quantity = ! empty( $cart_item['quantity'] ) ? intval( $cart_item['quantity'] ) : 1;
if ( is_object( $product ) && is_callable( array( $product, 'get_category_ids' ) ) ) {
$product_variation = ( is_callable( array( $product, 'is_type' ) ) ) ? $product->is_type( 'variation' ) : false;
if ( $product_variation ) {
$parent_id = ( is_callable( array( $product, 'get_parent_id' ) ) ) ? $product->get_parent_id() : 0;
if ( ! empty( $parent_id ) ) {
$product = wc_get_product( $parent_id );
}
}
$categories = $product->get_category_ids();
if ( ! empty( $categories ) ) {
foreach ( $categories as $category ) {
if ( isset( $categories_quantities[ $category ] ) ) {
$categories_quantities[ $category ] = $categories_quantities[ $category ] + $quantity;
} else {
$categories_quantities[ $category ] = $quantity;
}
}
}
}
}
return $categories_quantities;
}
}
}
WC_SC_Coupons_By_Product_Quantity::get_instance();

View File

@@ -1,380 +0,0 @@
<?php
/**
* Class to handle feature Coupons By Shipping Method
*
* @author StoreApps
* @category Admin
* @package wocommerce-smart-coupons/includes
* @version 1.5.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Coupons_By_Shipping_Method' ) ) {
/**
* Class WC_SC_Coupons_By_Shipping_Method
*/
class WC_SC_Coupons_By_Shipping_Method {
/**
* Variable to hold instance of this class
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
private function __construct() {
add_action( 'woocommerce_coupon_options_usage_restriction', array( $this, 'usage_restriction' ), 10, 2 );
add_action( 'woocommerce_coupon_options_save', array( $this, 'process_meta' ), 10, 2 );
add_filter( 'woocommerce_coupon_is_valid', array( $this, 'validate' ), 11, 2 );
add_filter( 'wc_smart_coupons_export_headers', array( $this, 'export_headers' ) );
add_filter( 'wc_sc_export_coupon_meta', array( $this, 'export_coupon_meta_data' ), 10, 2 );
add_filter( 'smart_coupons_parser_postmeta_defaults', array( $this, 'postmeta_defaults' ) );
add_filter( 'sc_generate_coupon_meta', array( $this, 'generate_coupon_meta' ), 10, 2 );
add_filter( 'wc_sc_process_coupon_meta_value_for_import', array( $this, 'process_coupon_meta_value_for_import' ), 10, 2 );
add_filter( 'is_protected_meta', array( $this, 'make_action_meta_protected' ), 10, 3 );
add_action( 'wc_sc_new_coupon_generated', array( $this, 'copy_coupon_shipping_method_meta' ) );
}
/**
* Get single instance of this class
*
* @return this class Singleton object of this class
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name = '', $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Display field for coupon by shipping method
*
* @param integer $coupon_id The coupon id.
* @param WC_Coupon $coupon The coupon object.
*/
public function usage_restriction( $coupon_id = 0, $coupon = null ) {
$shipping_method_ids = array();
if ( ! empty( $coupon_id ) ) {
$shipping_method_ids = ( $this->is_callable( $coupon, 'get_meta' ) ) ? $coupon->get_meta( 'wc_sc_shipping_method_ids' ) : $this->get_post_meta( $coupon_id, 'wc_sc_shipping_method_ids', true );
if ( empty( $shipping_method_ids ) || ! is_array( $shipping_method_ids ) ) {
$shipping_method_ids = array();
}
}
$available_shipping_methods = WC()->shipping->get_shipping_methods();
?>
<div class="options_group smart-coupons-field">
<p class="form-field">
<label for="wc_sc_shipping_method_ids"><?php echo esc_html__( 'Shipping methods', 'woocommerce-smart-coupons' ); ?></label>
<select id="wc_sc_shipping_method_ids" name="wc_sc_shipping_method_ids[]" style="width: 50%;" class="wc-enhanced-select" multiple="multiple" data-placeholder="<?php esc_attr_e( 'No shipping methods', 'woocommerce-smart-coupons' ); ?>">
<?php
if ( is_array( $available_shipping_methods ) && ! empty( $available_shipping_methods ) ) {
foreach ( $available_shipping_methods as $shipping_method ) {
echo '<option value="' . esc_attr( $shipping_method->id ) . '"' . esc_attr( selected( in_array( $shipping_method->id, $shipping_method_ids, true ), true, false ) ) . '>' . esc_html( $shipping_method->get_method_title() ) . '</option>';
}
}
?>
</select>
<?php
$tooltip_text = esc_html__( 'Shipping methods that must be selected during checkout for this coupon to be valid.', 'woocommerce-smart-coupons' );
echo wc_help_tip( $tooltip_text ); // phpcs:ignore
?>
</p>
</div>
<?php
}
/**
* Save coupon by shipping method data in meta
*
* @param Integer $post_id The coupon post ID.
* @param WC_Coupon $coupon The coupon object.
*/
public function process_meta( $post_id = 0, $coupon = null ) {
if ( empty( $post_id ) ) {
return;
}
if ( is_null( $coupon ) || ! is_a( $coupon, 'WC_Coupon' ) ) {
$coupon = new WC_Coupon( $post_id );
}
$shipping_method_ids = ( isset( $_POST['wc_sc_shipping_method_ids'] ) ) ? wc_clean( wp_unslash( $_POST['wc_sc_shipping_method_ids'] ) ) : array(); // phpcs:ignore
if ( $this->is_callable( $coupon, 'update_meta_data' ) && $this->is_callable( $coupon, 'save' ) ) {
$coupon->update_meta_data( 'wc_sc_shipping_method_ids', $shipping_method_ids );
$coupon->save();
} else {
$this->update_post_meta( $post_id, 'wc_sc_shipping_method_ids', $shipping_method_ids );
}
}
/**
* Validate the coupon based on shipping method
*
* @param boolean $valid Is valid or not.
* @param WC_Coupon $coupon The coupon object.
*
* @throws Exception If the coupon is invalid.
* @return boolean Is valid or not
*/
public function validate( $valid = false, $coupon = object ) {
// If coupon is already invalid, no need for further checks.
if ( false === $valid ) {
return $valid;
}
$coupon_id = ( $this->is_wc_gte_30() ) ? $coupon->get_id() : $coupon->id;
$shipping_method_ids = ( $this->is_callable( $coupon, 'get_meta' ) ) ? $coupon->get_meta( 'wc_sc_shipping_method_ids' ) : $this->get_post_meta( $coupon_id, 'wc_sc_shipping_method_ids', true );
if ( is_array( $shipping_method_ids ) && ! empty( $shipping_method_ids ) ) {
$chosen_shipping_method_data = WC()->session->__isset( 'chosen_shipping_methods' ) ? WC()->session->get( 'chosen_shipping_methods' ) : '';
$chosen_shipping_method_string = is_array( $chosen_shipping_method_data ) && ! empty( $chosen_shipping_method_data ) ? $chosen_shipping_method_data[0] : '';
if ( ! empty( $chosen_shipping_method_string ) ) {
$chosen_shipping_method_string = explode( ':', $chosen_shipping_method_string );
$chosen_shipping_method_id = $chosen_shipping_method_string[0];
if ( ! in_array( $chosen_shipping_method_id, $shipping_method_ids, true ) ) {
$wc_shipping_packages = ( is_callable( array( WC()->shipping, 'get_packages' ) ) ) ? WC()->shipping->get_packages() : null;
if ( empty( $wc_shipping_packages ) && is_callable( array( WC()->cart, 'calculate_shipping' ) ) ) {
WC()->cart->calculate_shipping();
}
$chosen_shipping_method_rate_id = is_array( $chosen_shipping_method_data ) && ! empty( $chosen_shipping_method_data ) ? $chosen_shipping_method_data[0] : '';
$shipping_method_id = '';
$available_shipping_packages = ( is_callable( array( WC()->shipping, 'get_packages' ) ) ) ? WC()->shipping->get_packages() : '';
if ( ! empty( $available_shipping_packages ) ) {
foreach ( $available_shipping_packages as $key => $package ) {
if ( ! empty( $shipping_method_id ) ) {
break;
}
// Loop through Shipping rates.
if ( isset( $package['rates'] ) && ! empty( $package['rates'] ) ) {
foreach ( $package['rates'] as $rate_id => $rate ) {
if ( $chosen_shipping_method_rate_id === $rate_id ) {
$shipping_method_id = ( is_callable( array( $rate, 'get_method_id' ) ) ) ? $rate->get_method_id() : '';
break;
}
}
}
}
if ( ! in_array( $shipping_method_id, $shipping_method_ids, true ) ) {
if ( ! apply_filters( 'wc_sc_coupon_validate_shipping_method', false, $chosen_shipping_method_id, $shipping_method_ids ) ) {
throw new Exception( __( 'This coupon is not valid for selected shipping method.', 'woocommerce-smart-coupons' ) );
}
}
} else {
if ( ! apply_filters( 'wc_sc_coupon_validate_shipping_method', false, $chosen_shipping_method_id, $shipping_method_ids ) ) {
throw new Exception( __( 'This coupon is not valid for selected shipping method.', 'woocommerce-smart-coupons' ) );
}
}
}
}
}
return $valid;
}
/**
* Add meta in export headers
*
* @param array $headers Existing headers.
* @return array
*/
public function export_headers( $headers = array() ) {
$headers['wc_sc_shipping_method_ids'] = __( 'Shipping methods', 'woocommerce-smart-coupons' );
return $headers;
}
/**
* Function to handle coupon meta data during export of existing coupons
*
* @param mixed $meta_value The meta value.
* @param array $args Additional arguments.
* @return string Processed meta value
*/
public function export_coupon_meta_data( $meta_value = '', $args = array() ) {
if ( ! empty( $args['meta_key'] ) && 'wc_sc_shipping_method_ids' === $args['meta_key'] ) {
if ( isset( $args['meta_value'] ) && ! empty( $args['meta_value'] ) ) {
$shipping_method_ids = maybe_unserialize( stripslashes( $args['meta_value'] ) );
if ( is_array( $shipping_method_ids ) && ! empty( $shipping_method_ids ) ) {
$shipping_method_titles = $this->get_shipping_method_titles_by_ids( $shipping_method_ids );
if ( is_array( $shipping_method_titles ) && ! empty( $shipping_method_titles ) ) {
$meta_value = implode( '|', wc_clean( wp_unslash( $shipping_method_titles ) ) ); // Replace shipping method ids with their respective method titles.
}
}
}
}
return $meta_value;
}
/**
* Post meta defaults for shipping method ids meta
*
* @param array $defaults Existing postmeta defaults.
* @return array $defaults Modified postmeta defaults
*/
public function postmeta_defaults( $defaults = array() ) {
$defaults['wc_sc_shipping_method_ids'] = '';
return $defaults;
}
/**
* Add shipping method's meta with value in coupon meta
*
* @param array $data The row data.
* @param array $post The POST values.
* @return array $data Modified row data
*/
public function generate_coupon_meta( $data = array(), $post = array() ) {
$shipping_method_titles = '';
if ( ! empty( $post['wc_sc_shipping_method_ids'] ) && is_array( $post['wc_sc_shipping_method_ids'] ) ) {
$shipping_method_titles = $this->get_shipping_method_titles_by_ids( $post['wc_sc_shipping_method_ids'] );
if ( is_array( $shipping_method_titles ) && ! empty( $shipping_method_titles ) ) {
$shipping_method_titles = implode( '|', wc_clean( wp_unslash( $shipping_method_titles ) ) );
}
}
$data['wc_sc_shipping_method_ids'] = $shipping_method_titles; // Replace shipping method ids with their respective method titles.
return $data;
}
/**
* Function to get shipping method titles for given shipping method ids
*
* @param array $shipping_method_ids ids of shipping methods.
* @return array $shipping_method_titles titles of shipping methods
*/
public function get_shipping_method_titles_by_ids( $shipping_method_ids = array() ) {
$shipping_method_titles = array();
if ( is_array( $shipping_method_ids ) && ! empty( $shipping_method_ids ) ) {
$available_shipping_methods = WC()->shipping->load_shipping_methods();
foreach ( $shipping_method_ids as $index => $shipping_method_id ) {
$shipping_method = ( isset( $available_shipping_methods[ $shipping_method_id ] ) && ! empty( $available_shipping_methods[ $shipping_method_id ] ) ) ? $available_shipping_methods[ $shipping_method_id ] : '';
if ( ! empty( $shipping_method ) && is_a( $shipping_method, 'WC_Shipping_Method' ) ) {
$shipping_method_title = is_callable( array( $shipping_method, 'get_method_title' ) ) ? $shipping_method->get_method_title() : '';
if ( ! empty( $shipping_method_title ) ) {
$shipping_method_titles[ $index ] = $shipping_method_title; // Replace shipping method id with it's repective title.
} else {
$shipping_method_titles[ $index ] = $shipping_method->id; // In case of empty shipping method title replace it with method id.
}
}
}
}
return $shipping_method_titles;
}
/**
* Process coupon meta value for import
*
* @param mixed $meta_value The meta value.
* @param array $args Additional Arguments.
* @return mixed $meta_value
*/
public function process_coupon_meta_value_for_import( $meta_value = null, $args = array() ) {
if ( ! empty( $args['meta_key'] ) && 'wc_sc_shipping_method_ids' === $args['meta_key'] ) {
$meta_value = ( ! empty( $args['postmeta']['wc_sc_shipping_method_ids'] ) ) ? explode( '|', wc_clean( wp_unslash( $args['postmeta']['wc_sc_shipping_method_ids'] ) ) ) : array();
if ( is_array( $meta_value ) && ! empty( $meta_value ) ) {
$available_shipping_methods = WC()->shipping->load_shipping_methods();
if ( is_array( $available_shipping_methods ) && ! empty( $available_shipping_methods ) ) {
foreach ( $meta_value as $index => $shipping_method_title ) {
foreach ( $available_shipping_methods as $shipping_method ) {
$method_title = is_callable( array( $shipping_method, 'get_method_title' ) ) ? $shipping_method->get_method_title() : '';
if ( $method_title === $shipping_method_title && ! empty( $shipping_method->id ) ) {
$meta_value[ $index ] = $shipping_method->id; // Replace shipping method title with it's repective id.
}
}
}
}
}
}
return $meta_value;
}
/**
* Function to copy shipping method restriction meta in newly generated coupon
*
* @param array $args The arguments.
*/
public function copy_coupon_shipping_method_meta( $args = array() ) {
// Copy meta data to new coupon.
$this->copy_coupon_meta_data(
$args,
array( 'wc_sc_shipping_method_ids' )
);
}
/**
* Make meta data of shipping method ids protected
*
* @param bool $protected Is protected.
* @param string $meta_key The meta key.
* @param string $meta_type The meta type.
* @return bool $protected
*/
public function make_action_meta_protected( $protected = false, $meta_key = '', $meta_type = '' ) {
if ( 'wc_sc_shipping_method_ids' === $meta_key ) {
return true;
}
return $protected;
}
}
}
WC_SC_Coupons_By_Shipping_Method::get_instance();

View File

@@ -1,811 +0,0 @@
<?php
/**
* Class to handle feature Coupons By Taxonomy
*
* @author StoreApps
* @category Admin
* @package wocommerce-smart-coupons/includes
* @since 4.13.0
* @version 1.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Coupons_By_Taxonomy' ) ) {
/**
* Class WC_SC_Coupons_By_Taxonomy
*/
class WC_SC_Coupons_By_Taxonomy {
/**
* Variable to hold instance of this class
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
private function __construct() {
add_action( 'woocommerce_coupon_options_usage_restriction', array( $this, 'usage_restriction' ), 99, 2 );
add_action( 'wp_ajax_taxonomy_restriction_row_html', array( $this, 'ajax_taxonomy_restriction_row_html' ) );
add_action( 'wp_ajax_taxonomy_restriction_select_tag_html', array( $this, 'ajax_taxonomy_restriction_select_tag_html' ) );
add_action( 'wp_ajax_default_taxonomy_restriction_row_html', array( $this, 'ajax_default_taxonomy_restriction_row_html' ) );
add_action( 'admin_footer', array( $this, 'styles_and_scripts' ) );
add_action( 'woocommerce_coupon_options_save', array( $this, 'process_meta' ), 10, 2 );
add_filter( 'woocommerce_coupon_is_valid_for_product', array( $this, 'validate' ), 11, 4 );
add_filter( 'woocommerce_coupon_is_valid', array( $this, 'handle_non_product_type_coupons' ), 11, 3 );
add_filter( 'is_protected_meta', array( $this, 'make_action_meta_protected' ), 10, 3 );
add_action( 'wc_sc_new_coupon_generated', array( $this, 'copy_coupon_taxonomy_meta' ) );
}
/**
* Get single instance of this class
*
* @return this class Singleton object of this class
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name = '', $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Display field for coupon by payment method
*
* @param integer $coupon_id The coupon id.
* @param WC_Coupon $coupon The coupon object.
*/
public function usage_restriction( $coupon_id = 0, $coupon = null ) {
$taxonomy_to_label = $this->get_taxonomy_with_label();
$terms = $this->get_terms_grouped_by_taxonomy();
$operators = array(
'incl' => __( 'Include', 'woocommerce-smart-coupons' ),
'excl' => __( 'Exclude', 'woocommerce-smart-coupons' ),
);
$taxonomy_restrictions = ( $this->is_callable( $coupon, 'get_meta' ) ) ? $coupon->get_meta( 'wc_sc_taxonomy_restrictions' ) : $this->get_post_meta( $coupon_id, 'wc_sc_taxonomy_restrictions', true );
?>
<div class="options_group smart-coupons-field wc_sc_taxonomy_restrictions">
<?php
if ( empty( $taxonomy_restrictions ) ) {
$this->get_default_taxonomy_restriction_row();
}
if ( ! empty( $taxonomy_restrictions ) ) {
$count = count( $taxonomy_restrictions );
for ( $i = 0; $i < $count; $i++ ) {
$args = array(
'index' => $i,
'taxonomy_restriction' => $taxonomy_restrictions[ $i ],
'taxonomy_to_label' => $taxonomy_to_label,
'operators' => $operators,
'terms' => $terms,
);
$this->get_taxonomy_restriction_row( $args );
}
}
?>
</div>
<?php
}
/**
* Get default taxonomy restriction row
*/
public function get_default_taxonomy_restriction_row() {
?>
<p class="form-field">
<label>
<?php
echo esc_html__( 'Taxonomy', 'woocommerce-smart-coupons' );
$tooltip_text = esc_html__( 'Product taxonomies that the coupon will be applicable for, or its availability in the cart in order for the "Fixed cart discount" to be applied, based on whether the taxonomies are included or excluded. All the taxonomies selected here, should be valid, for this coupon to be valid.', 'woocommerce-smart-coupons' );
echo wc_help_tip( $tooltip_text ); // phpcs:ignore
?>
</label>
<span id="wc_sc_add_taxonomy_row" class="button wc_sc_add_taxonomy_row" title="<?php echo esc_attr__( 'Add taxonomy restriction', 'woocommerce-smart-coupons' ); ?>"><?php echo esc_html__( 'Add taxonomy restriction', 'woocommerce-smart-coupons' ); ?></span>
</p>
<?php
}
/**
* Get taxonomy restriction row HTML via AJAX
*/
public function ajax_default_taxonomy_restriction_row_html() {
check_ajax_referer( 'wc-sc-default-taxonomy-restriction-row', 'security' );
$this->get_default_taxonomy_restriction_row();
die();
}
/**
* Get taxonomy restriction row
*
* @param array $args Arguments.
*/
public function get_taxonomy_restriction_row( $args = array() ) {
$index = ( ! empty( $args['index'] ) ) ? absint( $args['index'] ) : 0;
$taxonomy_restriction = ( ! empty( $args['taxonomy_restriction'] ) ) ? $args['taxonomy_restriction'] : array();
$taxonomy_to_label = ( ! empty( $args['taxonomy_to_label'] ) ) ? $args['taxonomy_to_label'] : array();
$terms = ( ! empty( $args['terms'] ) ) ? $args['terms'] : array();
$operators = ( ! empty( $args['operators'] ) ) ? $args['operators'] : array();
$tax = $taxonomy_restriction['tax'];
$op = $taxonomy_restriction['op'];
$value = $taxonomy_restriction['val'];
?>
<p class="form-field wc_sc_taxonomy_restrictions_row wc_sc_taxonomy_restrictions-<?php echo esc_attr( $index ); ?>">
<label>
<?php
if ( 0 === $index ) {
echo esc_html__( 'Taxonomy', 'woocommerce-smart-coupons' );
$tooltip_text = esc_html__( 'Product taxonomies that the coupon will be applicable for, or its availability in the cart in order for the "Fixed cart discount" to be applied, based on whether the taxonomies are included or excluded.', 'woocommerce-smart-coupons' );
echo wc_help_tip( $tooltip_text ); // phpcs:ignore
} else {
echo esc_html( ' ' );
}
?>
</label>
<?php
$args = array(
'index' => $index,
'column' => 'tax',
'all' => $taxonomy_to_label,
'selected' => $tax,
'width' => '140px',
);
$this->get_taxonomy_restriction_select_tag( $args );
?>
<?php
$args = array(
'index' => $index,
'column' => 'op',
'all' => $operators,
'selected' => $op,
'width' => '70px',
);
$this->get_taxonomy_restriction_select_tag( $args );
?>
<?php
$args = array(
'index' => $index,
'column' => 'val',
'all' => $terms[ $tax ],
'selected' => $value,
);
$this->get_taxonomy_restriction_select_tag( $args );
?>
<span id="wc_sc_add_taxonomy_row" class="button wc_sc_add_taxonomy_row dashicons dashicons-plus-alt2" title="<?php echo esc_attr__( 'Add taxonomy restriction', 'woocommerce-smart-coupons' ); ?>"></span><span id="remove_wc_sc_taxonomy_restrictions-<?php echo esc_attr( $index ); ?>" class="button remove_wc_sc_taxonomy_restrictions-<?php echo esc_attr( $index ); ?> dashicons dashicons-no-alt" title="<?php echo esc_attr__( 'Remove taxonomy restriction', 'woocommerce-smart-coupons' ); ?>"></span>
</p>
<?php
}
/**
* Draw taxonomy restriction select tag
*
* @param array $args Arguments.
*/
public function get_taxonomy_restriction_select_tag( $args = array() ) {
$index = ( ! empty( $args['index'] ) ) ? $args['index'] : 0;
$column = ( ! empty( $args['column'] ) ) ? $args['column'] : '';
$all = ( ! empty( $args['all'] ) ) ? $args['all'] : array();
$selected = ( ! empty( $args['selected'] ) ) ? $args['selected'] : array();
$width = ( ! empty( $args['width'] ) ) ? $args['width'] : '350px';
?>
<select name="wc_sc_taxonomy_restrictions[<?php echo esc_attr( $index ); ?>][<?php echo esc_attr( $column ); ?>]<?php echo esc_attr( 'val' === $column ? '[]' : '' ); ?>" id="wc_sc_taxonomy_restrictions-<?php echo esc_attr( $index ); ?>-<?php echo esc_attr( $column ); ?>" style="min-width: <?php echo esc_attr( $width ); ?>;" class="wc-enhanced-select" <?php echo ( 'val' === $column ? 'multiple="multiple"' : '' ); ?> tabindex="-1" aria-hidden="true">
<?php
foreach ( $all as $key => $val ) {
?>
<option value="<?php echo esc_attr( $key ); ?>"
<?php
if ( is_array( $selected ) ) {
selected( in_array( (string) $key, $selected, true ), true );
} else {
selected( $selected, (string) $key );
}
?>
><?php echo esc_html( ucfirst( $val ) ); ?></option>
<?php
}
?>
</select>
<?php
}
/**
* Get taxonomy restriction row HTML via AJAX
*/
public function ajax_taxonomy_restriction_select_tag_html() {
check_ajax_referer( 'wc-sc-taxonomy-restriction-select-tag', 'security' );
$index = ( ! empty( $_POST['index'] ) ) ? sanitize_text_field( wp_unslash( $_POST['index'] ) ) : 0;
$tax = ( ! empty( $_POST['tax'] ) ) ? sanitize_text_field( wp_unslash( $_POST['tax'] ) ) : '';
$terms = $this->get_terms_grouped_by_taxonomy();
$args = array(
'index' => $index,
'column' => 'val',
'all' => $terms[ $tax ],
);
$this->get_taxonomy_restriction_select_tag( $args );
die();
}
/**
* Get taxonomy restriction row HTML via AJAX
*/
public function ajax_taxonomy_restriction_row_html() {
check_ajax_referer( 'wc-sc-taxonomy-restriction-row', 'security' );
$index = ( ! empty( $_POST['index'] ) ) ? sanitize_text_field( wp_unslash( $_POST['index'] ) ) : 0;
$taxonomy_to_label = $this->get_taxonomy_with_label();
$terms = $this->get_terms_grouped_by_taxonomy();
$operators = array(
'incl' => __( 'Include', 'woocommerce-smart-coupons' ),
'excl' => __( 'Exclude', 'woocommerce-smart-coupons' ),
);
$tax = current( array_keys( $taxonomy_to_label ) );
$op = current( array_keys( $operators ) );
$args = array(
'index' => $index,
'taxonomy_restriction' => array(
'tax' => $tax,
'op' => $op,
'val' => array(),
),
'taxonomy_to_label' => $taxonomy_to_label,
'operators' => $operators,
'terms' => $terms,
);
$this->get_taxonomy_restriction_row( $args );
die();
}
/**
* Styles and scripts
*/
public function styles_and_scripts() {
if ( ! wp_script_is( 'jquery' ) ) {
wp_enqueue_script( 'jquery' );
}
?>
<style type="text/css">
.options_group.wc_sc_taxonomy_restrictions span.select2.select2-container {
margin: 0 1em 1em 0;
}
.options_group.wc_sc_taxonomy_restrictions .button {
margin: 0 0 0.5em 0.5em;
}
.options_group.wc_sc_taxonomy_restrictions .button.dashicons {
width: auto;
}
.options_group.wc_sc_taxonomy_restrictions .dashicons.dashicons-no-alt::before {
opacity: 0.5;
font-weight: 100;
}
.options_group.wc_sc_taxonomy_restrictions .dashicons {
vertical-align: middle;
}
.options_group.wc_sc_taxonomy_restrictions .woocommerce-help-tip {
float: right;
margin: 0 0.4em;
transform: translateY(25%);
}
</style>
<script type="text/javascript">
jQuery(function(){
function wc_sc_taxonomy_restrictions_field_loaded() {
jQuery('.wc_sc_taxonomy_restrictions').find('.wc_sc_add_taxonomy_row').filter(':not(:last)').remove();
}
function wc_sc_add_taxonomy_clicked() {
jQuery('.wc_sc_taxonomy_restrictions').find('.wc_sc_add_taxonomy_row').remove();
jQuery('.wc_sc_taxonomy_restrictions').find('p.form-field').filter(':not(p.wc_sc_taxonomy_restrictions_row)').remove();
}
wc_sc_taxonomy_restrictions_field_loaded();
jQuery('body').on('click', '#wc_sc_add_taxonomy_row', function(){
var count = jQuery('.wc_sc_taxonomy_restrictions').find('.wc_sc_taxonomy_restrictions_row').length;
jQuery.ajax({
url: '<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>',
type: 'post',
dataType: 'html',
data: {
action: 'taxonomy_restriction_row_html',
security: '<?php echo esc_html( wp_create_nonce( 'wc-sc-taxonomy-restriction-row' ) ); ?>',
index: count
},
success: function( response ){
if ( response != undefined && response != '' ) {
wc_sc_add_taxonomy_clicked();
jQuery('.wc_sc_taxonomy_restrictions').append(response);
jQuery(document.body).trigger('wc-enhanced-select-init');
if ( count <= 0 ) {
jQuery(document.body).trigger('init_tooltips');
}
}
}
});
});
jQuery('body').on('change', '[id^="wc_sc_taxonomy_restrictions-"][id$="-tax"]', function(){
var current_element = jQuery(this);
var element_id = current_element.attr('id');
var selected_value = current_element.val();
var index = element_id.replace('wc_sc_taxonomy_restrictions-', '').replace('-tax', '');
jQuery.ajax({
url: '<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>',
type: 'post',
dataType: 'html',
data: {
action: 'taxonomy_restriction_select_tag_html',
security: '<?php echo esc_html( wp_create_nonce( 'wc-sc-taxonomy-restriction-select-tag' ) ); ?>',
index: index,
tax: selected_value
},
success: function( response ){
if ( response != undefined && response != '' ) {
jQuery('#wc_sc_taxonomy_restrictions-'+index+'-val').selectWoo('destroy').remove();
jQuery('#wc_sc_taxonomy_restrictions-'+index+'-op').parent().append(response);
jQuery(document.body).trigger('wc-enhanced-select-init');
}
}
});
});
jQuery('body').on('click', '[id^="remove_wc_sc_taxonomy_restrictions-"]', function(){
var current_element = jQuery(this);
if ( current_element.parent().find( '#wc_sc_add_taxonomy_row' ).length > 0 ) {
current_element.parent().prev().find('[id^=remove_wc_sc_taxonomy_restrictions-]').before(current_element.parent().find('#wc_sc_add_taxonomy_row'));
}
if ( current_element.parent().find( '.woocommerce-help-tip' ).length > 0 ) {
current_element.parent().next().find('label').replaceWith(current_element.parent().find('label'));
}
current_element.parent().find('.wc-enhanced-select').selectWoo('destroy');
current_element.parent().remove();
var count = jQuery('.wc_sc_taxonomy_restrictions').find('.wc_sc_taxonomy_restrictions_row').length;
if ( count <= 0 ) {
jQuery.ajax({
url: '<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>',
type: 'post',
dataType: 'html',
data: {
action: 'default_taxonomy_restriction_row_html',
security: '<?php echo esc_html( wp_create_nonce( 'wc-sc-default-taxonomy-restriction-row' ) ); ?>'
},
success: function( response ){
if ( response != undefined && response != '' ) {
jQuery('.wc_sc_taxonomy_restrictions').append(response);
jQuery(document.body).trigger('wc-enhanced-select-init');
jQuery(document.body).trigger('init_tooltips');
}
}
});
}
});
});
</script>
<?php
}
/**
* Get taxonomy with label
*
* @return array
*/
public function get_taxonomy_with_label() {
global $wp_taxonomies;
$taxonomy_to_label = array();
$include_taxonomy = array(
'product_type',
'product_visibility',
'product_tag',
'product_shipping_class',
);
$include_taxonomy = apply_filters( 'wc_sc_include_taxonomy_for_restrictions', $include_taxonomy, array( 'source' => $this ) );
if ( ! empty( $wp_taxonomies ) ) {
foreach ( $wp_taxonomies as $taxonomy => $wp_taxonomy ) {
if ( in_array( $taxonomy, $include_taxonomy, true ) ) {
$taxonomy_to_label[ $taxonomy ] = $wp_taxonomy->label;
}
}
}
return $taxonomy_to_label;
}
/**
* Get terms grouped by taxonomy
*
* @return array
*/
public function get_terms_grouped_by_taxonomy() {
$terms_by_taxonomy = array();
$args = array(
'hide_empty' => false,
);
$terms = get_terms( $args );
if ( ! empty( $terms ) ) {
foreach ( $terms as $term ) {
if ( empty( $terms_by_taxonomy[ $term->taxonomy ] ) || ! is_array( $terms_by_taxonomy[ $term->taxonomy ] ) ) {
$terms_by_taxonomy[ $term->taxonomy ] = array();
}
$terms_by_taxonomy[ $term->taxonomy ][ $term->slug ] = $term->name;
}
}
return $terms_by_taxonomy;
}
/**
* Save coupon by payment method data in meta
*
* @param Integer $post_id The coupon post ID.
* @param WC_Coupon $coupon The coupon object.
*/
public function process_meta( $post_id = 0, $coupon = null ) {
if ( empty( $post_id ) ) {
return;
}
if ( is_null( $coupon ) || ! is_a( $coupon, 'WC_Coupon' ) ) {
$coupon = new WC_Coupon( $post_id );
}
$taxonomy_restrictions = ( isset( $_POST['wc_sc_taxonomy_restrictions'] ) ) ? wc_clean( wp_unslash( $_POST['wc_sc_taxonomy_restrictions'] ) ) : array(); // phpcs:ignore
if ( ! empty( $taxonomy_restrictions ) ) {
$taxonomy_restrictions = array_values( $taxonomy_restrictions );
}
if ( $this->is_callable( $coupon, 'update_meta_data' ) && $this->is_callable( $coupon, 'save' ) ) {
$coupon->update_meta_data( 'wc_sc_taxonomy_restrictions', $taxonomy_restrictions );
$coupon->save();
} else {
$this->update_post_meta( $post_id, 'wc_sc_taxonomy_restrictions', $taxonomy_restrictions );
}
}
/**
* Function to validate coupons against taxonomy
*
* @param bool $valid Coupon validity.
* @param WC_Product|null $product Product object.
* @param WC_Coupon|null $coupon Coupon object.
* @param array|null $values Values.
* @return bool $valid
*/
public function validate( $valid = false, $product = null, $coupon = null, $values = null ) {
$backtrace = wp_list_pluck( debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ), 'function' ); // phpcs:ignore
// If coupon is already invalid, no need for further checks.
// Ignore this check if the discount type is a non-product-type discount.
if ( true !== $valid && ! in_array( 'handle_non_product_type_coupons', $backtrace, true ) ) {
return $valid;
}
if ( empty( $product ) || empty( $coupon ) ) {
return $valid;
}
$product_ids = array();
if ( $this->is_wc_gte_30() ) {
$coupon_id = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_id' ) ) ) ? $coupon->get_id() : 0;
$product_ids[] = ( is_object( $product ) && is_callable( array( $product, 'get_id' ) ) ) ? $product->get_id() : 0;
$product_ids[] = ( is_object( $product ) && is_callable( array( $product, 'get_parent_id' ) ) ) ? $product->get_parent_id() : 0;
} else {
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
$product_ids[] = ( ! empty( $product->id ) ) ? $product->id : 0;
$product_ids[] = ( is_object( $product ) && is_callable( array( $product, 'get_parent' ) ) ) ? $product->get_parent() : 0;
}
$product_ids = array_unique( array_filter( $product_ids ) );
if ( ! empty( $coupon_id ) ) {
$taxonomy_restrictions = ( $this->is_callable( $coupon, 'get_meta' ) ) ? $coupon->get_meta( 'wc_sc_taxonomy_restrictions' ) : $this->get_post_meta( $coupon_id, 'wc_sc_taxonomy_restrictions', true );
if ( ! empty( $taxonomy_restrictions ) ) {
$term_ids = $this->get_restricted_term_ids( array( 'taxonomy_restrictions' => $taxonomy_restrictions ) );
$include_ids = array();
$exclude_ids = array();
if ( isset( $term_ids['include'] ) && is_array( $term_ids['include'] ) ) {
$include_ids = $term_ids['include'];
}
if ( isset( $term_ids['exclude'] ) && is_array( $term_ids['exclude'] ) ) {
$exclude_ids = $term_ids['exclude'];
}
$taxonomies = wp_list_pluck( $taxonomy_restrictions, 'tax' );
$args = array(
'fields' => 'ids',
);
$object_term_ids = wp_get_object_terms( $product_ids, $taxonomies, $args );
$object_term_ids = array_unique( array_filter( $object_term_ids ) );
$taxonomy_found = true;
if ( ! empty( $include_ids ) && is_array( $include_ids ) ) {
$common_term_ids = array_intersect( $include_ids, $object_term_ids );
if ( count( $common_term_ids ) > 0 ) {
$taxonomy_found = true;
} else {
$taxonomy_found = false;
}
}
$exclude_taxonomy_found = false;
if ( ! empty( $exclude_ids ) && is_array( $exclude_ids ) ) {
$common_exclude_term_ids = array_intersect( $exclude_ids, $object_term_ids );
if ( count( $common_exclude_term_ids ) > 0 ) {
$exclude_taxonomy_found = true;
} else {
$exclude_taxonomy_found = false;
}
}
$valid = ( $taxonomy_found && ! $exclude_taxonomy_found ) ? true : false;
}
}
return $valid;
}
/**
* Function to validate non product type coupons against taxonomy restriction
* We need to remove coupon if it does not pass taxonomy validation even for single cart item in case of non product type coupons e.g fixed_cart, smart_coupon since these coupon type require all products in the cart to be valid
*
* @param boolean $valid Coupon validity.
* @param WC_Coupon $coupon Coupon object.
* @param WC_Discounts $discounts Discounts object.
* @throws Exception Validation exception.
* @return boolean $valid Coupon validity
*/
public function handle_non_product_type_coupons( $valid = true, $coupon = null, $discounts = null ) {
// If coupon is already invalid, no need for further checks.
if ( true !== $valid ) {
return $valid;
}
if ( ! is_a( $coupon, 'WC_Coupon' ) ) {
return $valid;
}
if ( $this->is_wc_gte_30() ) {
$coupon_id = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_id' ) ) ) ? $coupon->get_id() : 0;
$discount_type = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_discount_type' ) ) ) ? $coupon->get_discount_type() : '';
} else {
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
}
if ( ! empty( $coupon_id ) ) {
$taxonomy_restrictions = ( $this->is_callable( $coupon, 'get_meta' ) ) ? $coupon->get_meta( 'wc_sc_taxonomy_restrictions' ) : $this->get_post_meta( $coupon_id, 'wc_sc_taxonomy_restrictions', true );
// If product attributes are not set in coupon, stop further processing and return from here.
if ( empty( $taxonomy_restrictions ) ) {
return $valid;
}
} else {
return $valid;
}
$product_coupon_types = wc_get_product_coupon_types();
// Proceed if it is non product type coupon.
if ( ! in_array( $discount_type, $product_coupon_types, true ) ) {
if ( class_exists( 'WC_Discounts' ) && isset( WC()->cart ) ) {
$wc_cart = WC()->cart;
$wc_discounts = new WC_Discounts( $wc_cart );
$items_to_validate = array();
if ( is_callable( array( $wc_discounts, 'get_items_to_validate' ) ) ) {
$items_to_validate = $wc_discounts->get_items_to_validate();
} elseif ( is_callable( array( $wc_discounts, 'get_items' ) ) ) {
$items_to_validate = $wc_discounts->get_items();
} elseif ( isset( $wc_discounts->items ) && is_array( $wc_discounts->items ) ) {
$items_to_validate = $wc_discounts->items;
}
if ( ! empty( $items_to_validate ) && is_array( $items_to_validate ) ) {
$term_ids = $this->get_restricted_term_ids( array( 'taxonomy_restrictions' => $taxonomy_restrictions ) );
$include_ids = array();
$exclude_ids = array();
if ( isset( $term_ids['include'] ) && is_array( $term_ids['include'] ) ) {
$include_ids = $term_ids['include'];
}
if ( isset( $term_ids['exclude'] ) && is_array( $term_ids['exclude'] ) ) {
$exclude_ids = $term_ids['exclude'];
}
$taxonomies = wp_list_pluck( $taxonomy_restrictions, 'tax' );
$valid_products = array();
$invalid_products = array();
foreach ( $items_to_validate as $item ) {
$cart_item = clone $item; // Clone the item so changes to wc_discounts item do not affect the originals.
$item_product = isset( $cart_item->product ) ? $cart_item->product : null;
$item_object = isset( $cart_item->object ) ? $cart_item->object : null;
if ( ! is_null( $item_product ) && ! is_null( $item_object ) ) {
if ( $coupon->is_valid_for_product( $item_product, $item_object ) ) {
$valid_products[] = $item_product;
} else {
$invalid_products[] = $item_product;
}
}
}
// If cart does not have any valid product then throw Exception.
if ( 0 === count( $valid_products ) ) {
$error_message = __( 'Sorry, this coupon is not applicable to selected products.', 'woocommerce-smart-coupons' );
$error_code = defined( 'E_WC_COUPON_NOT_APPLICABLE' ) ? E_WC_COUPON_NOT_APPLICABLE : 0;
throw new Exception( $error_message, $error_code );
} elseif ( count( $invalid_products ) > 0 && ! empty( $exclude_ids ) ) {
$excluded_products = array();
foreach ( $invalid_products as $invalid_product ) {
$product_ids = array();
$product_ids[] = ( is_object( $invalid_product ) && is_callable( array( $invalid_product, 'get_id' ) ) ) ? $invalid_product->get_id() : 0;
$product_ids[] = ( is_object( $invalid_product ) && is_callable( array( $invalid_product, 'get_parent_id' ) ) ) ? $invalid_product->get_parent_id() : 0;
$product_name = ( is_object( $invalid_product ) && is_callable( array( $invalid_product, 'get_name' ) ) ) ? $invalid_product->get_name() : '';
$args = array(
'fields' => 'ids',
);
$object_term_ids = wp_get_object_terms( $product_ids, $taxonomies, $args );
$object_term_ids = array_unique( array_filter( $object_term_ids ) );
if ( ! empty( $object_term_ids ) && is_array( $object_term_ids ) ) {
$common_exclude_term_ids = array_intersect( $exclude_ids, $object_term_ids );
if ( count( $common_exclude_term_ids ) > 0 ) {
$excluded_products[] = $product_name;
}
}
}
if ( count( $excluded_products ) > 0 ) {
// If cart contains any excluded product and it is being excluded from our excluded product attributes then throw Exception.
/* translators: 1. Singular/plural label for product(s) 2. Excluded product names */
$error_message = sprintf( __( 'Sorry, this coupon is not applicable to the %1$s: %2$s.', 'woocommerce-smart-coupons' ), _n( 'product', 'products', count( $excluded_products ), 'woocommerce-smart-coupons' ), implode( ', ', $excluded_products ) );
$error_code = defined( 'E_WC_COUPON_EXCLUDED_PRODUCTS' ) ? E_WC_COUPON_EXCLUDED_PRODUCTS : 0;
throw new Exception( $error_message, $error_code );
}
}
}
}
}
return $valid;
}
/**
* Get restricted term ids
*
* @param array $args Arguments.
* @return array
*/
public function get_restricted_term_ids( $args = array() ) {
global $wp_taxonomies;
$term_ids = array();
$taxonomy_restrictions = ( ! empty( $args['taxonomy_restrictions'] ) ) ? $args['taxonomy_restrictions'] : array();
if ( ! empty( $taxonomy_restrictions ) ) {
$include_ids = array();
$exclude_ids = array();
foreach ( $taxonomy_restrictions as $taxonomy_restriction ) {
$taxonomy = ( ! empty( $taxonomy_restriction['tax'] ) ) ? $taxonomy_restriction['tax'] : '';
$operator = ( ! empty( $taxonomy_restriction['op'] ) ) ? $taxonomy_restriction['op'] : '';
$value = ( ! empty( $taxonomy_restriction['val'] ) ) ? $taxonomy_restriction['val'] : array();
if ( ! empty( $taxonomy ) && ! empty( $operator ) && ! empty( $value ) ) {
$args = array(
'taxonomy' => $taxonomy,
'hide_empty' => false,
'fields' => 'ids',
'slug' => $value,
);
$found_ids = get_terms( $args );
$found_ids = array_unique( array_filter( $found_ids ) );
if ( ! empty( $found_ids ) ) {
switch ( $operator ) {
case 'incl':
$include_ids = array_merge( $include_ids, $found_ids );
break;
case 'excl':
$exclude_ids = array_merge( $exclude_ids, $found_ids );
break;
}
}
}
}
if ( ! empty( $include_ids ) ) {
$term_ids['include'] = array_unique( array_filter( $include_ids ) );
}
if ( ! empty( $exclude_ids ) ) {
$term_ids['exclude'] = array_unique( array_filter( $exclude_ids ) );
}
}
return $term_ids;
}
/**
* Function to copy taxonomy restriction meta in newly generated coupon
*
* @param array $args The arguments.
*/
public function copy_coupon_taxonomy_meta( $args = array() ) {
// Copy meta data to new coupon.
$this->copy_coupon_meta_data(
$args,
array( 'wc_sc_taxonomy_restrictions' )
);
}
/**
* Make meta data of payment method ids protected
*
* @param bool $protected Is protected.
* @param string $meta_key The meta key.
* @param string $meta_type The meta type.
* @return bool $protected
*/
public function make_action_meta_protected( $protected = false, $meta_key = '', $meta_type = '' ) {
if ( 'wc_sc_taxonomy_restrictions' === $meta_key ) {
return true;
}
return $protected;
}
}
}
WC_SC_Coupons_By_Taxonomy::get_instance();

View File

@@ -1,548 +0,0 @@
<?php
/**
* Class to handle feature Coupons By User Role
*
* @author StoreApps
* @category Admin
* @package wocommerce-smart-coupons/includes
* @version 1.9.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Coupons_By_User_Role' ) ) {
/**
* Class WC_SC_Coupons_By_User_Role
*/
class WC_SC_Coupons_By_User_Role {
/**
* Variable to hold instance of this class
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
public function __construct() {
add_action( 'woocommerce_coupon_options_usage_restriction', array( $this, 'usage_restriction' ), 10, 2 );
add_action( 'woocommerce_coupon_options_save', array( $this, 'process_meta' ), 10, 2 );
add_filter( 'woocommerce_coupon_is_valid', array( $this, 'validate' ), 11, 2 );
add_action( 'woocommerce_after_checkout_validation', array( $this, 'validate_after_checkout' ), 99, 2 );
add_filter( 'wc_smart_coupons_export_headers', array( $this, 'export_headers' ) );
add_filter( 'wc_sc_export_coupon_meta', array( $this, 'export_coupon_meta_data' ), 10, 2 );
add_filter( 'smart_coupons_parser_postmeta_defaults', array( $this, 'postmeta_defaults' ) );
add_filter( 'sc_generate_coupon_meta', array( $this, 'generate_coupon_meta' ), 10, 2 );
add_filter( 'wc_sc_process_coupon_meta_value_for_import', array( $this, 'process_coupon_meta_value_for_import' ), 10, 2 );
add_filter( 'is_protected_meta', array( $this, 'make_action_meta_protected' ), 10, 3 );
add_action( 'wc_sc_new_coupon_generated', array( $this, 'copy_coupon_user_role_meta' ) );
}
/**
* Get single instance of this class
*
* @return this class Singleton object of this class
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name = '', $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Display field for coupon by user role
*
* @param integer $coupon_id The coupon id.
* @param WC_Coupon $coupon The coupon object.
*/
public function usage_restriction( $coupon_id = 0, $coupon = null ) {
$user_role_ids = array();
$exclude_user_role_ids = array();
if ( ! empty( $coupon_id ) ) {
if ( ! is_a( $coupon, 'WC_Coupon' ) ) {
$coupon = new WC_Coupon( $coupon_id );
}
$is_callable_coupon_get_meta = $this->is_callable( $coupon, 'get_meta' );
$user_role_ids = ( true === $is_callable_coupon_get_meta ) ? $coupon->get_meta( 'wc_sc_user_role_ids' ) : get_post_meta( $coupon_id, 'wc_sc_user_role_ids', true );
if ( empty( $user_role_ids ) || ! is_array( $user_role_ids ) ) {
$user_role_ids = array();
}
$exclude_user_role_ids = ( true === $is_callable_coupon_get_meta ) ? $coupon->get_meta( 'wc_sc_exclude_user_role_ids' ) : get_post_meta( $coupon_id, 'wc_sc_exclude_user_role_ids', true );
if ( empty( $exclude_user_role_ids ) || ! is_array( $exclude_user_role_ids ) ) {
$exclude_user_role_ids = array();
}
}
$available_user_roles = $this->get_available_user_roles();
?>
<div class="options_group smart-coupons-field">
<p class="form-field">
<label for="wc_sc_user_role_ids"><?php echo esc_html__( 'Allowed user roles', 'woocommerce-smart-coupons' ); ?></label>
<select id="wc_sc_user_role_ids" name="wc_sc_user_role_ids[]" style="width: 50%;" class="wc-enhanced-select" multiple="multiple" data-placeholder="<?php esc_attr_e( 'No user roles', 'woocommerce-smart-coupons' ); ?>">
<?php
if ( ! empty( $available_user_roles ) && is_array( $available_user_roles ) ) {
foreach ( $available_user_roles as $role_id => $role ) {
$role_name = translate_user_role( $role['name'] );
echo '<option value="' . esc_attr( $role_id ) . '"' . esc_attr( selected( in_array( $role_id, $user_role_ids, true ), true, false ) ) . '>' . esc_html( $role_name ) . '</option>';
}
}
?>
</select>
<?php
$tooltip_text = esc_html__( 'Role of the users for whom this coupon is valid. Keep empty if you want this coupon to be valid for users with any role.', 'woocommerce-smart-coupons' );
echo wc_help_tip( $tooltip_text ); // phpcs:ignore
?>
</p>
<p class="form-field">
<label for="wc_sc_exclude_user_role_ids"><?php echo esc_html__( 'Exclude user roles', 'woocommerce-smart-coupons' ); ?></label>
<select id="wc_sc_exclude_user_role_ids" name="wc_sc_exclude_user_role_ids[]" style="width: 50%;" class="wc-enhanced-select" multiple="multiple" data-placeholder="<?php esc_attr_e( 'No user roles', 'woocommerce-smart-coupons' ); ?>">
<?php
if ( ! empty( $available_user_roles ) && is_array( $available_user_roles ) ) {
foreach ( $available_user_roles as $role_id => $role ) {
$role_name = translate_user_role( $role['name'] );
echo '<option value="' . esc_attr( $role_id ) . '"' . esc_attr( selected( in_array( $role_id, $exclude_user_role_ids, true ), true, false ) ) . '>' . esc_html( $role_name ) . '</option>';
}
}
?>
</select>
<?php
$tooltip_text = esc_html__( 'Role of the users for whom this coupon is not valid. Keep empty if you want this coupon to be valid for users with any role.', 'woocommerce-smart-coupons' );
echo wc_help_tip( $tooltip_text ); // phpcs:ignore
?>
</p>
</div>
<?php
}
/**
* Save coupon by user role data in meta
*
* @param Integer $post_id The coupon post ID.
* @param WC_Coupon $coupon The coupon object.
*/
public function process_meta( $post_id = 0, $coupon = null ) {
if ( empty( $post_id ) ) {
return;
}
if ( is_null( $coupon ) || ! is_a( $coupon, 'WC_Coupon' ) ) {
$coupon = new WC_Coupon( $post_id );
}
$user_role_ids = ( isset( $_POST['wc_sc_user_role_ids'] ) ) ? wc_clean( wp_unslash( $_POST['wc_sc_user_role_ids'] ) ) : array(); // phpcs:ignore
$exclude_user_role_ids = ( isset( $_POST['wc_sc_exclude_user_role_ids'] ) ) ? wc_clean( wp_unslash( $_POST['wc_sc_exclude_user_role_ids'] ) ) : array(); // phpcs:ignore
if ( $this->is_callable( $coupon, 'update_meta_data' ) && $this->is_callable( $coupon, 'save' ) ) {
$coupon->update_meta_data( 'wc_sc_user_role_ids', $user_role_ids );
$coupon->update_meta_data( 'wc_sc_exclude_user_role_ids', $exclude_user_role_ids );
$coupon->save();
} else {
update_post_meta( $post_id, 'wc_sc_user_role_ids', $user_role_ids );
update_post_meta( $post_id, 'wc_sc_exclude_user_role_ids', $exclude_user_role_ids );
}
}
/**
* Validate the coupon based on user role
*
* @param boolean $valid Is valid or not.
* @param WC_Coupon $coupon The coupon object.
*
* @throws Exception If the coupon is invalid.
* @return boolean Is valid or not
*/
public function validate( $valid = false, $coupon = object ) {
// If coupon is invalid already, no need for further checks.
if ( false === $valid ) {
return $valid;
}
$coupon_id = ( $this->is_wc_gte_30() ) ? $coupon->get_id() : $coupon->id;
if ( ! is_a( $coupon, 'WC_Coupon' ) ) {
$coupon = new WC_Coupon( $coupon_id );
}
if ( $this->is_callable( $coupon, 'get_meta' ) ) {
$user_role_ids = $coupon->get_meta( 'wc_sc_user_role_ids' );
$exclude_user_role_ids = $coupon->get_meta( 'wc_sc_exclude_user_role_ids' );
} else {
$user_role_ids = get_post_meta( $coupon_id, 'wc_sc_user_role_ids', true );
$exclude_user_role_ids = get_post_meta( $coupon_id, 'wc_sc_exclude_user_role_ids', true );
}
$current_user = wp_get_current_user();
$post_action = ( ! empty( $_POST['action'] ) ) ? wc_clean( wp_unslash( $_POST['action'] ) ) : ''; // phpcs:ignore
if ( is_admin() && wp_doing_ajax() && 'woocommerce_add_coupon_discount' === $post_action ) { // This condition will allow the addition of coupon from admin side, in the order even if the user role is not matching.
return true;
}
if ( is_array( $user_role_ids ) && ! empty( $user_role_ids ) ) {
// Check if current user's role is allowed.
if ( ! array_intersect( $current_user->roles, $user_role_ids ) ) {
throw new Exception( __( 'This coupon is not valid for you.', 'woocommerce-smart-coupons' ) );
}
}
if ( is_array( $exclude_user_role_ids ) && ! empty( $exclude_user_role_ids ) ) {
// Check if current user's role is excluded.
if ( array_intersect( $current_user->roles, $exclude_user_role_ids ) ) {
throw new Exception( __( 'This coupon is not valid for you.', 'woocommerce-smart-coupons' ) );
}
}
return $valid;
}
/**
* Add meta in export headers
*
* @param array $headers Existing headers.
* @return array
*/
public function export_headers( $headers = array() ) {
$headers['wc_sc_user_role_ids'] = __( 'User Role', 'woocommerce-smart-coupons' );
$headers['wc_sc_exclude_user_role_ids'] = __( 'Exclude User Role', 'woocommerce-smart-coupons' );
return $headers;
}
/**
* Function to handle coupon meta data during export of existing coupons
*
* @param mixed $meta_value The meta value.
* @param array $args Additional arguments.
* @return string Processed meta value
*/
public function export_coupon_meta_data( $meta_value = '', $args = array() ) {
if ( ! empty( $args['meta_key'] ) ) {
if ( 'wc_sc_user_role_ids' === $args['meta_key'] ) {
if ( isset( $args['meta_value'] ) && ! empty( $args['meta_value'] ) ) {
$user_role_ids = maybe_unserialize( stripslashes( $args['meta_value'] ) );
if ( is_array( $user_role_ids ) && ! empty( $user_role_ids ) ) {
$user_role_names = $this->get_user_role_names_by_ids( $user_role_ids );
if ( is_array( $user_role_names ) && ! empty( $user_role_names ) ) {
$meta_value = implode( '|', wc_clean( wp_unslash( $user_role_names ) ) ); // Replace user role ids with their respective role name.
}
}
}
} elseif ( 'wc_sc_exclude_user_role_ids' === $args['meta_key'] ) {
if ( isset( $args['meta_value'] ) && ! empty( $args['meta_value'] ) ) {
$exclude_user_role_ids = maybe_unserialize( stripslashes( $args['meta_value'] ) );
if ( is_array( $exclude_user_role_ids ) && ! empty( $exclude_user_role_ids ) ) {
$exclude_user_role_names = $this->get_user_role_names_by_ids( $exclude_user_role_ids );
if ( is_array( $exclude_user_role_names ) && ! empty( $exclude_user_role_names ) ) {
$meta_value = implode( '|', wc_clean( wp_unslash( $exclude_user_role_names ) ) ); // Replace user role ids with their respective role name.
}
}
}
}
}
return $meta_value;
}
/**
* Post meta defaults for user role ids meta
*
* @param array $defaults Existing postmeta defaults.
* @return array
*/
public function postmeta_defaults( $defaults = array() ) {
$defaults['wc_sc_user_role_ids'] = '';
$defaults['wc_sc_exclude_user_role_ids'] = '';
return $defaults;
}
/**
* Add user role's meta with value in coupon meta
*
* @param array $data The row data.
* @param array $post The POST values.
* @return array Modified data
*/
public function generate_coupon_meta( $data = array(), $post = array() ) {
$user_role_names = '';
$exclude_user_role_names = '';
if ( ! empty( $post['wc_sc_user_role_ids'] ) && is_array( $post['wc_sc_user_role_ids'] ) ) {
$user_role_names = $this->get_user_role_names_by_ids( $post['wc_sc_user_role_ids'] );
if ( is_array( $user_role_names ) && ! empty( $user_role_names ) ) {
$user_role_names = implode( '|', wc_clean( wp_unslash( $user_role_names ) ) );
}
}
if ( ! empty( $post['wc_sc_exclude_user_role_ids'] ) && is_array( $post['wc_sc_exclude_user_role_ids'] ) ) {
$exclude_user_role_names = $this->get_user_role_names_by_ids( $post['wc_sc_exclude_user_role_ids'] );
if ( is_array( $exclude_user_role_names ) && ! empty( $exclude_user_role_names ) ) {
$exclude_user_role_names = implode( '|', wc_clean( wp_unslash( $exclude_user_role_names ) ) );
}
}
$data['wc_sc_user_role_ids'] = $user_role_names; // Replace user role ids with their respective role name.
$data['wc_sc_exclude_user_role_ids'] = $exclude_user_role_names; // Replace user role ids with their respective role name.
return $data;
}
/**
* Function to get user role titles for given user role ids
*
* @param array $user_role_ids ids of user roles.
* @return array $user_role_names titles of user roles
*/
public function get_user_role_names_by_ids( $user_role_ids = array() ) {
$user_role_names = array();
if ( is_array( $user_role_ids ) && ! empty( $user_role_ids ) ) {
$available_user_roles = $this->get_available_user_roles();
foreach ( $user_role_ids as $index => $user_role_id ) {
$user_role = ( isset( $available_user_roles[ $user_role_id ] ) && ! empty( $available_user_roles[ $user_role_id ] ) ) ? $available_user_roles[ $user_role_id ] : '';
if ( is_array( $user_role ) && ! empty( $user_role ) ) {
$user_role_name = ! empty( $user_role['name'] ) ? $user_role['name'] : '';
if ( ! empty( $user_role_name ) ) {
$user_role_names[ $index ] = $user_role_name; // Replace user role id with it's repective name.
} else {
$user_role_names[ $index ] = $user_role_id; // In case of empty user role name replace it with role id.
}
}
}
}
return $user_role_names;
}
/**
* Process coupon meta value for import
*
* @param mixed $meta_value The meta value.
* @param array $args Additional Arguments.
* @return mixed $meta_value
*/
public function process_coupon_meta_value_for_import( $meta_value = null, $args = array() ) {
if ( ! empty( $args['meta_key'] ) ) {
$available_user_roles = $this->get_available_user_roles();
if ( 'wc_sc_user_role_ids' === $args['meta_key'] ) {
$meta_value = ( ! empty( $args['postmeta']['wc_sc_user_role_ids'] ) ) ? explode( '|', wc_clean( wp_unslash( $args['postmeta']['wc_sc_user_role_ids'] ) ) ) : array();
if ( is_array( $meta_value ) && ! empty( $meta_value ) ) {
if ( is_array( $available_user_roles ) && ! empty( $available_user_roles ) ) {
foreach ( $meta_value as $index => $user_role_name ) {
foreach ( $available_user_roles as $role_id => $user_role ) {
$role_name = isset( $user_role['name'] ) ? $user_role['name'] : '';
if ( $role_name === $user_role_name ) {
$meta_value[ $index ] = $role_id; // Replace user role title with it's repective id.
}
}
}
}
}
} elseif ( 'wc_sc_exclude_user_role_ids' === $args['meta_key'] ) {
$meta_value = ( ! empty( $args['postmeta']['wc_sc_exclude_user_role_ids'] ) ) ? explode( '|', wc_clean( wp_unslash( $args['postmeta']['wc_sc_exclude_user_role_ids'] ) ) ) : array();
if ( is_array( $meta_value ) && ! empty( $meta_value ) ) {
if ( is_array( $available_user_roles ) && ! empty( $available_user_roles ) ) {
foreach ( $meta_value as $index => $user_role_name ) {
foreach ( $available_user_roles as $role_id => $user_role ) {
$role_name = isset( $user_role['name'] ) ? $user_role['name'] : '';
if ( $role_name === $user_role_name ) {
$meta_value[ $index ] = $role_id; // Replace user role title with it's repective id.
}
}
}
}
}
}
}
return $meta_value;
}
/**
* Make meta data of user role ids protected
*
* @param bool $protected Is protected.
* @param string $meta_key The meta key.
* @param string $meta_type The meta type.
* @return bool $protected
*/
public function make_action_meta_protected( $protected = false, $meta_key = '', $meta_type = '' ) {
if ( in_array( $meta_key, array( 'wc_sc_user_role_ids', 'wc_sc_exclude_user_role_ids' ), true ) ) {
return true;
}
return $protected;
}
/**
* Function to get available user roles which current user use.
*
* @return array $available_user_roles Available user roles
*/
public function get_available_user_roles() {
$available_user_roles = array();
if ( ! function_exists( 'get_editable_roles' ) ) {
require_once ABSPATH . 'wp-admin/includes/user.php';
}
if ( function_exists( 'get_editable_roles' ) ) {
$available_user_roles = get_editable_roles();
}
return $available_user_roles;
}
/**
* Function to copy user role restriction meta in newly generated coupon
*
* @param array $args The arguments.
*/
public function copy_coupon_user_role_meta( $args = array() ) {
// Copy meta data to new coupon.
$this->copy_coupon_meta_data(
$args,
array( 'wc_sc_user_role_ids', 'wc_sc_exclude_user_role_ids' )
);
}
/**
* Validate user role after checkout.
*
* @param array $posted Post data.
* @param WP_Error $errors Validation errors.
* @return void
*/
public function validate_after_checkout( $posted = array(), $errors = object ) {
$current_user_id = get_current_user_id();
if ( ! empty( $current_user_id ) ) {
return;
}
$billing_email = ! empty( $posted['billing_email'] ) ? $posted['billing_email'] : '';
if ( empty( $posted['billing_email'] ) ) {
return;
}
$cart = ( function_exists( 'WC' ) && isset( WC()->cart ) ) ? WC()->cart : null;
if ( is_a( $cart, 'WC_Cart' ) ) {
$is_cart_empty = is_callable( array( $cart, 'is_empty' ) ) && $cart->is_empty();
if ( false === $is_cart_empty ) {
$applied_coupons = ( is_callable( array( $cart, 'get_applied_coupons' ) ) ) ? $cart->get_applied_coupons() : array();
if ( ! empty( $applied_coupons ) ) {
foreach ( $applied_coupons as $code ) {
$coupon = new WC_Coupon( $code );
if ( ! is_object( $coupon ) ) {
continue;
}
if ( is_callable( array( $coupon, 'get_meta' ) ) ) {
$user_role_ids = $coupon->get_meta( 'wc_sc_user_role_ids' );
$exclude_user_role_ids = $coupon->get_meta( 'wc_sc_exclude_user_role_ids' );
} else {
if ( is_callable( array( $coupon, 'get_id' ) ) ) {
$coupon_id = $coupon->get_id();
} else {
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
}
if ( empty( $coupon_id ) ) {
continue;
}
$user_role_ids = get_post_meta( $coupon_id, 'wc_sc_user_role_ids', true );
$exclude_user_role_ids = get_post_meta( $coupon_id, 'wc_sc_exclude_user_role_ids', true );
}
if ( empty( $exclude_user_role_ids ) && empty( $user_role_ids ) ) {
continue;
}
$current_user = get_user_by( 'email', $billing_email );
$current_user_roles = ! empty( $current_user->roles ) ? $current_user->roles : array();
$is_message = is_callable( array( $coupon, 'add_coupon_message' ) );
$is_remove = is_callable( array( $cart, 'remove_coupon' ) );
if ( is_array( $user_role_ids ) && ! empty( $user_role_ids ) ) {
// Check if current user's role is allowed.
if ( ! array_intersect( $current_user_roles, $user_role_ids ) ) {
if ( true === $is_message ) {
$coupon->add_coupon_message( WC_Coupon::E_WC_COUPON_NOT_YOURS_REMOVED );
}
if ( true === $is_remove ) {
$cart->remove_coupon( $code );
}
}
}
if ( is_array( $exclude_user_role_ids ) && ! empty( $exclude_user_role_ids ) ) {
// Check if current user's role is excluded.
if ( array_intersect( $current_user_roles, $exclude_user_role_ids ) ) {
if ( true === $is_message ) {
$coupon->add_coupon_message( WC_Coupon::E_WC_COUPON_NOT_YOURS_REMOVED );
}
if ( true === $is_remove ) {
$cart->remove_coupon( $code );
}
}
}
}
}
}
}
}
}
}
WC_SC_Coupons_By_User_Role::get_instance();

View File

@@ -1,349 +0,0 @@
<?php
/**
* Maintain Global Coupon's record
*
* @author StoreApps
* @since 3.3.0
* @version 1.5.0
*
* @package woocommerce-smart-coupons/includes/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Global_Coupons' ) ) {
/**
* Class for handling global coupons
*/
class WC_SC_Global_Coupons {
/**
* Variable to hold instance of WC_SC_Global_Coupons
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
private function __construct() {
add_action( 'admin_init', array( $this, 'set_global_coupons' ) );
add_action( 'woocommerce_coupon_options_save', array( $this, 'update_global_coupons' ), 10, 2 );
add_action( 'deleted_post', array( $this, 'sc_delete_global_coupons' ) );
add_action( 'trashed_post', array( $this, 'sc_delete_global_coupons' ) );
add_action( 'untrashed_post', array( $this, 'sc_untrash_global_coupons' ) );
add_action( 'future_to_publish', array( $this, 'future_to_publish_global_coupons' ) );
}
/**
* Get single instance of WC_SC_Global_Coupons
*
* @return WC_SC_Global_Coupons Singleton object of WC_SC_Global_Coupons
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name = '', $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Set global coupons in options table for faster fetching
*/
public function set_global_coupons() {
global $wpdb;
$global_coupon_option_name = 'sc_display_global_coupons';
$global_coupons = get_option( $global_coupon_option_name );
$current_sc_version = get_option( 'sa_sc_db_version', '' ); // code for updating the db - for autoload related fix.
if ( false === $global_coupons ) {
$wpdb->query( $wpdb->prepare( 'SET SESSION group_concat_max_len=%d', 999999 ) ); // phpcs:ignore
$wpdb->delete( $wpdb->prefix . 'options', array( 'option_name' => $global_coupon_option_name ) ); // WPCS: cache ok, db call ok.
$wpdb->query( // phpcs:ignore
$wpdb->prepare(
"REPLACE INTO {$wpdb->prefix}options (option_name, option_value, autoload)
SELECT %s,
IFNULL(GROUP_CONCAT(p.id SEPARATOR ','), ''),
%s
FROM {$wpdb->prefix}posts AS p
JOIN {$wpdb->prefix}postmeta AS pm
ON(pm.post_id = p.ID
AND p.post_type = %s
AND p.post_status = %s
AND pm.meta_key = %s
AND pm.meta_value = %s)
",
$global_coupon_option_name,
'no',
'shop_coupon',
'publish',
'sc_is_visible_storewide',
'yes'
)
);
if ( ! empty( $this->sc_get_option( $global_coupon_option_name ) ) ) {
$wpdb->query( // phpcs:ignore
$wpdb->prepare(
"UPDATE {$wpdb->prefix}options
SET option_value = (SELECT IFNULL(GROUP_CONCAT(DISTINCT pm.post_id SEPARATOR ','), '')
FROM {$wpdb->prefix}postmeta AS pm
WHERE ( ( pm.meta_key = %s AND CAST(pm.meta_value AS CHAR) = %s )
OR NOT EXISTS( SELECT 1 FROM {$wpdb->prefix}postmeta AS pm1 WHERE pm1.meta_key = %s AND pm.post_id = pm1.post_id ) )
AND FIND_IN_SET(pm.post_id, (SELECT option_value FROM (SELECT option_value FROM {$wpdb->prefix}options WHERE option_name = %s) as temp )) > 0 )
WHERE option_name = %s",
'customer_email',
'a:0:{}',
'customer_email',
$global_coupon_option_name,
$global_coupon_option_name
)
);
if ( ! empty( $this->sc_get_option( $global_coupon_option_name ) ) ) {
$wpdb->query( // phpcs:ignore
$wpdb->prepare(
"UPDATE {$wpdb->prefix}options
SET option_value = (SELECT IFNULL(GROUP_CONCAT(post_id SEPARATOR ','), '')
FROM {$wpdb->prefix}postmeta
WHERE meta_key = %s
AND CAST(meta_value AS CHAR) != %s
AND FIND_IN_SET(post_id, (SELECT option_value FROM (SELECT option_value FROM {$wpdb->prefix}options WHERE option_name = %s) as temp )) > 0 )
WHERE option_name = %s",
'auto_generate_coupon',
'yes',
$global_coupon_option_name,
$global_coupon_option_name
)
);
if ( ! empty( $this->sc_get_option( $global_coupon_option_name ) ) ) {
$wpdb->query( // phpcs:ignore
$wpdb->prepare(
"UPDATE {$wpdb->prefix}options
SET option_value = (SELECT IFNULL(GROUP_CONCAT(post_id SEPARATOR ','), '')
FROM {$wpdb->prefix}postmeta
WHERE meta_key = %s
AND CAST(meta_value AS CHAR) != %s
AND FIND_IN_SET(post_id, (SELECT option_value FROM (SELECT option_value FROM {$wpdb->prefix}options WHERE option_name = %s) as temp )) > 0 )
WHERE option_name = %s",
'discount_type',
'smart_coupon',
$global_coupon_option_name,
$global_coupon_option_name
)
);
if ( ! empty( $this->sc_get_option( $global_coupon_option_name ) ) ) {
$wpdb->query( // phpcs:ignore
$wpdb->prepare(
"UPDATE {$wpdb->prefix}options
SET option_value = (SELECT IFNULL(GROUP_CONCAT(DISTINCT pm_expiry_date.post_id SEPARATOR ','), '')
FROM {$wpdb->prefix}postmeta AS pm_expiry_date
JOIN {$wpdb->prefix}postmeta AS pm_expiry_time
on ( pm_expiry_time.post_id = pm_expiry_date.post_id
AND pm_expiry_date.meta_key = %s
AND pm_expiry_time.meta_key = %s
)
WHERE ( (pm_expiry_date.meta_value IS NULL OR pm_expiry_date.meta_value = '')
OR ( IFNULL(pm_expiry_date.meta_value, 0) + IFNULL(pm_expiry_time.meta_value, 0) ) > %d )
AND FIND_IN_SET(pm_expiry_date.post_id, (SELECT option_value FROM (SELECT option_value FROM {$wpdb->prefix}options WHERE option_name = %s) as temp )) > 0 )
WHERE option_name = %s",
'date_expires',
'wc_sc_expiry_time',
time(),
$global_coupon_option_name,
$global_coupon_option_name
)
);
$global_coupons = $this->sc_get_option( $global_coupon_option_name );
}
}
}
}
}
if ( ( empty( $current_sc_version ) || version_compare( $current_sc_version, '3.3.6', '<' ) ) && ! empty( $this->sc_get_option( $global_coupon_option_name ) ) ) {
$wpdb->query( // phpcs:ignore
$wpdb->prepare(
"UPDATE {$wpdb->prefix}options
SET autoload = %s
WHERE option_name = %s",
'no',
$global_coupon_option_name
)
);
$current_sc_version = '3.3.6';
update_option( 'sa_sc_db_version', $current_sc_version, 'no' );
}
}
/**
* Function to update list of global coupons
*
* @param int $post_id The post id.
* @param string $action Action.
* @param WC_Coupn $coupon The coupon object.
*/
public function sc_update_global_coupons( $post_id, $action = 'add', $coupon = null ) {
if ( empty( $post_id ) ) {
return;
}
if ( 'shop_coupon' !== get_post_type( $post_id ) ) {
return;
}
if ( is_null( $coupon ) || ! is_a( $coupon, 'WC_Coupon' ) ) {
$coupon = new WC_Coupon( $post_id );
}
$coupon_status = ( $this->is_callable( $coupon, 'get_status' ) ) ? $coupon->get_status() : get_post_status( $post_id );
if ( $this->is_callable( $coupon, 'get_meta' ) ) {
$customer_email = $coupon->get_email_restrictions();
$sc_is_visible_storewide = $coupon->get_meta( 'sc_is_visible_storewide' );
$auto_generate_coupon = $coupon->get_meta( 'auto_generate_coupon' );
$discount_type = $coupon->get_discount_type();
} else {
$coupon_meta = get_post_meta( $post_id );
$customer_email = ( ! empty( $coupon_meta['customer_email'] ) ) ? $coupon_meta['customer_email'][0] : '';
$sc_is_visible_storewide = ( ! empty( $coupon_meta['sc_is_visible_storewide'] ) ) ? $coupon_meta['sc_is_visible_storewide'][0] : '';
$auto_generate_coupon = ( ! empty( $coupon_meta['auto_generate_coupon'] ) ) ? $coupon_meta['auto_generate_coupon'][0] : '';
$discount_type = ( ! empty( $coupon_meta['discount_type'] ) ) ? $coupon_meta['discount_type'][0] : '';
}
$global_coupons_list = get_option( 'sc_display_global_coupons' );
$global_coupons = ( ! empty( $global_coupons_list ) ) ? explode( ',', $global_coupons_list ) : array();
$key = array_search( (string) $post_id, $global_coupons, true );
if ( ( 'publish' === $coupon_status
&& ( empty( $customer_email ) || serialize( array() ) === $customer_email ) // phpcs:ignore
&& ( ! empty( $sc_is_visible_storewide ) && 'yes' === $sc_is_visible_storewide )
&& ( ! empty( $auto_generate_coupon ) && 'yes' !== $auto_generate_coupon )
&& ( ! empty( $discount_type ) && 'smart_coupon' !== $discount_type ) )
|| ( 'trash' === $coupon_status && 'delete' === $action ) ) {
if ( 'add' === $action && false === $key ) {
$global_coupons[] = $post_id;
} elseif ( 'delete' === $action && false !== $key ) {
unset( $global_coupons[ $key ] );
}
} else {
if ( false !== $key ) {
unset( $global_coupons[ $key ] );
}
}
update_option( 'sc_display_global_coupons', implode( ',', array_unique( $global_coupons ) ), 'no' );
}
/**
* Function to update list of global coupons on trash / delete coupon
*
* @param int $post_id The post id.
*/
public function sc_delete_global_coupons( $post_id ) {
if ( empty( $post_id ) ) {
return;
}
if ( 'shop_coupon' !== get_post_type( $post_id ) ) {
return;
}
$this->sc_update_global_coupons( $post_id, 'delete' );
}
/**
* Function to update list of global coupons on untrash coupon
*
* @param int $post_id The post id.
*/
public function sc_untrash_global_coupons( $post_id ) {
if ( empty( $post_id ) ) {
return;
}
if ( 'shop_coupon' !== get_post_type( $post_id ) ) {
return;
}
$this->sc_update_global_coupons( $post_id );
}
/**
* Update global coupons data for sheduled coupons
*
* @param WP_Post $post The post object.
*/
public function future_to_publish_global_coupons( $post = null ) {
$post_id = ( ! empty( $post->ID ) ) ? $post->ID : 0;
if ( empty( $post ) || empty( $post_id ) ) {
return;
}
if ( 'shop_coupon' !== $post->post_type ) {
return;
}
$this->sc_update_global_coupons( $post_id );
}
/**
* Update global coupons on saving coupon
*
* @param int $post_id The post id.
* @param WC_Coupon $coupon The coupon object.
*/
public function update_global_coupons( $post_id = 0, $coupon = null ) {
if ( empty( $post_id ) ) {
return;
}
if ( is_null( $coupon ) || ! is_a( $coupon, 'WC_Coupon' ) ) {
$coupon = new WC_Coupon( $post_id );
}
$this->sc_update_global_coupons( $post_id, 'add', $coupon );
}
}
}
WC_SC_Global_Coupons::get_instance();

View File

@@ -1,513 +0,0 @@
<?php
/**
* Smart Coupons fields in orders
*
* @author StoreApps
* @since 3.3.0
* @version 1.5.0
*
* @package woocommerce-smart-coupons/includes/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Order_Fields' ) ) {
/**
* Class for handling Smart Coupons' field in orders
*/
class WC_SC_Order_Fields {
/**
* Variable to hold instance of WC_SC_Order_Fields
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
private function __construct() {
add_action( 'woocommerce_admin_order_totals_after_tax', array( $this, 'admin_order_totals_add_smart_coupons_discount_details' ) );
add_filter( 'woocommerce_get_order_item_totals', array( $this, 'add_smart_coupons_discount_details' ), 10, 2 );
add_action( 'wp_loaded', array( $this, 'order_fields_hooks' ) );
add_filter( 'woocommerce_cart_totals_coupon_label', array( $this, 'cart_totals_smart_coupons_label' ), 10, 2 );
add_filter( 'woocommerce_cart_totals_order_total_html', array( $this, 'cart_totals_order_total_html' ), 99 );
add_filter( 'woocommerce_get_formatted_order_total', array( $this, 'get_formatted_order_total' ), 99, 2 );
add_action( 'woocommerce_email_after_order_table', array( $this, 'show_store_credit_balance' ), 10, 3 );
add_filter( 'woocommerce_get_coupon_id_from_code', array( $this, 'get_coupon_id_from_code' ), 1000, 3 );
}
/**
* Get single instance of WC_SC_Order_Fields
*
* @return WC_SC_Order_Fields Singleton object of WC_SC_Order_Fields
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Function to get total credit used in an order
*
* @param WC_Order $order The order object.
* @return float $total_credit_used
*/
public function get_total_credit_used_in_order( $order = null ) {
if ( empty( $order ) ) {
return 0;
}
$total_credit_used = 0;
$coupons = $order->get_items( 'coupon' );
if ( ! empty( $coupons ) ) {
foreach ( $coupons as $item_id => $item ) {
$code = ( is_object( $item ) && is_callable( array( $item, 'get_code' ) ) ) ? $item->get_code() : $item['code'];
if ( empty( $code ) ) {
continue;
}
$coupon = new WC_Coupon( $code );
if ( ! empty( $coupon ) && $coupon instanceof WC_Coupon ) {
if ( $this->is_wc_gte_30() ) {
$coupon_discount_type = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_discount_type' ) ) ) ? $coupon->get_discount_type() : '';
$discount_type = ( ! empty( $coupon_discount_type ) ) ? $coupon_discount_type : '';
} else {
$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
}
if ( 'smart_coupon' !== $discount_type ) {
continue;
}
$discount = ( is_object( $item ) && is_callable( array( $item, 'get_discount' ) ) ) ? $item->get_discount() : $item['discount_amount'];
$discount_tax = ( is_object( $item ) && is_callable( array( $item, 'get_discount_tax' ) ) ) ? $item->get_discount_tax() : $item['discount_amount_tax'];
$total_credit_used += $discount;
$sc_include_tax = $this->is_store_credit_include_tax();
// Check if discount include tax.
if ( 'yes' === $sc_include_tax && ! empty( $discount_tax ) ) {
$total_credit_used += $discount_tax;
} else {
$prices_include_tax = ( 'incl' === get_option( 'woocommerce_tax_display_cart' ) ) ? true : false;
if ( true === $prices_include_tax ) {
$apply_before_tax = get_option( 'woocommerce_smart_coupon_apply_before_tax', 'no' );
if ( 'yes' === $apply_before_tax ) {
$_sc_include_tax = get_option( 'woocommerce_smart_coupon_include_tax', 'no' );
if ( 'no' === $_sc_include_tax ) {
$total_credit_used += $discount_tax;
}
}
}
}
}
}
}
return $total_credit_used;
}
/**
* Function to show store credit used in order admin panel
*
* @param int $order_id The order id.
*/
public function admin_order_totals_add_smart_coupons_discount_details( $order_id = 0 ) {
global $store_credit_label;
if ( empty( $order_id ) ) {
return;
}
$order = wc_get_order( $order_id );
$total_credit_used = $this->get_total_credit_used_in_order( $order );
if ( empty( $total_credit_used ) ) {
return;
}
?>
<tr>
<td class="label">
<?php
/* translators: %s: singular name for store credit */
echo ! empty( $store_credit_label['singular'] ) ? sprintf( esc_html__( '%s Used', 'woocommerce-smart-coupons' ), esc_html( ucwords( $store_credit_label['singular'] ) ) ) : esc_html__( 'Store Credit Used', 'woocommerce-smart-coupons' );
?>
<span class="tips" data-tip="<?php echo esc_attr__( 'This is the total credit used.', 'woocommerce-smart-coupons' ); ?>">[?]</span>:</td>
<td width="1%"></td>
<td class="total">
<?php
if ( $this->is_wc_gte_30() ) {
echo wc_price( $total_credit_used, array( 'currency' => $order->get_currency() ) ); // phpcs:ignore
} else {
echo wc_price( $total_credit_used, array( 'currency' => $order->get_order_currency() ) ); // phpcs:ignore
}
?>
</td>
</tr>
<?php
}
/**
* Function to add hooks based on conditions
*/
public function order_fields_hooks() {
if ( $this->is_wc_gte_30() ) {
add_filter( 'woocommerce_order_get_total_discount', array( $this, 'smart_coupons_order_amount_total_discount' ), 10, 2 );
} else {
add_filter( 'woocommerce_order_amount_total_discount', array( $this, 'smart_coupons_order_amount_total_discount' ), 10, 2 );
}
}
/**
* Function to add details of discount coming from Smart Coupons
*
* @param array $total_rows All rows.
* @param WC_Order $order The order object.
* @return array $total_rows
*/
public function add_smart_coupons_discount_details( $total_rows = array(), $order = null ) {
global $store_credit_label;
if ( empty( $order ) ) {
return $total_rows;
}
$total_credit_used = $this->get_total_credit_used_in_order( $order );
$offset = array_search( 'order_total', array_keys( $total_rows ), true );
if ( false !== $offset && ! empty( $total_credit_used ) && ! empty( $total_rows ) ) {
$total_rows = array_merge(
array_slice( $total_rows, 0, $offset ),
array(
'smart_coupon' => array(
/* translators: %s: singular name for store credit */
'label' => ! empty( $store_credit_label['singular'] ) ? sprintf( __( '%s Used:', 'woocommerce-smart-coupons' ), ucwords( $store_credit_label['singular'] ) ) : __( 'Store Credit Used:', 'woocommerce-smart-coupons' ),
'value' => '-' . wc_price( $total_credit_used ),
),
),
array_slice( $total_rows, $offset, null )
);
$total_discount = $order->get_total_discount();
// code to check and manipulate 'Discount' amount based on Store Credit used.
if ( $total_discount === $total_credit_used ) {
unset( $total_rows['discount'] );
} else {
$total_discount = $total_discount - $total_credit_used;
$total_rows['discount']['value'] = '-' . wc_price( $total_discount );
}
}
return $total_rows;
}
/**
* Function to include discounts from Smart Coupons in total discount of order
*
* @param float $total_discount Total discount.
* @param WC_Order $order The order object.
* @return float $total_discount
*/
public function smart_coupons_order_amount_total_discount( $total_discount, $order = null ) {
// To avoid adding store credit in 'Discount' field on order admin panel.
if ( did_action( 'woocommerce_admin_order_item_headers' ) >= 1 ) {
return $total_discount;
}
$total_credit_used = $this->get_total_credit_used_in_order( $order );
if ( $total_credit_used > 0 ) {
$total_discount += $total_credit_used;
}
return $total_discount;
}
/**
* Function to add label for smart_coupons in cart total
*
* @param string $default_label Default label.
* @param WC_Coupon $coupon The coupon object.
* @return string $new_label
*/
public function cart_totals_smart_coupons_label( $default_label = '', $coupon = null ) {
global $store_credit_label;
if ( empty( $coupon ) ) {
return $default_label;
}
if ( $this->is_wc_gte_30() ) {
$discount_type = ( ! empty( $coupon ) && is_callable( array( $coupon, 'get_discount_type' ) ) ) ? $coupon->get_discount_type() : '';
$coupon_code = ( ! empty( $coupon ) && is_callable( array( $coupon, 'get_code' ) ) ) ? $coupon->get_code() : '';
} else {
$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
$coupon_code = ( ! empty( $coupon->code ) ) ? $coupon->code : '';
}
if ( ! empty( $discount_type ) && 'smart_coupon' === $discount_type ) {
$credit_label = ! empty( $store_credit_label['singular'] ) ? ucwords( $store_credit_label['singular'] ) . ':' : __( 'Store Credit:', 'woocommerce-smart-coupons' );
return $credit_label . ' ' . $coupon_code;
}
return $default_label;
}
/**
* Modify Tax detail HTML if store credit is applied, in cart
*
* @param string $html The total html.
* @return string $html
*/
public function cart_totals_order_total_html( $html = null ) {
if ( empty( $html ) ) {
return $html;
}
if ( ! class_exists( 'WCS_SC_Compatibility' ) ) {
include_once 'class-wcs-compatibility.php';
}
$is_display_price_incl_tax = ( $this->is_wc_gte_33() ) ? WC()->cart->display_prices_including_tax() : ( 'incl' === WC()->cart->tax_display_cart );
if ( wc_tax_enabled() && true === $is_display_price_incl_tax ) {
$applied_coupons = ( is_object( WC()->cart ) && is_callable( array( WC()->cart, 'get_applied_coupons' ) ) ) ? WC()->cart->get_applied_coupons() : array();
if ( empty( $applied_coupons ) ) {
return $html;
}
foreach ( $applied_coupons as $code ) {
$coupon = new WC_Coupon( $code );
if ( $this->is_wc_gte_30() ) {
$discount_type = $coupon->get_discount_type();
} else {
$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
}
if ( ! is_a( $coupon, 'WC_Coupon' ) || 'smart_coupon' !== $discount_type ) {
continue;
}
if ( WC()->cart->get_total() === 0 || WC()->cart->get_total() <= WC()->cart->get_taxes_total() ) {
$cart_contains_subscription = WCS_SC_Compatibility::is_cart_contains_subscription();
$calculation_type = '';
if ( $cart_contains_subscription ) {
$calculation_type = WC_Subscriptions_Cart::get_calculation_type();
if ( 'recurring_total' !== $calculation_type ) {
return '<strong>' . WC()->cart->get_total() . '</strong> ';
} else {
return $html;
}
} else {
return '<strong>' . WC()->cart->get_total() . '</strong> ';
}
}
}
}
return $html;
}
/**
* Modify Tax detail HTML if store credit is applied, in order
*
* @param string $html The order total html.
* @param WC_Order $order The order object (optional).
* @return string $html
*/
public function get_formatted_order_total( $html = null, $order = null ) {
if ( empty( $html ) || empty( $order ) ) {
return $html;
}
if ( $this->is_wc_gte_30() ) {
$tax_display = get_option( 'woocommerce_tax_display_cart' );
} else {
$tax_display = ( ! empty( $order->tax_display_cart ) ) ? $order->tax_display_cart : '';
}
if ( wc_tax_enabled() && 'incl' === $tax_display ) {
$applied_coupons = $this->get_coupon_codes( $order );
if ( empty( $applied_coupons ) ) {
return $html;
}
foreach ( $applied_coupons as $code ) {
$coupon = new WC_Coupon( $code );
if ( $this->is_wc_gte_30() ) {
$discount_type = $coupon->get_discount_type();
} else {
$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
}
if ( ! is_a( $coupon, 'WC_Coupon' ) || 'smart_coupon' !== $discount_type ) {
continue;
}
if ( $order->get_total() === 0 || $order->get_total() <= $order->get_total_tax() ) {
return wc_price( $order->get_total() );
}
}
}
return $html;
}
/**
* Function to notify user about remaining balance in Store Credit in "Order Complete" email
*
* @param WC_Order $order The order object.
* @param boolean $send_to_admin Is send to admin.
* @param boolean $plain_text Is plain text email.
*/
public function show_store_credit_balance( $order = false, $send_to_admin = false, $plain_text = false ) {
global $store_credit_label;
if ( $send_to_admin ) {
return;
}
if ( $this->is_wc_gte_30() ) {
$order_refunds = ( ! empty( $order ) && is_callable( array( $order, 'get_refunds' ) ) ) ? $order->get_refunds() : array();
} else {
$order_refunds = ( ! empty( $order->refunds ) ) ? $order->refunds : array();
}
if ( ! empty( $order_refunds ) ) {
return;
}
$used_coupons = $this->get_coupon_codes( $order );
if ( count( $used_coupons ) > 0 ) {
$store_credit_balance = '';
foreach ( $used_coupons as $code ) {
if ( ! $code ) {
continue;
}
$coupon = new WC_Coupon( $code );
if ( $this->is_wc_gte_30() ) {
$discount_type = $coupon->get_discount_type();
$coupon_code = $coupon->get_code();
} else {
$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
$coupon_code = ( ! empty( $coupon->code ) ) ? $coupon->code : '';
}
$coupon_amount = $this->get_amount( $coupon, true, $order );
if ( 'smart_coupon' === $discount_type && $coupon_amount > 0 ) {
$store_credit_balance .= '<li><strong>' . $coupon_code . '</strong> &mdash; ' . wc_price( $coupon_amount ) . '</li>';
}
}
if ( ! empty( $store_credit_balance ) ) {
/* translators: %s: singular name for store credit */
$balance_left_txt = ! empty( $store_credit_label['singular'] ) ? sprintf( __( '%s Balance ', 'woocommerce-smart-coupons' ), esc_html( ucwords( $store_credit_label['singular'] ) ) ) : __( 'Store Credit / Gift Card Balance', 'woocommerce-smart-coupons' );
echo '<br /><h3>' . esc_html( $balance_left_txt ) . ': </h3>';
echo '<ul>' . wp_kses_post( $store_credit_balance ) . '</ul><br />'; // phpcs:ignore
}
}
}
/**
* Force try to find the coupon's id by code
* in some cases like when coupon is trashed
*
* @param integer $id The coupon's id.
* @param string $code The coupon code.
* @param integer $exclude_id Exclude coupon's id.
* @return integer
*/
public function get_coupon_id_from_code( $id = 0, $code = '', $exclude_id = 0 ) {
if ( empty( $id ) ) {
$backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore
$backtrace_functions = wp_list_pluck( $backtrace, 'function' );
if ( in_array( 'get_total_credit_used_in_order', $backtrace_functions, true ) ) {
$index = array_search( 'get_total_credit_used_in_order', $backtrace_functions, true );
$traced = ( ! empty( $backtrace[ $index ] ) && 'WC_SC_Order_Fields' === $backtrace[ $index ]['class'] && 'get_total_credit_used_in_order' === $backtrace[ $index ]['function'] );
if ( true === $traced ) {
global $wpdb;
$post_id = $wpdb->get_var( // phpcs:ignore
$wpdb->prepare(
"
SELECT ID
FROM $wpdb->posts
WHERE post_title = %s
AND post_type = 'shop_coupon'
ORDER BY ID DESC
",
$code
)
);
if ( ! empty( $post_id ) ) {
return absint( $post_id );
}
}
}
}
return $id;
}
}
}
WC_SC_Order_Fields::get_instance();

View File

@@ -1,470 +0,0 @@
<?php
/**
* Coupons via URL
*
* @author StoreApps
* @since 4.7.0
* @version 1.3.0
*
* @package woocommerce-smart-coupons/includes/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Print_Coupon' ) ) {
/**
* Class for handling coupons applied via URL
*/
class WC_SC_Print_Coupon {
/**
* Variable to hold instance of WC_SC_Print_Coupon
*
* @var $instance
*/
private static $instance = null;
/**
* HTML template path.
*
* @var string
*/
private $template_html;
/**
* Template path.
*
* @var string
*/
private $template_base;
/**
* Constructor
*/
private function __construct() {
// Use our plugin templates directory as the template base.
$this->template_base = dirname( WC_SC_PLUGIN_FILE ) . '/templates/';
// Email template location.
$print_style = get_option( 'wc_sc_coupon_print_style', 'default' );
$this->template_html = 'print-coupons-' . $print_style . '.php';
add_action( 'init', array( $this, 'may_be_save_terms_page' ) );
add_action( 'admin_notices', array( $this, 'may_be_show_terms_notice' ) );
add_action( 'wp_ajax_wc_sc_terms_notice_action', array( $this, 'terms_notice_action' ) );
add_action( 'wp_loaded', array( $this, 'print_coupon_from_url' ), 20 );
add_filter( 'display_post_states', array( $this, 'display_post_states' ), 10, 2 );
add_filter( 'pre_delete_post', array( $this, 'prevent_deletion_of_terms_page' ), 10, 3 );
add_filter( 'pre_trash_post', array( $this, 'prevent_deletion_of_terms_page' ), 10, 2 );
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts_and_styles' ), 99 );
}
/**
* Get single instance of WC_SC_Print_Coupon
*
* @return WC_SC_Print_Coupon Singleton object of WC_SC_Print_Coupon
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Function to create and save terms page if already not created
*/
public function may_be_save_terms_page() {
$terms_page_option = $this->get_terms_page_option();
$terms_page_id = get_option( $terms_page_option, false );
// If terms page option is not created yet or may be deleted.
if ( empty( $terms_page_id ) ) {
$terms_page_id = $this->add_terms_page();
$this->update_terms_page_option( $terms_page_id );
}
}
/**
* Function to add create terms page
*/
public function add_terms_page() {
$name = _x( 'wc-sc-coupons-terms', 'Page slug', 'woocommerce-smart-coupons' );
$title = _x( 'Smart Coupons Terms', 'Page title', 'woocommerce-smart-coupons' );
$terms_page_id = $this->create_page( $name, $title, '', 'private' );
return $terms_page_id;
}
/**
* Utility function for creating Smart Coupons' pages
*
* @param string $slug Page slug.
* @param string $page_title Page title.
* @param string $page_content Page content.
* @param string $post_status Page status.
* @param int $post_parent Page parent.
* @return int $page_id Create page id
*/
public function create_page( $slug = '', $page_title = '', $page_content = '', $post_status = 'publish', $post_parent = 0 ) {
$page_id = 0;
if ( empty( $slug ) ) {
return $page_id;
}
$args = array(
'role' => 'administrator',
'orderby' => 'ID',
'order' => 'ASC',
'fields' => 'ID',
);
$admin_user_ids = get_users( $args );
$page_data = array(
'post_author' => current( $admin_user_ids ),
'post_status' => $post_status,
'post_type' => 'page',
'post_name' => $slug,
'post_title' => $page_title,
'post_content' => $page_content,
'post_parent' => $post_parent,
'comment_status' => 'closed',
);
$page_id = wp_insert_post( $page_data );
return $page_id;
}
/**
* Function to get terms page id
*/
public function get_terms_page_id() {
$terms_page_option = $this->get_terms_page_option();
$terms_page_id = get_option( $terms_page_option, false );
return $terms_page_id;
}
/**
* Function to get the option key name for terms page
*/
public function get_terms_page_option() {
// Option key name for Smart Coupons' term page id.
$terms_page_option = 'wc_sc_terms_page_id';
return $terms_page_option;
}
/**
* Function to update terms' page id in the options table
*
* @param int $terms_page_id Page parent.
*/
public function update_terms_page_option( $terms_page_id = 0 ) {
if ( ! empty( $terms_page_id ) && is_numeric( $terms_page_id ) ) {
$terms_page_option = $this->get_terms_page_option();
update_option( $terms_page_option, $terms_page_id, 'no' );
}
}
/**
* Function to show notice for entering terms' page content
*/
public function may_be_show_terms_notice() {
global $pagenow, $post;
$is_coupon_enabled = wc_coupons_enabled();
// Don't show message if coupons are not enabled.
if ( false === $is_coupon_enabled ) {
return;
}
$terms_page_id = $this->get_terms_page_id();
// Return if terms page hasn't been set.
if ( empty( $terms_page_id ) ) {
return;
}
$valid_post_types = array( 'shop_coupon', 'shop_order', 'product' );
$valid_pagenow = array( 'edit.php', 'post.php', 'plugins.php' );
$is_show_terms_notice = get_option( 'wc_sc_is_show_terms_notice', false );
$get_post_type = ( ! empty( $post->post_type ) ) ? $post->post_type : '';
$get_page = ( ! empty( $_GET['page'] ) ) ? wc_clean( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore
$get_tab = ( ! empty( $_GET['tab'] ) ) ? wc_clean( wp_unslash( $_GET['tab'] ) ) : ''; // phpcs:ignore
$is_page = ( in_array( $pagenow, $valid_pagenow, true ) || in_array( $get_post_type, $valid_post_types, true ) || ( 'admin.php' === $pagenow && ( 'wc-smart-coupons' === $get_page || 'wc-smart-coupons' === $get_tab ) ) );
// Terms page notice.
if ( $is_page && 'no' !== $is_show_terms_notice ) {
if ( ! wp_script_is( 'jquery' ) ) {
wp_enqueue_script( 'jquery' );
}
?>
<style type="text/css" media="screen">
#wc_sc_terms_notice .wc_sc_terms_notice_action {
float: right;
padding: 0.5em 0;
text-align: right;
}
</style>
<script type="text/javascript">
jQuery(function(){
jQuery('body').on('click', '#wc_sc_terms_notice a.wc_sc_terms_notice_remove, #wc_sc_terms_notice a.wc_sc_terms_redirect', function(){
let notice_action = jQuery( this ).data('action');
jQuery.ajax({
url: decodeURIComponent( '<?php echo rawurlencode( admin_url( 'admin-ajax.php' ) ); ?>' ),
type: 'post',
dataType: 'json',
data: {
action: 'wc_sc_terms_notice_action',
security: '<?php echo esc_html( wp_create_nonce( 'wc-sc-terms-notice-action' ) ); ?>',
do: notice_action
},
success: function( response ){
if ( response.success != undefined && response.success != '' && response.success == 'yes' ) {
if( response.redirect_url != undefined && response.redirect_url != '' ) {
window.location.href = response.redirect_url;
} else {
jQuery('#wc_sc_terms_notice').fadeOut(500, function(){ jQuery('#wc_sc_terms_notice').remove(); });
}
}
}
});
return false;
});
});
</script>
<div id="wc_sc_terms_notice" class="updated fade">
<div class="wc_sc_terms_notice_action">
<a href="javascript:void(0)" class="wc_sc_terms_notice_remove" data-action="remove"><?php echo esc_html__( 'Never show again', 'woocommerce-smart-coupons' ); ?></a>
</div>
<p>
<?php echo esc_html__( 'Smart Coupons has created a coupon\'s terms page (used during coupon printing) for you. Please edit it as required from', 'woocommerce-smart-coupons' ) . ' <a href="javascript:void(0)" class="wc_sc_terms_redirect" data-action="redirect">' . esc_html__( 'here', 'woocommerce-smart-coupons' ) . '</a>'; ?>
</p>
</div>
<?php
}
}
/**
* Function to handle Smart Coupons terms notice action
*/
public function terms_notice_action() {
check_ajax_referer( 'wc-sc-terms-notice-action', 'security' );
$post_do = ( ! empty( $_POST['do'] ) ) ? wc_clean( wp_unslash( $_POST['do'] ) ) : ''; // phpcs:ignore
if ( empty( $post_do ) ) {
return;
}
$response = array(
'success' => 'no',
);
$option_updated = update_option( 'wc_sc_is_show_terms_notice', 'no', 'no' );
if ( true === $option_updated ) {
$response['success'] = 'yes';
if ( 'redirect' === $post_do ) {
$terms_page_id = $this->get_terms_page_id();
$terms_edit_url = get_edit_post_link( $terms_page_id, 'edit' );
if ( ! empty( $terms_edit_url ) ) {
$response['redirect_url'] = $terms_edit_url;
}
}
}
wp_send_json( $response );
}
/**
* Print coupon codes along with terms' page content
*/
public function print_coupon_from_url() {
global $woocommerce_smart_coupon;
if ( empty( $_SERVER['QUERY_STRING'] ) ) {
return;
}
parse_str( wp_unslash( $_SERVER['QUERY_STRING'] ), $coupon_args ); // phpcs:ignore
$coupon_args = wc_clean( $coupon_args );
if ( ! empty( $coupon_args['print-coupons'] ) && 'yes' === $coupon_args['print-coupons'] && ! empty( $coupon_args['source'] ) && 'wc-smart-coupons' === $coupon_args['source'] && ! empty( $coupon_args['coupon-codes'] ) ) {
$coupon_args['coupon-codes'] = urldecode( $coupon_args['coupon-codes'] );
$coupon_codes = explode( ',', $coupon_args['coupon-codes'] );
$coupon_codes = array_filter( $coupon_codes ); // Remove empty coupon codes if any.
$coupons_data = array();
foreach ( $coupon_codes as $coupon_code ) {
if ( empty( $coupon_code ) ) {
continue;
}
$coupons_data[] = array(
'code' => $coupon_code,
);
}
if ( ! empty( $coupons_data ) ) {
$terms_page_id = $this->get_terms_page_id();
$terms_page_title = '';
$terms_page_content = '';
if ( ! empty( $terms_page_id ) ) {
$terms_page = get_post( $terms_page_id );
if ( is_a( $terms_page, 'WP_Post' ) ) {
$terms_page_title = ( ! empty( $terms_page->post_title ) ) ? $terms_page->post_title : '';
$terms_page_content = ( ! empty( $terms_page->post_content ) ) ? $terms_page->post_content : '';
if ( ! empty( $terms_page_content ) ) {
$terms_page_content = apply_filters( 'the_content', $terms_page_content );
}
}
}
$design = get_option( 'wc_sc_setting_coupon_design', 'basic' );
$background_color = get_option( 'wc_sc_setting_coupon_background_color', '#39cccc' );
$foreground_color = get_option( 'wc_sc_setting_coupon_foreground_color', '#30050b' );
$third_color = get_option( 'wc_sc_setting_coupon_third_color', '#39cccc' );
$show_coupon_description = get_option( 'smart_coupons_show_coupon_description', 'no' );
$valid_designs = $this->get_valid_coupon_designs();
if ( ! in_array( $design, $valid_designs, true ) ) {
$design = 'basic';
}
$coupon_styles = $woocommerce_smart_coupon->get_coupon_styles( $design );
$default_path = $this->template_base;
$template_path = $woocommerce_smart_coupon->get_template_base_dir( $this->template_html );
wc_get_template(
$this->template_html,
array(
'coupon_codes' => $coupons_data,
'terms_page_title' => $terms_page_title,
'terms_page_content' => $terms_page_content,
'background_color' => $background_color,
'foreground_color' => $foreground_color,
'third_color' => $third_color,
'coupon_styles' => $coupon_styles,
'design' => $design,
'show_coupon_description' => $show_coupon_description,
),
$template_path,
$default_path
);
}
exit;
}
}
/**
* Add display state for printable coupon's terms page
*
* @param array $post_states An array of post display states.
* @param WP_Post $post The current post object.
*/
public function display_post_states( $post_states, $post ) {
$terms_page_id = $this->get_terms_page_id();
if ( ! empty( $post->ID ) && ! empty( $terms_page_id ) && absint( $terms_page_id ) === absint( $post->ID ) ) {
if ( isset( $post_states['private'] ) ) {
unset( $post_states['private'] );
}
$post_states['wc_sc_coupons_terms'] = __( 'Used during coupon printing', 'woocommerce-smart-coupons' );
}
return $post_states;
}
/**
* Prevent Deletion Of Terms Page
*
* @param mixed $is_delete Whether to allow deletion or not.
* @param WP_Post $post The post to delete.
* @param boolean $force_delete Whether to permanently delete or not.
* @return mixed
*/
public function prevent_deletion_of_terms_page( $is_delete = null, $post = null, $force_delete = false ) {
$terms_page_id = $this->get_terms_page_id();
if ( ! empty( $post->ID ) && ! empty( $terms_page_id ) && absint( $terms_page_id ) === absint( $post->ID ) ) {
return false;
}
return $is_delete;
}
/**
* Scripts & styles
*/
public function enqueue_scripts_and_styles() {
global $woocommerce_smart_coupon;
if ( empty( $_SERVER['QUERY_STRING'] ) ) {
return;
}
parse_str( wp_unslash( $_SERVER['QUERY_STRING'] ), $coupon_args ); // phpcs:ignore
$coupon_args = wc_clean( $coupon_args );
$design = get_option( 'wc_sc_setting_coupon_design', 'basic' );
if ( ! empty( $coupon_args['print-coupons'] ) && 'yes' === $coupon_args['print-coupons'] && ! empty( $coupon_args['source'] ) && 'wc-smart-coupons' === $coupon_args['source'] && ! empty( $coupon_args['coupon-codes'] ) ) {
if ( 'custom-design' !== $design ) {
if ( ! wp_style_is( 'smart-coupon-designs' ) ) {
wp_enqueue_style( 'smart-coupon-designs' );
}
}
}
}
}
}
WC_SC_Print_Coupon::get_instance();

View File

@@ -1,783 +0,0 @@
<?php
/**
* Handle privacy of customers
*
* @author StoreApps
* @since 3.3.0
* @version 1.1.0
*
* @package woocommerce-smart-coupons/includes/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_Abstract_Privacy' ) ) {
return;
}
if ( ! class_exists( 'WC_SC_Privacy' ) ) {
/**
* Class for handling privacy for customer & maintaining GDPR compliance of the plugin
*/
class WC_SC_Privacy extends WC_Abstract_Privacy {
/**
* Variable to hold instance of WC_SC_Privacy
*
* @var $instance
*/
private static $instance = null;
/**
* Plugin data
*
* @var $plugin_data
*/
public $plugin_data = array();
/**
* Constructor
*/
public function __construct() {
$this->plugin_data = WC_Smart_Coupons::get_smart_coupons_plugin_data();
parent::__construct( $this->plugin_data['Name'] );
/* translators: Plugin's name */
$this->add_exporter( WC_SC_PLUGIN_DIRNAME . '-coupon-data-exporter', sprintf( __( '%s - Coupon Personal Data Exporter', 'woocommerce-smart-coupons' ), $this->plugin_data['Name'] ), array( $this, 'wc_sc_coupon_data_exporter' ) );
/* translators: Plugin's name */
$this->add_eraser( WC_SC_PLUGIN_DIRNAME . '-coupon-data-eraser', sprintf( __( '%s - Coupon Personal Data Eraser', 'woocommerce-smart-coupons' ), $this->plugin_data['Name'] ), array( $this, 'wc_sc_coupon_data_eraser' ) );
/* translators: Plugin's name */
$this->add_exporter( WC_SC_PLUGIN_DIRNAME . '-order-data-exporter', sprintf( __( '%s - Order Personal Data Exporter', 'woocommerce-smart-coupons' ), $this->plugin_data['Name'] ), array( $this, 'wc_sc_order_data_exporter' ) );
/* translators: Plugin's name */
$this->add_eraser( WC_SC_PLUGIN_DIRNAME . '-order-data-eraser', sprintf( __( '%s - Order Personal Data Eraser', 'woocommerce-smart-coupons' ), $this->plugin_data['Name'] ), array( $this, 'wc_sc_order_data_eraser' ) );
/* translators: Plugin's name */
$this->add_exporter( WC_SC_PLUGIN_DIRNAME . '-user-data-exporter', sprintf( __( '%s - User Personal Data Exporter', 'woocommerce-smart-coupons' ), $this->plugin_data['Name'] ), array( $this, 'wc_sc_user_data_exporter' ) );
/* translators: Plugin's name */
$this->add_eraser( WC_SC_PLUGIN_DIRNAME . '-user-data-eraser', sprintf( __( '%s - User Personal Data Eraser', 'woocommerce-smart-coupons' ), $this->plugin_data['Name'] ), array( $this, 'wc_sc_user_data_eraser' ) );
add_action( 'woocommerce_privacy_before_remove_order_personal_data', array( $this, 'remove_order_personal_data' ) );
add_filter( 'woocommerce_get_settings_account', array( $this, 'account_settings' ) );
}
/**
* Get single instance of WC_SC_Privacy
*
* @return WC_SC_Privacy Singleton object of WC_SC_Privacy
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Gets the message of the privacy to display.
*/
public function get_privacy_message() {
$content = '<h2>' . esc_html__( 'Store Credit/Gift Certificate', 'woocommerce-smart-coupons' ) . '</h2>
<strong>' . esc_html__( 'What we access?', 'woocommerce-smart-coupons' ) . '</strong>
<ul>
<li>' . esc_html__( 'If you are logged in: We access your billing email address saved in your account & billing email address entered during purchase', 'woocommerce-smart-coupons' ) . '</li>
<li>' . esc_html__( 'If you are a visitor: We access your billing email address entered during purchase', 'woocommerce-smart-coupons' ) . '</li>
</ul>
<strong>' . esc_html__( 'What we store & why?', 'woocommerce-smart-coupons' ) . '</strong>
<ul>
<li>' . esc_html__( 'Coupon code generated for you', 'woocommerce-smart-coupons' ) . '</li>
<li>' . esc_html__( 'Coupon code passed via URL', 'woocommerce-smart-coupons' ) . '</li>
<li>' . esc_html__( 'Coupon amount, email & message entered for gift card receiver', 'woocommerce-smart-coupons' ) . '</li>
</ul>
<p>' . esc_html__( 'We store these data so that we can process it for you whenever required.', 'woocommerce-smart-coupons' ) . '</p>';
return $content;
}
/**
* Returns Smart Coupons data based on email.
*
* @param string $email_address The email address.
* @param int $page Pagination.
*
* @return array
*/
protected function get_wc_sc_data( $email_address, $page ) {
global $wpdb;
$wpdb->query( $wpdb->prepare( 'SET SESSION group_concat_max_len=%d', 999999 ) ); // phpcs:ignore
$results = wp_cache_get( 'wc_sc_coupon_data_' . sanitize_key( $email_address ), 'woocommerce_smart_coupons' );
if ( false === $results ) {
$results = $wpdb->get_results( // phpcs:ignore
$wpdb->prepare(
"SELECT p.ID,
p.post_title,
p.post_date,
GROUP_CONCAT( pm.meta_key ORDER BY pm.meta_id SEPARATOR '###' ) AS meta_keys,
GROUP_CONCAT( pm.meta_value ORDER BY pm.meta_id SEPARATOR '###' ) AS meta_values
FROM $wpdb->posts AS p
LEFT JOIN $wpdb->postmeta AS pm
ON ( p.ID = pm.post_id AND p.post_type = %s AND pm.meta_key IN ( %s, %s, %s ) )
WHERE pm.meta_value = %s
OR pm.meta_value LIKE %s
OR pm.meta_value <> ''
GROUP BY p.ID
ORDER BY p.ID",
'shop_coupon',
'discount_type',
'customer_email',
'generated_from_order_id',
'smart_coupon',
'%' . $wpdb->esc_like( $email_address ) . '%'
),
ARRAY_A
);
wp_cache_set( 'wc_sc_coupon_data_' . sanitize_key( $email_address ), $results, 'woocommerce_smart_coupons' );
$this->maybe_add_cache_key( 'wc_sc_coupon_data_' . sanitize_key( $email_address ) );
}
$coupon_data = array();
if ( ! empty( $results ) ) {
foreach ( $results as $result ) {
$meta_keys = ( ! empty( $result['meta_keys'] ) ) ? explode( '###', $result['meta_keys'] ) : array();
$meta_values = ( ! empty( $result['meta_values'] ) ) ? explode( '###', $result['meta_values'] ) : array();
if ( count( $meta_keys ) === count( $meta_values ) ) {
$meta_values = array_map( 'maybe_unserialize', $meta_values );
$meta = array_combine( $meta_keys, $meta_values );
if ( empty( $meta['discount_type'] ) || 'smart_coupon' !== $meta['discount_type'] ) {
continue;
}
unset( $meta['discount_type'] );
if ( empty( $meta['customer_email'] ) ) {
continue;
}
$customer_emails = array_unique( $meta['customer_email'] );
$common_email = array_intersect( array( $email_address ), $customer_emails );
if ( empty( $common_email ) ) {
continue;
}
$meta['customer_email'] = current( $common_email );
} else {
continue;
}
if ( empty( $coupon_data[ $result['ID'] ] ) || ! is_array( $coupon_data[ $result['ID'] ] ) ) {
$coupon_data[ $result['ID'] ] = array();
}
$coupon_data[ $result['ID'] ]['coupon_id'] = $result['ID'];
$coupon_data[ $result['ID'] ]['coupon_code'] = $result['post_title'];
$coupon_data[ $result['ID'] ]['created_date'] = $result['post_date'];
if ( ! empty( $meta ) ) {
foreach ( $meta as $key => $value ) {
$coupon_data[ $result['ID'] ][ $key ] = $value;
}
}
}
}
return $coupon_data;
}
/**
* Handle exporting data for Smart Coupons' Coupon data.
*
* @param string $email_address E-mail address to export.
* @param int $page Pagination of data.
*
* @return array
*/
public function wc_sc_coupon_data_exporter( $email_address, $page = 0 ) {
$done = false;
$data_to_export = array();
$coupon_data = $this->get_wc_sc_data( $email_address, (int) $page );
if ( 0 < count( $coupon_data ) ) {
$data = array();
$index = 0;
foreach ( $coupon_data as $coupon_id => $coupon ) {
$data[] = array(
'name' => $coupon['coupon_code'],
'value' => $coupon['customer_email'],
);
}
$data_to_export[] = array(
'group_id' => 'wc_smart_coupons_coupon_data',
'group_label' => __( 'Store Credit/Gift Certificate - Coupon Data', 'woocommerce-smart-coupons' ),
'item_id' => 'wc-smart-coupons-coupon-data-' . sanitize_title( $email_address ),
'data' => $data,
);
$done = 10 > count( $coupon_data );
} else {
$done = true;
}
return array(
'data' => $data_to_export,
'done' => $done,
);
}
/**
* Finds and erases Smart Coupons by email address.
*
* @param string $email_address The user email address.
* @param int $page Pagination.
* @return array An array of personal data in name value pairs
*/
public function wc_sc_coupon_data_eraser( $email_address, $page ) {
$coupon_data = $this->get_wc_sc_data( $email_address, (int) $page );
$done = false;
$items_removed = false;
$items_retained = false;
$messages = array();
foreach ( $coupon_data as $coupon ) {
list( $removed, $retained, $msgs ) = $this->maybe_handle_coupon_data( $coupon );
$items_removed |= $removed;
$items_retained |= $retained;
$messages = array_merge( $messages, $msgs );
}
// Tell core if we have more coupons to work on still.
$done = count( $coupon_data ) < 10;
return array(
'items_removed' => $items_removed,
'items_retained' => $items_retained,
'messages' => $messages,
'done' => $done,
);
}
/**
* Handle eraser of Coupon data
*
* @param array $coupon The coupon data.
* @return array
*/
protected function maybe_handle_coupon_data( $coupon ) {
if ( empty( $coupon ) || ! $this->is_retention_expired( $coupon['created_date'] ) ) {
return array( false, false, array() );
}
if ( $this->is_wc_gte_30() ) {
$_coupon = ( ! empty( $coupon['coupon_id'] ) ) ? new WC_Coupon( $coupon['coupon_id'] ) : null;
if ( $this->is_callable( $_coupon, 'delete_meta_data' ) && $this->is_callable( $_coupon, 'save' ) && $this->is_callable( $_coupon, 'delete' ) ) {
if ( $this->is_callable( $_coupon, 'set_email_restrictions' ) ) {
$_coupon->set_email_restrictions( array() );
}
$_coupon->delete_meta_data( 'customer_email' );
$_coupon->delete_meta_data( 'generated_from_order_id' );
$_coupon->save();
$_coupon->delete( true );
}
} else {
delete_post_meta( $coupon['coupon_id'], 'customer_email' );
delete_post_meta( $coupon['coupon_id'], 'generated_from_order_id' );
wp_delete_post( $coupon['coupon_id'], true );
}
return array( true, false, array( '<strong>' . __( 'Store Credit/Gift Certificate', 'woocommerce-smart-coupons' ) . '</strong> - ' . __( 'Removed Coupon Personal Data', 'woocommerce-smart-coupons' ) ) );
}
/**
* Returns Smart Coupons data based on email.
*
* @param string $email_address The email addres.
* @param int $page Pagination.
*
* @return array
*/
protected function get_wc_sc_user_data( $email_address, $page ) {
$user_data = array();
$user = get_user_by( 'email', $email_address );
if ( ! empty( $user->ID ) ) {
$sc_shortcode_generated_coupons = get_user_meta( $user->ID, '_sc_shortcode_generated_coupons', true );
if ( ! empty( $sc_shortcode_generated_coupons ) ) {
$user_data['shortcode'] = array();
foreach ( $sc_shortcode_generated_coupons as $sc_shortcode_generated_coupons ) {
$user_data['shortcode'][] = implode( ', ', $sc_shortcode_generated_coupons );
}
}
$sc_applied_coupon_from_url = get_user_meta( $user->ID, 'sc_applied_coupon_from_url', true );
if ( ! empty( $sc_applied_coupon_from_url ) ) {
$user_data['url'] = implode( ', ', $sc_applied_coupon_from_url );
}
}
return $user_data;
}
/**
* Handle exporting data for Smart Coupons User data.
*
* @param string $email_address E-mail address to export.
* @param int $page Pagination of data.
*
* @return array
*/
public function wc_sc_user_data_exporter( $email_address, $page = 0 ) {
$done = false;
$data_to_export = array();
$user_data = $this->get_wc_sc_user_data( $email_address, (int) $page );
if ( 0 < count( $user_data ) ) {
$shortcode = array();
$url = array();
$index = 0;
foreach ( $user_data as $key => $value ) {
if ( 'shortcode' === $key ) {
foreach ( $value as $val ) {
$shortcode[] = array(
'name' => __( 'Coupon', 'woocommerce-smart-coupons' ),
'value' => $val,
);
}
$data_to_export[] = array(
'group_id' => 'wc_smart_coupons_coupon_shortcode_data',
'group_label' => __( 'Generated Coupon Data', 'woocommerce-smart-coupons' ),
'item_id' => 'wc-smart-coupons-shorcode-data-' . sanitize_title( $email_address ),
'data' => $shortcode,
);
} elseif ( 'url' === $key ) {
$url[] = array(
'name' => __( 'Coupon' ),
'value' => $value,
);
$data_to_export[] = array(
'group_id' => 'wc_smart_coupons_url_data',
'group_label' => __( 'Coupon passed in URL', 'woocommerce-smart-coupons' ),
'item_id' => 'wc-smart-coupons-url-data-' . sanitize_title( $email_address ),
'data' => $url,
);
}
}
$done = 10 > count( $user_data );
} else {
$done = true;
}
return array(
'data' => $data_to_export,
'done' => $done,
);
}
/**
* Finds and erases Smart Coupons by email address.
*
* @param string $email_address The user email address.
* @param int $page Pagination.
* @return array An array of personal data in name value pairs
*/
public function wc_sc_user_data_eraser( $email_address, $page ) {
$user = get_user_by( 'email', $email_address );
$done = false;
$items_removed = false;
$items_retained = false;
$messages = array();
if ( ! empty( $user->ID ) ) {
$meta_keys = array( '_sc_shortcode_generated_coupons', 'sc_applied_coupon_from_url' );
foreach ( $meta_keys as $meta_key ) {
delete_user_meta( $user->ID, $meta_key );
$removed = true;
$retained = false;
$msgs = array( '<strong>' . __( 'Store Credit/Gift Certificate', 'woocommerce-smart-coupons' ) . '</strong> - ' . __( 'Removed User Personal Data', 'woocommerce-smart-coupons' ) );
$items_removed |= $removed;
$items_retained |= $retained;
$messages = array_merge( $messages, $msgs );
}
}
// Tell core if we have more coupons to work on still.
$done = true;
return array(
'items_removed' => $items_removed,
'items_retained' => $items_retained,
'messages' => $messages,
'done' => $done,
);
}
/**
* Returns Smart Coupons data based on email.
*
* @param string $email_address The email address.
* @param int $page Pagination.
*
* @return array
*/
protected function get_wc_sc_order_data( $email_address, $page ) {
global $wpdb;
$user = get_user_by( 'email', $email_address );
$order_ids = wp_cache_get( 'wc_sc_order_ids_for_' . sanitize_key( $email_address ), 'woocommerce_smart_coupons' );
if ( false === $order_ids ) {
$order_ids = $wpdb->get_col( // phpcs:ignore
$wpdb->prepare(
"SELECT pm.post_id
FROM {$wpdb->posts} AS p
LEFT JOIN {$wpdb->postmeta} AS pm
ON ( p.ID = pm.post_id AND p.post_type = %s )
WHERE pm.meta_key = %s
AND pm.meta_value = %d",
'shop_order',
'_customer_user',
$user->ID
)
);
wp_cache_set( 'wc_sc_order_ids_for_' . sanitize_key( $email_address ), $order_ids, 'woocommerce_smart_coupons' );
$this->maybe_add_cache_key( 'wc_sc_order_ids_for_' . sanitize_key( $email_address ) );
}
if ( empty( $order_ids ) ) {
return array();
}
$how_many = count( $order_ids );
$placeholders = array_fill( 0, $how_many, '%d' );
$query = $wpdb->prepare(
"SELECT p.ID,
pm.meta_value AS sc_coupon_receiver_details
FROM $wpdb->posts AS p
LEFT JOIN $wpdb->postmeta AS pm
ON ( p.ID = pm.post_id AND p.post_type = %s AND pm.meta_key = %s )",
'shop_order',
'sc_coupon_receiver_details'
);
$query .= $wpdb->prepare( 'WHERE p.ID IN (' . implode( ',', $placeholders ) . ') ', $order_ids ); // phpcs:ignore
$query .= $wpdb->prepare(
' AND pm.meta_value <> %s
GROUP BY p.ID
ORDER BY p.ID',
''
);
$unique_order_ids = array_unique( $order_ids );
$results = wp_cache_get( 'wc_sc_receiver_detail_in_orders_' . implode( '_', $unique_order_ids ), 'woocommerce_smart_coupons' );
if ( false === $results ) {
$results = $wpdb->get_results( $query, ARRAY_A ); // phpcs:ignore
wp_cache_set( 'wc_sc_receiver_detail_in_orders_' . implode( '_', $unique_order_ids ), $results, 'woocommerce_smart_coupons' );
$this->maybe_add_cache_key( 'wc_sc_receiver_detail_in_orders_' . implode( '_', $unique_order_ids ) );
}
$order_data = array();
if ( ! empty( $results ) ) {
foreach ( $results as $result ) {
$order_data[ $result['ID'] ] = maybe_unserialize( $result['sc_coupon_receiver_details'] );
}
}
return $order_data;
}
/**
* Handle exporting data for Smart Coupons User data.
*
* @param string $email_address E-mail address to export.
* @param int $page Pagination of data.
*
* @return array
*/
public function wc_sc_order_data_exporter( $email_address, $page = 0 ) {
$done = false;
$data_to_export = array();
$order_data = $this->get_wc_sc_order_data( $email_address, (int) $page );
if ( 0 < count( $order_data ) ) {
$index = 0;
foreach ( $order_data as $key => $value ) {
foreach ( $value as $val ) {
$index++;
$data = array();
foreach ( $val as $k => $v ) {
if ( $val['email'] !== $email_address && 'code' === $k ) {
continue;
}
switch ( $k ) {
case 'code':
$name = __( 'Coupon Code', 'woocommerce-smart-coupons' );
break;
case 'amount':
$name = __( 'Coupon Amount', 'woocommerce-smart-coupons' );
break;
case 'email':
$name = __( 'Coupon For', 'woocommerce-smart-coupons' );
break;
case 'message':
$name = __( 'Message', 'woocommerce-smart-coupons' );
break;
}
$data[] = array(
'name' => $name,
'value' => $v,
);
}
$data_to_export[] = array(
'group_id' => 'wc_smart_coupons_order_data_' . $index,
'group_label' => __( 'Store Credit/Gift Certificate - Order Data', 'woocommerce-smart-coupons' ),
'item_id' => 'wc-smart-coupons-order-data-' . $index,
'data' => $data,
);
}
}
$done = 10 > count( $order_data );
} else {
$done = true;
}
return array(
'data' => $data_to_export,
'done' => $done,
);
}
/**
* Finds and erases Smart Coupons by email address.
*
* @param string $email_address The user email address.
* @param int $page Pagination.
* @return array An array of personal data in name value pairs
*/
public function wc_sc_order_data_eraser( $email_address, $page ) {
global $wpdb;
$user = get_user_by( 'email', $email_address );
$orders = wp_cache_get( 'wc_sc_order_by_email_for_' . $user->ID, 'woocommerce_smart_coupons' );
if ( false === $orders ) {
$orders = $wpdb->get_results( // phpcs:ignore
$wpdb->prepare(
"SELECT p.post_date AS created_date,
pm.post_id
FROM {$wpdb->posts} AS p
LEFT JOIN {$wpdb->postmeta} AS pm
ON ( p.ID = pm.post_id AND p.post_type = %s )
WHERE pm.meta_key = %s
AND pm.meta_value = %d",
'shop_order',
'_customer_user',
$user->ID
),
ARRAY_A
);
wp_cache_set( 'wc_sc_order_by_email_for_' . $user->ID, $orders, 'woocommerce_smart_coupons' );
$this->maybe_add_cache_key( 'wc_sc_order_by_email_for_' . $user->ID );
}
$done = false;
$items_removed = false;
$items_retained = false;
$messages = array();
if ( ! empty( $orders ) ) {
foreach ( $orders as $order ) {
list( $removed, $retained, $msgs ) = $this->maybe_handle_order_data( $order );
$items_removed |= $removed;
$items_retained |= $retained;
$messages = array_merge( $messages, $msgs );
}
}
// Tell core if we have more coupons to work on still.
$done = count( $orders ) < 10;
return array(
'items_removed' => $items_removed,
'items_retained' => $items_retained,
'messages' => $messages,
'done' => $done,
);
}
/**
* Handle eraser of Coupon data
*
* @param array $order The order data.
* @return array
*/
protected function maybe_handle_order_data( $order ) {
if ( empty( $order ) || ! $this->is_retention_expired( $order['created_date'] ) ) {
return array( false, false, array() );
}
$order = ( ! empty( $order['post_id'] ) && function_exists( 'wc_get_order' ) ) ? wc_get_order( $order['post_id'] ) : null;
if ( $this->is_callable( $order, 'delete_meta_data' ) && $this->is_callable( $order, 'save' ) ) {
$order->delete_meta_data( 'sc_coupon_receiver_details' );
$order->delete_meta_data( 'gift_receiver_email' );
$order->delete_meta_data( 'gift_receiver_message' );
$order->delete_meta_data( 'gift_sending_timestamp' );
$order->save();
} else {
delete_post_meta( $order['post_id'], 'sc_coupon_receiver_details' );
delete_post_meta( $order['post_id'], 'gift_receiver_email' );
delete_post_meta( $order['post_id'], 'gift_receiver_message' );
delete_post_meta( $order['post_id'], 'gift_sending_timestamp' );
}
return array( true, false, array( '<strong>' . __( 'Store Credit/Gift Certificate', 'woocommerce-smart-coupons' ) . '</strong> - ' . __( 'Removed Order Personal Data', 'woocommerce-smart-coupons' ) ) );
}
/**
* Remove Smart Coupons order personal data
*
* @param WC_Order $order The order object.
*/
public function remove_order_personal_data( $order ) {
$created_date = $order->get_date_created();
$args = array(
'post_id' => $order->get_id(),
'created_date' => $created_date,
);
$result = $this->maybe_handle_order_data( $args );
}
/**
* Checks if create date is passed retention duration.
*
* @param string $created_date The date.
*/
public function is_retention_expired( $created_date ) {
$retention = wc_parse_relative_date_option( get_option( 'woocommerce_smart_coupons_retention' ) );
$is_expired = false;
$time_span = time() - strtotime( $created_date );
if ( empty( $retention ) || empty( $created_date ) ) {
return false;
}
switch ( $retention['unit'] ) {
case 'days':
$retention = $retention['number'] * DAY_IN_SECONDS;
if ( $time_span > $retention ) {
$is_expired = true;
}
break;
case 'weeks':
$retention = $retention['number'] * WEEK_IN_SECONDS;
if ( $time_span > $retention ) {
$is_expired = true;
}
break;
case 'months':
$retention = $retention['number'] * MONTH_IN_SECONDS;
if ( $time_span > $retention ) {
$is_expired = true;
}
break;
case 'years':
$retention = $retention['number'] * YEAR_IN_SECONDS;
if ( $time_span > $retention ) {
$is_expired = true;
}
break;
}
return $is_expired;
}
/**
* Add retention settings to account tab.
*
* @param array $settings Settings.
* @return array $settings Updated
*/
public function account_settings( $settings ) {
$insert_setting = array(
array(
'title' => __( 'Retain Store Credit/Gift Certificate', 'woocommerce-smart-coupons' ),
'desc_tip' => __( 'Store Credit/Gift Certificate that are stored for customers via coupons. If erased, the customer will not be able to use the coupons.', 'woocommerce-smart-coupons' ),
'id' => 'woocommerce_smart_coupons_retention',
'type' => 'relative_date_selector',
'placeholder' => __( 'N/A', 'woocommerce-smart-coupons' ),
'default' => '',
'autoload' => false,
),
);
array_splice( $settings, ( count( $settings ) - 1 ), 0, $insert_setting );
return $settings;
}
}
}
WC_SC_Privacy::get_instance();

View File

@@ -1,524 +0,0 @@
<?php
/**
* Smart Coupons fields in products
*
* @author StoreApps
* @since 3.3.0
* @version 1.3.0
*
* @package woocommerce-smart-coupons/includes/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Product_Fields' ) ) {
/**
* Class for handling Smart Coupons' field in products
*/
class WC_SC_Product_Fields {
/**
* Variable to hold instance of WC_SC_Product_Fields
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
private function __construct() {
add_action( 'woocommerce_product_options_general_product_data', array( $this, 'woocommerce_product_options_coupons' ) );
add_action( 'woocommerce_product_after_variable_attributes', array( $this, 'woocommerce_product_options_coupons_variable' ), 11, 3 );
add_action( 'woocommerce_process_product_meta', array( $this, 'woocommerce_process_product_meta_coupons' ), 10, 2 );
add_action( 'woocommerce_save_product_variation', array( $this, 'woocommerce_process_product_meta_coupons_variable' ), 10, 2 );
}
/**
* Get single instance of WC_SC_Product_Fields
*
* @return WC_SC_Product_Fields Singleton object of WC_SC_Product_Fields
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Function to provide area for entering coupon code
*/
public function woocommerce_product_options_coupons() {
global $post;
$product_type = WC_Product_Factory::get_product_type( $post->ID );
$product = ( ! empty( $post->ID ) && function_exists( 'wc_get_product' ) ) ? wc_get_product( $post->ID ) : null;
$is_callable_product_get_meta = $this->is_callable( $product, 'get_meta' );
$is_send_coupons_on_renewals = ( true === $is_callable_product_get_meta ) ? $product->get_meta( 'send_coupons_on_renewals' ) : get_post_meta( $post->ID, 'send_coupons_on_renewals', true );
echo '<div class="options_group smart-coupons-field">';
$all_discount_types = wc_get_coupon_types();
?>
<p class="form-field smart-coupon-search post_<?php echo esc_attr( $post->ID ); ?>">
<label for="_coupon_title"><?php echo esc_html__( 'Coupons', 'woocommerce-smart-coupons' ); ?></label>
<select class="wc-coupon-search" style="width: 50%;" multiple="multiple" id="_coupon_title_<?php echo esc_attr( $post->ID ); ?>" name="_coupon_title[<?php echo esc_attr( $post->ID ); ?>][]" data-placeholder="<?php echo esc_attr__( 'Search for a coupon&hellip;', 'woocommerce-smart-coupons' ); ?>" data-action="sc_json_search_coupons" data-security="<?php echo esc_attr( wp_create_nonce( 'search-coupons' ) ); ?>" >
<?php
$coupon_titles = ( true === $is_callable_product_get_meta ) ? $product->get_meta( '_coupon_title' ) : get_post_meta( $post->ID, '_coupon_title', true );
if ( ! empty( $coupon_titles ) ) {
foreach ( $coupon_titles as $coupon_title ) {
$coupon = new WC_Coupon( $coupon_title );
$discount_type = $coupon->get_discount_type();
if ( ! empty( $discount_type ) ) {
/* translators: 1. Discount type 2. Discount Type Label */
$discount_type = sprintf( __( ' ( %1$s: %2$s )', 'woocommerce-smart-coupons' ), __( 'Type', 'woocommerce-smart-coupons' ), $all_discount_types[ $discount_type ] );
}
echo '<option value="' . esc_attr( $coupon_title ) . '"' . selected( true, true, false ) . '>' . esc_html( $coupon_title . $discount_type ) . '</option>';
}
}
?>
</select>
<?php
echo wc_help_tip( esc_html__( 'These coupon/s will be given to customers who buy this product. The coupon code will be automatically sent to their email address on purchase.', 'woocommerce-smart-coupons' ) ); // phpcs:ignore
?>
</p>
<p class="form-field send_coupons_on_renewals_field post_<?php echo esc_attr( $post->ID ); ?>" style="display: none;">
<label for="send_coupons_on_renewals"><?php echo esc_html__( 'Send coupons on renewals?', 'woocommerce-smart-coupons' ); ?></label>
<input type="checkbox" class="checkbox" style="" name="send_coupons_on_renewals[<?php echo esc_attr( $post->ID ); ?>]" id="send_coupons_on_renewals_<?php echo esc_attr( $post->ID ); ?>" value="yes" <?php checked( $is_send_coupons_on_renewals, 'yes' ); ?>/>
<?php echo wc_help_tip( esc_html__( 'Check this box to send above coupons on each renewal order.', 'woocommerce-smart-coupons' ) ); // phpcs:ignore ?>
</p>
<?php $this->product_options_admin_js(); ?>
<?php
echo '</div>';
}
/**
* Coupon fields for variation
*
* @param int $loop Position in the loop.
* @param array $variation_data Variation data.
* @param WP_Post $variation Post data.
*/
public function woocommerce_product_options_coupons_variable( $loop = 0, $variation_data = array(), $variation = null ) {
$variation_id = $variation->ID;
$all_discount_types = wc_get_coupon_types();
$product = ( ! empty( $variation_id ) && function_exists( 'wc_get_product' ) ) ? wc_get_product( $variation_id ) : null;
$is_callable_product_get_meta = $this->is_callable( $product, 'get_meta' );
$is_send_coupons_on_renewals = ( true === $is_callable_product_get_meta ) ? $product->get_meta( 'send_coupons_on_renewals' ) : get_post_meta( $variation_id, 'send_coupons_on_renewals', true );
?>
<div class="smart_coupons_product_options_variable smart-coupons-field">
<p class="form-field smart-coupon-search _coupon_title_field post_<?php echo esc_attr( $variation_id ); ?> form-row form-row-full">
<label for="_coupon_title_<?php echo esc_attr( $loop ); ?>"><?php echo esc_html__( 'Coupons', 'woocommerce-smart-coupons' ); ?></label>
<?php echo wc_help_tip( esc_html__( 'These coupon/s will be given to customers who buy this product. The coupon code will be automatically sent to their email address on purchase.', 'woocommerce-smart-coupons' ) ); // phpcs:ignore ?>
<select class="wc-coupon-search" style="width: 100% !important;" multiple="multiple" id="_coupon_title_<?php echo esc_attr( $variation_id ); ?>" name="_coupon_title[<?php echo esc_attr( $variation_id ); ?>][<?php echo esc_attr( $loop ); ?>][]" data-placeholder="<?php echo esc_attr__( 'Search for a coupon&hellip;', 'woocommerce-smart-coupons' ); ?>" data-action="sc_json_search_coupons" data-security="<?php echo esc_attr( wp_create_nonce( 'search-coupons' ) ); ?>" >
<?php
$coupon_titles = ( true === $is_callable_product_get_meta ) ? $product->get_meta( '_coupon_title' ) : get_post_meta( $variation_id, '_coupon_title', true );
if ( ! empty( $coupon_titles ) ) {
foreach ( $coupon_titles as $coupon_title ) {
$coupon = new WC_Coupon( $coupon_title );
$discount_type = $coupon->get_discount_type();
if ( ! empty( $discount_type ) ) {
/* translators: 1. Discount type 2. Discount Type Label */
$discount_type = sprintf( __( ' ( %1$s: %2$s )', 'woocommerce-smart-coupons' ), __( 'Type', 'woocommerce-smart-coupons' ), $all_discount_types[ $discount_type ] );
}
echo '<option value="' . esc_attr( $coupon_title ) . '"' . selected( true, true, false ) . '>' . esc_html( $coupon_title . $discount_type ) . '</option>';
}
}
?>
</select>
</p>
<p class="form-field send_coupons_on_renewals_field post_<?php echo esc_attr( $variation_id ); ?> form-row form-row-full">
<label class="tips" data-tip="<?php echo esc_attr__( 'Check this box to send above coupons on each renewal order.', 'woocommerce-smart-coupons' ); ?>">
<?php echo esc_html__( 'Send coupons on renewals?', 'woocommerce-smart-coupons' ); ?>
<input type="checkbox" class="checkbox" id="send_coupons_on_renewals_<?php echo esc_attr( $variation_id ); ?>" name="send_coupons_on_renewals[<?php echo esc_attr( $variation_id ); ?>][<?php echo esc_attr( $loop ); ?>]" style="margin: 0.1em 0.5em 0.1em 0 !important;" value="yes" <?php checked( $is_send_coupons_on_renewals, 'yes' ); ?>/>
</label>
</p>
<?php $this->product_options_admin_js(); ?>
</div>
<?php
}
/**
* Product options admin JS
*/
public function product_options_admin_js() {
?>
<script type="text/javascript">
jQuery(function(){
var updateSendCouponOnRenewals = function(theElement) {
let element;
if (typeof theElement == "undefined") {
element = jQuery('.smart-coupons-field');
} else {
element = [theElement];
}
jQuery.each(element, function(index, value){
var prodType = jQuery('select#product-type').find('option:selected').val();
<?php if ( $this->is_wc_gte_30() ) { ?>
var associatedCouponCount = jQuery(value).find('.smart-coupon-search span.select2-selection ul.select2-selection__rendered li.select2-selection__choice').length;
<?php } else { ?>
var associatedCouponCount = jQuery(value).find('.smart-coupon-search ul.select2-choices li.select2-search-choice').length;
<?php } ?>
if ( ( prodType == 'subscription' || prodType == 'variable-subscription' || prodType == 'subscription_variation' ) && associatedCouponCount > 0 ) {
jQuery(value).find('p.send_coupons_on_renewals_field').show();
} else {
jQuery(value).find('p.send_coupons_on_renewals_field').hide();
}
});
};
setTimeout(function(){updateSendCouponOnRenewals();}, 100);
jQuery('select#product-type').on('change', function() {
var productType = jQuery(this).find('option:selected').val();
if ( productType == 'simple' || productType == 'variable' || productType == 'subscription' || productType == 'variable-subscription' || productType == 'subscription_variation' ) {
jQuery('.wc-coupon-search').show();
} else {
jQuery('.wc-coupon-search').hide();
}
updateSendCouponOnRenewals();
});
jQuery('.wc-coupon-search').on('change', function(){
let theElement = jQuery(this).parent().parent();
setTimeout( function() {
updateSendCouponOnRenewals(theElement);
}, 10 );
});
if ( typeof getEnhancedSelectFormatString == "undefined" ) {
function getEnhancedSelectFormatString() {
var formatString = {
formatMatches: function( matches ) {
if ( 1 === matches ) {
return smart_coupons_select_params.i18n_matches_1;
}
return smart_coupons_select_params.i18n_matches_n.replace( '%qty%', matches );
},
formatNoMatches: function() {
return smart_coupons_select_params.i18n_no_matches;
},
formatAjaxError: function( jqXHR, textStatus, errorThrown ) {
return smart_coupons_select_params.i18n_ajax_error;
},
formatInputTooShort: function( input, min ) {
var number = min - input.length;
if ( 1 === number ) {
return smart_coupons_select_params.i18n_input_too_short_1
}
return smart_coupons_select_params.i18n_input_too_short_n.replace( '%qty%', number );
},
formatInputTooLong: function( input, max ) {
var number = input.length - max;
if ( 1 === number ) {
return smart_coupons_select_params.i18n_input_too_long_1
}
return smart_coupons_select_params.i18n_input_too_long_n.replace( '%qty%', number );
},
formatSelectionTooBig: function( limit ) {
if ( 1 === limit ) {
return smart_coupons_select_params.i18n_selection_too_long_1;
}
return smart_coupons_select_params.i18n_selection_too_long_n.replace( '%qty%', number );
},
formatLoadMore: function( pageNumber ) {
return smart_coupons_select_params.i18n_load_more;
},
formatSearching: function() {
return smart_coupons_select_params.i18n_searching;
}
};
return formatString;
}
}
<?php if ( $this->is_wc_gte_30() ) { // Ajax product search box. ?>
jQuery( '[class= "wc-coupon-search"]' ).filter( ':not(.enhanced)' ).each( function() {
var select2_args = {
allowClear: jQuery( this ).data( 'allow_clear' ) ? true : false,
placeholder: jQuery( this ).data( 'placeholder' ),
minimumInputLength: jQuery( this ).data( 'minimum_input_length' ) ? jQuery( this ).data( 'minimum_input_length' ) : '3',
escapeMarkup: function( m ) {
return m;
},
ajax: {
url: '<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>',
dataType: 'json',
quietMillis: 250,
data: function( params, page ) {
return {
term: params.term,
action: jQuery( this ).data( 'action' ) || 'sc_json_search_coupons',
security: jQuery( this ).data( 'security' )
};
},
processResults: function( data, page ) {
var terms = [];
if ( data ) {
jQuery.each( data, function( id, text ) {
terms.push( { id: id, text: text } );
});
}
return { results: terms };
},
cache: true
}
};
select2_args = jQuery.extend( select2_args, getEnhancedSelectFormatString() );
jQuery( this ).select2( select2_args );
});
<?php } else { ?>
jQuery( ':input.wc-coupon-search' ).filter( ':not(.enhanced)' ).each( function() {
var select2_args = {
allowClear: jQuery( this ).data( 'allow_clear' ) ? true : false,
placeholder: jQuery( this ).data( 'placeholder' ),
minimumInputLength: jQuery( this ).data( 'minimum_input_length' ) ? jQuery( this ).data( 'minimum_input_length' ) : '3',
escapeMarkup: function( m ) {
return m;
},
ajax: {
url: decodeURIComponent( '<?php echo rawurlencode( admin_url( 'admin-ajax.php' ) ); ?>' ),
dataType: 'json',
quietMillis: 250,
data: function( term, page ) {
return {
term: term,
action: jQuery( this ).data( 'action' ) || 'sc_json_search_coupons',
security: '<?php echo esc_attr( wp_create_nonce( 'search-coupons' ) ); ?>'
};
},
results: function( data, page ) {
var terms = [];
if ( data ) {
jQuery.each( data, function( id, text ) {
terms.push( { id: id, text: text } );
});
}
return { results: terms };
},
cache: true
}
};
if ( jQuery( this ).data( 'multiple' ) === true ) {
select2_args.multiple = true;
select2_args.initSelection = function( element, callback ) {
var data = jQuery.parseJSON( element.attr( 'data-selected' ) );
var selected = [];
jQuery( element.val().split( "," ) ).each( function( i, val ) {
selected.push( { id: val, text: data[ val ] } );
});
return callback( selected );
};
select2_args.formatSelection = function( data ) {
return '<div class="selected-option" data-id="' + data.id + '">' + data.text + '</div>';
};
} else {
select2_args.multiple = false;
select2_args.initSelection = function( element, callback ) {
var data = {id: element.val(), text: element.attr( 'data-selected' )};
return callback( data );
};
}
select2_args = jQuery.extend( select2_args, getEnhancedSelectFormatString() );
jQuery( this ).select2( select2_args ).addClass( 'enhanced' );
});
<?php } ?>
});
</script>
<?php
}
/**
* Function to save coupon code to database
*
* @param int $post_id The post id.
* @param object $post The post object.
*/
public function woocommerce_process_product_meta_coupons( $post_id = 0, $post = null ) {
$post_id = absint( $post_id );
$post_coupon_title = ( ! empty( $_POST['_coupon_title'][ $post_id ] ) ) ? wc_clean( wp_unslash( $_POST['_coupon_title'][ $post_id ] ) ) : ''; // phpcs:ignore
$product = ( ! empty( $post_id ) ) ? wc_get_product( $post_id ) : null;
$is_callable_product_update_meta = $this->is_callable( $product, 'update_meta_data' );
if ( ! empty( $post_coupon_title ) ) {
if ( $this->is_wc_gte_30() ) {
$coupon_titles = $post_coupon_title;
} else {
$coupon_titles = array_filter( array_map( 'trim', explode( ',', $post_coupon_title ) ) );
}
if ( true === $is_callable_product_update_meta ) {
$product->update_meta_data( '_coupon_title', $coupon_titles );
} else {
update_post_meta( $post_id, '_coupon_title', $coupon_titles );
}
} else {
if ( true === $is_callable_product_update_meta ) {
$product->update_meta_data( '_coupon_title', array() );
} else {
update_post_meta( $post_id, '_coupon_title', array() );
}
}
if ( isset( $_POST['send_coupons_on_renewals'][ $post_id ] ) ) { // phpcs:ignore
if ( true === $is_callable_product_update_meta ) {
$product->update_meta_data( 'send_coupons_on_renewals', wc_clean( wp_unslash( $_POST['send_coupons_on_renewals'][ $post_id ] ) ) ); // phpcs:ignore
} else {
update_post_meta( $post_id, 'send_coupons_on_renewals', wc_clean( wp_unslash( $_POST['send_coupons_on_renewals'][ $post_id ] ) ) ); // phpcs:ignore
}
} else {
if ( true === $is_callable_product_update_meta ) {
$product->update_meta_data( 'send_coupons_on_renewals', 'no' );
} else {
update_post_meta( $post_id, 'send_coupons_on_renewals', 'no' );
}
}
if ( $this->is_callable( $product, 'save' ) ) {
$product->save();
}
}
/**
* Function for saving coupon details in product meta
*
* @param integer $variation_id Variation ID.
* @param integer $i Loop ID.
*/
public function woocommerce_process_product_meta_coupons_variable( $variation_id = 0, $i = 0 ) {
if ( empty( $variation_id ) ) {
return;
}
$variation_id = absint( $variation_id );
$variation = ( ! empty( $variation_id ) ) ? wc_get_product( $variation_id ) : null;
$is_callable_variation_update_meta = $this->is_callable( $variation, 'update_meta_data' );
$post_coupon_title = ( ! empty( $_POST['_coupon_title'][ $variation_id ][ $i ] ) ) ? wc_clean( wp_unslash( $_POST['_coupon_title'][ $variation_id ][ $i ] ) ) : ''; // phpcs:ignore
if ( ! empty( $post_coupon_title ) ) {
if ( $this->is_wc_gte_30() ) {
$coupon_titles = $post_coupon_title;
} else {
$coupon_titles = array_filter( array_map( 'trim', explode( ',', $post_coupon_title ) ) );
}
if ( true === $is_callable_variation_update_meta ) {
$variation->update_meta_data( '_coupon_title', $coupon_titles );
} else {
update_post_meta( $variation_id, '_coupon_title', $coupon_titles );
}
} else {
if ( true === $is_callable_variation_update_meta ) {
$variation->update_meta_data( '_coupon_title', array() );
} else {
update_post_meta( $variation_id, '_coupon_title', array() );
}
}
if ( isset( $_POST['send_coupons_on_renewals'][ $variation_id ][ $i ] ) ) { // phpcs:ignore
if ( true === $is_callable_variation_update_meta ) {
$variation->update_meta_data( 'send_coupons_on_renewals', wc_clean( wp_unslash( $_POST['send_coupons_on_renewals'][ $variation_id ][ $i ] ) ) ); // phpcs:ignore
} else {
update_post_meta( $variation_id, 'send_coupons_on_renewals', wc_clean( wp_unslash( $_POST['send_coupons_on_renewals'][ $variation_id ][ $i ] ) ) ); // phpcs:ignore
}
} else {
if ( true === $is_callable_variation_update_meta ) {
$variation->update_meta_data( 'send_coupons_on_renewals', 'no' );
} else {
update_post_meta( $variation_id, 'send_coupons_on_renewals', 'no' );
}
}
if ( $this->is_callable( $variation, 'save' ) ) {
$variation->save();
}
}
}
}
WC_SC_Product_Fields::get_instance();

View File

@@ -1,236 +0,0 @@
<?php
/**
* REST API Coupons controller for Smart Coupons
*
* Handles requests to the wc/sc/v1/coupons endpoint.
*
* @author StoreApps
* @since 4.10.0
* @version 1.2.0
*
* @package woocommerce-smart-coupons/includes/
*/
defined( 'ABSPATH' ) || exit;
if ( ! class_exists( 'WC_SC_REST_Coupons_Controller' ) ) {
/**
* REST API Coupons controller class.
*
* @package Automattic/WooCommerce/RestApi
* @extends WC_REST_CRUD_Controller
*/
class WC_SC_REST_Coupons_Controller extends WC_REST_Coupons_Controller {
/**
* Endpoint namespace.
*
* @var string
*/
protected $namespace = 'wc/v3/sc';
/**
* Route base.
*
* @var string
*/
protected $rest_base = 'coupons';
/**
* Post type.
*
* @var string
*/
protected $post_type = 'shop_coupon';
/**
* Constructor
*/
public function __construct() {
add_filter( "woocommerce_rest_prepare_{$this->post_type}_object", array( $this, 'handle_response_data' ), 99, 3 );
}
/**
* Register the routes for coupons.
*/
public function register_routes() {
register_rest_route(
$this->namespace,
'/' . $this->rest_base,
array(
array(
'methods' => WP_REST_Server::CREATABLE,
'callback' => array( $this, 'create_item' ),
'permission_callback' => array( $this, 'create_item_permissions_check' ),
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
),
'schema' => array( $this, 'get_public_item_schema' ),
)
);
}
/**
* Prepare a single coupon for create or update.
*
* @param WP_REST_Request $request Request object.
* @param bool $creating If is creating a new object.
* @return WP_Error|WC_Data
*/
protected function prepare_object_for_database( $request, $creating = false ) {
global $woocommerce_smart_coupon;
$id = isset( $request['id'] ) ? absint( $request['id'] ) : 0;
$coupon = new WC_Coupon( $id );
$schema = $this->get_item_schema();
$data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) );
$email_restrictions = ( ! empty( $request['email_restrictions'] ) && count( $request['email_restrictions'] ) === 1 ) ? $request['email_restrictions'] : '';
// Validate required POST fields.
if ( $creating ) {
if ( empty( $request['code'] ) ) {
$request['code'] = $woocommerce_smart_coupon->generate_unique_code( $email_restrictions );
} else {
$_coupon = new WC_Coupon( $request['code'] );
$is_auto_generate = ( is_object( $_coupon ) && is_callable( array( $_coupon, 'get_meta' ) ) ) ? $_coupon->get_meta( 'auto_generate_coupon' ) : 'no';
if ( 'yes' === $is_auto_generate ) {
$request['code'] = $woocommerce_smart_coupon->generate_unique_code( $email_restrictions );
foreach ( $data_keys as $key ) {
if ( empty( $request[ $key ] ) ) {
switch ( $key ) {
case 'code':
// do nothing.
break;
case 'meta_data':
$meta_data = ( is_object( $_coupon ) && is_callable( array( $_coupon, 'get_meta_data' ) ) ) ? $_coupon->get_meta_data() : null;
$new_meta_data = array();
if ( ! empty( $meta_data ) ) {
foreach ( $meta_data as $meta ) {
if ( is_object( $meta ) && is_callable( array( $meta, 'get_data' ) ) ) {
$data = $meta->get_data();
if ( isset( $data['id'] ) ) {
unset( $data['id'] );
}
$new_meta_data[] = $data;
}
}
}
$request[ $key ] = $new_meta_data;
break;
case 'description':
$request[ $key ] = ( is_object( $_coupon ) && is_callable( array( $_coupon, 'get_description' ) ) ) ? $_coupon->get_description() : null;
break;
default:
if ( is_callable( array( $_coupon, "get_{$key}" ) ) ) {
$request[ $key ] = $_coupon->{"get_{$key}"}();
}
break;
}
}
}
}
}
}
// Handle all writable props.
foreach ( $data_keys as $key ) {
$value = $request[ $key ];
if ( ! is_null( $value ) ) {
switch ( $key ) {
case 'code':
$coupon_code = wc_format_coupon_code( $value );
$id = $coupon->get_id() ? $coupon->get_id() : 0;
$id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id );
if ( $id_from_code ) {
return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce-smart-coupons' ), array( 'status' => 400 ) );
}
$coupon->set_code( $coupon_code );
break;
case 'meta_data':
if ( is_array( $value ) ) {
foreach ( $value as $meta ) {
$coupon->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' );
}
}
break;
case 'description':
$coupon->set_description( wp_filter_post_kses( $value ) );
break;
default:
if ( is_callable( array( $coupon, "set_{$key}" ) ) ) {
$coupon->{"set_{$key}"}( $value );
}
break;
}
}
}
/**
* Filters an object before it is inserted via the REST API.
*
* The dynamic portion of the hook name, `$this->post_type`,
* refers to the object type slug.
*
* @param WC_Data $coupon Object object.
* @param WP_REST_Request $request Request object.
* @param bool $creating If is creating a new object.
*/
return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $coupon, $request, $creating );
}
/**
* Handle REST response data
*
* @param WP_REST_Response|mixed $response The response.
* @param WC_Coupon|mixed $object The object.
* @param WP_REST_Request|mixed $request The request.
* @return WP_REST_Response
*/
public function handle_response_data( $response = null, $object = null, $request = null ) {
global $woocommerce_smart_coupon;
if ( ! empty( $request['sc_is_send_email'] ) && 'yes' === $request['sc_is_send_email'] ) {
$is_send_email = $woocommerce_smart_coupon->is_email_template_enabled();
$email_restrictions = ( ! empty( $request['email_restrictions'] ) ) ? current( $request['email_restrictions'] ) : '';
if ( 'yes' === $is_send_email && ! empty( $email_restrictions ) ) {
$coupon = array(
'code' => ( is_object( $object ) && is_callable( array( $object, 'get_code' ) ) ) ? $object->get_code() : '',
'amount' => ( is_object( $object ) && is_callable( array( $object, 'get_amount' ) ) ) ? $object->get_amount() : 0,
);
$action_args = apply_filters(
'wc_sc_email_coupon_notification_args',
array(
'email' => $email_restrictions,
'coupon' => $coupon,
'discount_type' => ( is_object( $object ) && is_callable( array( $object, 'get_discount_type' ) ) ) ? $object->get_discount_type() : '',
)
);
// Trigger email notification.
do_action( 'wc_sc_email_coupon_notification', $action_args );
}
}
if ( ! empty( $request['sc_is_html'] ) && 'yes' === $request['sc_is_html'] ) {
$data = '';
ob_start();
do_action(
'wc_sc_paint_coupon',
array(
'coupon' => $object,
'with_css' => 'yes',
'with_container' => 'yes',
)
);
$data = ob_get_clean();
$response = rest_ensure_response( $data );
}
return $response;
}
}
}

View File

@@ -1,920 +0,0 @@
<?php
/**
* Smart Coupons Shortcode
*
* @author StoreApps
* @since 3.3.0
* @version 2.2.0
*
* @package woocommerce-smart-coupons/includes/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Shortcode' ) ) {
/**
* Class for handling Smart Coupons Shortcode
*/
class WC_SC_Shortcode {
/**
* Variable to hold instance of WC_SC_Shortcode
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
private function __construct() {
add_action( 'admin_enqueue_scripts', array( $this, 'smart_coupon_shortcode_button_init' ), 20 ); // Use 'admin_enqueue_scripts' instead of 'init' // Credit: Jonathan Desrosiers <jdesrosiers@linchpinagency.com>.
add_action( 'init', array( $this, 'register_smart_coupon_shortcode' ) );
add_action( 'after_wp_tiny_mce', array( $this, 'smart_coupons_after_wp_tiny_mce' ) );
}
/**
* Get single instance of WC_SC_Shortcode
*
* @return WC_SC_Shortcode Singleton object of WC_SC_Shortcode
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Add Smart Coupons shortcode button in WP editor
*/
public function smart_coupon_shortcode_button_init() {
if ( get_user_option( 'rich_editing' ) === 'true' && ! current_user_can( 'manage_options' ) ) { // Add shortcode button to WP Editor only when the user is from the top level.
return;
}
if ( ! wp_script_is( 'wpdialogs' ) ) {
wp_enqueue_script( 'wpdialogs' );
}
if ( ! wp_style_is( 'wp-jquery-ui-dialog' ) ) {
wp_enqueue_style( 'wp-jquery-ui-dialog' );
}
if ( ! wp_style_is( 'smart-coupon' ) ) {
wp_enqueue_style( 'smart-coupon' );
}
add_filter( 'mce_external_plugins', array( $this, 'smart_coupon_register_tinymce_plugin' ) );
add_filter( 'mce_buttons', array( $this, 'smart_coupon_add_tinymce_button' ) );
}
/**
* Add Smart Coupon short code button in TinyMCE
*
* @param array $plugin_array Existing plugin.
* @return array $plugin array with SMart Coupon shortcode
*/
public function smart_coupon_register_tinymce_plugin( $plugin_array ) {
$plugin_array['sc_shortcode_button'] = plugins_url( 'assets/js/sc-shortcode.js', WC_SC_PLUGIN_FILE );
return $plugin_array;
}
/**
* Add Smart coupon shortcode button in TinyMCE
*
* @param array $buttons Existing button.
* @return array $buttons With Smart Coupons shortcode button
*/
public function smart_coupon_add_tinymce_button( $buttons ) {
$buttons[] = 'sc_shortcode_button';
return $buttons;
}
/**
* Register shortcode for Smart Coupons
*/
public function register_smart_coupon_shortcode() {
add_shortcode( 'smart_coupons', array( $this, 'execute_smart_coupons_shortcode' ) );
add_shortcode( 'wc_sc_available_coupons', array( $this, 'show_available_coupons_shortcode' ) );
}
/**
* Execute Smart Coupons shortcode
*
* @param array $atts Shortcode attributes.
* @return HTML code for coupon to be displayed
*/
public function execute_smart_coupons_shortcode( $atts ) {
ob_start();
global $wpdb, $store_credit_label;
$current_user = wp_get_current_user();
$customer_id = $current_user->ID;
$shortcode = shortcode_atts(
array(
'coupon_code' => '',
'discount_type' => 'smart_coupon',
'coupon_amount' => '',
'individual_use' => 'no',
'product_ids' => '',
'exclude_product_ids' => '',
'usage_limit' => '',
'usage_limit_per_user' => '',
'limit_usage_to_x_items' => '',
'expiry_date' => '',
'apply_before_tax' => 'no',
'free_shipping' => 'no',
'product_categories' => '',
'exclude_product_categories' => '',
'minimum_amount' => '',
'maximum_amount' => '',
'exclude_sale_items' => 'no',
'auto_generate' => 'no',
'coupon_prefix' => '',
'coupon_suffix' => '',
'customer_email' => '',
'coupon_style' => '',
'disable_email' => 'no',
'expiry_days' => '',
'is_email' => 'no',
'is_clickable' => 'no',
),
$atts
);
$_coupon_code = $shortcode['coupon_code'];
$_discount_type = $shortcode['discount_type'];
$_coupon_amount = $shortcode['coupon_amount'];
$_expiry_date = $shortcode['expiry_date'];
$_free_shipping = $shortcode['free_shipping'];
$customer_email = $shortcode['customer_email'];
$coupon_prefix = $shortcode['coupon_prefix'];
$coupon_suffix = $shortcode['coupon_suffix'];
$individual_use = $shortcode['individual_use'];
$minimum_amount = $shortcode['minimum_amount'];
$maximum_amount = $shortcode['maximum_amount'];
$usage_limit = $shortcode['usage_limit'];
$apply_before_tax = $shortcode['apply_before_tax'];
$disable_email = $shortcode['disable_email'];
$expiry_days = $shortcode['expiry_days'];
$is_email = $shortcode['is_email'];
$is_clickable = $shortcode['is_clickable'];
if ( empty( $_coupon_code ) && empty( $_coupon_amount ) ) {
return; // Minimum requirement for shortcode is either $_coupon_code or $_coupon_amount.
}
if ( empty( $customer_email ) ) {
if ( ! ( $current_user instanceof WP_User ) ) {
$current_user = wp_get_current_user();
$customer_email = ( isset( $current_user->user_email ) ) ? $current_user->user_email : '';
} else {
$customer_email = ( ! empty( $current_user->data->user_email ) ) ? $current_user->data->user_email : '';
}
}
if ( ! empty( $_coupon_code ) && ! empty( $customer_email ) ) {
$coupon_exists = wp_cache_get( 'wc_sc_shortcode_coupon_id_' . sanitize_key( $customer_email ), 'woocommerce_smart_coupons' );
if ( false === $coupon_exists ) {
$coupon_exists = $wpdb->get_var( // phpcs:ignore
$wpdb->prepare(
"SELECT ID
FROM {$wpdb->prefix}posts AS posts
LEFT JOIN {$wpdb->prefix}postmeta AS postmeta
ON ( postmeta.post_id = posts.ID )
WHERE posts.post_title = %s
AND posts.post_type = %s
AND posts.post_status = %s
AND postmeta.meta_key = %s
AND postmeta.meta_value LIKE %s",
strtolower( $_coupon_code ),
'shop_coupon',
'publish',
'customer_email',
'%' . $wpdb->esc_like( $customer_email ) . '%'
)
);
wp_cache_set( 'wc_sc_shortcode_coupon_id_' . sanitize_key( $customer_email ), $coupon_exists, 'woocommerce_smart_coupons' );
$this->maybe_add_cache_key( 'wc_sc_shortcode_coupon_id_' . sanitize_key( $customer_email ) );
}
} else {
$coupon_exists = null;
}
$is_generate = apply_filters(
'wc_sc_shortcode_always_generate_coupon',
( null === $coupon_exists ),
array(
'source' => $this,
'shortcode_attributes' => $shortcode,
)
);
$_expiry_date = '';
if ( ! wp_style_is( 'smart-coupon' ) ) {
wp_enqueue_style( 'smart-coupon' );
}
$all_discount_types = wc_get_coupon_types();
if ( true === $is_generate ) {
if ( ! empty( $_coupon_code ) ) {
$coupon = new WC_Coupon( $_coupon_code );
$is_callable_coupon_update_meta = $this->is_callable( $coupon, 'update_meta_data' );
if ( $this->is_wc_gte_30() ) {
if ( ! is_object( $coupon ) || ! is_callable( array( $coupon, 'get_id' ) ) ) {
return;
}
$coupon_id = $coupon->get_id();
if ( empty( $coupon_id ) ) {
return;
}
$is_free_shipping = ( $coupon->get_free_shipping() ) ? 'yes' : 'no';
$discount_type = $coupon->get_discount_type();
$expiry_date = $coupon->get_date_expires();
$coupon_code = $coupon->get_code();
} else {
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
$is_free_shipping = ( ! empty( $coupon->free_shipping ) ) ? $coupon->free_shipping : '';
$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
$expiry_date = ( ! empty( $coupon->expiry_date ) ) ? $coupon->expiry_date : '';
$coupon_code = ( ! empty( $coupon->code ) ) ? $coupon->code : '';
}
$coupon_amount = $this->get_amount( $coupon, true );
$is_callable_coupon_get_meta = $this->is_callable( $coupon, 'get_meta' );
if ( ! empty( $discount_type ) ) {
$is_auto_generate = ( true === $is_callable_coupon_get_meta ) ? $coupon->get_meta( 'auto_generate_coupon' ) : get_post_meta( $coupon_id, 'auto_generate_coupon', true );
$is_disable_email_restriction = ( true === $is_callable_coupon_get_meta ) ? $coupon->get_meta( 'sc_disable_email_restriction' ) : get_post_meta( $coupon_id, 'sc_disable_email_restriction', true );
if ( ( empty( $is_disable_email_restriction ) || 'no' === $is_disable_email_restriction ) && ( empty( $is_auto_generate ) || 'no' === $is_auto_generate ) ) {
$existing_customer_emails = ( $this->is_callable( $coupon, 'get_email_restrictions' ) ) ? $coupon->get_email_restrictions() : get_post_meta( $coupon_id, 'customer_email', true );
if ( empty( $existing_customer_emails ) || ! is_array( $existing_customer_emails ) ) {
$existing_customer_emails = array();
}
$existing_customer_emails[] = $customer_email;
if ( true === $is_callable_coupon_update_meta ) {
$coupon->set_email_restrictions( $existing_customer_emails );
} else {
update_post_meta( $coupon_id, 'customer_email', $existing_customer_emails );
}
}
if ( ! empty( $is_auto_generate ) && 'yes' === $is_auto_generate ) {
if ( 0 === $current_user->ID ) {
if ( 'smart_coupon' === $discount_type ) {
return; // Don't generate & don't show coupon if coupon of the shortcode is store credit & user is guest, otherwise it'll lead to unlimited generation of coupon.
} else {
$new_generated_coupon_code = $coupon_code;
}
} elseif ( true === $is_generate && 'yes' === $is_email ) {
$generated_coupon_details = apply_filters( 'generate_smart_coupon_action', $customer_email, $coupon_amount, '', $coupon );
$last_element = end( $generated_coupon_details[ $customer_email ] );
$new_generated_coupon_code = $last_element['code'];
} else {
$shortcode_generated_coupon = $this->get_shortcode_generated_coupon( $current_user, $coupon );
if ( empty( $shortcode_generated_coupon ) || ( true === $is_generate && 'yes' === $is_email ) ) {
$generated_coupon_details = apply_filters( 'generate_smart_coupon_action', $customer_email, $coupon_amount, '', $coupon );
$last_element = end( $generated_coupon_details[ $customer_email ] );
$new_generated_coupon_code = $last_element['code'];
$this->save_shortcode_generated_coupon( $new_generated_coupon_code, $current_user, $coupon );
} else {
$new_generated_coupon_code = $shortcode_generated_coupon;
}
}
} else {
$new_generated_coupon_code = $_coupon_code;
}
}
}
if ( ( ! empty( $_coupon_code ) && empty( $discount_type ) ) || ( empty( $_coupon_code ) ) ) {
if ( empty( $current_user->ID ) && ( 'smart_coupon' === $_discount_type || 'smart_coupon' === $discount_type ) ) {
return; // It'll prevent generation of unlimited coupons for guest.
}
if ( empty( $coupon ) ) {
$coupon = null;
}
$shortcode_generated_coupon = $this->get_shortcode_generated_coupon( $current_user, $coupon );
if ( empty( $shortcode_generated_coupon ) ) {
if ( empty( $_coupon_code ) ) {
$_coupon_code = $this->generate_unique_code( $customer_email );
$_coupon_code = $coupon_prefix . $_coupon_code . $coupon_suffix;
}
$coupon_args = array(
'post_title' => strtolower( $_coupon_code ),
'post_content' => '',
'post_status' => 'publish',
'post_author' => 1,
'post_type' => 'shop_coupon',
'post_parent' => ! empty( $coupon_id ) ? absint( $coupon_id ) : 0,
);
$new_coupon = new WC_Coupon();
$new_coupon->set_code( $coupon_args['post_title'] );
$new_coupon->set_status( $coupon_args['post_status'] );
$new_coupon_id = $new_coupon->save();
if ( ! empty( $new_coupon_id ) ) {
$coupon_args = array_diff_key( $coupon_args, array_flip( array( 'post_title', 'post_status', 'post_type' ) ) );
$coupon_args['ID'] = $new_coupon_id;
wp_update_post( $coupon_args );
}
$new_coupon_id = absint( $new_coupon_id );
$new_coupon = new WC_Coupon( $new_coupon_id );
$is_callable_new_coupon_update_meta = $this->is_callable( $new_coupon, 'update_meta_data' );
if ( ! empty( $shortcode['expiry_date'] ) ) {
$timestamp = strtotime( $shortcode['expiry_date'] ) + $this->wc_timezone_offset();
$_expiry_date = gmdate( 'Y-m-d', $timestamp );
} elseif ( ! empty( $expiry_days ) ) {
$timestamp = strtotime( "+$expiry_days days" ) + $this->wc_timezone_offset();
$_expiry_date = gmdate( 'Y-m-d', $timestamp );
}
if ( $this->is_wc_gte_30() ) {
if ( ! empty( $_expiry_date ) ) {
$_expiry_date = strtotime( $_expiry_date ) - $this->wc_timezone_offset();
$_expiry_date = $this->get_date_expires_value( $_expiry_date );
if ( true === $is_callable_new_coupon_update_meta ) {
$new_coupon->set_date_expires( $_expiry_date );
} else {
update_post_meta( $new_coupon_id, 'date_expires', $_expiry_date );
}
}
} else {
if ( true === $is_callable_new_coupon_update_meta ) {
$new_coupon->update_meta_data( 'expiry_date', $_expiry_date );
} else {
update_post_meta( $new_coupon_id, 'expiry_date', $_expiry_date );
}
}
if ( 'smart_coupon' === $_discount_type ) {
$this->update_post_meta( $new_coupon_id, 'wc_sc_original_amount', $_coupon_amount, false );
}
if ( true === $is_callable_new_coupon_update_meta ) {
$new_coupon->set_discount_type( $_discount_type );
$new_coupon->set_amount( $_coupon_amount );
$new_coupon->set_individual_use( $this->wc_string_to_bool( $individual_use ) );
$new_coupon->set_minimum_amount( $minimum_amount );
$new_coupon->set_maximum_amount( $maximum_amount );
$new_coupon->set_usage_limit( $usage_limit );
$new_coupon->set_email_restrictions( array( $customer_email ) );
$new_coupon->update_meta_data( 'apply_before_tax', $apply_before_tax );
$new_coupon->set_free_shipping( $this->wc_string_to_bool( $_free_shipping ) );
$new_coupon->set_product_categories( array() );
$new_coupon->set_excluded_product_categories( array() );
$new_coupon->update_meta_data( 'sc_disable_email_restriction', $disable_email );
} else {
update_post_meta( $new_coupon_id, 'discount_type', $_discount_type );
update_post_meta( $new_coupon_id, 'coupon_amount', $_coupon_amount );
update_post_meta( $new_coupon_id, 'individual_use', $individual_use );
update_post_meta( $new_coupon_id, 'minimum_amount', $minimum_amount );
update_post_meta( $new_coupon_id, 'maximum_amount', $maximum_amount );
update_post_meta( $new_coupon_id, 'usage_limit', $usage_limit );
update_post_meta( $new_coupon_id, 'customer_email', array( $customer_email ) );
update_post_meta( $new_coupon_id, 'apply_before_tax', $apply_before_tax );
update_post_meta( $new_coupon_id, 'free_shipping', $_free_shipping );
update_post_meta( $new_coupon_id, 'product_categories', array() );
update_post_meta( $new_coupon_id, 'exclude_product_categories', array() );
update_post_meta( $new_coupon_id, 'sc_disable_email_restriction', $disable_email );
}
if ( $this->is_callable( $new_coupon, 'save' ) ) {
$new_coupon->save();
}
$new_generated_coupon_code = $_coupon_code;
$this->save_shortcode_generated_coupon( $new_generated_coupon_code, $current_user, $coupon );
} else {
$new_generated_coupon_code = $shortcode_generated_coupon;
}
}
} else {
$new_generated_coupon_code = $_coupon_code;
}
$new_coupon_generated = false;
if ( ! empty( $new_generated_coupon_code ) ) {
$coupon = new WC_Coupon( $new_generated_coupon_code );
$new_coupon_generated = true;
}
if ( $new_coupon_generated ) {
if ( $this->is_wc_gte_30() ) {
if ( ! is_object( $coupon ) || ! is_callable( array( $coupon, 'get_id' ) ) ) {
return;
}
$coupon_id = $coupon->get_id();
if ( empty( $coupon_id ) ) {
return;
}
$is_free_shipping = ( $coupon->get_free_shipping() ) ? 'yes' : 'no';
$discount_type = $coupon->get_discount_type();
$expiry_date = $coupon->get_date_expires();
$coupon_code = $coupon->get_code();
} else {
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
$is_free_shipping = ( ! empty( $coupon->free_shipping ) ) ? $coupon->free_shipping : '';
$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
$expiry_date = ( ! empty( $coupon->expiry_date ) ) ? $coupon->expiry_date : '';
$coupon_code = ( ! empty( $coupon->code ) ) ? $coupon->code : '';
}
}
$coupon_amount = $this->get_amount( $coupon, true );
$coupon_post = get_post( $coupon_id );
$coupon_data = $this->get_coupon_meta_data( $coupon );
$design = get_option( 'wc_sc_setting_coupon_design', 'basic' );
$background_color = get_option( 'wc_sc_setting_coupon_background_color', '#39cccc' );
$foreground_color = get_option( 'wc_sc_setting_coupon_foreground_color', '#30050b' );
$third_color = get_option( 'wc_sc_setting_coupon_third_color', '#39cccc' );
$show_coupon_description = get_option( 'smart_coupons_show_coupon_description', 'no' );
$valid_designs = $this->get_valid_coupon_designs();
if ( ! in_array( $design, $valid_designs, true ) ) {
$design = 'basic';
}
if ( 'yes' === $is_email ) {
$design = ( 'custom-design' !== $design ) ? 'email-coupon' : $design;
}
?>
<style type="text/css"><?php echo esc_html( wp_strip_all_tags( $this->get_coupon_styles( $design, array( 'is_email' => $is_email ) ), true ) ); // phpcs:ignore ?></style>
<?php
if ( ! in_array( $design, array( 'custom-design', 'email-coupon' ), true ) ) {
?>
<style type="text/css">
:root {
--sc-color1: <?php echo esc_html( $background_color ); ?>;
--sc-color2: <?php echo esc_html( $foreground_color ); ?>;
--sc-color3: <?php echo esc_html( $third_color ); ?>;
}
</style>
<?php
}
?>
<?php
$coupon_type = ( ! empty( $coupon_data['coupon_type'] ) ) ? $coupon_data['coupon_type'] : '';
if ( 'yes' === $is_free_shipping ) {
if ( ! empty( $coupon_type ) ) {
$coupon_type .= __( ' & ', 'woocommerce-smart-coupons' );
}
$coupon_type .= __( 'Free Shipping', 'woocommerce-smart-coupons' );
}
if ( $this->is_wc_gte_30() && $expiry_date instanceof WC_DateTime ) {
$expiry_date = ( is_callable( array( $expiry_date, 'getTimestamp' ) ) ) ? $expiry_date->getTimestamp() : null;
} elseif ( ! is_int( $expiry_date ) ) {
$expiry_date = strtotime( $expiry_date );
}
if ( ! empty( $expiry_date ) && is_int( $expiry_date ) ) {
$expiry_time = ( $this->is_callable( $coupon, 'get_meta' ) ) ? (int) $coupon->get_meta( 'wc_sc_expiry_time' ) : (int) get_post_meta( $coupon_id, 'wc_sc_expiry_time', true );
if ( ! empty( $expiry_time ) ) {
$expiry_date += $expiry_time; // Adding expiry time to expiry date.
}
}
$coupon_description = '';
if ( ! empty( $coupon_post->post_excerpt ) && 'yes' === $show_coupon_description ) {
$coupon_description = $coupon_post->post_excerpt;
}
$is_percent = $this->is_percent_coupon( array( 'coupon_object' => $coupon ) );
$args = array(
'coupon_object' => $coupon,
'coupon_amount' => $coupon_amount,
'amount_symbol' => ( true === $is_percent ) ? '%' : get_woocommerce_currency_symbol(),
'discount_type' => wp_strip_all_tags( $coupon_type ),
'coupon_description' => ( ! empty( $coupon_description ) ) ? $coupon_description : wp_strip_all_tags( $this->generate_coupon_description( array( 'coupon_object' => $coupon ) ) ),
'coupon_code' => $new_generated_coupon_code,
'coupon_expiry' => ( ! empty( $expiry_date ) ) ? $this->get_expiration_format( $expiry_date ) : __( 'Never expires', 'woocommerce-smart-coupons' ),
'thumbnail_src' => $this->get_coupon_design_thumbnail_src(
array(
'design' => $design,
'coupon_object' => $coupon,
)
),
'classes' => '',
'template_id' => $design,
'is_percent' => $is_percent,
);
$coupon_target = '';
$wc_url_coupons_active_urls = get_option( 'wc_url_coupons_active_urls' ); // From plugin WooCommerce URL coupons.
if ( ! empty( $wc_url_coupons_active_urls ) ) {
$coupon_target = ( ! empty( $wc_url_coupons_active_urls[ $coupon_id ]['url'] ) ) ? $wc_url_coupons_active_urls[ $coupon_id ]['url'] : '';
}
if ( ! empty( $coupon_target ) ) {
$coupon_target = home_url( '/' . $coupon_target );
} else {
$coupon_target = home_url( '/?sc-page=shop&coupon-code=' . $coupon_code );
}
$coupon_target = apply_filters( 'sc_coupon_url_in_email', $coupon_target, $coupon );
do_action(
'wc_sc_before_shortcode_smart_coupons_html_start',
array(
'source' => $this,
'shortcode_attributes' => $shortcode,
'coupon_object' => $coupon,
)
);
if ( 'yes' === $is_email ) {
echo '<div style="margin: 10px 0;" title="' . esc_html__( 'Click to visit store. This coupon will be applied automatically.', 'woocommerce-smart-coupons' ) . '">';
}
if ( 'yes' === $is_clickable ) {
echo '<a href="' . esc_url( $coupon_target ) . '" style="color: #444;">';
}
echo '<div id="sc-cc"><div class="sc-coupons-list">';
wc_get_template( 'coupon-design/' . $design . '.php', $args, '', plugin_dir_path( WC_SC_PLUGIN_FILE ) . 'templates/' );
echo '</div></div>';
if ( 'yes' === $is_clickable ) {
echo '</a>';
}
if ( 'yes' === $is_email ) {
echo '</div>';
}
return ob_get_clean();
}
/**
* Show available coupons
*
* @param array $atts Shortcode attributes.
* @return HTML code for coupon to be displayed
*/
public function show_available_coupons_shortcode( $atts ) {
$shortcode = shortcode_atts(
array(
'title' => get_option( 'smart_coupon_cart_page_text' ),
),
$atts
);
$title = $shortcode['title'];
$title = ( ! empty( $title ) ) ? $title : __( 'Available Coupons (click on a coupon to use it)', 'woocommerce-smart-coupons' );
if ( ! class_exists( 'WC_SC_Display_Coupons' ) ) {
include_once 'class-wc-sc-display-coupons.php';
}
$wc_sc_display_coupons = WC_SC_Display_Coupons::get_instance();
if ( ! is_object( $wc_sc_display_coupons ) || ! is_callable( array( $wc_sc_display_coupons, 'show_available_coupons' ) ) ) {
return '';
}
ob_start();
$wc_sc_display_coupons->show_available_coupons( $title, get_the_title() );
return ob_get_clean();
}
/**
* Function to check whether to generate a new coupon through shortcode for current user
* Don't create if it is already generated.
*
* @param WP_User $current_user The user object.
* @param WC_Coupon $coupon The coupon object.
* @return string $code
*/
public function get_shortcode_generated_coupon( $current_user = null, $coupon = null ) {
$max_in_a_session = get_option( '_sc_max_coupon_generate_in_a_session', 1 );
$max_per_coupon_per_user = get_option( '_sc_max_coupon_per_coupon_per_user', 1 );
if ( $this->is_wc_gte_30() ) {
$coupon_code = ( ! empty( $coupon ) && is_callable( array( $coupon, 'get_code' ) ) ) ? $coupon->get_code() : '';
} else {
$coupon_code = ( ! empty( $coupon->code ) ) ? $coupon->code : '';
}
$code = ( ! empty( $coupon_code ) ) ? $coupon_code : '';
if ( ! empty( $current_user->ID ) ) {
$generated_coupons = get_user_meta( $current_user->ID, '_sc_shortcode_generated_coupons', true );
if ( ! empty( $generated_coupons[ $code ] ) && count( $generated_coupons[ $code ] ) >= $max_per_coupon_per_user ) {
return end( $generated_coupons[ $code ] );
}
}
$session_shortcode_coupons = ( is_object( WC()->session ) && is_callable( array( WC()->session, 'get' ) ) ) ? WC()->session->get( '_sc_session_shortcode_generated_coupons' ) : array();
if ( ! empty( $session_shortcode_coupons[ $code ] ) && count( $session_shortcode_coupons[ $code ] ) >= $max_in_a_session ) {
return end( $session_shortcode_coupons[ $code ] );
}
return false;
}
/**
* Function to save shortcode generated coupon details
*
* @param string $new_code The coupon code.
* @param WP_User $current_user The user object.
* @param WC_Coupon $coupon The coupon object.
*/
public function save_shortcode_generated_coupon( $new_code, $current_user, $coupon ) {
if ( $this->is_wc_gte_30() ) {
$coupon_code = ( ! empty( $coupon ) && is_callable( array( $coupon, 'get_code' ) ) ) ? $coupon->get_code() : '';
} else {
$coupon_code = ( ! empty( $coupon->code ) ) ? $coupon->code : '';
}
$code = ( ! empty( $coupon_code ) ) ? $coupon_code : 0;
$session_shortcode_coupons = ( is_object( WC()->session ) && is_callable( array( WC()->session, 'get' ) ) ) ? WC()->session->get( '_sc_session_shortcode_generated_coupons' ) : array();
if ( empty( $session_shortcode_coupons ) || ! is_array( $session_shortcode_coupons ) ) {
$session_shortcode_coupons = array();
}
if ( empty( $session_shortcode_coupons[ $code ] ) ) {
$session_shortcode_coupons[ $code ] = array();
}
if ( ! in_array( $new_code, $session_shortcode_coupons[ $code ], true ) ) {
$session_shortcode_coupons[ $code ][] = $new_code;
if ( is_object( WC()->session ) && is_callable( array( WC()->session, 'set' ) ) ) {
WC()->session->set( '_sc_session_shortcode_generated_coupons', $session_shortcode_coupons );
}
}
if ( ! empty( $current_user->ID ) ) {
$generated_coupons = get_user_meta( $current_user->ID, '_sc_shortcode_generated_coupons', true );
if ( empty( $generated_coupons ) ) {
$generated_coupons = array();
}
if ( empty( $generated_coupons[ $code ] ) ) {
$generated_coupons[ $code ] = array();
}
if ( ! in_array( $new_code, $generated_coupons[ $code ], true ) ) {
$generated_coupons[ $code ][] = $new_code;
update_user_meta( $current_user->ID, '_sc_shortcode_generated_coupons', $generated_coupons );
}
}
}
/**
* Smart coupon button after TinyMCE
*
* @param mixed $mce_settings The editor settings.
*/
public function smart_coupons_after_wp_tiny_mce( $mce_settings ) {
if ( ! is_admin() || ! current_user_can( 'manage_options' ) ) { // Show shortcode attribute dialog to only top level users.
return;
}
$this->sc_attributes_dialog();
}
/**
* Smart Coupons dialog content for shortcode
*/
public function sc_attributes_dialog() {
?>
<div style="display:none;">
<form id="sc_coupons_attributes" tabindex="-1" style="background-color: #F5F5F5;">
<?php wp_nonce_field( 'internal_coupon_shortcode', '_ajax_coupon_shortcode_nonce', false ); ?>
<script type="text/javascript">
jQuery(function(){
jQuery('input#search-coupon-field').on('keyup',function() {
jQuery('div#search-results ul').empty();
var searchString = jQuery(this).val().trim();
if ( searchString.length == 0 ) {
jQuery('#default-text').html('<?php echo esc_html__( 'No search term specified.', 'woocommerce-smart-coupons' ); ?>');
return true;
}
if ( searchString.length == 1 ) {
jQuery('#default-text').html('<?php echo esc_html__( 'Enter more than one character to search.', 'woocommerce-smart-coupons' ); ?>');
return true;
}
jQuery.ajax({
url: '<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>',
method: 'GET',
afterTypeDelay: 100,
data: {
action : 'smart_coupons_json_search',
security : '<?php echo esc_attr( wp_create_nonce( 'search-coupons' ) ); ?>',
term : searchString
},
dataType: 'json',
success: function( response ) {
if ( response ) {
jQuery('#default-text').html('<?php echo esc_html__( 'Click to select coupon code.', 'woocommerce-smart-coupons' ); ?>');
} else {
jQuery('#default-text').html('<?php echo esc_html__( 'No coupon code found.', 'woocommerce-smart-coupons' ); ?>');
return;
}
jQuery('div#search-results ul').html('');
jQuery.each(response, function (i, val) {
jQuery('div#search-results ul').append('<li class="'+i+'">'+ i +val.substr(val.indexOf('(')-1)+'</li>');
});
}
});
});
jQuery('div#sc_shortcode_cancel a').on('click', function() {
emptyAllFormElement();
jQuery('.ui-dialog-titlebar-close').trigger('click');
});
function emptyAllFormElement() {
jQuery('#search-coupon-field').val('');
jQuery('#default-text').html('<?php echo esc_html__( 'No search term specified.', 'woocommerce-smart-coupons' ); ?>');
jQuery('#search-results ul').empty();
}
jQuery('div#search-results').on('click', 'ul li', function() {
var couponCode = jQuery(this).attr('class');
jQuery('input#search-coupon-field').val(couponCode);
});
jQuery('input#sc_shortcode_submit').on('click', function() {
var couponShortcode = '[smart_coupons';
var couponCode = jQuery('#search-coupon-field').val();
if ( couponCode != undefined && couponCode != '' ) {
couponShortcode += ' coupon_code="'+couponCode.trim()+'"';
}
couponShortcode += ' is_clickable="yes"';
couponShortcode += ']';
tinyMCE.execCommand("mceInsertContent", false, couponShortcode);
emptyAllFormElement();
jQuery('.ui-dialog-titlebar-close').trigger('click');
});
});
</script>
<div id="coupon-selector">
<div id="coupon-option">
<div>
<label><span><?php echo esc_html__( 'Coupon code', 'woocommerce-smart-coupons' ); ?></span><input id="search-coupon-field" type="text" name="search_coupon_code" placeholder="<?php echo esc_attr__( 'Search coupon...', 'woocommerce-smart-coupons' ); ?>"/></label>
</div>
<div id="search-panel">
<div id="search-results">
<div id="default-text"><?php echo esc_html__( 'No search term specified.', 'woocommerce-smart-coupons' ); ?></div>
<ul></ul>
</div>
</div>
</div>
</div>
<div id="sc-cc">
<div class="coupon-preview sc-coupons-list">
<div class="preview-heading">
<?php echo esc_html__( 'Preview', 'woocommerce-smart-coupons' ); ?>
</div>
<?php
$design = get_option( 'wc_sc_setting_coupon_design', 'basic' );
$background_color = get_option( 'wc_sc_setting_coupon_background_color', '#39cccc' );
$foreground_color = get_option( 'wc_sc_setting_coupon_foreground_color', '#30050b' );
$third_color = get_option( 'wc_sc_setting_coupon_third_color', '#39cccc' );
$show_coupon_description = get_option( 'smart_coupons_show_coupon_description', 'no' );
$valid_designs = $this->get_valid_coupon_designs();
if ( ! in_array( $design, $valid_designs, true ) ) {
$design = 'basic';
}
?>
<style type="text/css"><?php echo esc_html( wp_strip_all_tags( $this->get_coupon_styles( $design ), true ) ); // phpcs:ignore ?></style>
<?php
if ( 'custom-design' !== $design ) {
?>
<style type="text/css">
:root {
--sc-color1: <?php echo esc_html( $background_color ); ?>;
--sc-color2: <?php echo esc_html( $foreground_color ); ?>;
--sc-color3: <?php echo esc_html( $third_color ); ?>;
}
</style>
<?php
}
?>
<?php
$args = array(
'coupon_amount' => 'XX',
'amount_symbol' => get_woocommerce_currency_symbol(),
'discount_type' => 'Discount type',
'coupon_description' => 'Description',
'coupon_code' => 'coupon-code',
'coupon_expiry' => 'Expires on xx date',
'thumbnail_src' => '',
'classes' => '',
'template_id' => $design,
'is_percent' => false,
);
wc_get_template( 'coupon-design/' . $design . '.php', $args, '', plugin_dir_path( WC_SC_PLUGIN_FILE ) . 'templates/' );
?>
</div>
</div>
<div class="submitbox">
<div id="sc_shortcode_update">
<input type="button" value="<?php echo esc_attr__( 'Insert Shortcode', 'woocommerce-smart-coupons' ); ?>" class="button-primary" id="sc_shortcode_submit" name="sc_shortcode_submit">
</div>
<div id="sc_shortcode_cancel">
<a class="submitdelete deletion" href="#"><?php echo esc_html__( 'Cancel', 'woocommerce-smart-coupons' ); ?></a>
</div>
</div>
</form>
</div>
<?php
}
}
}
WC_SC_Shortcode::get_instance();

View File

@@ -1,581 +0,0 @@
<?php
/**
* Coupons via URL
*
* @author StoreApps
* @since 3.3.0
* @version 1.9.0
*
* @package woocommerce-smart-coupons/includes/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_URL_Coupon' ) ) {
/**
* Class for handling coupons applied via URL
*/
class WC_SC_URL_Coupon {
/**
* Variable to hold instance of WC_SC_URL_Coupon
*
* @var $instance
*/
private static $instance = null;
/**
* Variable to hold coupon notices
*
* @var $coupon_notices
*/
private $coupon_notices = array();
/**
* Constructor
*/
private function __construct() {
add_action( 'wp_loaded', array( $this, 'apply_coupon_from_url' ), 19 );
add_action( 'wp_loaded', array( $this, 'apply_coupon_from_session' ), 20 );
add_action( 'wp_loaded', array( $this, 'move_applied_coupon_from_cookies_to_account' ) );
add_action( 'wp_head', array( $this, 'convert_sc_coupon_notices_to_wc_notices' ) );
add_filter( 'the_content', array( $this, 'show_coupon_notices' ) );
}
/**
* Get single instance of WC_SC_URL_Coupon
*
* @return WC_SC_URL_Coupon Singleton object of WC_SC_URL_Coupon
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name The function name.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return result of function call
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Apply coupon code if passed in url
*/
public function apply_coupon_from_url() {
if ( empty( $_SERVER['QUERY_STRING'] ) ) {
return;
}
parse_str( wp_unslash( $_SERVER['QUERY_STRING'] ), $coupon_args ); // phpcs:ignore
$coupon_args = wc_clean( $coupon_args );
if ( ! empty( $coupon_args['coupon-code'] ) ) {
$coupons_data = array();
$coupon_args['coupon-code'] = urldecode( $coupon_args['coupon-code'] );
$coupon_codes = explode( ',', $coupon_args['coupon-code'] );
$coupon_codes = array_filter( $coupon_codes ); // Remove empty coupon codes if any.
$cart = ( is_object( WC() ) && isset( WC()->cart ) ) ? WC()->cart : null;
foreach ( $coupon_codes as $coupon_index => $coupon_code ) {
// Process only first five coupons to avoid GET request parameter limit.
if ( apply_filters( 'wc_sc_max_url_coupons_limit', 5 ) === $coupon_index ) {
break;
}
if ( empty( $coupon_code ) ) {
continue;
}
$coupons_data[] = array(
'coupon-code' => $coupon_code,
);
}
$is_cart_empty = is_a( $cart, 'WC_Cart' ) && is_callable( array( $cart, 'is_empty' ) ) && $cart->is_empty();
if ( true === $is_cart_empty ) {
$is_hold = apply_filters(
'wc_sc_hold_applied_coupons',
true,
array(
'coupons_data' => $coupons_data,
'source' => $this,
)
);
if ( true === $is_hold ) {
$this->hold_applied_coupon( $coupons_data );
}
// Set a session cookie to persist the coupon in case the cart is empty. This code will persist the coupon even if the param sc-page is not supplied.
WC()->session->set_customer_session_cookie( true ); // Thanks to: Devon Godfrey.
} else {
foreach ( $coupons_data as $coupon_data ) {
$coupon_code = $coupon_data['coupon-code'];
if ( ! WC()->cart->has_discount( $coupon_code ) ) {
WC()->cart->add_discount( trim( $coupon_code ) );
}
}
}
if ( ! empty( $coupon_args['add-to-cart'] ) ) {
add_filter( 'woocommerce_add_to_cart_redirect', array( $this, 'add_to_cart_redirect' ), 20, 2 );
return; // Redirection handed over to WooCommerce.
}
if ( empty( $coupon_args['sc-page'] ) ) {
return;
}
$redirect_url = $this->get_sc_redirect_url( $coupon_args );
wp_safe_redirect( $redirect_url );
exit;
}
}
/**
* Get Smart Coupons redirect url
*
* @param array $coupon_args Coupon args.
* @return string
*/
public function get_sc_redirect_url( $coupon_args = array() ) {
$redirect_url = '';
if ( in_array( $coupon_args['sc-page'], array( 'shop', 'cart', 'checkout', 'myaccount' ), true ) ) {
if ( $this->is_wc_gte_30() ) {
$page_id = wc_get_page_id( $coupon_args['sc-page'] );
} else {
$page_id = woocommerce_get_page_id( $coupon_args['sc-page'] );
}
$redirect_url = get_permalink( $page_id );
} elseif ( is_string( $coupon_args['sc-page'] ) ) {
if ( is_numeric( $coupon_args['sc-page'] ) && ! is_float( $coupon_args['sc-page'] ) ) {
$page = $coupon_args['sc-page'];
} else {
$page = ( function_exists( 'wpcom_vip_get_page_by_path' ) ) ? wpcom_vip_get_page_by_path( $coupon_args['sc-page'], OBJECT, get_post_types() ) : get_page_by_path( $coupon_args['sc-page'], OBJECT, get_post_types() ); // phpcs:ignore
}
$redirect_url = get_permalink( $page );
} elseif ( is_numeric( $coupon_args['sc-page'] ) && ! is_float( $coupon_args['sc-page'] ) ) {
$redirect_url = get_permalink( $coupon_args['sc-page'] );
}
if ( empty( $redirect_url ) ) {
$redirect_url = home_url();
}
return $this->get_redirect_url_after_smart_coupons_process( $redirect_url );
}
/**
* WooCommerce handles add to cart redirect.
*
* @param string $url The redirect URL.
* @param WC_Product $product Product.
* @return string
*/
public function add_to_cart_redirect( $url = '', $product = null ) {
remove_filter( 'woocommerce_add_to_cart_redirect', array( $this, 'add_to_cart_redirect' ), 20 );
if ( empty( $_SERVER['QUERY_STRING'] ) ) {
return $url;
}
parse_str( wp_unslash( $_SERVER['QUERY_STRING'] ), $coupon_args ); // phpcs:ignore
$coupon_args = wc_clean( $coupon_args );
if ( ! empty( $coupon_args['sc-page'] ) ) {
return $this->get_sc_redirect_url( $coupon_args );
}
return $url;
}
/**
* Apply coupon code from session, if any
*/
public function apply_coupon_from_session() {
$cart = ( is_object( WC() ) && isset( WC()->cart ) ) ? WC()->cart : null;
if ( empty( $cart ) || WC()->cart->is_empty() ) {
return;
}
$user_id = get_current_user_id();
if ( 0 === $user_id ) {
$unique_id = ( ! empty( $_COOKIE['sc_applied_coupon_profile_id'] ) ) ? wc_clean( wp_unslash( $_COOKIE['sc_applied_coupon_profile_id'] ) ) : ''; // phpcs:ignore
$applied_coupon_from_url = ( ! empty( $unique_id ) ) ? $this->get_applied_coupons_by_guest_user( $unique_id ) : array();
} else {
$applied_coupon_from_url = get_user_meta( $user_id, 'sc_applied_coupon_from_url', true );
}
if ( empty( $applied_coupon_from_url ) ) {
return;
}
foreach ( $applied_coupon_from_url as $index => $coupon_code ) {
$coupon = new WC_Coupon( $coupon_code );
if ( $coupon->is_valid() && ! WC()->cart->has_discount( $coupon_code ) ) {
WC()->cart->add_discount( trim( $coupon_code ) );
unset( $applied_coupon_from_url[ $index ] );
}
}
if ( 0 === $user_id ) {
$this->set_applied_coupon_for_guest_user( $unique_id, $applied_coupon_from_url );
} else {
update_user_meta( $user_id, 'sc_applied_coupon_from_url', $applied_coupon_from_url );
}
}
/**
* Apply coupon code from session, if any
*
* @param array $coupons_args The coupon arguments.
*/
public function hold_applied_coupon( $coupons_args = array() ) {
$user_id = get_current_user_id();
$saved_status = array();
if ( 0 === $user_id ) {
$saved_status = $this->save_applied_coupon_in_cookie( $coupons_args );
} else {
$saved_status = $this->save_applied_coupon_in_account( $coupons_args, $user_id );
}
if ( ! empty( $saved_status ) ) {
foreach ( $coupons_args as $coupon_args ) {
$coupon_code = $coupon_args['coupon-code'];
$save_status = isset( $saved_status[ $coupon_code ] ) ? $saved_status[ $coupon_code ] : '';
if ( 'saved' === $save_status ) {
/* translators: %s: $coupon_code coupon code */
$notice = sprintf( __( 'Coupon code "%s" applied successfully. Please add some products to the cart to see the discount.', 'woocommerce-smart-coupons' ), $coupon_code );
$this->set_coupon_notices( $notice, 'success' );
} elseif ( 'already_saved' === $save_status ) {
/* translators: %s: $coupon_code coupon code */
$notice = sprintf( __( 'Coupon code "%s" already applied! Please add some products to the cart to see the discount.', 'woocommerce-smart-coupons' ), $coupon_code );
$this->set_coupon_notices( $notice, 'error' );
}
}
}
}
/**
* Apply coupon code from session, if any
*
* @param array $coupons_args The coupon arguments.
* @return array $saved_status
*/
public function save_applied_coupon_in_cookie( $coupons_args = array() ) {
$saved_status = array(); // Variable to store whether coupons saved/already saved in cookie.
if ( ! empty( $coupons_args ) ) {
if ( empty( $_COOKIE['sc_applied_coupon_profile_id'] ) ) {
$unique_id = $this->generate_unique_id();
} else {
$unique_id = wc_clean( wp_unslash( $_COOKIE['sc_applied_coupon_profile_id'] ) ); // phpcs:ignore
}
$applied_coupons = $this->get_applied_coupons_by_guest_user( $unique_id );
foreach ( $coupons_args as $coupon_args ) {
$coupon_code = isset( $coupon_args['coupon-code'] ) ? $coupon_args['coupon-code'] : '';
if ( is_array( $applied_coupons ) && in_array( $coupon_code, $applied_coupons, true ) ) {
$saved_status[ $coupon_code ] = 'already_saved';
} else {
$applied_coupons[] = $coupon_code;
$saved_status[ $coupon_code ] = 'saved';
}
}
$this->set_applied_coupon_for_guest_user( $unique_id, $applied_coupons );
wc_setcookie( 'sc_applied_coupon_profile_id', $unique_id, $this->get_cookie_life() );
}
return $saved_status;
}
/**
* Apply coupon code from session, if any
*
* @param array $coupons_args The coupon arguments.
* @param int $user_id The user id.
* @return array $saved_status
*/
public function save_applied_coupon_in_account( $coupons_args = array(), $user_id = 0 ) {
$saved_status = array(); // Variable to store whether coupons saved/already saved in user meta.
if ( ! empty( $coupons_args ) ) {
$applied_coupons = get_user_meta( $user_id, 'sc_applied_coupon_from_url', true );
if ( empty( $applied_coupons ) ) {
$applied_coupons = array();
}
foreach ( $coupons_args as $coupon_args ) {
$coupon_code = $coupon_args['coupon-code'];
if ( ! in_array( $coupon_code, $applied_coupons, true ) ) {
$applied_coupons[] = $coupon_args['coupon-code'];
$saved_status[ $coupon_code ] = 'saved';
} else {
$saved_status[ $coupon_code ] = 'already_saved';
}
}
update_user_meta( $user_id, 'sc_applied_coupon_from_url', $applied_coupons );
}
return $saved_status;
}
/**
* Apply coupon code from session, if any
*/
public function move_applied_coupon_from_cookies_to_account() {
$user_id = get_current_user_id();
if ( $user_id > 0 && ! empty( $_COOKIE['sc_applied_coupon_profile_id'] ) ) {
$unique_id = wc_clean( wp_unslash( $_COOKIE['sc_applied_coupon_profile_id'] ) ); // phpcs:ignore
$applied_coupons = $this->get_applied_coupons_by_guest_user( $unique_id );
if ( false !== $applied_coupons && is_array( $applied_coupons ) && ! empty( $applied_coupons ) ) {
$saved_coupons = get_user_meta( $user_id, 'sc_applied_coupon_from_url', true );
if ( empty( $saved_coupons ) || ! is_array( $saved_coupons ) ) {
$saved_coupons = array();
}
$saved_coupons = array_merge( $saved_coupons, $applied_coupons );
update_user_meta( $user_id, 'sc_applied_coupon_from_url', $saved_coupons );
wc_setcookie( 'sc_applied_coupon_profile_id', '' );
$this->delete_applied_coupons_of_guest_user( $unique_id );
delete_option( 'sc_applied_coupon_profile_' . $unique_id );
}
}
}
/**
* Function to get redirect URL after processing Smart Coupons params
*
* @param string $url The URL.
* @return string $url
*/
public function get_redirect_url_after_smart_coupons_process( $url = '' ) {
if ( empty( $url ) ) {
return $url;
}
$query_string = ( ! empty( $_SERVER['QUERY_STRING'] ) ) ? wc_clean( wp_unslash( $_SERVER['QUERY_STRING'] ) ) : array(); // phpcs:ignore
parse_str( $query_string, $url_args );
$sc_params = array( 'coupon-code', 'sc-page' );
$url_params = array_diff_key( $url_args, array_flip( $sc_params ) );
if ( empty( $url_params['add-to-cart'] ) ) {
$redirect_url = apply_filters( 'wc_sc_redirect_url_after_smart_coupons_process', add_query_arg( $url_params, $url ), array( 'source' => $this ) );
} else {
$redirect_url = apply_filters( 'wc_sc_redirect_url_after_smart_coupons_process', $url, array( 'source' => $this ) );
}
return $redirect_url;
}
/**
* Function to convert sc coupon notices to wc notices
*/
public function convert_sc_coupon_notices_to_wc_notices() {
$coupon_notices = $this->get_coupon_notices();
// If we have coupon notices to be shown and we are on a woocommerce page then convert them to wc notices.
if ( count( $coupon_notices ) > 0 && ( is_woocommerce() || is_cart() || is_checkout() || is_account_page() ) ) {
foreach ( $coupon_notices as $notice_type => $notices ) {
if ( count( $notices ) > 0 ) {
foreach ( $notices as $notice ) {
wc_add_notice( $notice, $notice_type );
}
}
}
$this->remove_coupon_notices();
}
}
/**
* Function to get sc coupon notices
*/
public function get_coupon_notices() {
return apply_filters( 'wc_sc_coupon_notices', $this->coupon_notices );
}
/**
* Function to set sc coupon notices
*
* @param string $notice notice.
* @param string $type notice type.
*/
public function set_coupon_notices( $notice = '', $type = '' ) {
if ( empty( $notice ) || empty( $type ) ) {
return;
}
if ( empty( $this->coupon_notices[ $type ] ) || ! is_array( $this->coupon_notices[ $type ] ) ) {
$this->coupon_notices[ $type ] = array();
}
$this->coupon_notices[ $type ][] = $notice;
}
/**
* Function to remove sc coupon notices
*/
public function remove_coupon_notices() {
$this->coupon_notices = array();
}
/**
* Function to add coupon notices to wp content
*
* @param string $content page content.
* @return string $content page content
*/
public function show_coupon_notices( $content = '' ) {
$coupon_notices = $this->get_coupon_notices();
if ( count( $coupon_notices ) > 0 ) {
// Buffer output.
ob_start();
foreach ( $coupon_notices as $notice_type => $notices ) {
if ( count( $coupon_notices[ $notice_type ] ) > 0 ) {
wc_get_template(
"notices/{$notice_type}.php",
array(
'messages' => $coupon_notices[ $notice_type ],
)
);
}
}
$notices = wc_kses_notice( ob_get_clean() );
$content = $notices . $content;
$this->remove_coupon_notices(); // Empty out notice data.
}
return $content;
}
/**
* Function to get coupon codes by guest user's unique id.
*
* @param string $unique_id Unique id for guest user.
*
* @return array.
*/
public function get_applied_coupons_by_guest_user( $unique_id = '' ) {
$key = sprintf( 'sc_applied_coupon_profile_%s', $unique_id );
// Get coupons from `transient`.
$coupons = get_transient( $key );
if ( ! empty( $coupons ) && is_array( $coupons ) ) {
return $coupons;
}
// Get coupon from `wp_option`.
return get_option( $key, array() );
}
/**
* Function to set applied coupons for guest user.
*
* @param string $unique_id Unique id for guest user.
* @param array $coupons Array of coupon codes.
*
* @return bool.
*/
public function set_applied_coupon_for_guest_user( $unique_id = '', $coupons = array() ) {
if ( ! empty( $unique_id ) && is_array( $coupons ) ) {
$key = sprintf( 'sc_applied_coupon_profile_%s', $unique_id );
if ( empty( $coupons ) ) {
return delete_transient( $key );
} else {
return set_transient(
$key,
$coupons,
apply_filters( 'wc_sc_applied_coupon_by_url_expire_time', MONTH_IN_SECONDS )
);
}
}
return false;
}
/**
* Function to delete all applied coupons for a guest user.
*
* @param string $unique_id Unique id for guest user.
*
* @return bool.
*/
public function delete_applied_coupons_of_guest_user( $unique_id = '' ) {
if ( ! empty( $unique_id ) ) {
$key = sprintf( 'sc_applied_coupon_profile_%s', $unique_id );
return delete_transient( $key );
}
return false;
}
}
}
WC_SC_URL_Coupon::get_instance();

View File

@@ -1,203 +0,0 @@
<?php
/**
* Compatibility class for WooCommerce 4.4.0
*
* @category Class
* @package WC-compat
* @author StoreApps
* @version 1.1.0
* @since WooCommerce 4.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'SA_WC_Compatibility_4_4' ) ) {
/**
* Class to check WooCommerce version is greater than and equal to 4.4.0
*/
class SA_WC_Compatibility_4_4 {
/**
* Function to check if WooCommerce is Greater Than And Equal To 4.4.0
*
* @return boolean
*/
public static function is_wc_gte_44() {
return self::is_wc_greater_than( '4.3.3' );
}
/**
* Function to check if WooCommerce is Greater Than And Equal To 4.3.0
*
* @return boolean
*/
public static function is_wc_gte_43() {
return self::is_wc_greater_than( '4.2.2' );
}
/**
* Function to check if WooCommerce is Greater Than And Equal To 4.2.0
*
* @return boolean
*/
public static function is_wc_gte_42() {
return self::is_wc_greater_than( '4.1.1' );
}
/**
* Function to check if WooCommerce is Greater Than And Equal To 4.1.0
*
* @return boolean
*/
public static function is_wc_gte_41() {
return self::is_wc_greater_than( '4.0.1' );
}
/**
* Function to check if WooCommerce is Greater Than And Equal To 4.0.0
*
* @return boolean
*/
public static function is_wc_gte_40() {
return self::is_wc_greater_than( '3.9.3' );
}
/**
* Function to check if WooCommerce is Greater Than And Equal To 3.9.0
*
* @return boolean
*/
public static function is_wc_gte_39() {
return self::is_wc_greater_than( '3.8.1' );
}
/**
* Function to check if WooCommerce is Greater Than And Equal To 3.8.0
*
* @return boolean
*/
public static function is_wc_gte_38() {
return self::is_wc_greater_than( '3.7.1' );
}
/**
* Function to check if WooCommerce is Greater Than And Equal To 3.7.0
*
* @return boolean
*/
public static function is_wc_gte_37() {
return self::is_wc_greater_than( '3.6.5' );
}
/**
* Function to check if WooCommerce is Greater Than And Equal To 3.6.0
*
* @return boolean
*/
public static function is_wc_gte_36() {
return self::is_wc_greater_than( '3.5.8' );
}
/**
* Function to check if WooCommerce is Greater Than And Equal To 3.5.0
*
* @return boolean
*/
public static function is_wc_gte_35() {
return self::is_wc_greater_than( '3.4.7' );
}
/**
* Function to check if WooCommerce is Greater Than And Equal To 3.3.0
*
* @return boolean
*/
public static function is_wc_gte_34() {
return self::is_wc_greater_than( '3.3.5' );
}
/**
* Function to check if WooCommerce is Greater Than And Equal To 3.3.0
*
* @return boolean
*/
public static function is_wc_gte_33() {
return self::is_wc_greater_than( '3.2.6' );
}
/**
* Function to check if WooCommerce is Greater Than And Equal To 3.2.0
*
* @return boolean
*/
public static function is_wc_gte_32() {
return self::is_wc_greater_than( '3.1.2' );
}
/**
* Function to check if WooCommerce is Greater Than And Equal To 3.1.0
*
* @return boolean
*/
public static function is_wc_gte_31() {
return self::is_wc_greater_than( '3.0.9' );
}
/**
* Function to check if WooCommerce is Greater Than And Equal To 3.0.0
*
* @return boolean
*/
public static function is_wc_gte_30() {
return self::is_wc_greater_than( '2.6.14' );
}
/**
* Function to check if WooCommerce version is greater than and equal to 2.6
*
* @return boolean
*/
public static function is_wc_gte_26() {
return self::is_wc_greater_than( '2.5.5' );
}
/**
* Function to check if WooCommerce version is greater than and equal To 2.5
*
* @return boolean
*/
public static function is_wc_gte_25() {
return self::is_wc_greater_than( '2.4.13' );
}
/**
* Function to get WooCommerce version
*
* @return string version or null.
*/
public static function get_wc_version() {
if ( defined( 'WC_VERSION' ) && WC_VERSION ) {
return WC_VERSION;
}
if ( defined( 'WOOCOMMERCE_VERSION' ) && WOOCOMMERCE_VERSION ) {
return WOOCOMMERCE_VERSION;
}
return null;
}
/**
* Function to compare current version of WooCommerce on site with active version of WooCommerce
*
* @param string $version Version number to compare.
* @return bool
*/
public static function is_wc_greater_than( $version ) {
return version_compare( self::get_wc_version(), $version, '>' );
}
}
}

View File

@@ -1,89 +0,0 @@
<?php
/**
* Compatibility file for WooCommerce Aelia Currency Switcher
*
* @author StoreApps
* @since 6.1.0
* @version 1.0.1
*
* @package woocommerce-smart-coupons/includes/compat/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Aelia_CS_Compatibility' ) ) {
/**
* Class for handling compatibility with WooCommerce Aelia Currency Switcher
*/
class WC_SC_Aelia_CS_Compatibility {
/**
* Variable to hold instance of WC_SC_Aelia_CS_Compatibility
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
public function __construct() {
add_filter( 'wc_aelia_cs_coupon_types_to_convert', array( $this, 'add_smart_coupon' ) );
}
/**
* Get single instance of WC_SC_Aelia_CS_Compatibility
*
* @return WC_SC_Aelia_CS_Compatibility Singleton object of WC_SC_Aelia_CS_Compatibility
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Add discount type 'smart_coupon' in Aelia Currency Switcher's framework
*
* @param array $coupon_types Existing coupon types.
* @return array $coupon_types
*/
public function add_smart_coupon( $coupon_types = array() ) {
if ( empty( $coupon_types ) || ! is_array( $coupon_types ) ) {
return $coupon_types;
}
if ( ! in_array( 'smart_coupon', $coupon_types, true ) ) {
$coupon_types[] = 'smart_coupon';
}
return $coupon_types;
}
/**
* Check & convert price
*
* @param float $price The price need to be converted.
* @param string $to_currency The price will be converted to this currency.
* @param string $from_currency The price will be converted from this currency.
* @return float
*/
public function convert_price( $price = 0, $to_currency = null, $from_currency = null ) {
if ( empty( $from_currency ) ) {
$from_currency = get_option( 'woocommerce_currency' ); // Shop base currency.
}
if ( empty( $to_currency ) ) {
$to_currency = get_woocommerce_currency(); // Active currency.
}
return apply_filters( 'wc_aelia_cs_convert', $price, $from_currency, $to_currency );
}
}
}
WC_SC_Aelia_CS_Compatibility::get_instance();

View File

@@ -1,140 +0,0 @@
<?php
/**
* Compatibility file for Klarna Checkout for WooCommerce
*
* @author StoreApps
* @since 7.1.0
* @version 1.0.0
*
* @package woocommerce-smart-coupons/includes/compat/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_KCO_Compatibility' ) ) {
/**
* Class for handling compatibility with Klarna Checkout for WooCommerce
*/
class WC_SC_KCO_Compatibility {
/**
* Variable to hold instance of WC_SC_KCO_Compatibility
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
public function __construct() {
add_action( 'wp_loaded', array( $this, 'hooks_for_compatibility' ) );
}
/**
* Add compatibility related functionality
*/
public function hooks_for_compatibility() {
if ( ! function_exists( 'is_plugin_active' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
if ( is_plugin_active( 'klarna-checkout-for-woocommerce/klarna-checkout-for-woocommerce.php' ) ) {
if ( ! class_exists( 'WC_SC_Purchase_Credit' ) ) {
include_once '../class-wc-sc-purchase-credit.php';
}
if ( class_exists( 'WC_SC_Purchase_Credit' ) ) {
$wc_sc_purchase_credit = WC_SC_Purchase_Credit::get_instance();
$form_position_hook = apply_filters( 'wc_sc_kco_coupon_receiver_detail_form_position_hook', get_option( 'wc_sc_kco_coupon_receiver_detail_form_position_hook', 'kco_wc_before_snippet' ), array( 'source' => $this ) );
add_action( $form_position_hook, array( $wc_sc_purchase_credit, 'gift_certificate_receiver_detail_form' ) );
}
add_action( 'wp_footer', array( $this, 'enqueue_styles_scripts' ), 99 );
}
}
/**
* Get single instance of WC_SC_KCO_Compatibility
*
* @return WC_SC_KCO_Compatibility Singleton object of WC_SC_KCO_Compatibility
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name Function to call.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return mixed Result of function call.
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Enqueue required styles/scripts for store credit frontend form
*/
public function enqueue_styles_scripts() {
// Return if gift certificate form is not shown.
if ( ! did_action( 'wc_sc_gift_certificate_form_shown' ) ) {
return;
}
if ( ! wp_script_is( 'jquery' ) ) {
wp_enqueue_script( 'jquery' );
}
?>
<script type="text/javascript">
jQuery(function(){
if ( typeof wc_sc_ajax_save_coupon_receiver_details_in_session === 'undefined' ) {
function wc_sc_ajax_save_coupon_receiver_details_in_session(){
jQuery.ajax({
url: '<?php echo esc_url( is_callable( array( 'WC_AJAX', 'get_endpoint' ) ) ? WC_AJAX::get_endpoint( 'wc_sc_save_coupon_receiver_details' ) : '/?wc-ajax=wc_sc_save_coupon_receiver_details' ); ?>',
type: 'POST',
dataType: 'json',
data: {
security: '<?php echo esc_html( wp_create_nonce( 'wc-sc-save-coupon-receiver-details' ) ); ?>',
data: jQuery( 'form.checkout' ).serialize()
},
success: function( response ) {
if ( 'yes' !== response.success ) {
console.log('<?php echo esc_html__( 'Failed to update coupon receiver details in session.', 'woocommerce-smart-coupons' ); ?>');
}
}
});
}
}
jQuery('body').on('click', '#klarna-checkout-select-other', wc_sc_ajax_save_coupon_receiver_details_in_session);
});
</script>
<?php
}
}
}
WC_SC_KCO_Compatibility::get_instance();

View File

@@ -1,88 +0,0 @@
<?php
/**
* Compatibility file for Woo Multi Currency by VillaTheme https://wordpress.org/plugins/woo-multi-currency/
*
* @author StoreApps
* @since 4.17.0
* @version 1.0.0
*
* @package woocommerce-smart-coupons/includes/compat/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_WMC_Compatibility' ) ) {
/**
* Class for handling compatibility with Woo Multi Currency
*/
class WC_SC_WMC_Compatibility {
/**
* Variable to hold instance of WC_SC_WMC_Compatibility
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
private function __construct() {
add_filter( 'wc_sc_credit_called_price_order', array( $this, 'credit_called_price_order' ), 10, 2 );
add_filter( 'wc_sc_credit_called_price_cart', array( $this, 'credit_called_price_cart' ), 10, 2 );
}
/**
* Get single instance of WC_SC_WMC_Compatibility
*
* @return WC_SC_WMC_Compatibility Singleton object of WC_SC_WMC_Compatibility
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Function to modify the value of the credit called
*
* @param mized $price The price.
* @param array $args Additional arguments.
* @return mized
*/
public function credit_called_price_order( $price = 0, $args = array() ) {
if ( function_exists( 'wmc_get_price' ) ) {
$order = ( ! empty( $args['order_obj'] ) ) ? $args['order_obj'] : null;
$currency = ( is_object( $order ) && is_callable( array( $order, 'get_currency' ) ) ) ? $order->get_currency() : false;
$price = wmc_get_price( $price, $currency );
}
return $price;
}
/**
* Function to modify the value of the credit called
*
* @param mized $price The price.
* @param array $args Additional arguments.
* @return mized
*/
public function credit_called_price_cart( $price = 0, $args = array() ) {
if ( function_exists( 'wmc_get_price' ) ) {
$price = wmc_get_price( $price );
}
return $price;
}
}
}
WC_SC_WMC_Compatibility::get_instance();

View File

@@ -1,72 +0,0 @@
<?php
/**
* Compatibility file for WPML
*
* @author StoreApps
* @since 3.3.0
* @version 1.1.0
*
* @package woocommerce-smart-coupons/includes/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_WPML_Compatibility' ) ) {
/**
* Class for handling compatibility with WPML
*/
class WC_SC_WPML_Compatibility {
/**
* Variable to hold instance of WC_SC_WPML_Compatibility
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
public function __construct() {
add_action( 'init', array( $this, 'woocommerce_wpml_compatibility' ), 11 );
}
/**
* Get single instance of WC_SC_WPML_Compatibility
*
* @return WC_SC_WPML_Compatibility Singleton object of WC_SC_WPML_Compatibility
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Function to handle compatibility with WooCommerce Multilingual
*/
public function woocommerce_wpml_compatibility() {
global $woocommerce_wpml;
if ( class_exists( 'woocommerce_wpml' ) && $woocommerce_wpml instanceof woocommerce_wpml ) {
if ( ! empty( $woocommerce_wpml->products ) && has_action( 'woocommerce_before_checkout_process', array( $woocommerce_wpml->products, 'wcml_refresh_cart_total' ) ) ) {
remove_action( 'woocommerce_before_checkout_process', array( $woocommerce_wpml->products, 'wcml_refresh_cart_total' ) );
}
if ( ! empty( $woocommerce_wpml->cart ) && has_action( 'woocommerce_before_checkout_process', array( $woocommerce_wpml->cart, 'wcml_refresh_cart_total' ) ) ) {
remove_action( 'woocommerce_before_checkout_process', array( $woocommerce_wpml->cart, 'wcml_refresh_cart_total' ) );
}
}
}
}
}
WC_SC_WPML_Compatibility::get_instance();

View File

@@ -1,166 +0,0 @@
<?php
/**
* Compatibility file for WooCommerce One Page Checkout
*
* @author StoreApps
* @since 3.3.0
* @version 1.1.0
* @package WooCommerce Smart Coupons
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WCOPC_SC_Compatibility' ) ) {
/**
* Class for handling compatibility with WooCommerce One Page Checkout
*/
class WCOPC_SC_Compatibility {
/**
* Variable to hold instance of WCOPC_SC_Compatibility
*
* @var $instance
*/
private static $instance = null;
/**
* Constructor
*/
public function __construct() {
add_filter( 'woocommerce_update_order_review_fragments', array( $this, 'update_order_review_fragments' ) );
add_action( 'wcopc_before_display_checkout', array( $this, 'add_styles_and_scripts' ) );
add_filter( 'wc_sc_call_for_credit_product_id', array( $this, 'call_for_credit_product_id' ), 10, 2 );
}
/**
* Get single instance of WCOPC_SC_Compatibility
*
* @return WCOPC_SC_Compatibility Singleton object of WCOPC_SC_Compatibility
*/
public static function get_instance() {
// Check if instance is already exists.
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Handle call to functions which is not available in this class
*
* @param string $function_name Function to call.
* @param array $arguments Array of arguments passed while calling $function_name.
* @return mixed Result of function call.
*/
public function __call( $function_name, $arguments = array() ) {
global $woocommerce_smart_coupon;
if ( ! is_callable( array( $woocommerce_smart_coupon, $function_name ) ) ) {
return;
}
if ( ! empty( $arguments ) ) {
return call_user_func_array( array( $woocommerce_smart_coupon, $function_name ), $arguments );
} else {
return call_user_func( array( $woocommerce_smart_coupon, $function_name ) );
}
}
/**
* Generate & add coupon receiver details form in update order review fragments
*
* @param array $fragments Existing fragments.
* @return array $fragments
*/
public function update_order_review_fragments( $fragments = array() ) {
if ( ! class_exists( 'WC_SC_Purchase_Credit' ) ) {
include_once '../class-wc-sc-purchase-credit.php';
}
$wc_sc_purchase_credit = WC_SC_Purchase_Credit::get_instance();
ob_start();
$wc_sc_purchase_credit->gift_certificate_receiver_detail_form();
$fragments['wc_sc_receiver_detail_form'] = ob_get_clean();
return $fragments;
}
/**
* Add Styles And Scripts
*/
public function add_styles_and_scripts() {
if ( ! class_exists( 'WC_SC_Purchase_Credit' ) ) {
include_once '../class-wc-sc-purchase-credit.php';
}
$wc_sc_purchase_credit = WC_SC_Purchase_Credit::get_instance();
$wc_sc_purchase_credit->enqueue_timepicker();
add_action( 'wp_footer', array( $this, 'styles_and_scripts' ) );
}
/**
* Styles And Scripts
*/
public function styles_and_scripts() {
if ( ! wp_script_is( 'jquery' ) ) {
wp_enqueue_script( 'jquery' );
}
?>
<script type="text/javascript">
jQuery(function(){
jQuery(document.body).on('updated_checkout', function( e, data ){
if ( typeof data === 'undefined' ) {
return;
}
if ( data.fragments.wc_sc_receiver_detail_form ) {
if ( jQuery('div.gift-certificate.sc_info_box').length > 0 ) {
jQuery('div.gift-certificate.sc_info_box').replaceWith( data.fragments.wc_sc_receiver_detail_form );
} else {
jQuery('div#customer_details').after( data.fragments.wc_sc_receiver_detail_form );
}
} else {
jQuery('div.gift-certificate.sc_info_box').remove();
}
});
});
</script>
<?php
}
/**
* Call For Credit Product Id
*
* @param integer $product_id The product id.
* @param array $args Additional arguments.
* @return integer
*/
public function call_for_credit_product_id( $product_id = 0, $args = array() ) {
$action = ( ! empty( $_REQUEST['action'] ) ) ? wc_clean( wp_unslash( $_REQUEST['action'] ) ) : ''; // phpcs:ignore
if ( 'pp_add_to_cart' === $action && empty( $product_id ) ) {
$product_id = ( ! empty( $_REQUEST['add_to_cart'] ) ) ? absint( $_REQUEST['add_to_cart'] ) : 0; // phpcs:ignore
}
return $product_id;
}
}
}
/**
* Initialize the Compatibility
*/
function initialize_wcopc_sc_compatibility() {
WCOPC_SC_Compatibility::get_instance();
}
add_action( 'wcopc_loaded', 'initialize_wcopc_sc_compatibility' );

View File

@@ -1,348 +0,0 @@
<?php
/**
* Main class for Smart Coupons Acknowledgement Email
*
* @author StoreApps
* @since 4.7.8
* @version 1.1.0
*
* @package woocommerce-smart-coupons/includes/emails/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Acknowledgement_Email' ) ) {
/**
* The Smart Coupons Email class
*
* @extends \WC_SC_Email
*/
class WC_SC_Acknowledgement_Email extends WC_SC_Email {
/**
* Whether email is a scheduled email or not.
*
* @var bool
*/
public $is_email_scheduled = false;
/**
* Set email defaults
*/
public function __construct() {
$this->id = 'wc_sc_acknowledgement_email';
$this->customer_email = true;
// Set email title and description.
$this->title = __( 'Smart Coupons - Acknowledgement email', 'woocommerce-smart-coupons' );
$this->description = __( 'Send an acknowledgement email to the purchaser. One email per customer.', 'woocommerce-smart-coupons' );
// Use our plugin templates directory as the template base.
$this->template_base = dirname( WC_SC_PLUGIN_FILE ) . '/templates/';
// Email template location.
$this->template_html = 'acknowledgement-email.php';
$this->template_plain = 'plain/acknowledgement-email.php';
$this->placeholders = array(
'{coupon_type}' => '',
);
// Trigger for this email.
add_action( 'wc_sc_acknowledgement_email_notification', array( $this, 'trigger' ) );
// Call parent constructor to load any other defaults not explicity defined here.
parent::__construct();
}
/**
* Get default email subject.
*
* @return string Default email subject
*/
public function get_default_subject() {
return __( '{site_title}: {coupon_type} sent successfully', 'woocommerce-smart-coupons' );
}
/**
* Get default email heading.
*
* @return string Default email heading
*/
public function get_default_heading() {
return __( '{coupon_type} sent successfully', 'woocommerce-smart-coupons' );
}
/**
* Get default scheduled email subject.
*
* @return string Default email subject
*/
public function get_default_scheduled_subject() {
return __( '{site_title}: {coupon_type} has been successfully scheduled', 'woocommerce-smart-coupons' );
}
/**
* Get default scheduled email heading.
*
* @return string Default email heading
*/
public function get_default_scheduled_heading() {
return __( '{coupon_type} has been successfully scheduled', 'woocommerce-smart-coupons' );
}
/**
* Initialize Settings Form Fields
*/
public function init_form_fields() {
/* translators: %s: list of placeholders */
$placeholder_text = sprintf( __( 'This will be used when the setting "WooCommerce > Settings > Smart Coupons > Allow schedule sending of coupons?" is enabled. Available placeholders: %s.', 'woocommerce-smart-coupons' ), '<code>' . implode( '</code>, <code>', array_keys( $this->placeholders ) ) . '</code>' );
$form_fields = array(
'scheduled_subject' => array(
'title' => __( 'Scheduled email subject', 'woocommerce-smart-coupons' ),
'type' => 'text',
'desc_tip' => true,
'description' => $placeholder_text,
'placeholder' => $this->get_default_scheduled_subject(),
'default' => '',
),
'scheduled_heading' => array(
'title' => __( 'Scheduled email heading', 'woocommerce-smart-coupons' ),
'type' => 'text',
'desc_tip' => true,
'description' => $placeholder_text,
'placeholder' => $this->get_default_scheduled_heading(),
'default' => '',
),
);
parent::init_form_fields();
$this->form_fields = array_merge( $this->form_fields, $form_fields );
}
/**
* Determine if the email should actually be sent and setup email merge variables
*
* @param array $args Email arguments.
*/
public function trigger( $args = array() ) {
$this->email_args = wp_parse_args( $args, $this->email_args );
if ( ! isset( $this->email_args['email'] ) || empty( $this->email_args['email'] ) ) {
return;
}
$email_scheduled_details = ! empty( $this->email_args['scheduled_email'] ) ? $this->email_args['scheduled_email'] : array();
$this->is_email_scheduled = ! empty( $email_scheduled_details );
$this->setup_locale();
$this->recipient = $this->email_args['email'];
$order_id = isset( $this->email_args['order_id'] ) ? $this->email_args['order_id'] : 0;
// Get order object.
if ( ! empty( $order_id ) && 0 !== $order_id ) {
$order = wc_get_order( $order_id );
if ( is_a( $order, 'WC_Order' ) ) {
$this->object = $order;
}
}
$this->set_placeholders();
$email_content = $this->get_content();
// Replace placeholders with values in the email content.
$email_content = ( is_callable( array( $this, 'format_string' ) ) ) ? $this->format_string( $email_content ) : $email_content;
// Send email.
if ( $this->is_enabled() && $this->get_recipient() ) {
$this->send( $this->get_recipient(), $this->get_subject(), $email_content, $this->get_headers(), $this->get_attachments() );
}
$this->restore_locale();
}
/**
* Function to get email subject.
*
* @return string Email subject.
*/
public function get_subject() {
if ( true === $this->is_email_scheduled ) {
return $this->get_scheduled_subject();
}
return parent::get_subject();
}
/**
* Function to get email subject.
*
* @return string Email subject.
*/
public function get_heading() {
if ( true === $this->is_email_scheduled ) {
return $this->get_scheduled_heading();
}
return parent::get_heading();
}
/**
* Get scheduled email subject.
*
* @return string
*/
public function get_scheduled_subject() {
return apply_filters(
$this->id . '_scheduled_subject',
$this->format_string( $this->get_option( 'scheduled_subject', $this->get_default_scheduled_subject() ) ),
array(
'email_object' => $this->object,
'source' => $this,
)
);
}
/**
* Get scheduled email heading.
*
* @return string
*/
public function get_scheduled_heading() {
return apply_filters(
$this->id . '_scheduled_heading',
$this->format_string( $this->get_option( 'scheduled_heading', $this->get_default_scheduled_heading() ) ),
array(
'email_object' => $this->object,
'source' => $this,
)
);
}
/**
* Function to set placeholder variables used in email subject/heading
*/
public function set_placeholders() {
$this->placeholders['{coupon_type}'] = $this->get_coupon_type();
}
/**
* Function to load email html content
*
* @return string Email content html
*/
public function get_content_html() {
global $woocommerce_smart_coupon;
$order = $this->object;
$email_heading = $this->get_heading();
$email = isset( $this->email_args['email'] ) ? $this->email_args['email'] : '';
$receivers_detail = isset( $this->email_args['receivers_detail'] ) ? $this->email_args['receivers_detail'] : array();
$receiver_name = isset( $this->email_args['receiver_name'] ) ? $this->email_args['receiver_name'] : '';
$receiver_count = isset( $this->email_args['receiver_count'] ) ? $this->email_args['receiver_count'] : 0;
$email_scheduled_details = isset( $this->email_args['scheduled_email'] ) ? $this->email_args['scheduled_email'] : array();
$contains_core_coupons = ( isset( $this->email_args['contains_core_coupons'] ) && 'yes' === $this->email_args['contains_core_coupons'] ) ? $this->email_args['contains_core_coupons'] : 'no';
$default_path = $this->template_base;
$template_path = $woocommerce_smart_coupon->get_template_base_dir( $this->template_html );
ob_start();
wc_get_template(
$this->template_html,
array(
'email' => $email,
'email_heading' => $email_heading,
'order' => $order,
'receivers_detail' => $receivers_detail,
'gift_certificate_receiver_name' => $receiver_name,
'receiver_count' => $receiver_count,
'email_scheduled_details' => $email_scheduled_details,
'contains_core_coupons' => $contains_core_coupons,
),
$template_path,
$default_path
);
return ob_get_clean();
}
/**
* Function to load email plain content
*
* @return string Email plain content
*/
public function get_content_plain() {
global $woocommerce_smart_coupon;
$order = $this->object;
$email_heading = $this->get_heading();
$email = isset( $this->email_args['email'] ) ? $this->email_args['email'] : '';
$receivers_detail = isset( $this->email_args['receivers_detail'] ) ? $this->email_args['receivers_detail'] : array();
$receiver_name = isset( $this->email_args['receiver_name'] ) ? $this->email_args['receiver_name'] : '';
$receiver_count = isset( $this->email_args['receiver_count'] ) ? $this->email_args['receiver_count'] : 0;
$email_scheduled_details = isset( $this->email_args['scheduled_email'] ) ? $this->email_args['scheduled_email'] : array();
$contains_core_coupons = ( isset( $this->email_args['contains_core_coupons'] ) && 'yes' === $this->email_args['contains_core_coupons'] ) ? $this->email_args['contains_core_coupons'] : 'no';
$default_path = $this->template_base;
$template_path = $woocommerce_smart_coupon->get_template_base_dir( $this->template_html );
ob_start();
wc_get_template(
$this->template_plain,
array(
'email' => $email,
'email_heading' => $email_heading,
'order' => $order,
'receivers_detail' => $receivers_detail,
'gift_certificate_receiver_name' => $receiver_name,
'receiver_count' => $receiver_count,
'email_scheduled_details' => $email_scheduled_details,
'contains_core_coupons' => $contains_core_coupons,
),
$template_path,
$default_path
);
return ob_get_clean();
}
/**
* Function to get coupon type for current coupon being sent.
*
* @return string $coupon_type Coupon type.
*/
public function get_coupon_type() {
global $store_credit_label;
$receiver_count = isset( $this->email_args['receiver_count'] ) ? $this->email_args['receiver_count'] : 0;
$singular = ( ! empty( $store_credit_label['singular'] ) ) ? ucwords( $store_credit_label['singular'] ) : __( 'Gift card', 'woocommerce-smart-coupons' );
$plural = ( ! empty( $store_credit_label['plural'] ) ) ? ucwords( $store_credit_label['plural'] ) : __( 'Gift cards', 'woocommerce-smart-coupons' );
$coupon_type = ( $receiver_count > 1 ) ? $plural : $singular;
$contains_core_coupons = ( isset( $this->email_args['contains_core_coupons'] ) && 'yes' === $this->email_args['contains_core_coupons'] ) ? $this->email_args['contains_core_coupons'] : 'no';
if ( 'yes' === $contains_core_coupons ) {
$coupon_type = _n( 'Coupon', 'Coupons', $receiver_count, 'woocommerce-smart-coupons' );
}
return $coupon_type;
}
}
}

View File

@@ -1,265 +0,0 @@
<?php
/**
* Main class for Smart Coupons Email
*
* @author StoreApps
* @since 4.4.1
* @version 1.2.2
*
* @package woocommerce-smart-coupons/includes/emails/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Combined_Email_Coupon' ) ) {
/**
* The Smart Coupons Combined Email class
*
* @extends \WC_SC_Email
*/
class WC_SC_Combined_Email_Coupon extends WC_SC_Email {
/**
* Set email defaults
*/
public function __construct() {
$this->id = 'wc_sc_combined_email_coupon';
$this->customer_email = true;
// Set email title and description.
$this->title = __( 'Smart Coupons - Combined auto generated coupons email', 'woocommerce-smart-coupons' );
$this->description = __( 'Send only one email instead of multiple emails when multiple coupons are generated per recipient.', 'woocommerce-smart-coupons' );
// Use our plugin templates directory as the template base.
$this->template_base = dirname( WC_SC_PLUGIN_FILE ) . '/templates/';
// Email template location.
$this->template_html = 'combined-email.php';
$this->template_plain = 'plain/combined-email.php';
$this->placeholders = array(
'{sender_name}' => '',
);
// Trigger for this email.
add_action( 'wc_sc_combined_email_coupon_notification', array( $this, 'trigger' ) );
// Call parent constructor to load any other defaults not explicity defined here.
parent::__construct();
}
/**
* Get default email subject.
*
* @return string Default email subject
*/
public function get_default_subject() {
return __( '{site_title}: Congratulations! You\'ve received coupons from {sender_name}', 'woocommerce-smart-coupons' );
}
/**
* Get default email heading.
*
* @return string Default email heading
*/
public function get_default_heading() {
return __( 'You have received coupons.', 'woocommerce-smart-coupons' );
}
/**
* Determine if the email should actually be sent and setup email merge variables
*
* @param array $args Email arguments.
*/
public function trigger( $args = array() ) {
$this->email_args = wp_parse_args( $args, $this->email_args );
if ( ! isset( $this->email_args['email'] ) || empty( $this->email_args['email'] ) ) {
return;
}
$this->setup_locale();
$this->recipient = $this->email_args['email'];
$order_id = isset( $this->email_args['order_id'] ) ? $this->email_args['order_id'] : 0;
// Get order object.
if ( ! empty( $order_id ) && 0 !== $order_id ) {
$order = wc_get_order( $order_id );
if ( is_a( $order, 'WC_Order' ) ) {
$this->object = $order;
}
}
$this->set_placeholders();
$email_content = $this->get_content();
// Replace placeholders with values in the email content.
$email_content = ( is_callable( array( $this, 'format_string' ) ) ) ? $this->format_string( $email_content ) : $email_content;
// Send email.
if ( $this->is_enabled() && $this->get_recipient() ) {
$this->send( $this->get_recipient(), $this->get_subject(), $email_content, $this->get_headers(), $this->get_attachments() );
}
$this->restore_locale();
}
/**
* Function to set placeholder variables used in email subject/heading
*/
public function set_placeholders() {
$this->placeholders['{sender_name}'] = $this->get_sender_name();
}
/**
* Function to load email html content
*
* @return string Email content html
*/
public function get_content_html() {
global $woocommerce_smart_coupon;
$order = $this->object;
$url = $this->get_url();
$email_heading = $this->get_heading();
$sender = '';
$from = '';
$is_gift = isset( $this->email_args['is_gift'] ) ? $this->email_args['is_gift'] : '';
if ( 'yes' === $is_gift ) {
$sender_name = $this->get_sender_name();
$sender_email = $this->get_sender_email();
if ( ! empty( $sender_name ) && ! empty( $sender_email ) ) {
$sender = $sender_name . ' (' . $sender_email . ') ';
$from = ' ' . __( 'from', 'woocommerce-smart-coupons' ) . ' ';
}
}
$email = isset( $this->email_args['email'] ) ? $this->email_args['email'] : '';
$receiver_details = isset( $this->email_args['receiver_details'] ) ? $this->email_args['receiver_details'] : '';
$design = get_option( 'wc_sc_setting_coupon_design', 'basic' );
$background_color = get_option( 'wc_sc_setting_coupon_background_color', '#39cccc' );
$foreground_color = get_option( 'wc_sc_setting_coupon_foreground_color', '#30050b' );
$third_color = get_option( 'wc_sc_setting_coupon_third_color', '#39cccc' );
$show_coupon_description = get_option( 'smart_coupons_show_coupon_description', 'no' );
$valid_designs = $woocommerce_smart_coupon->get_valid_coupon_designs();
if ( ! in_array( $design, $valid_designs, true ) ) {
$design = 'basic';
}
$design = ( 'custom-design' !== $design ) ? 'email-coupon' : $design;
$coupon_styles = $woocommerce_smart_coupon->get_coupon_styles( $design, array( 'is_email' => 'yes' ) );
$default_path = $this->template_base;
$template_path = $woocommerce_smart_coupon->get_template_base_dir( $this->template_html );
ob_start();
wc_get_template(
$this->template_html,
array(
'email' => $email,
'email_heading' => $email_heading,
'order' => $order,
'url' => $url,
'from' => $from,
'background_color' => $background_color,
'foreground_color' => $foreground_color,
'third_color' => $third_color,
'coupon_styles' => $coupon_styles,
'sender' => $sender,
'receiver_details' => $receiver_details,
'show_coupon_description' => $show_coupon_description,
'design' => $design,
),
$template_path,
$default_path
);
return ob_get_clean();
}
/**
* Function to load email plain content
*
* @return string Email plain content
*/
public function get_content_plain() {
global $woocommerce_smart_coupon;
$order = $this->object;
$url = $this->get_url();
$email_heading = $this->get_heading();
$sender = '';
$from = '';
$is_gift = isset( $this->email_args['is_gift'] ) ? $this->email_args['is_gift'] : '';
if ( 'yes' === $is_gift ) {
$sender_name = $this->get_sender_name();
$sender_email = $this->get_sender_email();
if ( ! empty( $sender_name ) && ! empty( $sender_email ) ) {
$sender = $sender_name . ' (' . $sender_email . ') ';
$from = ' ' . __( 'from', 'woocommerce-smart-coupons' ) . ' ';
}
}
$email = isset( $this->email_args['email'] ) ? $this->email_args['email'] : '';
$receiver_details = isset( $this->email_args['receiver_details'] ) ? $this->email_args['receiver_details'] : '';
$default_path = $this->template_base;
$template_path = $woocommerce_smart_coupon->get_template_base_dir( $this->template_plain );
ob_start();
wc_get_template(
$this->template_plain,
array(
'email' => $email,
'email_heading' => $email_heading,
'order' => $order,
'url' => $url,
'from' => $from,
'sender' => $sender,
'receiver_details' => $receiver_details,
),
$template_path,
$default_path
);
return ob_get_clean();
}
/**
* Function to update SC admin email settings when WC email settings get updated
*/
public function process_admin_options() {
// Save regular options.
parent::process_admin_options();
$is_email_enabled = $this->get_field_value( 'enabled', $this->form_fields['enabled'] );
if ( ! empty( $is_email_enabled ) ) {
update_option( 'smart_coupons_combine_emails', $is_email_enabled, 'no' );
}
}
}
}

View File

@@ -1,506 +0,0 @@
<?php
/**
* Main class for Smart Coupons Email
*
* @author StoreApps
* @since 4.4.1
* @version 1.6.0
*
* @package woocommerce-smart-coupons/includes/emails/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Email_Coupon' ) ) {
/**
* The Smart Coupons Email class
*
* @extends \WC_SC_Email
*/
class WC_SC_Email_Coupon extends WC_SC_Email {
/**
* Set email defaults
*/
public function __construct() {
$this->id = 'wc_sc_email_coupon';
$this->customer_email = true;
// Set email title and description.
$this->title = __( 'Smart Coupons - Auto generated coupon email', 'woocommerce-smart-coupons' );
$this->description = __( 'Email auto generated coupon to recipients. One email per coupon.', 'woocommerce-smart-coupons' );
// Use our plugin templates directory as the template base.
$this->template_base = dirname( WC_SC_PLUGIN_FILE ) . '/templates/';
// Email template location.
$this->template_html = 'email.php';
$this->template_plain = 'plain/email.php';
$this->placeholders = array(
'{coupon_code}' => '',
'{coupon_type}' => '',
'{coupon_value}' => '',
'{sender_name}' => '',
);
// Trigger for this email.
add_action( 'wc_sc_email_coupon_notification', array( $this, 'trigger' ) );
// Call parent constructor to load any other defaults not explicity defined here.
parent::__construct();
}
/**
* Get default email subject.
*
* @return string Default email subject
*/
public function get_default_subject() {
return __( '{site_title}: Congratulations! You\'ve received a {coupon_type} from {sender_name}', 'woocommerce-smart-coupons' );
}
/**
* Get default email heading.
*
* @return string Default email heading
*/
public function get_default_heading() {
return __( 'You have received a {coupon_type} {coupon_value}', 'woocommerce-smart-coupons' );
}
/**
* Determine if the email should actually be sent and setup email merge variables
*
* @param array $args Email arguments.
*/
public function trigger( $args = array() ) {
$this->email_args = wp_parse_args( $args, $this->email_args );
if ( ! isset( $this->email_args['email'] ) || empty( $this->email_args['email'] ) ) {
return;
}
$this->setup_locale();
$this->recipient = $this->email_args['email'];
$order_id = isset( $this->email_args['order_id'] ) ? $this->email_args['order_id'] : 0;
// Get order object.
if ( ! empty( $order_id ) && 0 !== $order_id ) {
$order = wc_get_order( $order_id );
if ( is_a( $order, 'WC_Order' ) ) {
$this->object = $order;
}
}
$this->set_placeholders();
$email_content = $this->get_content();
// Replace placeholders with values in the email content.
$email_content = ( is_callable( array( $this, 'format_string' ) ) ) ? $this->format_string( $email_content ) : $email_content;
// Send email.
if ( $this->is_enabled() && $this->get_recipient() ) {
$this->send( $this->get_recipient(), $this->get_subject(), $email_content, $this->get_headers(), $this->get_attachments() );
}
$this->restore_locale();
}
/**
* Function to set placeholder variables used in email subject/heading
*/
public function set_placeholders() {
$this->placeholders['{coupon_code}'] = $this->get_coupon_code();
$this->placeholders['{coupon_type}'] = $this->get_coupon_type();
$this->placeholders['{coupon_value}'] = $this->get_coupon_value();
$this->placeholders['{coupon_expiry}'] = $this->get_coupon_expiry();
$this->placeholders['{sender_name}'] = $this->get_sender_name();
}
/**
* Function to get coupon expiry date/time for current coupon being sent.
*
* @return string $coupon_expiry Coupon expiry.
*/
public function get_coupon_expiry() {
global $woocommerce_smart_coupon;
$coupon_expiry = '';
$coupon = isset( $this->email_args['coupon'] ) ? $this->email_args['coupon'] : '';
if ( empty( $coupon ) ) {
return $coupon_expiry;
}
$coupon_code = ( ! empty( $coupon['code'] ) ) ? $coupon['code'] : '';
if ( empty( $coupon_code ) ) {
return $coupon_expiry;
}
$_coupon = new WC_Coupon( $coupon_code );
if ( $woocommerce_smart_coupon->is_wc_gte_30() ) {
$coupon_id = ( is_object( $_coupon ) && is_callable( array( $_coupon, 'get_id' ) ) ) ? $_coupon->get_id() : 0;
$expiry_date = ( is_object( $_coupon ) && is_callable( array( $_coupon, 'get_date_expires' ) ) ) ? $_coupon->get_date_expires() : '';
} else {
$coupon_id = ( ! empty( $_coupon->id ) ) ? $_coupon->id : 0;
$expiry_date = ( ! empty( $_coupon->expiry_date ) ) ? $_coupon->expiry_date : '';
}
if ( ! empty( $expiry_date ) ) {
if ( $woocommerce_smart_coupon->is_wc_gte_30() && $expiry_date instanceof WC_DateTime ) {
$expiry_date = ( is_callable( array( $expiry_date, 'getTimestamp' ) ) ) ? $expiry_date->getTimestamp() : null;
} elseif ( ! is_int( $expiry_date ) ) {
$expiry_date = strtotime( $expiry_date );
}
if ( ! empty( $expiry_date ) && is_int( $expiry_date ) ) {
$expiry_time = (int) $woocommerce_smart_coupon->get_post_meta( $coupon_id, 'wc_sc_expiry_time', true );
if ( ! empty( $expiry_time ) ) {
$expiry_date += $expiry_time; // Adding expiry time to expiry date.
}
}
$coupon_expiry = $woocommerce_smart_coupon->get_expiration_format( $expiry_date );
} else {
$coupon_expiry = esc_html__( 'Never expires', 'woocommerce-smart-coupons' );
}
return $coupon_expiry;
}
/**
* Function to load email html content
*
* @return string Email content html
*/
public function get_content_html() {
global $woocommerce_smart_coupon;
$order = $this->object;
$url = $this->get_url();
$email_heading = $this->get_heading();
$sender = '';
$from = '';
$is_gift = isset( $this->email_args['is_gift'] ) ? $this->email_args['is_gift'] : '';
if ( 'yes' === $is_gift ) {
$sender_name = $this->get_sender_name();
$sender_email = $this->get_sender_email();
if ( ! empty( $sender_name ) && ! empty( $sender_email ) ) {
$sender = $sender_name . ' (' . $sender_email . ') ';
$from = ' ' . __( 'from', 'woocommerce-smart-coupons' ) . ' ';
}
}
$email = isset( $this->email_args['email'] ) ? $this->email_args['email'] : '';
$message_from_sender = isset( $this->email_args['message_from_sender'] ) ? $this->email_args['message_from_sender'] : '';
$coupon_code = isset( $this->email_args['coupon']['code'] ) ? $this->email_args['coupon']['code'] : '';
$design = get_option( 'wc_sc_setting_coupon_design', 'basic' );
$background_color = get_option( 'wc_sc_setting_coupon_background_color', '#39cccc' );
$foreground_color = get_option( 'wc_sc_setting_coupon_foreground_color', '#30050b' );
$third_color = get_option( 'wc_sc_setting_coupon_third_color', '#39cccc' );
$show_coupon_description = get_option( 'smart_coupons_show_coupon_description', 'no' );
$valid_designs = $woocommerce_smart_coupon->get_valid_coupon_designs();
if ( ! in_array( $design, $valid_designs, true ) ) {
$design = 'basic';
}
$design = ( 'custom-design' !== $design ) ? 'email-coupon' : $design;
$coupon_styles = $woocommerce_smart_coupon->get_coupon_styles( $design, array( 'is_email' => 'yes' ) );
$default_path = $this->template_base;
$template_path = $woocommerce_smart_coupon->get_template_base_dir( $this->template_html );
ob_start();
wc_get_template(
$this->template_html,
array(
'email' => $email,
'email_heading' => $email_heading,
'order' => $order,
'url' => $url,
'message_from_sender' => $message_from_sender,
'from' => $from,
'coupon_code' => $coupon_code,
'background_color' => $background_color,
'foreground_color' => $foreground_color,
'third_color' => $third_color,
'coupon_styles' => $coupon_styles,
'sender' => $sender,
'design' => $design,
'show_coupon_description' => $show_coupon_description,
),
$template_path,
$default_path
);
return ob_get_clean();
}
/**
* Function to load email plain content
*
* @return string Email plain content
*/
public function get_content_plain() {
global $woocommerce_smart_coupon;
$order = $this->object;
$url = $this->get_url();
$email_heading = $this->get_heading();
$sender = '';
$from = '';
$is_gift = isset( $this->email_args['is_gift'] ) ? $this->email_args['is_gift'] : '';
if ( 'yes' === $is_gift ) {
$sender_name = $this->get_sender_name();
$sender_email = $this->get_sender_email();
if ( ! empty( $sender_name ) && ! empty( $sender_email ) ) {
$sender = $sender_name . ' (' . $sender_email . ') ';
$from = ' ' . __( 'from', 'woocommerce-smart-coupons' ) . ' ';
}
}
$email = isset( $this->email_args['email'] ) ? $this->email_args['email'] : '';
$message_from_sender = isset( $this->email_args['message_from_sender'] ) ? $this->email_args['message_from_sender'] : '';
$coupon_code = isset( $this->email_args['coupon']['code'] ) ? $this->email_args['coupon']['code'] : '';
$default_path = $this->template_base;
$template_path = $woocommerce_smart_coupon->get_template_base_dir( $this->template_plain );
ob_start();
wc_get_template(
$this->template_plain,
array(
'email' => $email,
'email_heading' => $email_heading,
'order' => $order,
'url' => $url,
'message_from_sender' => $message_from_sender,
'from' => $from,
'coupon_code' => $coupon_code,
'sender' => $sender,
),
$template_path,
$default_path
);
return ob_get_clean();
}
/**
* Get coupon code
*
* @return string
*/
public function get_coupon_code() {
$coupon_code = isset( $this->email_args['coupon']['code'] ) ? $this->email_args['coupon']['code'] : '';
return $coupon_code;
}
/**
* Get coupon value
*
* @return string
*/
public function get_coupon_value() {
global $woocommerce_smart_coupon, $store_credit_label;
$coupon = isset( $this->email_args['coupon'] ) ? $this->email_args['coupon'] : '';
if ( empty( $coupon ) ) {
return '';
}
$order_id = isset( $this->email_args['order_id'] ) ? $this->email_args['order_id'] : 0;
$order = ( ! empty( $order_id ) ) ? wc_get_order( $order_id ) : null;
$wc_price_args = array(
'currency' => is_callable( array( $order, 'get_currency' ) ) ? $order->get_currency() : '',
);
$discount_type = isset( $this->email_args['discount_type'] ) ? $this->email_args['discount_type'] : '';
$is_gift = isset( $this->email_args['is_gift'] ) ? $this->email_args['is_gift'] : '';
// Get smart coupon type string.
if ( 'smart_coupon' === $discount_type && 'yes' === $is_gift ) {
$smart_coupon_type = __( 'Gift Card', 'woocommerce-smart-coupons' );
} else {
$smart_coupon_type = __( 'Store Credit', 'woocommerce-smart-coupons' );
}
if ( ! empty( $store_credit_label['singular'] ) ) {
$smart_coupon_type = ucwords( $store_credit_label['singular'] );
}
$amount = $coupon['amount'];
$coupon_code = $coupon['code'];
// Get coupon types.
$all_discount_types = wc_get_coupon_types();
$_coupon = new WC_Coupon( $coupon_code );
if ( $woocommerce_smart_coupon->is_wc_gte_30() ) {
$_coupon_id = ( is_object( $_coupon ) && is_callable( array( $_coupon, 'get_id' ) ) ) ? $_coupon->get_id() : 0;
$_is_free_shipping = ( $_coupon->get_free_shipping() ) ? 'yes' : 'no';
$_discount_type = $_coupon->get_discount_type();
$_product_ids = $_coupon->get_product_ids();
$_excluded_product_ids = $_coupon->get_excluded_product_ids();
$_product_categories = $_coupon->get_product_categories();
$_excluded_product_categories = $_coupon->get_excluded_product_categories();
} else {
$_coupon_id = ( ! empty( $_coupon->id ) ) ? $_coupon->id : 0;
$_is_free_shipping = ( ! empty( $_coupon->free_shipping ) ) ? $_coupon->free_shipping : '';
$_discount_type = ( ! empty( $_coupon->discount_type ) ) ? $_coupon->discount_type : '';
$_product_ids = ( ! empty( $_coupon->product_ids ) ) ? $_coupon->product_ids : array();
$_excluded_product_ids = ( ! empty( $_coupon->exclude_product_ids ) ) ? $_coupon->exclude_product_ids : array();
$_product_categories = ( ! empty( $_coupon->product_categories ) ) ? $_coupon->product_categories : array();
$_excluded_product_categories = ( ! empty( $_coupon->exclude_product_categories ) ) ? $_coupon->exclude_product_categories : array();
}
if ( false === stripos( $discount_type, 'percent' ) ) {
$amount = $woocommerce_smart_coupon->read_price( $amount, true, $order );
}
switch ( $discount_type ) {
case 'smart_coupon':
/* translators: %s coupon amount */
$coupon_value = sprintf( __( 'worth %s ', 'woocommerce-smart-coupons' ), wc_price( $amount, $wc_price_args ) );
break;
case 'fixed_cart':
/* translators: %s: coupon amount */
$coupon_value = sprintf( __( 'worth %s (for entire purchase) ', 'woocommerce-smart-coupons' ), wc_price( $amount, $wc_price_args ) );
break;
case 'fixed_product':
if ( ! empty( $_product_ids ) || ! empty( $_excluded_product_ids ) || ! empty( $_product_categories ) || ! empty( $_excluded_product_categories ) ) {
$_discount_for_text = __( 'for some products', 'woocommerce-smart-coupons' );
} else {
$_discount_for_text = __( 'for all products', 'woocommerce-smart-coupons' );
}
/* translators: 1: coupon amount 2: discount for text */
$coupon_value = sprintf( __( 'worth %1$s (%2$s) ', 'woocommerce-smart-coupons' ), wc_price( $amount, $wc_price_args ), $_discount_for_text );
break;
case 'percent_product':
if ( ! empty( $_product_ids ) || ! empty( $_excluded_product_ids ) || ! empty( $_product_categories ) || ! empty( $_excluded_product_categories ) ) {
$_discount_for_text = __( 'for some products', 'woocommerce-smart-coupons' );
} else {
$_discount_for_text = __( 'for all products', 'woocommerce-smart-coupons' );
}
/* translators: 1: coupon amount 2: discount for text */
$coupon_value = sprintf( __( 'worth %1$s%% (%2$s) ', 'woocommerce-smart-coupons' ), $amount, $_discount_for_text );
break;
case 'percent':
if ( ! empty( $_product_ids ) || ! empty( $_excluded_product_ids ) || ! empty( $_product_categories ) || ! empty( $_excluded_product_categories ) ) {
$_discount_for_text = __( 'for some products', 'woocommerce-smart-coupons' );
} else {
$_discount_for_text = __( 'for entire purchase', 'woocommerce-smart-coupons' );
}
$max_discount_text = '';
$max_discount = $woocommerce_smart_coupon->get_post_meta( $_coupon_id, 'wc_sc_max_discount', true, true, $order );
if ( ! empty( $max_discount ) && is_numeric( $max_discount ) ) {
/* translators: %s: Maximum coupon discount amount */
$max_discount_text = sprintf( __( ' upto %s', 'woocommerce-smart-coupons' ), wc_price( $max_discount, $wc_price_args ) );
}
/* translators: 1: coupon amount 2: max discount text 3: discount for text */
$coupon_value = sprintf( __( 'worth %1$s%% %2$s (%3$s) ', 'woocommerce-smart-coupons' ), $amount, $max_discount_text, $_discount_for_text );
break;
default:
$default_coupon_type = ( ! empty( $all_discount_types[ $discount_type ] ) ) ? $all_discount_types[ $discount_type ] : ucwords( str_replace( array( '_', '-' ), ' ', $discount_type ) );
$coupon_type = apply_filters( 'wc_sc_coupon_type', $default_coupon_type, $_coupon, $all_discount_types );
$coupon_amount = apply_filters( 'wc_sc_coupon_amount', $amount, $_coupon );
/* translators: 1: coupon type 2: coupon amount */
$coupon_value = sprintf( __( '%1$s coupon of %2$s', 'woocommerce-smart-coupons' ), $coupon_type, $coupon_amount );
$coupon_value = apply_filters( 'wc_sc_email_heading', $coupon_value, $_coupon );
break;
}
if ( 'yes' === $_is_free_shipping && in_array( $_discount_type, array( 'fixed_cart', 'fixed_product', 'percent_product', 'percent' ), true ) ) {
/* translators: 1: email heading 2: suffix */
$coupon_value = sprintf( __( '%1$s Free Shipping%2$s', 'woocommerce-smart-coupons' ), ( ( ! empty( $amount ) ) ? $coupon_value . __( '&', 'woocommerce-smart-coupons' ) : __( 'You have received a', 'woocommerce-smart-coupons' ) ), ( ( empty( $amount ) ) ? __( ' coupon', 'woocommerce-smart-coupons' ) : '' ) );
}
return wp_strip_all_tags( $coupon_value );
}
/**
* Function to get coupon type for current coupon being sent.
*
* @return string $coupon_type Coupon type.
*/
public function get_coupon_type() {
global $store_credit_label;
$discount_type = isset( $this->email_args['discount_type'] ) ? $this->email_args['discount_type'] : '';
$is_gift = isset( $this->email_args['is_gift'] ) ? $this->email_args['is_gift'] : '';
if ( 'smart_coupon' === $discount_type && 'yes' === $is_gift ) {
$smart_coupon_type = __( 'Gift Card', 'woocommerce-smart-coupons' );
} else {
$smart_coupon_type = __( 'Store Credit', 'woocommerce-smart-coupons' );
}
if ( ! empty( $store_credit_label['singular'] ) ) {
$smart_coupon_type = ucwords( $store_credit_label['singular'] );
}
$coupon_type = ( 'smart_coupon' === $discount_type && ! empty( $smart_coupon_type ) ) ? $smart_coupon_type : __( 'coupon', 'woocommerce-smart-coupons' );
return $coupon_type;
}
/**
* Function to update SC admin email settings when WC email settings get updated
*/
public function process_admin_options() {
// Save regular options.
parent::process_admin_options();
$is_email_enabled = $this->get_field_value( 'enabled', $this->form_fields['enabled'] );
if ( ! empty( $is_email_enabled ) ) {
update_option( 'smart_coupons_is_send_email', $is_email_enabled, 'no' );
}
}
}
}

View File

@@ -1,149 +0,0 @@
<?php
/**
* Main class for Smart Coupons Email
*
* @author StoreApps
* @since 4.4.1
* @version 1.2.1
*
* @package woocommerce-smart-coupons/includes/emails/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WC_SC_Email' ) ) {
/**
* The Smart Coupons Email class
*
* @extends \WC_Email
*/
class WC_SC_Email extends WC_Email {
/**
* Email args defaults
*
* @var array
*/
public $email_args = array(
'email' => '',
'coupon' => array(),
'discount_type' => 'smart_coupon',
'smart_coupon_type' => '',
'receiver_name' => '',
'message_from_sender' => '',
'gift_certificate_sender_name' => '',
'gift_certificate_sender_email' => '',
'from' => '',
'sender' => '',
'is_gift' => false,
);
/**
* Get shop page url
*
* @return string $url Shop page url
*/
public function get_url() {
global $woocommerce_smart_coupon;
if ( $woocommerce_smart_coupon->is_wc_gte_30() ) {
$page_id = wc_get_page_id( 'shop' );
} else {
$page_id = woocommerce_get_page_id( 'shop' );
}
$url = ( get_option( 'permalink_structure' ) ) ? get_permalink( $page_id ) : get_post_type_archive_link( 'product' );
return $url;
}
/**
* Function to get sender name.
*
* @return string $sender_name Sender name.
*/
public function get_sender_name() {
if ( isset( $this->email_args['gift_certificate_sender_name'] ) && ! empty( $this->email_args['gift_certificate_sender_name'] ) ) {
$sender_name = $this->email_args['gift_certificate_sender_name'];
} else {
$sender_name = is_callable( array( $this, 'get_blogname' ) ) ? $this->get_blogname() : '';
}
return $sender_name;
}
/**
* Function to get sender email.
*
* @return string $sender_email Sender email.
*/
public function get_sender_email() {
$sender_email = isset( $this->email_args['gift_certificate_sender_email'] ) ? $this->email_args['gift_certificate_sender_email'] : '';
return $sender_email;
}
/**
* Initialize Settings Form Fields
*/
public function init_form_fields() {
/* translators: %s: list of placeholders */
$placeholder_text = sprintf( __( 'Available placeholders: %s', 'woocommerce-smart-coupons' ), '<code>' . implode( '</code>, <code>', array_keys( $this->placeholders ) ) . '</code>' );
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable', 'woocommerce-smart-coupons' ),
'type' => 'checkbox',
'label' => __( 'Enable this email notification', 'woocommerce-smart-coupons' ),
'default' => 'yes',
),
'email_type' => array(
'title' => __( 'Email type', 'woocommerce-smart-coupons' ),
'type' => 'select',
'description' => __( 'Choose which format of email to send.', 'woocommerce-smart-coupons' ),
'default' => 'html',
'class' => 'email_type wc-enhanced-select',
'options' => $this->get_email_type_options(),
'desc_tip' => true,
),
'subject' => array(
'title' => __( 'Subject', 'woocommerce-smart-coupons' ),
'type' => 'text',
'desc_tip' => true,
'description' => $placeholder_text,
'placeholder' => $this->get_default_subject(),
'default' => '',
),
'heading' => array(
'title' => __( 'Email heading', 'woocommerce-smart-coupons' ),
'type' => 'text',
'desc_tip' => true,
'description' => $placeholder_text,
'placeholder' => $this->get_default_heading(),
'default' => '',
),
);
}
/**
* Function to update SC admin email settings when WC email settings get updated
*/
public function process_admin_options() {
// Save regular options.
parent::process_admin_options();
$is_email_enabled = $this->get_field_value( 'enabled', $this->form_fields['enabled'] );
if ( ! empty( $is_email_enabled ) ) {
update_option( 'smart_coupons_is_send_email', $is_email_enabled, 'no' );
}
}
}
}

View File

@@ -1,35 +0,0 @@
# Action Scheduler - Job Queue for WordPress [![Build Status](https://travis-ci.org/woocommerce/action-scheduler.png?branch=master)](https://travis-ci.org/woocommerce/action-scheduler) [![codecov](https://codecov.io/gh/woocommerce/action-scheduler/branch/master/graph/badge.svg)](https://codecov.io/gh/woocommerce/action-scheduler)
Action Scheduler is a scalable, traceable job queue for background processing large sets of actions in WordPress. It's specially designed to be distributed in WordPress plugins.
Action Scheduler works by triggering an action hook to run at some time in the future. Each hook can be scheduled with unique data, to allow callbacks to perform operations on that data. The hook can also be scheduled to run on one or more occassions.
Think of it like an extension to `do_action()` which adds the ability to delay and repeat a hook.
## Battle-Tested Background Processing
Every month, Action Scheduler processes millions of payments for [Subscriptions](https://woocommerce.com/products/woocommerce-subscriptions/), webhooks for [WooCommerce](https://wordpress.org/plugins/woocommerce/), as well as emails and other events for a range of other plugins.
It's been seen on live sites processing queues in excess of 50,000 jobs and doing resource intensive operations, like processing payments and creating orders, at a sustained rate of over 10,000 / hour without negatively impacting normal site operations.
This is all on infrastructure and WordPress sites outside the control of the plugin author.
If your plugin needs background processing, especially of large sets of tasks, Action Scheduler can help.
## Learn More
To learn more about how to Action Scheduler works, and how to use it in your plugin, check out the docs on [ActionScheduler.org](https://actionscheduler.org).
There you will find:
* [Usage guide](https://actionscheduler.org/usage/): instructions on installing and using Action Scheduler
* [WP CLI guide](https://actionscheduler.org/wp-cli/): instructions on running Action Scheduler at scale via WP CLI
* [API Reference](https://actionscheduler.org/api/): complete reference guide for all API functions
* [Administration Guide](https://actionscheduler.org/admin/): guide to managing scheduled actions via the administration screen
* [Guide to Background Processing at Scale](https://actionscheduler.org/perf/): instructions for running Action Scheduler at scale via the default WP Cron queue runner
## Credits
Action Scheduler is developed and maintained by [Automattic](http://automattic.com/) with significant early development completed by [Flightless](https://flightless.us/).
Collaboration is cool. We'd love to work with you to improve Action Scheduler. [Pull Requests](https://github.com/woocommerce/action-scheduler/pulls) welcome.

View File

@@ -1,66 +0,0 @@
<?php
// phpcs:ignoreFile
/**
* Plugin Name: Action Scheduler
* Plugin URI: https://actionscheduler.org
* Description: A robust scheduling library for use in WordPress plugins.
* Author: Automattic
* Author URI: https://automattic.com/
* Version: 3.4.0
* License: GPLv3
*
* Copyright 2019 Automattic, Inc. (https://automattic.com/contact/)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* @package ActionScheduler
*/
if ( ! function_exists( 'action_scheduler_register_3_dot_4_dot_0' ) && function_exists( 'add_action' ) ) {
if ( ! class_exists( 'ActionScheduler_Versions', false ) ) {
require_once __DIR__ . '/classes/ActionScheduler_Versions.php';
add_action( 'plugins_loaded', array( 'ActionScheduler_Versions', 'initialize_latest_version' ), 1, 0 );
}
add_action( 'plugins_loaded', 'action_scheduler_register_3_dot_4_dot_0', 0, 0 );
/**
* Registers this version of Action Scheduler.
*/
function action_scheduler_register_3_dot_4_dot_0() {
$versions = ActionScheduler_Versions::instance();
$versions->register( '3.4.0', 'action_scheduler_initialize_3_dot_4_dot_0' );
}
/**
* Initializes this version of Action Scheduler.
*/
function action_scheduler_initialize_3_dot_4_dot_0() {
// A final safety check is required even here, because historic versions of Action Scheduler
// followed a different pattern (in some unusual cases, we could reach this point and the
// ActionScheduler class is already defined—so we need to guard against that).
if ( ! class_exists( 'ActionScheduler', false ) ) {
require_once __DIR__ . '/classes/abstracts/ActionScheduler.php';
ActionScheduler::init( __FILE__ );
}
}
// Support usage in themes - load this version if no plugin has loaded a version yet.
if ( did_action( 'plugins_loaded' ) && ! doing_action( 'plugins_loaded' ) && ! class_exists( 'ActionScheduler', false ) ) {
action_scheduler_initialize_3_dot_4_dot_0();
do_action( 'action_scheduler_pre_theme_init' );
ActionScheduler_Versions::initialize_latest_version();
}
}

View File

@@ -1,45 +0,0 @@
*** Changelog ***
= 3.4.0 - 2021-10-29 =
* Enhancement - Number of items per page can now be set for the Scheduled Actions view (props @ovidiul). #771
* Fix - Do not lower the max_execution_time if it is already set to 0 (unlimited) (props @barryhughes). #755
* Fix - Avoid triggering autoloaders during the version resolution process (props @olegabr). #731 & #776
* Dev - ActionScheduler_wcSystemStatus PHPCS fixes (props @ovidiul). #761
* Dev - ActionScheduler_DBLogger.php PHPCS fixes (props @ovidiul). #768
* Dev - Fixed phpcs for ActionScheduler_Schedule_Deprecated (props @ovidiul). #762
* Dev - Improve actions table indicies (props @glagonikas). #774 & #777
* Dev - PHPCS fixes for ActionScheduler_DBStore.php (props @ovidiul). #769 & #778
* Dev - PHPCS Fixes for ActionScheduler_Abstract_ListTable (props @ovidiul). #763 & #779
* Dev - Adds new filter action_scheduler_claim_actions_order_by to allow tuning of the claim query (props @glagonikas). #773
* Dev - PHPCS fixes for ActionScheduler_WpPostStore class (props @ovidiul). #780
= 3.3.0 - 2021-09-15 =
* Enhancement - Adds as_has_scheduled_action() to provide a performant way to test for existing actions. #645
* Fix - Improves compatibility with environments where NO_ZERO_DATE is enabled. #519
* Fix - Adds safety checks to guard against errors when our database tables cannot be created. #645
* Dev - Now supports queries that use multiple statuses. #649
* Dev - Minimum requirements for WordPress and PHP bumped (to 5.2 and 5.6 respectively). #723
= 3.2.1 - 2021-06-21 =
* Fix - Add extra safety/account for different versions of AS and different loading patterns. #714
* Fix - Handle hidden columns (Tools → Scheduled Actions) | #600.
= 3.2.0 - 2021-06-03 =
* Fix - Add "no ordering" option to as_next_scheduled_action().
* Fix - Add secondary scheduled date checks when claiming actions (DBStore) | #634.
* Fix - Add secondary scheduled date checks when claiming actions (wpPostStore) | #634.
* Fix - Adds a new index to the action table, reducing the potential for deadlocks (props: @glagonikas).
* Fix - Fix unit tests infrastructure and adapt tests to PHP 8.
* Fix - Identify in-use data store.
* Fix - Improve test_migration_is_scheduled.
* Fix - PHP notice on list table.
* Fix - Speed up clean up and batch selects.
* Fix - Update pending dependencies.
* Fix - [PHP 8.0] Only pass action arg values through to do_action_ref_array().
* Fix - [PHP 8] Set the PHP version to 7.1 in composer.json for PHP 8 compatibility.
* Fix - add is_initialized() to docs.
* Fix - fix file permissions.
* Fix - fixes #664 by replacing __ with esc_html__.
= 3.1.6 - 2020-05-12 =
* Change log starts.

View File

@@ -1,24 +0,0 @@
<?php
// phpcs:ignoreFile
/**
* Class ActionScheduler_ActionClaim
*/
class ActionScheduler_ActionClaim {
private $id = '';
private $action_ids = array();
public function __construct( $id, array $action_ids ) {
$this->id = $id;
$this->action_ids = $action_ids;
}
public function get_id() {
return $this->id;
}
public function get_actions() {
return $this->action_ids;
}
}

View File

@@ -1,180 +0,0 @@
<?php
// phpcs:ignoreFile
/**
* Class ActionScheduler_ActionFactory
*/
class ActionScheduler_ActionFactory {
/**
* @param string $status The action's status in the data store
* @param string $hook The hook to trigger when this action runs
* @param array $args Args to pass to callbacks when the hook is triggered
* @param ActionScheduler_Schedule $schedule The action's schedule
* @param string $group A group to put the action in
*
* @return ActionScheduler_Action An instance of the stored action
*/
public function get_stored_action( $status, $hook, array $args = array(), ActionScheduler_Schedule $schedule = null, $group = '' ) {
switch ( $status ) {
case ActionScheduler_Store::STATUS_PENDING :
$action_class = 'ActionScheduler_Action';
break;
case ActionScheduler_Store::STATUS_CANCELED :
$action_class = 'ActionScheduler_CanceledAction';
if ( ! is_null( $schedule ) && ! is_a( $schedule, 'ActionScheduler_CanceledSchedule' ) && ! is_a( $schedule, 'ActionScheduler_NullSchedule' ) ) {
$schedule = new ActionScheduler_CanceledSchedule( $schedule->get_date() );
}
break;
default :
$action_class = 'ActionScheduler_FinishedAction';
break;
}
$action_class = apply_filters( 'action_scheduler_stored_action_class', $action_class, $status, $hook, $args, $schedule, $group );
$action = new $action_class( $hook, $args, $schedule, $group );
/**
* Allow 3rd party code to change the instantiated action for a given hook, args, schedule and group.
*
* @param ActionScheduler_Action $action The instantiated action.
* @param string $hook The instantiated action's hook.
* @param array $args The instantiated action's args.
* @param ActionScheduler_Schedule $schedule The instantiated action's schedule.
* @param string $group The instantiated action's group.
*/
return apply_filters( 'action_scheduler_stored_action_instance', $action, $hook, $args, $schedule, $group );
}
/**
* Enqueue an action to run one time, as soon as possible (rather a specific scheduled time).
*
* This method creates a new action with the NULLSchedule. This schedule maps to a MySQL datetime string of
* 0000-00-00 00:00:00. This is done to create a psuedo "async action" type that is fully backward compatible.
* Existing queries to claim actions claim by date, meaning actions scheduled for 0000-00-00 00:00:00 will
* always be claimed prior to actions scheduled for a specific date. This makes sure that any async action is
* given priority in queue processing. This has the added advantage of making sure async actions can be
* claimed by both the existing WP Cron and WP CLI runners, as well as a new async request runner.
*
* @param string $hook The hook to trigger when this action runs
* @param array $args Args to pass when the hook is triggered
* @param string $group A group to put the action in
*
* @return int The ID of the stored action
*/
public function async( $hook, $args = array(), $group = '' ) {
$schedule = new ActionScheduler_NullSchedule();
$action = new ActionScheduler_Action( $hook, $args, $schedule, $group );
return $this->store( $action );
}
/**
* @param string $hook The hook to trigger when this action runs
* @param array $args Args to pass when the hook is triggered
* @param int $when Unix timestamp when the action will run
* @param string $group A group to put the action in
*
* @return int The ID of the stored action
*/
public function single( $hook, $args = array(), $when = null, $group = '' ) {
$date = as_get_datetime_object( $when );
$schedule = new ActionScheduler_SimpleSchedule( $date );
$action = new ActionScheduler_Action( $hook, $args, $schedule, $group );
return $this->store( $action );
}
/**
* Create the first instance of an action recurring on a given interval.
*
* @param string $hook The hook to trigger when this action runs
* @param array $args Args to pass when the hook is triggered
* @param int $first Unix timestamp for the first run
* @param int $interval Seconds between runs
* @param string $group A group to put the action in
*
* @return int The ID of the stored action
*/
public function recurring( $hook, $args = array(), $first = null, $interval = null, $group = '' ) {
if ( empty($interval) ) {
return $this->single( $hook, $args, $first, $group );
}
$date = as_get_datetime_object( $first );
$schedule = new ActionScheduler_IntervalSchedule( $date, $interval );
$action = new ActionScheduler_Action( $hook, $args, $schedule, $group );
return $this->store( $action );
}
/**
* Create the first instance of an action recurring on a Cron schedule.
*
* @param string $hook The hook to trigger when this action runs
* @param array $args Args to pass when the hook is triggered
* @param int $base_timestamp The first instance of the action will be scheduled
* to run at a time calculated after this timestamp matching the cron
* expression. This can be used to delay the first instance of the action.
* @param int $schedule A cron definition string
* @param string $group A group to put the action in
*
* @return int The ID of the stored action
*/
public function cron( $hook, $args = array(), $base_timestamp = null, $schedule = null, $group = '' ) {
if ( empty($schedule) ) {
return $this->single( $hook, $args, $base_timestamp, $group );
}
$date = as_get_datetime_object( $base_timestamp );
$cron = CronExpression::factory( $schedule );
$schedule = new ActionScheduler_CronSchedule( $date, $cron );
$action = new ActionScheduler_Action( $hook, $args, $schedule, $group );
return $this->store( $action );
}
/**
* Create a successive instance of a recurring or cron action.
*
* Importantly, the action will be rescheduled to run based on the current date/time.
* That means when the action is scheduled to run in the past, the next scheduled date
* will be pushed forward. For example, if a recurring action set to run every hour
* was scheduled to run 5 seconds ago, it will be next scheduled for 1 hour in the
* future, which is 1 hour and 5 seconds from when it was last scheduled to run.
*
* Alternatively, if the action is scheduled to run in the future, and is run early,
* likely via manual intervention, then its schedule will change based on the time now.
* For example, if a recurring action set to run every day, and is run 12 hours early,
* it will run again in 24 hours, not 36 hours.
*
* This slippage is less of an issue with Cron actions, as the specific run time can
* be set for them to run, e.g. 1am each day. In those cases, and entire period would
* need to be missed before there was any change is scheduled, e.g. in the case of an
* action scheduled for 1am each day, the action would need to run an entire day late.
*
* @param ActionScheduler_Action $action The existing action.
*
* @return string The ID of the stored action
* @throws InvalidArgumentException If $action is not a recurring action.
*/
public function repeat( $action ) {
$schedule = $action->get_schedule();
$next = $schedule->get_next( as_get_datetime_object() );
if ( is_null( $next ) || ! $schedule->is_recurring() ) {
throw new InvalidArgumentException( __( 'Invalid action - must be a recurring action.', 'action-scheduler' ) );
}
$schedule_class = get_class( $schedule );
$new_schedule = new $schedule( $next, $schedule->get_recurrence(), $schedule->get_first_date() );
$new_action = new ActionScheduler_Action( $action->get_hook(), $action->get_args(), $new_schedule, $action->get_group() );
return $this->store( $new_action );
}
/**
* @param ActionScheduler_Action $action
*
* @return int The ID of the stored action
*/
protected function store( ActionScheduler_Action $action ) {
$store = ActionScheduler_Store::instance();
return $store->save_action( $action );
}
}

View File

@@ -1,155 +0,0 @@
<?php
// phpcs:ignoreFile
/**
* Class ActionScheduler_AdminView
* @codeCoverageIgnore
*/
class ActionScheduler_AdminView extends ActionScheduler_AdminView_Deprecated {
private static $admin_view = NULL;
private static $screen_id = 'tools_page_action-scheduler';
/** @var ActionScheduler_ListTable */
protected $list_table;
/**
* @return ActionScheduler_AdminView
* @codeCoverageIgnore
*/
public static function instance() {
if ( empty( self::$admin_view ) ) {
$class = apply_filters('action_scheduler_admin_view_class', 'ActionScheduler_AdminView');
self::$admin_view = new $class();
}
return self::$admin_view;
}
/**
* @codeCoverageIgnore
*/
public function init() {
if ( is_admin() && ( ! defined( 'DOING_AJAX' ) || false == DOING_AJAX ) ) {
if ( class_exists( 'WooCommerce' ) ) {
add_action( 'woocommerce_admin_status_content_action-scheduler', array( $this, 'render_admin_ui' ) );
add_action( 'woocommerce_system_status_report', array( $this, 'system_status_report' ) );
add_filter( 'woocommerce_admin_status_tabs', array( $this, 'register_system_status_tab' ) );
}
add_action( 'admin_menu', array( $this, 'register_menu' ) );
add_action( 'current_screen', array( $this, 'add_help_tabs' ) );
}
}
public function system_status_report() {
$table = new ActionScheduler_wcSystemStatus( ActionScheduler::store() );
$table->render();
}
/**
* Registers action-scheduler into WooCommerce > System status.
*
* @param array $tabs An associative array of tab key => label.
* @return array $tabs An associative array of tab key => label, including Action Scheduler's tabs
*/
public function register_system_status_tab( array $tabs ) {
$tabs['action-scheduler'] = __( 'Scheduled Actions', 'action-scheduler' );
return $tabs;
}
/**
* Include Action Scheduler's administration under the Tools menu.
*
* A menu under the Tools menu is important for backward compatibility (as that's
* where it started), and also provides more convenient access than the WooCommerce
* System Status page, and for sites where WooCommerce isn't active.
*/
public function register_menu() {
$hook_suffix = add_submenu_page(
'tools.php',
__( 'Scheduled Actions', 'action-scheduler' ),
__( 'Scheduled Actions', 'action-scheduler' ),
'manage_options',
'action-scheduler',
array( $this, 'render_admin_ui' )
);
add_action( 'load-' . $hook_suffix , array( $this, 'process_admin_ui' ) );
}
/**
* Triggers processing of any pending actions.
*/
public function process_admin_ui() {
$this->get_list_table();
}
/**
* Renders the Admin UI
*/
public function render_admin_ui() {
$table = $this->get_list_table();
$table->display_page();
}
/**
* Get the admin UI object and process any requested actions.
*
* @return ActionScheduler_ListTable
*/
protected function get_list_table() {
if ( null === $this->list_table ) {
$this->list_table = new ActionScheduler_ListTable( ActionScheduler::store(), ActionScheduler::logger(), ActionScheduler::runner() );
$this->list_table->process_actions();
}
return $this->list_table;
}
/**
* Provide more information about the screen and its data in the help tab.
*/
public function add_help_tabs() {
$screen = get_current_screen();
if ( ! $screen || self::$screen_id != $screen->id ) {
return;
}
$as_version = ActionScheduler_Versions::instance()->latest_version();
$screen->add_help_tab(
array(
'id' => 'action_scheduler_about',
'title' => __( 'About', 'action-scheduler' ),
'content' =>
'<h2>' . sprintf( __( 'About Action Scheduler %s', 'action-scheduler' ), $as_version ) . '</h2>' .
'<p>' .
__( 'Action Scheduler is a scalable, traceable job queue for background processing large sets of actions. Action Scheduler works by triggering an action hook to run at some time in the future. Scheduled actions can also be scheduled to run on a recurring schedule.', 'action-scheduler' ) .
'</p>',
)
);
$screen->add_help_tab(
array(
'id' => 'action_scheduler_columns',
'title' => __( 'Columns', 'action-scheduler' ),
'content' =>
'<h2>' . __( 'Scheduled Action Columns', 'action-scheduler' ) . '</h2>' .
'<ul>' .
sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Hook', 'action-scheduler' ), __( 'Name of the action hook that will be triggered.', 'action-scheduler' ) ) .
sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Status', 'action-scheduler' ), __( 'Action statuses are Pending, Complete, Canceled, Failed', 'action-scheduler' ) ) .
sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Arguments', 'action-scheduler' ), __( 'Optional data array passed to the action hook.', 'action-scheduler' ) ) .
sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Group', 'action-scheduler' ), __( 'Optional action group.', 'action-scheduler' ) ) .
sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Recurrence', 'action-scheduler' ), __( 'The action\'s schedule frequency.', 'action-scheduler' ) ) .
sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Scheduled', 'action-scheduler' ), __( 'The date/time the action is/was scheduled to run.', 'action-scheduler' ) ) .
sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Log', 'action-scheduler' ), __( 'Activity log for the action.', 'action-scheduler' ) ) .
'</ul>',
)
);
}
}

View File

@@ -1,98 +0,0 @@
<?php
// phpcs:ignoreFile
/**
* ActionScheduler_AsyncRequest_QueueRunner
*/
defined( 'ABSPATH' ) || exit;
/**
* ActionScheduler_AsyncRequest_QueueRunner class.
*/
class ActionScheduler_AsyncRequest_QueueRunner extends WP_Async_Request {
/**
* Data store for querying actions
*
* @var ActionScheduler_Store
* @access protected
*/
protected $store;
/**
* Prefix for ajax hooks
*
* @var string
* @access protected
*/
protected $prefix = 'as';
/**
* Action for ajax hooks
*
* @var string
* @access protected
*/
protected $action = 'async_request_queue_runner';
/**
* Initiate new async request
*/
public function __construct( ActionScheduler_Store $store ) {
parent::__construct();
$this->store = $store;
}
/**
* Handle async requests
*
* Run a queue, and maybe dispatch another async request to run another queue
* if there are still pending actions after completing a queue in this request.
*/
protected function handle() {
do_action( 'action_scheduler_run_queue', 'Async Request' ); // run a queue in the same way as WP Cron, but declare the Async Request context
$sleep_seconds = $this->get_sleep_seconds();
if ( $sleep_seconds ) {
sleep( $sleep_seconds );
}
$this->maybe_dispatch();
}
/**
* If the async request runner is needed and allowed to run, dispatch a request.
*/
public function maybe_dispatch() {
if ( ! $this->allow() ) {
return;
}
$this->dispatch();
ActionScheduler_QueueRunner::instance()->unhook_dispatch_async_request();
}
/**
* Only allow async requests when needed.
*
* Also allow 3rd party code to disable running actions via async requests.
*/
protected function allow() {
if ( ! has_action( 'action_scheduler_run_queue' ) || ActionScheduler::runner()->has_maximum_concurrent_batches() || ! $this->store->has_pending_actions_due() ) {
$allow = false;
} else {
$allow = true;
}
return apply_filters( 'action_scheduler_allow_async_request_runner', $allow );
}
/**
* Chaining async requests can crash MySQL. A brief sleep call in PHP prevents that.
*/
protected function get_sleep_seconds() {
return apply_filters( 'action_scheduler_async_request_sleep_seconds', 5, $this );
}
}

View File

@@ -1,110 +0,0 @@
<?php
// phpcs:ignoreFile
/**
* Class ActionScheduler_Compatibility
*/
class ActionScheduler_Compatibility {
/**
* Converts a shorthand byte value to an integer byte value.
*
* Wrapper for wp_convert_hr_to_bytes(), moved to load.php in WordPress 4.6 from media.php
*
* @link https://secure.php.net/manual/en/function.ini-get.php
* @link https://secure.php.net/manual/en/faq.using.php#faq.using.shorthandbytes
*
* @param string $value A (PHP ini) byte value, either shorthand or ordinary.
* @return int An integer byte value.
*/
public static function convert_hr_to_bytes( $value ) {
if ( function_exists( 'wp_convert_hr_to_bytes' ) ) {
return wp_convert_hr_to_bytes( $value );
}
$value = strtolower( trim( $value ) );
$bytes = (int) $value;
if ( false !== strpos( $value, 'g' ) ) {
$bytes *= GB_IN_BYTES;
} elseif ( false !== strpos( $value, 'm' ) ) {
$bytes *= MB_IN_BYTES;
} elseif ( false !== strpos( $value, 'k' ) ) {
$bytes *= KB_IN_BYTES;
}
// Deal with large (float) values which run into the maximum integer size.
return min( $bytes, PHP_INT_MAX );
}
/**
* Attempts to raise the PHP memory limit for memory intensive processes.
*
* Only allows raising the existing limit and prevents lowering it.
*
* Wrapper for wp_raise_memory_limit(), added in WordPress v4.6.0
*
* @return bool|int|string The limit that was set or false on failure.
*/
public static function raise_memory_limit() {
if ( function_exists( 'wp_raise_memory_limit' ) ) {
return wp_raise_memory_limit( 'admin' );
}
$current_limit = @ini_get( 'memory_limit' );
$current_limit_int = self::convert_hr_to_bytes( $current_limit );
if ( -1 === $current_limit_int ) {
return false;
}
$wp_max_limit = WP_MAX_MEMORY_LIMIT;
$wp_max_limit_int = self::convert_hr_to_bytes( $wp_max_limit );
$filtered_limit = apply_filters( 'admin_memory_limit', $wp_max_limit );
$filtered_limit_int = self::convert_hr_to_bytes( $filtered_limit );
if ( -1 === $filtered_limit_int || ( $filtered_limit_int > $wp_max_limit_int && $filtered_limit_int > $current_limit_int ) ) {
if ( false !== @ini_set( 'memory_limit', $filtered_limit ) ) {
return $filtered_limit;
} else {
return false;
}
} elseif ( -1 === $wp_max_limit_int || $wp_max_limit_int > $current_limit_int ) {
if ( false !== @ini_set( 'memory_limit', $wp_max_limit ) ) {
return $wp_max_limit;
} else {
return false;
}
}
return false;
}
/**
* Attempts to raise the PHP timeout for time intensive processes.
*
* Only allows raising the existing limit and prevents lowering it. Wrapper for wc_set_time_limit(), when available.
*
* @param int $limit The time limit in seconds.
*/
public static function raise_time_limit( $limit = 0 ) {
$limit = (int) $limit;
$max_execution_time = (int) ini_get( 'max_execution_time' );
/*
* If the max execution time is already unlimited (zero), or if it exceeds or is equal to the proposed
* limit, there is no reason for us to make further changes (we never want to lower it).
*/
if (
0 === $max_execution_time
|| ( $max_execution_time >= $limit && $limit !== 0 )
) {
return;
}
if ( function_exists( 'wc_set_time_limit' ) ) {
wc_set_time_limit( $limit );
} elseif ( function_exists( 'set_time_limit' ) && false === strpos( ini_get( 'disable_functions' ), 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) { // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.safe_modeDeprecatedRemoved
@set_time_limit( $limit ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
}
}
}

View File

@@ -1,188 +0,0 @@
<?php
// phpcs:ignoreFile
use Action_Scheduler\Migration\Controller;
/**
* Class ActionScheduler_DataController
*
* The main plugin/initialization class for the data stores.
*
* Responsible for hooking everything up with WordPress.
*
* @package Action_Scheduler
*
* @since 3.0.0
*/
class ActionScheduler_DataController {
/** Action data store class name. */
const DATASTORE_CLASS = 'ActionScheduler_DBStore';
/** Logger data store class name. */
const LOGGER_CLASS = 'ActionScheduler_DBLogger';
/** Migration status option name. */
const STATUS_FLAG = 'action_scheduler_migration_status';
/** Migration status option value. */
const STATUS_COMPLETE = 'complete';
/** Migration minimum required PHP version. */
const MIN_PHP_VERSION = '5.5';
/** @var ActionScheduler_DataController */
private static $instance;
/** @var int */
private static $sleep_time = 0;
/** @var int */
private static $free_ticks = 50;
/**
* Get a flag indicating whether the migration environment dependencies are met.
*
* @return bool
*/
public static function dependencies_met() {
$php_support = version_compare( PHP_VERSION, self::MIN_PHP_VERSION, '>=' );
return $php_support && apply_filters( 'action_scheduler_migration_dependencies_met', true );
}
/**
* Get a flag indicating whether the migration is complete.
*
* @return bool Whether the flag has been set marking the migration as complete
*/
public static function is_migration_complete() {
return get_option( self::STATUS_FLAG ) === self::STATUS_COMPLETE;
}
/**
* Mark the migration as complete.
*/
public static function mark_migration_complete() {
update_option( self::STATUS_FLAG, self::STATUS_COMPLETE );
}
/**
* Unmark migration when a plugin is de-activated. Will not work in case of silent activation, for example in an update.
* We do this to mitigate the bug of lost actions which happens if there was an AS 2.x to AS 3.x migration in the past, but that plugin is now
* deactivated and the site was running on AS 2.x again.
*/
public static function mark_migration_incomplete() {
delete_option( self::STATUS_FLAG );
}
/**
* Set the action store class name.
*
* @param string $class Classname of the store class.
*
* @return string
*/
public static function set_store_class( $class ) {
return self::DATASTORE_CLASS;
}
/**
* Set the action logger class name.
*
* @param string $class Classname of the logger class.
*
* @return string
*/
public static function set_logger_class( $class ) {
return self::LOGGER_CLASS;
}
/**
* Set the sleep time in seconds.
*
* @param integer $sleep_time The number of seconds to pause before resuming operation.
*/
public static function set_sleep_time( $sleep_time ) {
self::$sleep_time = (int) $sleep_time;
}
/**
* Set the tick count required for freeing memory.
*
* @param integer $free_ticks The number of ticks to free memory on.
*/
public static function set_free_ticks( $free_ticks ) {
self::$free_ticks = (int) $free_ticks;
}
/**
* Free memory if conditions are met.
*
* @param int $ticks Current tick count.
*/
public static function maybe_free_memory( $ticks ) {
if ( self::$free_ticks && 0 === $ticks % self::$free_ticks ) {
self::free_memory();
}
}
/**
* Reduce memory footprint by clearing the database query and object caches.
*/
public static function free_memory() {
if ( 0 < self::$sleep_time ) {
/* translators: %d: amount of time */
\WP_CLI::warning( sprintf( _n( 'Stopped the insanity for %d second', 'Stopped the insanity for %d seconds', self::$sleep_time, 'action-scheduler' ), self::$sleep_time ) );
sleep( self::$sleep_time );
}
\WP_CLI::warning( __( 'Attempting to reduce used memory...', 'action-scheduler' ) );
/**
* @var $wpdb \wpdb
* @var $wp_object_cache \WP_Object_Cache
*/
global $wpdb, $wp_object_cache;
$wpdb->queries = array();
if ( ! is_a( $wp_object_cache, 'WP_Object_Cache' ) ) {
return;
}
$wp_object_cache->group_ops = array();
$wp_object_cache->stats = array();
$wp_object_cache->memcache_debug = array();
$wp_object_cache->cache = array();
if ( is_callable( array( $wp_object_cache, '__remoteset' ) ) ) {
call_user_func( array( $wp_object_cache, '__remoteset' ) ); // important
}
}
/**
* Connect to table datastores if migration is complete.
* Otherwise, proceed with the migration if the dependencies have been met.
*/
public static function init() {
if ( self::is_migration_complete() ) {
add_filter( 'action_scheduler_store_class', array( 'ActionScheduler_DataController', 'set_store_class' ), 100 );
add_filter( 'action_scheduler_logger_class', array( 'ActionScheduler_DataController', 'set_logger_class' ), 100 );
add_action( 'deactivate_plugin', array( 'ActionScheduler_DataController', 'mark_migration_incomplete' ) );
} elseif ( self::dependencies_met() ) {
Controller::init();
}
add_action( 'action_scheduler/progress_tick', array( 'ActionScheduler_DataController', 'maybe_free_memory' ) );
}
/**
* Singleton factory.
*/
public static function instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new static();
}
return self::$instance;
}
}

View File

@@ -1,77 +0,0 @@
<?php
// phpcs:ignoreFile
/**
* ActionScheduler DateTime class.
*
* This is a custom extension to DateTime that
*/
class ActionScheduler_DateTime extends DateTime {
/**
* UTC offset.
*
* Only used when a timezone is not set. When a timezone string is
* used, this will be set to 0.
*
* @var int
*/
protected $utcOffset = 0;
/**
* Get the unix timestamp of the current object.
*
* Missing in PHP 5.2 so just here so it can be supported consistently.
*
* @return int
*/
public function getTimestamp() {
return method_exists( 'DateTime', 'getTimestamp' ) ? parent::getTimestamp() : $this->format( 'U' );
}
/**
* Set the UTC offset.
*
* This represents a fixed offset instead of a timezone setting.
*
* @param $offset
*/
public function setUtcOffset( $offset ) {
$this->utcOffset = intval( $offset );
}
/**
* Returns the timezone offset.
*
* @return int
* @link http://php.net/manual/en/datetime.getoffset.php
*/
public function getOffset() {
return $this->utcOffset ? $this->utcOffset : parent::getOffset();
}
/**
* Set the TimeZone associated with the DateTime
*
* @param DateTimeZone $timezone
*
* @return static
* @link http://php.net/manual/en/datetime.settimezone.php
*/
public function setTimezone( $timezone ) {
$this->utcOffset = 0;
parent::setTimezone( $timezone );
return $this;
}
/**
* Get the timestamp with the WordPress timezone offset added or subtracted.
*
* @since 3.0.0
* @return int
*/
public function getOffsetTimestamp() {
return $this->getTimestamp() + $this->getOffset();
}
}

View File

@@ -1,12 +0,0 @@
<?php
// phpcs:ignoreFile
/**
* ActionScheduler Exception Interface.
*
* Facilitates catching Exceptions unique to Action Scheduler.
*
* @package ActionScheduler
* @since %VERSION%
*/
interface ActionScheduler_Exception {}

View File

@@ -1,56 +0,0 @@
<?php
// phpcs:ignoreFile
/**
* Class ActionScheduler_FatalErrorMonitor
*/
class ActionScheduler_FatalErrorMonitor {
/** @var ActionScheduler_ActionClaim */
private $claim = NULL;
/** @var ActionScheduler_Store */
private $store = NULL;
private $action_id = 0;
public function __construct( ActionScheduler_Store $store ) {
$this->store = $store;
}
public function attach( ActionScheduler_ActionClaim $claim ) {
$this->claim = $claim;
add_action( 'shutdown', array( $this, 'handle_unexpected_shutdown' ) );
add_action( 'action_scheduler_before_execute', array( $this, 'track_current_action' ), 0, 1 );
add_action( 'action_scheduler_after_execute', array( $this, 'untrack_action' ), 0, 0 );
add_action( 'action_scheduler_execution_ignored', array( $this, 'untrack_action' ), 0, 0 );
add_action( 'action_scheduler_failed_execution', array( $this, 'untrack_action' ), 0, 0 );
}
public function detach() {
$this->claim = NULL;
$this->untrack_action();
remove_action( 'shutdown', array( $this, 'handle_unexpected_shutdown' ) );
remove_action( 'action_scheduler_before_execute', array( $this, 'track_current_action' ), 0 );
remove_action( 'action_scheduler_after_execute', array( $this, 'untrack_action' ), 0 );
remove_action( 'action_scheduler_execution_ignored', array( $this, 'untrack_action' ), 0 );
remove_action( 'action_scheduler_failed_execution', array( $this, 'untrack_action' ), 0 );
}
public function track_current_action( $action_id ) {
$this->action_id = $action_id;
}
public function untrack_action() {
$this->action_id = 0;
}
public function handle_unexpected_shutdown() {
if ( $error = error_get_last() ) {
if ( in_array( $error['type'], array( E_ERROR, E_PARSE, E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR ) ) ) {
if ( !empty($this->action_id) ) {
$this->store->mark_failure( $this->action_id );
do_action( 'action_scheduler_unexpected_shutdown', $this->action_id, $error );
}
}
$this->store->release_claim( $this->claim );
}
}
}

View File

@@ -1,48 +0,0 @@
<?php
// phpcs:ignoreFile
/**
* InvalidAction Exception.
*
* Used for identifying actions that are invalid in some way.
*
* @package ActionScheduler
*/
class ActionScheduler_InvalidActionException extends \InvalidArgumentException implements ActionScheduler_Exception {
/**
* Create a new exception when the action's schedule cannot be fetched.
*
* @param string $action_id The action ID with bad args.
* @return static
*/
public static function from_schedule( $action_id, $schedule ) {
$message = sprintf(
/* translators: 1: action ID 2: schedule */
__( 'Action [%1$s] has an invalid schedule: %2$s', 'action-scheduler' ),
$action_id,
var_export( $schedule, true )
);
return new static( $message );
}
/**
* Create a new exception when the action's args cannot be decoded to an array.
*
* @author Jeremy Pry
*
* @param string $action_id The action ID with bad args.
* @return static
*/
public static function from_decoding_args( $action_id, $args = array() ) {
$message = sprintf(
/* translators: 1: action ID 2: arguments */
__( 'Action [%1$s] has invalid arguments. It cannot be JSON decoded to an array. $args = %2$s', 'action-scheduler' ),
$action_id,
var_export( $args, true )
);
return new static( $message );
}
}

View File

@@ -1,644 +0,0 @@
<?php
// phpcs:ignoreFile
/**
* Implements the admin view of the actions.
* @codeCoverageIgnore
*/
class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
/**
* The package name.
*
* @var string
*/
protected $package = 'action-scheduler';
/**
* Columns to show (name => label).
*
* @var array
*/
protected $columns = array();
/**
* Actions (name => label).
*
* @var array
*/
protected $row_actions = array();
/**
* The active data stores
*
* @var ActionScheduler_Store
*/
protected $store;
/**
* A logger to use for getting action logs to display
*
* @var ActionScheduler_Logger
*/
protected $logger;
/**
* A ActionScheduler_QueueRunner runner instance (or child class)
*
* @var ActionScheduler_QueueRunner
*/
protected $runner;
/**
* Bulk actions. The key of the array is the method name of the implementation:
*
* bulk_<key>(array $ids, string $sql_in).
*
* See the comments in the parent class for further details
*
* @var array
*/
protected $bulk_actions = array();
/**
* Flag variable to render our notifications, if any, once.
*
* @var bool
*/
protected static $did_notification = false;
/**
* Array of seconds for common time periods, like week or month, alongside an internationalised string representation, i.e. "Day" or "Days"
*
* @var array
*/
private static $time_periods;
/**
* Sets the current data store object into `store->action` and initialises the object.
*
* @param ActionScheduler_Store $store
* @param ActionScheduler_Logger $logger
* @param ActionScheduler_QueueRunner $runner
*/
public function __construct( ActionScheduler_Store $store, ActionScheduler_Logger $logger, ActionScheduler_QueueRunner $runner ) {
$this->store = $store;
$this->logger = $logger;
$this->runner = $runner;
$this->table_header = __( 'Scheduled Actions', 'action-scheduler' );
$this->bulk_actions = array(
'delete' => __( 'Delete', 'action-scheduler' ),
);
$this->columns = array(
'hook' => __( 'Hook', 'action-scheduler' ),
'status' => __( 'Status', 'action-scheduler' ),
'args' => __( 'Arguments', 'action-scheduler' ),
'group' => __( 'Group', 'action-scheduler' ),
'recurrence' => __( 'Recurrence', 'action-scheduler' ),
'schedule' => __( 'Scheduled Date', 'action-scheduler' ),
'log_entries' => __( 'Log', 'action-scheduler' ),
);
$this->sort_by = array(
'schedule',
'hook',
'group',
);
$this->search_by = array(
'hook',
'args',
'claim_id',
);
$request_status = $this->get_request_status();
if ( empty( $request_status ) ) {
$this->sort_by[] = 'status';
} elseif ( in_array( $request_status, array( 'in-progress', 'failed' ) ) ) {
$this->columns += array( 'claim_id' => __( 'Claim ID', 'action-scheduler' ) );
$this->sort_by[] = 'claim_id';
}
$this->row_actions = array(
'hook' => array(
'run' => array(
'name' => __( 'Run', 'action-scheduler' ),
'desc' => __( 'Process the action now as if it were run as part of a queue', 'action-scheduler' ),
),
'cancel' => array(
'name' => __( 'Cancel', 'action-scheduler' ),
'desc' => __( 'Cancel the action now to avoid it being run in future', 'action-scheduler' ),
'class' => 'cancel trash',
),
),
);
self::$time_periods = array(
array(
'seconds' => YEAR_IN_SECONDS,
/* translators: %s: amount of time */
'names' => _n_noop( '%s year', '%s years', 'action-scheduler' ),
),
array(
'seconds' => MONTH_IN_SECONDS,
/* translators: %s: amount of time */
'names' => _n_noop( '%s month', '%s months', 'action-scheduler' ),
),
array(
'seconds' => WEEK_IN_SECONDS,
/* translators: %s: amount of time */
'names' => _n_noop( '%s week', '%s weeks', 'action-scheduler' ),
),
array(
'seconds' => DAY_IN_SECONDS,
/* translators: %s: amount of time */
'names' => _n_noop( '%s day', '%s days', 'action-scheduler' ),
),
array(
'seconds' => HOUR_IN_SECONDS,
/* translators: %s: amount of time */
'names' => _n_noop( '%s hour', '%s hours', 'action-scheduler' ),
),
array(
'seconds' => MINUTE_IN_SECONDS,
/* translators: %s: amount of time */
'names' => _n_noop( '%s minute', '%s minutes', 'action-scheduler' ),
),
array(
'seconds' => 1,
/* translators: %s: amount of time */
'names' => _n_noop( '%s second', '%s seconds', 'action-scheduler' ),
),
);
parent::__construct(
array(
'singular' => 'action-scheduler',
'plural' => 'action-scheduler',
'ajax' => false,
)
);
add_screen_option(
'per_page',
array(
'default' => $this->items_per_page,
)
);
add_filter( 'set_screen_option_' . $this->get_per_page_option_name(), array( $this, 'set_items_per_page_option' ), 10, 3 );
set_screen_options();
}
/**
* Handles setting the items_per_page option for this screen.
*
* @param mixed $status Default false (to skip saving the current option).
* @param string $option Screen option name.
* @param int $value Screen option value.
* @return int
*/
public function set_items_per_page_option( $status, $option, $value ) {
return $value;
}
/**
* Convert an interval of seconds into a two part human friendly string.
*
* The WordPress human_time_diff() function only calculates the time difference to one degree, meaning
* even if an action is 1 day and 11 hours away, it will display "1 day". This function goes one step
* further to display two degrees of accuracy.
*
* Inspired by the Crontrol::interval() function by Edward Dale: https://wordpress.org/plugins/wp-crontrol/
*
* @param int $interval A interval in seconds.
* @param int $periods_to_include Depth of time periods to include, e.g. for an interval of 70, and $periods_to_include of 2, both minutes and seconds would be included. With a value of 1, only minutes would be included.
* @return string A human friendly string representation of the interval.
*/
private static function human_interval( $interval, $periods_to_include = 2 ) {
if ( $interval <= 0 ) {
return __( 'Now!', 'action-scheduler' );
}
$output = '';
for ( $time_period_index = 0, $periods_included = 0, $seconds_remaining = $interval; $time_period_index < count( self::$time_periods ) && $seconds_remaining > 0 && $periods_included < $periods_to_include; $time_period_index++ ) {
$periods_in_interval = floor( $seconds_remaining / self::$time_periods[ $time_period_index ]['seconds'] );
if ( $periods_in_interval > 0 ) {
if ( ! empty( $output ) ) {
$output .= ' ';
}
$output .= sprintf( _n( self::$time_periods[ $time_period_index ]['names'][0], self::$time_periods[ $time_period_index ]['names'][1], $periods_in_interval, 'action-scheduler' ), $periods_in_interval );
$seconds_remaining -= $periods_in_interval * self::$time_periods[ $time_period_index ]['seconds'];
$periods_included++;
}
}
return $output;
}
/**
* Returns the recurrence of an action or 'Non-repeating'. The output is human readable.
*
* @param ActionScheduler_Action $action
*
* @return string
*/
protected function get_recurrence( $action ) {
$schedule = $action->get_schedule();
if ( $schedule->is_recurring() ) {
$recurrence = $schedule->get_recurrence();
if ( is_numeric( $recurrence ) ) {
/* translators: %s: time interval */
return sprintf( __( 'Every %s', 'action-scheduler' ), self::human_interval( $recurrence ) );
} else {
return $recurrence;
}
}
return __( 'Non-repeating', 'action-scheduler' );
}
/**
* Serializes the argument of an action to render it in a human friendly format.
*
* @param array $row The array representation of the current row of the table
*
* @return string
*/
public function column_args( array $row ) {
if ( empty( $row['args'] ) ) {
return apply_filters( 'action_scheduler_list_table_column_args', '', $row );
}
$row_html = '<ul>';
foreach ( $row['args'] as $key => $value ) {
$row_html .= sprintf( '<li><code>%s => %s</code></li>', esc_html( var_export( $key, true ) ), esc_html( var_export( $value, true ) ) );
}
$row_html .= '</ul>';
return apply_filters( 'action_scheduler_list_table_column_args', $row_html, $row );
}
/**
* Prints the logs entries inline. We do so to avoid loading Javascript and other hacks to show it in a modal.
*
* @param array $row Action array.
* @return string
*/
public function column_log_entries( array $row ) {
$log_entries_html = '<ol>';
$timezone = new DateTimezone( 'UTC' );
foreach ( $row['log_entries'] as $log_entry ) {
$log_entries_html .= $this->get_log_entry_html( $log_entry, $timezone );
}
$log_entries_html .= '</ol>';
return $log_entries_html;
}
/**
* Prints the logs entries inline. We do so to avoid loading Javascript and other hacks to show it in a modal.
*
* @param ActionScheduler_LogEntry $log_entry
* @param DateTimezone $timezone
* @return string
*/
protected function get_log_entry_html( ActionScheduler_LogEntry $log_entry, DateTimezone $timezone ) {
$date = $log_entry->get_date();
$date->setTimezone( $timezone );
return sprintf( '<li><strong>%s</strong><br/>%s</li>', esc_html( $date->format( 'Y-m-d H:i:s O' ) ), esc_html( $log_entry->get_message() ) );
}
/**
* Only display row actions for pending actions.
*
* @param array $row Row to render
* @param string $column_name Current row
*
* @return string
*/
protected function maybe_render_actions( $row, $column_name ) {
if ( 'pending' === strtolower( $row[ 'status_name' ] ) ) {
return parent::maybe_render_actions( $row, $column_name );
}
return '';
}
/**
* Renders admin notifications
*
* Notifications:
* 1. When the maximum number of tasks are being executed simultaneously.
* 2. Notifications when a task is manually executed.
* 3. Tables are missing.
*/
public function display_admin_notices() {
global $wpdb;
if ( ( is_a( $this->store, 'ActionScheduler_HybridStore' ) || is_a( $this->store, 'ActionScheduler_DBStore' ) ) && apply_filters( 'action_scheduler_enable_recreate_data_store', true ) ) {
$table_list = array(
'actionscheduler_actions',
'actionscheduler_logs',
'actionscheduler_groups',
'actionscheduler_claims',
);
$found_tables = $wpdb->get_col( "SHOW TABLES LIKE '{$wpdb->prefix}actionscheduler%'" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
foreach ( $table_list as $table_name ) {
if ( ! in_array( $wpdb->prefix . $table_name, $found_tables ) ) {
$this->admin_notices[] = array(
'class' => 'error',
'message' => __( 'It appears one or more database tables were missing. Attempting to re-create the missing table(s).' , 'action-scheduler' ),
);
$this->recreate_tables();
parent::display_admin_notices();
return;
}
}
}
if ( $this->runner->has_maximum_concurrent_batches() ) {
$claim_count = $this->store->get_claim_count();
$this->admin_notices[] = array(
'class' => 'updated',
'message' => sprintf(
/* translators: %s: amount of claims */
_n(
'Maximum simultaneous queues already in progress (%s queue). No additional queues will begin processing until the current queues are complete.',
'Maximum simultaneous queues already in progress (%s queues). No additional queues will begin processing until the current queues are complete.',
$claim_count,
'action-scheduler'
),
$claim_count
),
);
} elseif ( $this->store->has_pending_actions_due() ) {
$async_request_lock_expiration = ActionScheduler::lock()->get_expiration( 'async-request-runner' );
// No lock set or lock expired
if ( false === $async_request_lock_expiration || $async_request_lock_expiration < time() ) {
$in_progress_url = add_query_arg( 'status', 'in-progress', remove_query_arg( 'status' ) );
/* translators: %s: process URL */
$async_request_message = sprintf( __( 'A new queue has begun processing. <a href="%s">View actions in-progress &raquo;</a>', 'action-scheduler' ), esc_url( $in_progress_url ) );
} else {
/* translators: %d: seconds */
$async_request_message = sprintf( __( 'The next queue will begin processing in approximately %d seconds.', 'action-scheduler' ), $async_request_lock_expiration - time() );
}
$this->admin_notices[] = array(
'class' => 'notice notice-info',
'message' => $async_request_message,
);
}
$notification = get_transient( 'action_scheduler_admin_notice' );
if ( is_array( $notification ) ) {
delete_transient( 'action_scheduler_admin_notice' );
$action = $this->store->fetch_action( $notification['action_id'] );
$action_hook_html = '<strong><code>' . $action->get_hook() . '</code></strong>';
if ( 1 == $notification['success'] ) {
$class = 'updated';
switch ( $notification['row_action_type'] ) {
case 'run' :
/* translators: %s: action HTML */
$action_message_html = sprintf( __( 'Successfully executed action: %s', 'action-scheduler' ), $action_hook_html );
break;
case 'cancel' :
/* translators: %s: action HTML */
$action_message_html = sprintf( __( 'Successfully canceled action: %s', 'action-scheduler' ), $action_hook_html );
break;
default :
/* translators: %s: action HTML */
$action_message_html = sprintf( __( 'Successfully processed change for action: %s', 'action-scheduler' ), $action_hook_html );
break;
}
} else {
$class = 'error';
/* translators: 1: action HTML 2: action ID 3: error message */
$action_message_html = sprintf( __( 'Could not process change for action: "%1$s" (ID: %2$d). Error: %3$s', 'action-scheduler' ), $action_hook_html, esc_html( $notification['action_id'] ), esc_html( $notification['error_message'] ) );
}
$action_message_html = apply_filters( 'action_scheduler_admin_notice_html', $action_message_html, $action, $notification );
$this->admin_notices[] = array(
'class' => $class,
'message' => $action_message_html,
);
}
parent::display_admin_notices();
}
/**
* Prints the scheduled date in a human friendly format.
*
* @param array $row The array representation of the current row of the table
*
* @return string
*/
public function column_schedule( $row ) {
return $this->get_schedule_display_string( $row['schedule'] );
}
/**
* Get the scheduled date in a human friendly format.
*
* @param ActionScheduler_Schedule $schedule
* @return string
*/
protected function get_schedule_display_string( ActionScheduler_Schedule $schedule ) {
$schedule_display_string = '';
if ( ! $schedule->get_date() ) {
return '0000-00-00 00:00:00';
}
$next_timestamp = $schedule->get_date()->getTimestamp();
$schedule_display_string .= $schedule->get_date()->format( 'Y-m-d H:i:s O' );
$schedule_display_string .= '<br/>';
if ( gmdate( 'U' ) > $next_timestamp ) {
/* translators: %s: date interval */
$schedule_display_string .= sprintf( __( ' (%s ago)', 'action-scheduler' ), self::human_interval( gmdate( 'U' ) - $next_timestamp ) );
} else {
/* translators: %s: date interval */
$schedule_display_string .= sprintf( __( ' (%s)', 'action-scheduler' ), self::human_interval( $next_timestamp - gmdate( 'U' ) ) );
}
return $schedule_display_string;
}
/**
* Bulk delete
*
* Deletes actions based on their ID. This is the handler for the bulk delete. It assumes the data
* properly validated by the callee and it will delete the actions without any extra validation.
*
* @param array $ids
* @param string $ids_sql Inherited and unused
*/
protected function bulk_delete( array $ids, $ids_sql ) {
foreach ( $ids as $id ) {
$this->store->delete_action( $id );
}
}
/**
* Implements the logic behind running an action. ActionScheduler_Abstract_ListTable validates the request and their
* parameters are valid.
*
* @param int $action_id
*/
protected function row_action_cancel( $action_id ) {
$this->process_row_action( $action_id, 'cancel' );
}
/**
* Implements the logic behind running an action. ActionScheduler_Abstract_ListTable validates the request and their
* parameters are valid.
*
* @param int $action_id
*/
protected function row_action_run( $action_id ) {
$this->process_row_action( $action_id, 'run' );
}
/**
* Force the data store schema updates.
*/
protected function recreate_tables() {
if ( is_a( $this->store, 'ActionScheduler_HybridStore' ) ) {
$store = $this->store;
} else {
$store = new ActionScheduler_HybridStore();
}
add_action( 'action_scheduler/created_table', array( $store, 'set_autoincrement' ), 10, 2 );
$store_schema = new ActionScheduler_StoreSchema();
$logger_schema = new ActionScheduler_LoggerSchema();
$store_schema->register_tables( true );
$logger_schema->register_tables( true );
remove_action( 'action_scheduler/created_table', array( $store, 'set_autoincrement' ), 10 );
}
/**
* Implements the logic behind processing an action once an action link is clicked on the list table.
*
* @param int $action_id
* @param string $row_action_type The type of action to perform on the action.
*/
protected function process_row_action( $action_id, $row_action_type ) {
try {
switch ( $row_action_type ) {
case 'run' :
$this->runner->process_action( $action_id, 'Admin List Table' );
break;
case 'cancel' :
$this->store->cancel_action( $action_id );
break;
}
$success = 1;
$error_message = '';
} catch ( Exception $e ) {
$success = 0;
$error_message = $e->getMessage();
}
set_transient( 'action_scheduler_admin_notice', compact( 'action_id', 'success', 'error_message', 'row_action_type' ), 30 );
}
/**
* {@inheritDoc}
*/
public function prepare_items() {
$this->prepare_column_headers();
$per_page = $this->get_items_per_page( $this->get_per_page_option_name(), $this->items_per_page );
$query = array(
'per_page' => $per_page,
'offset' => $this->get_items_offset(),
'status' => $this->get_request_status(),
'orderby' => $this->get_request_orderby(),
'order' => $this->get_request_order(),
'search' => $this->get_request_search_query(),
);
$this->items = array();
$total_items = $this->store->query_actions( $query, 'count' );
$status_labels = $this->store->get_status_labels();
foreach ( $this->store->query_actions( $query ) as $action_id ) {
try {
$action = $this->store->fetch_action( $action_id );
} catch ( Exception $e ) {
continue;
}
if ( is_a( $action, 'ActionScheduler_NullAction' ) ) {
continue;
}
$this->items[ $action_id ] = array(
'ID' => $action_id,
'hook' => $action->get_hook(),
'status_name' => $this->store->get_status( $action_id ),
'status' => $status_labels[ $this->store->get_status( $action_id ) ],
'args' => $action->get_args(),
'group' => $action->get_group(),
'log_entries' => $this->logger->get_logs( $action_id ),
'claim_id' => $this->store->get_claim_id( $action_id ),
'recurrence' => $this->get_recurrence( $action ),
'schedule' => $action->get_schedule(),
);
}
$this->set_pagination_args( array(
'total_items' => $total_items,
'per_page' => $per_page,
'total_pages' => ceil( $total_items / $per_page ),
) );
}
/**
* Prints the available statuses so the user can click to filter.
*/
protected function display_filter_by_status() {
$this->status_counts = $this->store->action_counts();
parent::display_filter_by_status();
}
/**
* Get the text to display in the search box on the list table.
*/
protected function get_search_box_button_text() {
return __( 'Search hook, args and claim ID', 'action-scheduler' );
}
/**
* {@inheritDoc}
*/
protected function get_per_page_option_name() {
return str_replace( '-', '_', $this->screen->id ) . '_per_page';
}
}

View File

@@ -1,68 +0,0 @@
<?php
// phpcs:ignoreFile
/**
* Class ActionScheduler_LogEntry
*/
class ActionScheduler_LogEntry {
/**
* @var int $action_id
*/
protected $action_id = '';
/**
* @var string $message
*/
protected $message = '';
/**
* @var Datetime $date
*/
protected $date;
/**
* Constructor
*
* @param mixed $action_id Action ID
* @param string $message Message
* @param Datetime $date Datetime object with the time when this log entry was created. If this parameter is
* not provided a new Datetime object (with current time) will be created.
*/
public function __construct( $action_id, $message, $date = null ) {
/*
* ActionScheduler_wpCommentLogger::get_entry() previously passed a 3rd param of $comment->comment_type
* to ActionScheduler_LogEntry::__construct(), goodness knows why, and the Follow-up Emails plugin
* hard-codes loading its own version of ActionScheduler_wpCommentLogger with that out-dated method,
* goodness knows why, so we need to guard against that here instead of using a DateTime type declaration
* for the constructor's 3rd param of $date and causing a fatal error with older versions of FUE.
*/
if ( null !== $date && ! is_a( $date, 'DateTime' ) ) {
_doing_it_wrong( __METHOD__, 'The third parameter must be a valid DateTime instance, or null.', '2.0.0' );
$date = null;
}
$this->action_id = $action_id;
$this->message = $message;
$this->date = $date ? $date : new Datetime;
}
/**
* Returns the date when this log entry was created
*
* @return Datetime
*/
public function get_date() {
return $this->date;
}
public function get_action_id() {
return $this->action_id;
}
public function get_message() {
return $this->message;
}
}

Some files were not shown because too many files have changed in this diff Show More