Merge branch 'master' into update/17252

This commit is contained in:
Mike Jolley 2018-01-03 11:44:28 +00:00
commit 89c1f83f70
98 changed files with 9785 additions and 1711 deletions

2
.gitattributes vendored
View File

@ -4,7 +4,7 @@ CHANGELOG.txt export-ignore
composer.* export-ignore
Gruntfile.js export-ignore
package.json export-ignore
phpcs.ruleset.xml export-ignore
phpcs.xml export-ignore
phpunit.* export-ignore
README.md export-ignore
tests export-ignore

View File

@ -278,9 +278,6 @@ module.exports = function( grunt ) {
bin: 'vendor/bin/phpcs'
},
dist: {
options: {
standard: './phpcs.ruleset.xml'
},
src: [
'**/*.php', // Include all files
'!apigen/**', // Exclude apigen/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1946,9 +1946,23 @@ ul.wc_coupon_list_block {
padding: 0 !important;
height: 2em !important;
width: 2em;
overflow: hidden;
&::after {
@include icon_dashicons;
font-family: 'Dashicons';
speak: none;
font-weight: normal;
font-variant: normal;
text-transform: none;
-webkit-font-smoothing: antialiased;
margin: 0;
text-indent: 0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
text-align: center;
line-height: 1.85;
}

File diff suppressed because one or more lines are too long

View File

@ -1,203 +1,275 @@
.select2-container {
box-sizing: border-box;
display: inline-block;
margin: 0;
position: relative;
vertical-align: middle; }
.select2-container .select2-selection--single {
box-sizing: border-box;
display: inline-block;
margin: 0;
position: relative;
vertical-align: middle;
}
.select2-container .select2-selection--single {
box-sizing: border-box;
cursor: pointer;
display: block;
height: 28px;
height: 28px;
margin: 0 0 -4px;
user-select: none;
-webkit-user-select: none; }
.select2-container .select2-selection--single .select2-selection__rendered {
display: block;
padding-left: 8px;
padding-right: 20px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap; }
.select2-container .select2-selection--single .select2-selection__clear {
position: relative; }
.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered {
-webkit-user-select: none;
}
.select2-container .select2-selection--single .select2-selection__rendered {
display: block;
padding-left: 8px;
padding-right: 20px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.select2-container .select2-selection--single .select2-selection__clear {
position: relative;
}
.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered {
padding-right: 8px;
padding-left: 20px; }
.select2-container .select2-selection--multiple {
padding-left: 20px;
}
.select2-container .select2-selection--multiple {
box-sizing: border-box;
cursor: pointer;
display: block;
min-height: 32px;
user-select: none;
-webkit-user-select: none; }
.select2-container .select2-selection--multiple .select2-selection__rendered {
display: inline-block;
overflow: hidden;
padding-left: 8px;
text-overflow: ellipsis;
white-space: nowrap; }
.select2-container .select2-search--inline {
float: left; }
.select2-container .select2-search--inline .select2-search__field {
box-sizing: border-box;
border: none;
font-size: 100%;
margin-top: 5px;
padding: 0; }
.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button {
-webkit-appearance: none; }
-webkit-user-select: none;
}
.select2-container .select2-selection--multiple .select2-selection__rendered {
display: inline-block;
overflow: hidden;
padding-left: 8px;
text-overflow: ellipsis;
white-space: nowrap;
}
.select2-container .select2-search--inline {
float: left;
padding: 0;
}
.select2-container .select2-search--inline .select2-search__field {
box-sizing: border-box;
border: none;
font-size: 100%;
margin: 0;
padding: 0;
}
.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button {
-webkit-appearance: none;
}
.select2-dropdown {
background-color: white;
border: 1px solid #aaa;
border-radius: 4px;
box-sizing: border-box;
display: block;
position: absolute;
left: -100000px;
width: 100%;
z-index: 1051; }
background-color: white;
border: 1px solid #aaa;
border-radius: 4px;
box-sizing: border-box;
display: block;
position: absolute;
left: -100000px;
width: 100%;
z-index: 1051;
}
.select2-results {
display: block; }
display: block;
}
.select2-results__options {
list-style: none;
margin: 0;
padding: 0; }
list-style: none;
margin: 0;
padding: 0;
}
.select2-results__option {
padding: 6px;
user-select: none;
-webkit-user-select: none; }
.select2-results__option[data-selected],
.select2-results__option[aria-selected] {
cursor: pointer; }
padding: 6px;
user-select: none;
-webkit-user-select: none;
}
.select2-results__option[data-selected],
.select2-results__option[aria-selected] {
cursor: pointer;
}
.select2-container--open .select2-dropdown {
left: 0; }
left: 0;
}
.select2-container--open .select2-dropdown--above {
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0; }
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.select2-container--open .select2-dropdown--below {
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0; }
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.select2-search--dropdown {
display: block;
padding: 4px; }
.select2-search--dropdown .select2-search__field {
display: block;
padding: 4px;
}
.select2-search--dropdown .select2-search__field {
padding: 4px;
width: 100%;
box-sizing: border-box; }
.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button {
-webkit-appearance: none; }
.select2-search--dropdown.select2-search--hide {
display: none; }
box-sizing: border-box;
}
.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button {
-webkit-appearance: none;
}
.select2-search--dropdown.select2-search--hide {
display: none;
}
.select2-close-mask {
border: 0;
margin: 0;
padding: 0;
display: block;
position: fixed;
left: 0;
top: 0;
min-height: 100%;
min-width: 100%;
height: auto;
width: auto;
opacity: 0;
z-index: 99;
background-color: #fff;
filter: alpha(opacity=0); }
border: 0;
margin: 0;
padding: 0;
display: block;
position: fixed;
left: 0;
top: 0;
min-height: 100%;
min-width: 100%;
height: auto;
width: auto;
opacity: 0;
z-index: 99;
background-color: #fff;
filter: alpha(opacity=0);
}
.select2-hidden-accessible {
border: 0 !important;
clip: rect(0 0 0 0) !important;
height: 1px !important;
margin: -1px !important;
overflow: hidden !important;
padding: 0 !important;
position: absolute !important;
width: 1px !important; }
border: 0 !important;
clip: rect(0 0 0 0) !important;
height: 1px !important;
margin: -1px !important;
overflow: hidden !important;
padding: 0 !important;
position: absolute !important;
width: 1px !important;
}
.select2-container--default .select2-selection--single {
background-color: #fff;
border: 1px solid #aaa;
border-radius: 4px; }
.select2-container--default .select2-selection--single .select2-selection__rendered {
background-color: #fff;
border: 1px solid #aaa;
border-radius: 4px;
}
.select2-container--default .select2-selection--single .select2-selection__rendered {
color: #444;
line-height: 28px; }
.select2-container--default .select2-selection--single .select2-selection__clear {
line-height: 28px;
}
.select2-container--default .select2-selection--single .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold; }
.select2-container--default .select2-selection--single .select2-selection__placeholder {
color: #999; }
.select2-container--default .select2-selection--single .select2-selection__arrow {
font-weight: bold;
}
.select2-container--default .select2-selection--single .select2-selection__placeholder {
color: #999;
}
.select2-container--default .select2-selection--single .select2-selection__arrow {
height: 26px;
position: absolute;
top: 1px;
right: 1px;
width: 20px; }
.select2-container--default .select2-selection--single .select2-selection__arrow b {
border-color: #888 transparent transparent transparent;
border-style: solid;
border-width: 5px 4px 0 4px;
height: 0;
left: 50%;
margin-left: -4px;
margin-top: -2px;
position: absolute;
top: 50%;
width: 0; }
width: 20px;
}
.select2-container--default .select2-selection--single .select2-selection__arrow b {
border-color: #888 transparent transparent transparent;
border-style: solid;
border-width: 5px 4px 0 4px;
height: 0;
left: 50%;
margin-left: -4px;
margin-top: -2px;
position: absolute;
top: 50%;
width: 0;
}
.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear {
float: left; }
float: left;
}
.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow {
left: 1px;
right: auto; }
left: 1px;
right: auto;
}
.select2-container--default.select2-container--disabled .select2-selection--single {
background-color: #eee;
cursor: default; }
.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear {
display: none; }
background-color: #eee;
cursor: default;
}
.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear {
display: none;
}
.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
border-color: transparent transparent #888 transparent;
border-width: 0 4px 5px 4px; }
border-color: transparent transparent #888 transparent;
border-width: 0 4px 5px 4px;
}
.select2-container--default .select2-selection--multiple {
background-color: white;
border: 1px solid #aaa;
border-radius: 4px;
cursor: text; }
.select2-container--default .select2-selection--multiple .select2-selection__rendered {
background-color: white;
border: 1px solid #aaa;
border-radius: 4px;
cursor: text;
}
.select2-container--default .select2-selection--multiple .select2-selection__rendered {
box-sizing: border-box;
list-style: none;
margin: 0;
padding: 0 5px;
width: 100%; }
.select2-container--default .select2-selection--multiple .select2-selection__rendered li {
list-style: none; }
.select2-container--default .select2-selection--multiple .select2-selection__placeholder {
width: 100%;
}
.select2-container--default .select2-selection--multiple .select2-selection__rendered li {
list-style: none;
margin: 5px 5px 0 0;
&:before {
content: '';
display: none;
}
}
.select2-container--default .select2-selection--multiple .select2-selection__placeholder {
color: #999;
margin-top: 5px;
float: left; }
.select2-container--default .select2-selection--multiple .select2-selection__clear {
float: left;
}
.select2-container--default .select2-selection--multiple .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold;
margin-top: 5px;
margin-right: 10px; }
.select2-container--default .select2-selection--multiple .select2-selection__choice {
margin-right: 10px;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice {
background-color: #e4e4e4;
border: 1px solid #aaa;
border-radius: 4px;
@ -205,121 +277,169 @@
float: left;
margin-right: 5px;
margin-top: 5px;
padding: 0 5px; }
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
padding: 0 5px;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
color: #999;
cursor: pointer;
display: inline-block;
font-weight: bold;
margin-right: 2px; }
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
color: #333; }
margin-right: 2px;
}
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline {
float: right; }
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
color: #333;
}
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder,
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline {
float: right;
}
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
margin-left: 5px;
margin-right: auto; }
margin-left: 5px;
margin-right: auto;
}
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
margin-left: 2px;
margin-right: auto; }
margin-left: 2px;
margin-right: auto;
}
.select2-container--default.select2-container--focus .select2-selection--multiple {
border: solid black 1px;
outline: 0; }
border: solid black 1px;
outline: 0;
}
.select2-container--default.select2-container--disabled .select2-selection--multiple {
background-color: #eee;
cursor: default; }
background-color: #eee;
cursor: default;
}
.select2-container--default.select2-container--disabled .select2-selection__choice__remove {
display: none; }
display: none;
}
.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple {
border-top-left-radius: 0;
border-top-right-radius: 0; }
.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,
.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0; }
.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,
.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.select2-container--default .select2-search--dropdown .select2-search__field {
border: 1px solid #aaa; }
border: 1px solid #aaa;
}
.select2-container--default .select2-search--inline .select2-search__field {
background: transparent;
border: none;
outline: 0;
box-shadow: none;
-webkit-appearance: textfield; }
background: transparent;
border: none;
outline: 0;
box-shadow: none;
-webkit-appearance: textfield;
}
.select2-container--default .select2-results > .select2-results__options {
max-height: 200px;
overflow-y: auto; }
.select2-container--default .select2-results>.select2-results__options {
max-height: 200px;
overflow-y: auto;
}
.select2-container--default .select2-results__option[role=group] {
padding: 0; }
padding: 0;
}
.select2-container--default .select2-results__option[aria-disabled=true] {
color: #999; }
color: #999;
}
.select2-container--default .select2-results__option[data-selected=true],
.select2-container--default .select2-results__option[aria-selected=true] {
background-color: #ddd; }
background-color: #ddd;
}
.select2-container--default .select2-results__option .select2-results__option {
padding-left: 1em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__group {
padding-left: 0; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option {
padding-left: 1em;
}
.select2-container--default .select2-results__option .select2-results__option .select2-results__group {
padding-left: 0;
}
.select2-container--default .select2-results__option .select2-results__option .select2-results__option {
margin-left: -1em;
padding-left: 2em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -2em;
padding-left: 3em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -3em;
padding-left: 4em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -4em;
padding-left: 5em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -5em;
padding-left: 6em; }
padding-left: 2em;
}
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -2em;
padding-left: 3em;
}
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -3em;
padding-left: 4em;
}
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -4em;
padding-left: 5em;
}
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -5em;
padding-left: 6em;
}
.select2-container--default .select2-results__option--highlighted[data-selected],
.select2-container--default .select2-results__option--highlighted[aria-selected] {
background-color: #0073aa;
color: white; }
background-color: #0073aa;
color: white;
}
.select2-container--default .select2-results__group {
cursor: default;
display: block;
padding: 6px; }
cursor: default;
display: block;
padding: 6px;
}
.select2-container--classic .select2-selection--single {
background-color: #f7f7f7;
border: 1px solid #aaa;
border-radius: 4px;
outline: 0;
background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
.select2-container--classic .select2-selection--single:focus {
border: 1px solid #0073aa; }
.select2-container--classic .select2-selection--single .select2-selection__rendered {
background-color: #f7f7f7;
border: 1px solid #aaa;
border-radius: 4px;
outline: 0;
background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0);
}
.select2-container--classic .select2-selection--single:focus {
border: 1px solid #0073aa;
}
.select2-container--classic .select2-selection--single .select2-selection__rendered {
color: #444;
line-height: 28px; }
.select2-container--classic .select2-selection--single .select2-selection__clear {
line-height: 28px;
}
.select2-container--classic .select2-selection--single .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold;
margin-right: 10px; }
.select2-container--classic .select2-selection--single .select2-selection__placeholder {
color: #999; }
.select2-container--classic .select2-selection--single .select2-selection__arrow {
margin-right: 10px;
}
.select2-container--classic .select2-selection--single .select2-selection__placeholder {
color: #999;
}
.select2-container--classic .select2-selection--single .select2-selection__arrow {
background-color: #ddd;
border: none;
border-left: 1px solid #aaa;
@ -332,71 +452,91 @@
width: 20px;
background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); }
.select2-container--classic .select2-selection--single .select2-selection__arrow b {
border-color: #888 transparent transparent transparent;
border-style: solid;
border-width: 5px 4px 0 4px;
height: 0;
left: 50%;
margin-left: -4px;
margin-top: -2px;
position: absolute;
top: 50%;
width: 0; }
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0);
}
.select2-container--classic .select2-selection--single .select2-selection__arrow b {
border-color: #888 transparent transparent transparent;
border-style: solid;
border-width: 5px 4px 0 4px;
height: 0;
left: 50%;
margin-left: -4px;
margin-top: -2px;
position: absolute;
top: 50%;
width: 0;
}
.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear {
float: left; }
float: left;
}
.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow {
border: none;
border-right: 1px solid #aaa;
border-radius: 0;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
left: 1px;
right: auto; }
border: none;
border-right: 1px solid #aaa;
border-radius: 0;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
left: 1px;
right: auto;
}
.select2-container--classic.select2-container--open .select2-selection--single {
border: 1px solid #0073aa; }
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow {
border: 1px solid #0073aa;
}
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow {
background: transparent;
border: none; }
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b {
border-color: transparent transparent #888 transparent;
border-width: 0 4px 5px 4px; }
border: none;
}
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b {
border-color: transparent transparent #888 transparent;
border-width: 0 4px 5px 4px;
}
.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single {
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0;
background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0;
background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0);
}
.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single {
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); }
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0);
}
.select2-container--classic .select2-selection--multiple {
background-color: white;
border: 1px solid #aaa;
border-radius: 4px;
cursor: text;
outline: 0; }
.select2-container--classic .select2-selection--multiple:focus {
border: 1px solid #0073aa; }
.select2-container--classic .select2-selection--multiple .select2-selection__rendered {
background-color: white;
border: 1px solid #aaa;
border-radius: 4px;
cursor: text;
outline: 0;
}
.select2-container--classic .select2-selection--multiple:focus {
border: 1px solid #0073aa;
}
.select2-container--classic .select2-selection--multiple .select2-selection__rendered {
list-style: none;
margin: 0;
padding: 0 5px; }
.select2-container--classic .select2-selection--multiple .select2-selection__clear {
display: none; }
.select2-container--classic .select2-selection--multiple .select2-selection__choice {
padding: 0 5px;
}
.select2-container--classic .select2-selection--multiple .select2-selection__clear {
display: none;
}
.select2-container--classic .select2-selection--multiple .select2-selection__choice {
background-color: #e4e4e4;
border: 1px solid #aaa;
border-radius: 4px;
@ -404,77 +544,99 @@
float: left;
margin-right: 5px;
margin-top: 5px;
padding: 0 5px; }
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove {
padding: 0 5px;
}
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove {
color: #888;
cursor: pointer;
display: inline-block;
font-weight: bold;
margin-right: 2px; }
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover {
color: #555; }
margin-right: 2px;
}
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover {
color: #555;
}
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
float: right; }
float: right;
}
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
margin-left: 5px;
margin-right: auto; }
margin-left: 5px;
margin-right: auto;
}
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
margin-left: 2px;
margin-right: auto; }
margin-left: 2px;
margin-right: auto;
}
.select2-container--classic.select2-container--open .select2-selection--multiple {
border: 1px solid #0073aa; }
border: 1px solid #0073aa;
}
.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple {
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0; }
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple {
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0; }
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.select2-container--classic .select2-search--dropdown .select2-search__field {
border: 1px solid #aaa;
outline: 0; }
border: 1px solid #aaa;
outline: 0;
}
.select2-container--classic .select2-search--inline .select2-search__field {
outline: 0;
box-shadow: none; }
outline: 0;
box-shadow: none;
}
.select2-container--classic .select2-dropdown {
background-color: white;
border: 1px solid transparent; }
background-color: white;
border: 1px solid transparent;
}
.select2-container--classic .select2-dropdown--above {
border-bottom: none; }
border-bottom: none;
}
.select2-container--classic .select2-dropdown--below {
border-top: none; }
border-top: none;
}
.select2-container--classic .select2-results > .select2-results__options {
max-height: 200px;
overflow-y: auto; }
.select2-container--classic .select2-results>.select2-results__options {
max-height: 200px;
overflow-y: auto;
}
.select2-container--classic .select2-results__option[role=group] {
padding: 0; }
padding: 0;
}
.select2-container--classic .select2-results__option[aria-disabled=true] {
color: grey; }
color: grey;
}
.select2-container--classic .select2-results__option--highlighted[data-selected],
.select2-container--classic .select2-results__option--highlighted[aria-selected] {
background-color: #3875d7;
color: white; }
background-color: #3875d7;
color: white;
}
.select2-container--classic .select2-results__group {
cursor: default;
display: block;
padding: 6px; }
cursor: default;
display: block;
padding: 6px;
}
.select2-container--classic.select2-container--open .select2-dropdown {
border-color: #0073aa; }
border-color: #0073aa;
}

View File

@ -1036,10 +1036,10 @@ p.jetpack-terms {
}
}
.wc-wizard-service-setting-stripe_email, .wc-wizard-service-setting-ppec_paypal_api_subject {
.wc-wizard-service-setting-stripe_email, .wc-wizard-service-setting-ppec_paypal_email {
margin-top: 0.75em;
label.stripe_email, label.ppec_paypal_api_subject {
label.stripe_email, label.ppec_paypal_email {
position: absolute;
margin: -1px;
padding: 0;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1500,7 +1500,7 @@ p.demo_store,
li {
float: left;
padding: 0 1px 1px 0;
padding: 0 1em 1px 1px;
list-style: none;
a {
@ -1509,6 +1509,8 @@ p.demo_store,
&::before {
@include iconbefore( '\e013' );
color: $red;
vertical-align: inherit;
margin-right: .5em;
}
}
}

View File

@ -1,4 +1,4 @@
/*global woocommerce_admin_meta_boxes, woocommerce_admin, accounting, woocommerce_admin_meta_boxes_order */
/*global woocommerce_admin_meta_boxes, woocommerce_admin, accounting, woocommerce_admin_meta_boxes_order, wcSetClipboard, wcClearClipboard */
jQuery( function ( $ ) {
/**
@ -1274,7 +1274,10 @@ jQuery( function ( $ ) {
init: function() {
$( '.order_download_permissions' )
.on( 'click', 'button.grant_access', this.grant_access )
.on( 'click', 'button.revoke_access', this.revoke_access );
.on( 'click', 'button.revoke_access', this.revoke_access )
.on( 'click', '#copy-download-link', this.copy_link )
.on( 'aftercopy', '#copy-download-link', this.copy_success )
.on( 'aftercopyfailure', '#copy-download-link', this.copy_fail );
},
grant_access: function() {
@ -1355,6 +1358,43 @@ jQuery( function ( $ ) {
}
}
return false;
},
/**
* Copy download link.
*
* @param {Object} evt Copy event.
*/
copy_link: function( evt ) {
wcClearClipboard();
wcSetClipboard( $( this ).attr( 'href' ), $( this ) );
evt.preventDefault();
},
/**
* Display a "Copied!" tip when success copying
*/
copy_success: function() {
$( this ).tipTip({
'attribute': 'data-tip',
'activation': 'focus',
'fadeIn': 50,
'fadeOut': 50,
'delay': 0
}).focus();
},
/**
* Displays the copy error message when failure copying.
*/
copy_fail: function() {
$( this ).tipTip({
'attribute': 'data-tip-failed',
'activation': 'focus',
'fadeIn': 50,
'fadeOut': 50,
'delay': 0
}).focus();
}
};

View File

@ -62,9 +62,11 @@ jQuery( function( $ ) {
*/
variable_manage_stock: function() {
$( this ).closest( '.woocommerce_variation' ).find( '.show_if_variation_manage_stock' ).hide();
$( this ).closest( '.woocommerce_variation' ).find( '.hide_if_variation_manage_stock' ).show();
if ( $( this ).is( ':checked' ) ) {
$( this ).closest( '.woocommerce_variation' ).find( '.show_if_variation_manage_stock' ).show();
$( this ).closest( '.woocommerce_variation' ).find( '.hide_if_variation_manage_stock' ).hide();
}
},

View File

@ -88,7 +88,7 @@ jQuery( function( $ ) {
return false;
});
// PRODUCT TYPE SPECIFIC OPTIONS.
// Product type specific options.
$( 'select#product-type' ).change( function() {
// Get value.
@ -228,7 +228,7 @@ jQuery( function( $ ) {
return false;
});
// STOCK OPTIONS.
// Stock options.
$( 'input#_manage_stock' ).change( function() {
if ( $( this ).is( ':checked' ) ) {
$( 'div.stock_fields' ).show();
@ -241,7 +241,7 @@ jQuery( function( $ ) {
}
}).change();
// DATE PICKER FIELDS.
// Date picker fields.
function date_picker_select( datepicker ) {
var option = $( datepicker ).next().is( '.hasDatepicker' ) ? 'minDate' : 'maxDate',
otherDateField = 'minDate' === option ? $( datepicker ).next() : $( datepicker ).prev(),
@ -264,7 +264,7 @@ jQuery( function( $ ) {
$( this ).find( 'input' ).each( function() { date_picker_select( $( this ) ); } );
});
// ATTRIBUTE TABLES.
// Attribute Tables.
// Initial order.
var woocommerce_attribute_items = $( '.product_attributes' ).find( '.woocommerce_attribute' ).get();

View File

@ -22,19 +22,27 @@
*/
productExportForm.prototype.onSubmit = function( event ) {
event.preventDefault();
var currentDate = new Date(),
day = currentDate.getDate(),
month = currentDate.getMonth() + 1,
year = currentDate.getFullYear(),
timestamp = currentDate.getTime(),
filename = 'wc-product-export-' + day + '-' + month + '-' + year + '-' + timestamp + '.csv';
event.data.productExportForm.$form.addClass( 'woocommerce-exporter__exporting' );
event.data.productExportForm.$form.find('.woocommerce-exporter-progress').val( 0 );
event.data.productExportForm.$form.find('.woocommerce-exporter-button').prop( 'disabled', true );
event.data.productExportForm.processStep( 1, $( this ).serialize(), '' );
event.data.productExportForm.processStep( 1, $( this ).serialize(), '', filename );
};
/**
* Process the current export step.
*/
productExportForm.prototype.processStep = function( step, data, columns ) {
var $this = this,
productExportForm.prototype.processStep = function( step, data, columns, filename ) {
var $this = this,
selected_columns = $( '.woocommerce-exporter-columns' ).val(),
export_meta = $( '#woocommerce-exporter-meta:checked' ).length ? 1 : 0,
export_meta = $( '#woocommerce-exporter-meta:checked' ).length ? 1: 0,
export_types = $( '.woocommerce-exporter-types' ).val();
$.ajax( {
@ -48,6 +56,7 @@
selected_columns : selected_columns,
export_meta : export_meta,
export_types : export_types,
filename : filename,
security : wc_product_export_params.export_nonce
},
dataType: 'json',
@ -62,7 +71,7 @@
}, 2000 );
} else {
$this.$form.find('.woocommerce-exporter-progress').val( response.data.percentage );
$this.processStep( parseInt( response.data.step, 10 ), data, response.data.columns );
$this.processStep( parseInt( response.data.step, 10 ), data, response.data.columns, filename );
}
}

View File

@ -130,14 +130,14 @@ jQuery( function( $ ) {
.find( 'input.payment-email-input' )
.prop( 'required', true );
$( this ).closest( '.wc-wizard-service-settings' )
.find( '.wc-wizard-service-setting-stripe_email, .wc-wizard-service-setting-ppec_paypal_api_subject' )
.find( '.wc-wizard-service-setting-stripe_email, .wc-wizard-service-setting-ppec_paypal_email' )
.show();
} else {
$( this ).closest( '.wc-wizard-service-settings' )
.find( 'input.payment-email-input' )
.prop( 'required', false );
$( this ).closest( '.wc-wizard-service-settings' )
.find( '.wc-wizard-service-setting-stripe_email, .wc-wizard-service-setting-ppec_paypal_api_subject' )
.find( '.wc-wizard-service-setting-stripe_email, .wc-wizard-service-setting-ppec_paypal_email' )
.hide();
}
} ).find( 'input#stripe_create_account, input#ppec_paypal_reroute_requests' ).change();

View File

@ -138,23 +138,17 @@ jQuery( function( $ ) {
var $target = this.$target,
gallery = this;
$target.flexslider( {
selector: '.woocommerce-product-gallery__wrapper > .woocommerce-product-gallery__image',
animation: wc_single_product_params.flexslider.animation,
smoothHeight: wc_single_product_params.flexslider.smoothHeight,
directionNav: wc_single_product_params.flexslider.directionNav,
controlNav: wc_single_product_params.flexslider.controlNav,
slideshow: wc_single_product_params.flexslider.slideshow,
animationSpeed: wc_single_product_params.flexslider.animationSpeed,
animationLoop: wc_single_product_params.flexslider.animationLoop, // Breaks photoswipe pagination if true.
allowOneSlide: wc_single_product_params.flexslider.allowOneSlide,
var options = $.extend( {
selector: '.woocommerce-product-gallery__wrapper > .woocommerce-product-gallery__image',
start: function() {
$target.css( 'opacity', 1 );
},
after: function( slider ) {
gallery.initZoomForTarget( gallery.$images.eq( slider.currentSlide ) );
}
} );
}, wc_single_product_params.flexslider );
$target.flexslider( options );
// Trigger resize after main image loads to ensure correct gallery size.
$( '.woocommerce-product-gallery__wrapper .woocommerce-product-gallery__image:eq(0) .wp-post-image' ).one( 'load', function() {

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{
"name": "woocommerce/woocommerce",
"description": "An e-commerce toolkit that helps you sell anything. Beautifully.",
"description": "An eCommerce toolkit that helps you sell anything. Beautifully.",
"homepage": "https://woocommerce.com/",
"type": "wordpress-plugin",
"license": "GPL-2.0+",
@ -11,7 +11,8 @@
"squizlabs/php_codesniffer": "*",
"wp-coding-standards/wpcs": "^0.14",
"phpunit/phpunit": "6.2.3",
"woocommerce/woocommerce-git-hooks": "1.0.3",
"woocommerce/woocommerce-git-hooks": "*",
"woocommerce/woocommerce-sniffs": "*",
"wimg/php-compatibility": "^8.0",
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.3"
},
@ -32,10 +33,10 @@
"phpunit"
],
"phpcs": [
"phpcs -s -p --standard=./phpcs.ruleset.xml"
"phpcs -s -p"
],
"phpcbf": [
"phpcbf -p --standard=./phpcs.ruleset.xml"
"phpcbf -p"
]
},
"extra": {

146
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "f8dbe5807f695e87ad3453a8b629b6bf",
"content-hash": "9e4cf8ae38469f0ca73e43f81be7b998",
"packages": [
{
"name": "composer/installers",
@ -127,16 +127,16 @@
"packages-dev": [
{
"name": "dealerdirect/phpcodesniffer-composer-installer",
"version": "v0.4.3",
"version": "v0.4.4",
"source": {
"type": "git",
"url": "https://github.com/DealerDirect/phpcodesniffer-composer-installer.git",
"reference": "63c0ec0ac286d31651d3c70e5bf76ad87db3ba23"
"url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git",
"reference": "2e41850d5f7797cbb1af7b030d245b3b24e63a08"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/DealerDirect/phpcodesniffer-composer-installer/zipball/63c0ec0ac286d31651d3c70e5bf76ad87db3ba23",
"reference": "63c0ec0ac286d31651d3c70e5bf76ad87db3ba23",
"url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/2e41850d5f7797cbb1af7b030d245b3b24e63a08",
"reference": "2e41850d5f7797cbb1af7b030d245b3b24e63a08",
"shasum": ""
},
"require": {
@ -191,7 +191,7 @@
"stylecheck",
"tests"
],
"time": "2017-09-18T07:49:36+00:00"
"time": "2017-12-06T16:27:17+00:00"
},
{
"name": "doctrine/instantiator",
@ -450,29 +450,35 @@
},
{
"name": "phpdocumentor/reflection-docblock",
"version": "4.1.1",
"version": "4.2.0",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
"reference": "2d3d238c433cf69caeb4842e97a3223a116f94b2"
"reference": "66465776cfc249844bde6d117abff1d22e06c2da"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/2d3d238c433cf69caeb4842e97a3223a116f94b2",
"reference": "2d3d238c433cf69caeb4842e97a3223a116f94b2",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/66465776cfc249844bde6d117abff1d22e06c2da",
"reference": "66465776cfc249844bde6d117abff1d22e06c2da",
"shasum": ""
},
"require": {
"php": "^7.0",
"phpdocumentor/reflection-common": "^1.0@dev",
"phpdocumentor/reflection-common": "^1.0.0",
"phpdocumentor/type-resolver": "^0.4.0",
"webmozart/assert": "^1.0"
},
"require-dev": {
"mockery/mockery": "^0.9.4",
"phpunit/phpunit": "^4.4"
"doctrine/instantiator": "~1.0.5",
"mockery/mockery": "^1.0",
"phpunit/phpunit": "^6.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.x-dev"
}
},
"autoload": {
"psr-4": {
"phpDocumentor\\Reflection\\": [
@ -491,7 +497,7 @@
}
],
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
"time": "2017-08-30T18:51:59+00:00"
"time": "2017-11-27T17:38:31+00:00"
},
{
"name": "phpdocumentor/type-resolver",
@ -542,16 +548,16 @@
},
{
"name": "phpspec/prophecy",
"version": "v1.7.2",
"version": "1.7.3",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
"reference": "c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6"
"reference": "e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6",
"reference": "c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf",
"reference": "e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf",
"shasum": ""
},
"require": {
@ -563,7 +569,7 @@
},
"require-dev": {
"phpspec/phpspec": "^2.5|^3.2",
"phpunit/phpunit": "^4.8 || ^5.6.5"
"phpunit/phpunit": "^4.8.35 || ^5.7"
},
"type": "library",
"extra": {
@ -601,20 +607,20 @@
"spy",
"stub"
],
"time": "2017-09-04T11:05:03+00:00"
"time": "2017-11-24T13:59:53+00:00"
},
{
"name": "phpunit/php-code-coverage",
"version": "5.2.3",
"version": "5.3.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "8e1d2397d8adf59a3f12b2878a3aaa66d1ab189d"
"reference": "661f34d0bd3f1a7225ef491a70a020ad23a057a1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/8e1d2397d8adf59a3f12b2878a3aaa66d1ab189d",
"reference": "8e1d2397d8adf59a3f12b2878a3aaa66d1ab189d",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/661f34d0bd3f1a7225ef491a70a020ad23a057a1",
"reference": "661f34d0bd3f1a7225ef491a70a020ad23a057a1",
"shasum": ""
},
"require": {
@ -623,14 +629,13 @@
"php": "^7.0",
"phpunit/php-file-iterator": "^1.4.2",
"phpunit/php-text-template": "^1.2.1",
"phpunit/php-token-stream": "^2.0",
"phpunit/php-token-stream": "^2.0.1",
"sebastian/code-unit-reverse-lookup": "^1.0.1",
"sebastian/environment": "^3.0",
"sebastian/version": "^2.0.1",
"theseer/tokenizer": "^1.1"
},
"require-dev": {
"ext-xdebug": "^2.5",
"phpunit/phpunit": "^6.0"
},
"suggest": {
@ -639,7 +644,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.2.x-dev"
"dev-master": "5.3.x-dev"
}
},
"autoload": {
@ -654,7 +659,7 @@
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
@ -665,20 +670,20 @@
"testing",
"xunit"
],
"time": "2017-11-03T13:47:33+00:00"
"time": "2017-12-06T09:29:45+00:00"
},
{
"name": "phpunit/php-file-iterator",
"version": "1.4.2",
"version": "1.4.5",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
"reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5"
"reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
"reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4",
"reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4",
"shasum": ""
},
"require": {
@ -712,7 +717,7 @@
"filesystem",
"iterator"
],
"time": "2016-10-03T07:40:28+00:00"
"time": "2017-11-27T13:52:08+00:00"
},
{
"name": "phpunit/php-text-template",
@ -806,16 +811,16 @@
},
{
"name": "phpunit/php-token-stream",
"version": "2.0.1",
"version": "2.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
"reference": "9a02332089ac48e704c70f6cefed30c224e3c0b0"
"reference": "791198a2c6254db10131eecfe8c06670700904db"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/9a02332089ac48e704c70f6cefed30c224e3c0b0",
"reference": "9a02332089ac48e704c70f6cefed30c224e3c0b0",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db",
"reference": "791198a2c6254db10131eecfe8c06670700904db",
"shasum": ""
},
"require": {
@ -851,7 +856,7 @@
"keywords": [
"tokenizer"
],
"time": "2017-08-20T05:47:52+00:00"
"time": "2017-11-27T05:48:46+00:00"
},
{
"name": "phpunit/phpunit",
@ -1557,16 +1562,16 @@
},
{
"name": "squizlabs/php_codesniffer",
"version": "3.1.1",
"version": "3.2.2",
"source": {
"type": "git",
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
"reference": "d667e245d5dcd4d7bf80f26f2c947d476b66213e"
"reference": "d7c00c3000ac0ce79c96fcbfef86b49a71158cd1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/d667e245d5dcd4d7bf80f26f2c947d476b66213e",
"reference": "d667e245d5dcd4d7bf80f26f2c947d476b66213e",
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/d7c00c3000ac0ce79c96fcbfef86b49a71158cd1",
"reference": "d7c00c3000ac0ce79c96fcbfef86b49a71158cd1",
"shasum": ""
},
"require": {
@ -1604,7 +1609,7 @@
"phpcs",
"standards"
],
"time": "2017-10-16T22:40:25+00:00"
"time": "2017-12-19T21:44:46+00:00"
},
{
"name": "theseer/tokenizer",
@ -1750,16 +1755,16 @@
},
{
"name": "woocommerce/woocommerce-git-hooks",
"version": "1.0.3",
"version": "1.0.5",
"source": {
"type": "git",
"url": "https://github.com/woocommerce/woocommerce-git-hooks.git",
"reference": "a9ea000877a996c57862aa81f0e61c04d8973d7e"
"reference": "1e55118258e8487c68b17c06cfde3b48a692d9d4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/woocommerce/woocommerce-git-hooks/zipball/a9ea000877a996c57862aa81f0e61c04d8973d7e",
"reference": "a9ea000877a996c57862aa81f0e61c04d8973d7e",
"url": "https://api.github.com/repos/woocommerce/woocommerce-git-hooks/zipball/1e55118258e8487c68b17c06cfde3b48a692d9d4",
"reference": "1e55118258e8487c68b17c06cfde3b48a692d9d4",
"shasum": ""
},
"type": "scripts",
@ -1779,7 +1784,48 @@
}
],
"description": "WooCommerce Git Hooks",
"time": "2017-11-09T18:27:22+00:00"
"time": "2017-12-18T16:55:42+00:00"
},
{
"name": "woocommerce/woocommerce-sniffs",
"version": "0.0.1",
"source": {
"type": "git",
"url": "https://github.com/woocommerce/woocommerce-sniffs.git",
"reference": "383d5b361c1d7532ae1ca6156fd7619fd37bbc05"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/woocommerce/woocommerce-sniffs/zipball/383d5b361c1d7532ae1ca6156fd7619fd37bbc05",
"reference": "383d5b361c1d7532ae1ca6156fd7619fd37bbc05",
"shasum": ""
},
"require": {
"php": ">=7.0",
"squizlabs/php_codesniffer": "^3.0.2"
},
"suggest": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.3"
},
"type": "phpcodesniffer-standard",
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Claudio Sanches",
"email": "claudio@automattic.com"
}
],
"description": "WooCommerce sniffs",
"keywords": [
"phpcs",
"standards",
"woocommerce",
"wordpress"
],
"time": "2017-12-21T22:52:52+00:00"
},
{
"name": "wp-coding-standards/wpcs",

View File

@ -9888,6 +9888,10 @@ msgstr ""
msgid "Learn more about coupons"
msgstr ""
#: includes/admin/list-tables/class-wc-admin-list-table-coupons.php:49
msgid "Create your first coupon"
msgstr ""
#: includes/admin/list-tables/class-wc-admin-list-table-coupons.php:83
msgid "Code"
msgstr ""
@ -24106,7 +24110,7 @@ msgid "https://woocommerce.com/"
msgstr ""
#. Description of the plugin/theme
msgid "An e-commerce toolkit that helps you sell anything. Beautifully."
msgid "An eCommerce toolkit that helps you sell anything. Beautifully."
msgstr ""
#. Author of the plugin/theme

View File

@ -378,6 +378,26 @@ return array(
),
),
),
'MD' => array(
'currency_code' => 'MDL',
'currency_pos' => 'right_space',
'thousand_sep' => '.',
'decimal_sep' => ',',
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => 'MD',
'state' => '',
'rate' => '20.0000',
'name' => 'TVA',
'shipping' => true,
),
),
),
),
'NL' => array(
'currency_code' => 'EUR',
'currency_pos' => 'left',

58
i18n/states/MD.php Normal file
View File

@ -0,0 +1,58 @@
<?php
/**
* Moldova states
*
* For more details check:
* https://ro.wikipedia.org/wiki/Organizarea_administrativ-teritorial%C4%83_a_Republicii_Moldova
* https://ro.wikipedia.org/wiki/Raioanele_Republicii_Moldova
* https://en.wikipedia.org/wiki/ISO_3166-2:MD
* https://en.wikipedia.org/wiki/Romanian_alphabet#Unicode_and_HTML
*
* @author Alexander Minza
* @package WooCommerce/i18n
* @version 3.3.0
*/
global $states;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$states['MD'] = array(
'C' => __( 'Chi&#537;in&abreve;u', 'woocommerce' ),
'BL' => __( 'B&abreve;l&#539;i', 'woocommerce' ),
'AN' => __( 'Anenii Noi', 'woocommerce' ),
'BS' => __( 'Basarabeasca', 'woocommerce' ),
'BR' => __( 'Briceni', 'woocommerce' ),
'CH' => __( 'Cahul', 'woocommerce' ),
'CT' => __( 'Cantemir', 'woocommerce' ),
'CL' => __( 'C&abreve;l&abreve;ra&#537;i', 'woocommerce' ),
'CS' => __( 'C&abreve;u&#537;eni', 'woocommerce' ),
'CM' => __( 'Cimi&#537;lia', 'woocommerce' ),
'CR' => __( 'Criuleni', 'woocommerce' ),
'DN' => __( 'Dondu&#537;eni', 'woocommerce' ),
'DR' => __( 'Drochia', 'woocommerce' ),
'DB' => __( 'Dub&abreve;sari', 'woocommerce' ),
'ED' => __( 'Edine&#539;', 'woocommerce' ),
'FL' => __( 'F&abreve;le&#537;ti', 'woocommerce' ),
'FR' => __( 'Flore&#537;ti', 'woocommerce' ),
'GE' => __( 'UTA G&abreve;g&abreve;uzia', 'woocommerce' ),
'GL' => __( 'Glodeni', 'woocommerce' ),
'HN' => __( 'H&icirc;nce&#537;ti', 'woocommerce' ),
'IL' => __( 'Ialoveni', 'woocommerce' ),
'LV' => __( 'Leova', 'woocommerce' ),
'NS' => __( 'Nisporeni', 'woocommerce' ),
'OC' => __( 'Ocni&#539;a', 'woocommerce' ),
'OR' => __( 'Orhei', 'woocommerce' ),
'RZ' => __( 'Rezina', 'woocommerce' ),
'RS' => __( 'R&icirc;&#537;cani', 'woocommerce' ),
'SG' => __( 'S&icirc;ngerei', 'woocommerce' ),
'SR' => __( 'Soroca', 'woocommerce' ),
'ST' => __( 'Str&abreve;&#537;eni', 'woocommerce' ),
'SD' => __( '&#536;old&abreve;ne&#537;ti', 'woocommerce' ),
'SV' => __( '&#536;tefan Vod&abreve;', 'woocommerce' ),
'TR' => __( 'Taraclia', 'woocommerce' ),
'TL' => __( 'Telene&#537;ti', 'woocommerce' ),
'UN' => __( 'Ungheni', 'woocommerce' ),
);

View File

@ -1,12 +1,15 @@
<?php
/**
* Romania
* Romania states
*
* @author Automattic
* @category i18n
* @package WooCommerce/i18n
* @version 3.1.0
* For more details check:
* https://ro.wikipedia.org/wiki/Jude%C8%9Bele_Rom%C3%A2niei
*
* @author Automattic
* @package WooCommerce/i18n
* @version 3.1.0
*/
global $states;
if ( ! defined( 'ABSPATH' ) ) {
@ -14,46 +17,46 @@ if ( ! defined( 'ABSPATH' ) ) {
}
$states['RO'] = array(
'AB' => __( 'Alba' , 'woocommerce' ),
'AR' => __( 'Arad' , 'woocommerce' ),
'AG' => __( 'Arges' , 'woocommerce' ),
'BC' => __( 'Bacau' , 'woocommerce' ),
'BH' => __( 'Bihor' , 'woocommerce' ),
'BN' => __( 'Bistrita-Nasaud' , 'woocommerce' ),
'BT' => __( 'Botosani' , 'woocommerce' ),
'BR' => __( 'Braila' , 'woocommerce' ),
'BV' => __( 'Brasov' , 'woocommerce' ),
'B' => __( 'Bucuresti' , 'woocommerce' ),
'BZ' => __( 'Buzau' , 'woocommerce' ),
'CL' => __( 'Calarasi' , 'woocommerce' ),
'CS' => __( 'Caras-Severin' , 'woocommerce' ),
'CJ' => __( 'Cluj' , 'woocommerce' ),
'CT' => __( 'Constanta' , 'woocommerce' ),
'CV' => __( 'Covasna' , 'woocommerce' ),
'DB' => __( 'Dambovita' , 'woocommerce' ),
'DJ' => __( 'Dolj' , 'woocommerce' ),
'GL' => __( 'Galati' , 'woocommerce' ),
'GR' => __( 'Giurgiu' , 'woocommerce' ),
'GJ' => __( 'Gorj' , 'woocommerce' ),
'HR' => __( 'Harghita' , 'woocommerce' ),
'HD' => __( 'Hunedoara' , 'woocommerce' ),
'IL' => __( 'Ialomita' , 'woocommerce' ),
'IS' => __( 'Iasi' , 'woocommerce' ),
'IF' => __( 'Ilfov' , 'woocommerce' ),
'MM' => __( 'Maramures' , 'woocommerce' ),
'MH' => __( 'Mehedinti' , 'woocommerce' ),
'MS' => __( 'Mures' , 'woocommerce' ),
'NT' => __( 'Neamt' , 'woocommerce' ),
'OT' => __( 'Olt' , 'woocommerce' ),
'PH' => __( 'Prahova' , 'woocommerce' ),
'SJ' => __( 'Salaj' , 'woocommerce' ),
'SM' => __( 'Satu Mare' , 'woocommerce' ),
'SB' => __( 'Sibiu' , 'woocommerce' ),
'SV' => __( 'Suceava' , 'woocommerce' ),
'TR' => __( 'Teleorman' , 'woocommerce' ),
'TM' => __( 'Timis' , 'woocommerce' ),
'TL' => __( 'Tulcea' , 'woocommerce' ),
'VL' => __( 'Valcea' , 'woocommerce' ),
'VS' => __( 'Vaslui' , 'woocommerce' ),
'VN' => __( 'Vrancea' , 'woocommerce' ),
'AB' => __( 'Alba', 'woocommerce' ),
'AR' => __( 'Arad', 'woocommerce' ),
'AG' => __( 'Arge&#537;', 'woocommerce' ),
'BC' => __( 'Bac&abreve;u', 'woocommerce' ),
'BH' => __( 'Bihor', 'woocommerce' ),
'BN' => __( 'Bistri&#539;a-N&abreve;s&abreve;ud', 'woocommerce' ),
'BT' => __( 'Boto&#537;ani', 'woocommerce' ),
'BR' => __( 'Br&abreve;ila', 'woocommerce' ),
'BV' => __( 'Bra&#537;ov', 'woocommerce' ),
'B' => __( 'Bucure&#537;ti', 'woocommerce' ),
'BZ' => __( 'Buz&abreve;u', 'woocommerce' ),
'CL' => __( 'C&abreve;l&abreve;ra&#537;i', 'woocommerce' ),
'CS' => __( 'Cara&#537;-Severin', 'woocommerce' ),
'CJ' => __( 'Cluj', 'woocommerce' ),
'CT' => __( 'Constan&#539;a', 'woocommerce' ),
'CV' => __( 'Covasna', 'woocommerce' ),
'DB' => __( 'D&acirc;mbovi&#539;a', 'woocommerce' ),
'DJ' => __( 'Dolj', 'woocommerce' ),
'GL' => __( 'Gala&#539;i', 'woocommerce' ),
'GR' => __( 'Giurgiu', 'woocommerce' ),
'GJ' => __( 'Gorj', 'woocommerce' ),
'HR' => __( 'Harghita', 'woocommerce' ),
'HD' => __( 'Hunedoara', 'woocommerce' ),
'IL' => __( 'Ialomi&#539;a', 'woocommerce' ),
'IS' => __( 'Ia&#537;i', 'woocommerce' ),
'IF' => __( 'Ilfov', 'woocommerce' ),
'MM' => __( 'Maramure&#537;', 'woocommerce' ),
'MH' => __( 'Mehedin&#539;i', 'woocommerce' ),
'MS' => __( 'Mure&#537;', 'woocommerce' ),
'NT' => __( 'Neam&#539;', 'woocommerce' ),
'OT' => __( 'Olt', 'woocommerce' ),
'PH' => __( 'Prahova', 'woocommerce' ),
'SJ' => __( 'S&abreve;laj', 'woocommerce' ),
'SM' => __( 'Satu Mare', 'woocommerce' ),
'SB' => __( 'Sibiu', 'woocommerce' ),
'SV' => __( 'Suceava', 'woocommerce' ),
'TR' => __( 'Teleorman', 'woocommerce' ),
'TM' => __( 'Timi&#537;', 'woocommerce' ),
'TL' => __( 'Tulcea', 'woocommerce' ),
'VL' => __( 'V&acirc;lcea', 'woocommerce' ),
'VS' => __( 'Vaslui', 'woocommerce' ),
'VN' => __( 'Vrancea', 'woocommerce' ),
);

View File

@ -1,9 +1,4 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
<?php // @codingStandardsIgnoreLine.
/**
* Handle data for the current customers session
*
@ -11,23 +6,55 @@ if ( ! defined( 'ABSPATH' ) ) {
* @version 2.0.0
* @package WooCommerce/Abstracts
* @category Abstract Class
* @author WooThemes
* @author Automattic
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* WC_Session
*/
abstract class WC_Session {
/** @var int $_customer_id */
/**
* Customer ID.
*
* @var int $_customer_id Customer ID.
*/
protected $_customer_id;
/** @var array $_data */
/**
* Session Data.
*
* @var array $_data Data array.
*/
protected $_data = array();
/** @var bool $_dirty When something changes */
/**
* Dirty when the session needs saving.
*
* @var bool $_dirty When something changes
*/
protected $_dirty = false;
/**
* __get function.
* Init hooks and session data. Extended by child classes.
*
* @param mixed $key
* @since 3.3.0
*/
public function init() {}
/**
* Cleanup session data. Extended by child classes.
*/
public function cleanup_sessions() {}
/**
* Magic get method.
*
* @param mixed $key Key to get.
* @return mixed
*/
public function __get( $key ) {
@ -35,29 +62,29 @@ abstract class WC_Session {
}
/**
* __set function.
* Magic set method.
*
* @param mixed $key
* @param mixed $value
* @param mixed $key Key to set.
* @param mixed $value Value to set.
*/
public function __set( $key, $value ) {
$this->set( $key, $value );
}
/**
* __isset function.
*
* @param mixed $key
* @return bool
*/
/**
* Magic isset method.
*
* @param mixed $key Key to check.
* @return bool
*/
public function __isset( $key ) {
return isset( $this->_data[ sanitize_title( $key ) ] );
}
/**
* __unset function.
* Magic unset method.
*
* @param mixed $key
* @param mixed $key Key to unset.
*/
public function __unset( $key ) {
if ( isset( $this->_data[ $key ] ) ) {
@ -69,8 +96,8 @@ abstract class WC_Session {
/**
* Get a session variable.
*
* @param string $key
* @param mixed $default used if the session variable isn't set
* @param string $key Key to get.
* @param mixed $default used if the session variable isn't set.
* @return array|string value of session variable
*/
public function get( $key, $default = null ) {
@ -81,20 +108,19 @@ abstract class WC_Session {
/**
* Set a session variable.
*
* @param string $key
* @param mixed $value
* @param string $key Key to set.
* @param mixed $value Value to set.
*/
public function set( $key, $value ) {
if ( $value !== $this->get( $key ) ) {
$this->_data[ sanitize_key( $key ) ] = maybe_serialize( $value );
$this->_dirty = true;
$this->_dirty = true;
}
}
/**
* get_customer_id function.
* Get customer ID.
*
* @access public
* @return int
*/
public function get_customer_id() {

View File

@ -279,8 +279,9 @@ abstract class WC_Widget extends WP_Widget {
* Get current page URL with various filtering props supported by WC.
*
* @return string
* @since 3.3.0
*/
protected function get_page_base_url() {
protected function get_current_page_url() {
if ( defined( 'SHOP_IS_ON_FRONT' ) ) {
$link = home_url();
} elseif ( is_shop() ) {

View File

@ -238,7 +238,7 @@ class WC_Admin_Assets {
if ( in_array( str_replace( 'edit-', '', $screen_id ), wc_get_order_types( 'order-meta-boxes' ) ) ) {
$default_location = wc_get_customer_default_location();
wp_enqueue_script( 'wc-admin-order-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-order' . $suffix . '.js', array( 'wc-admin-meta-boxes', 'wc-backbone-modal', 'selectWoo' ), WC_VERSION );
wp_enqueue_script( 'wc-admin-order-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-order' . $suffix . '.js', array( 'wc-admin-meta-boxes', 'wc-backbone-modal', 'selectWoo', 'wc-clipboard' ), WC_VERSION );
wp_localize_script( 'wc-admin-order-meta-boxes', 'woocommerce_admin_meta_boxes_order', array(
'countries' => json_encode( array_merge( WC()->countries->get_allowed_country_states(), WC()->countries->get_shipping_country_states() ) ),
'i18n_select_state_text' => esc_attr__( 'Select an option&hellip;', 'woocommerce' ),

View File

@ -2,8 +2,6 @@
/**
* Init WooCommerce data exporters.
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin
* @version 3.1.0
*/
@ -95,6 +93,11 @@ class WC_Admin_Exporters {
if ( isset( $_GET['action'], $_GET['nonce'] ) && wp_verify_nonce( wp_unslash( $_GET['nonce'] ), 'product-csv' ) && 'download_product_csv' === wp_unslash( $_GET['action'] ) ) { // WPCS: input var ok, sanitization ok.
include_once( WC_ABSPATH . 'includes/export/class-wc-product-csv-exporter.php' );
$exporter = new WC_Product_CSV_Exporter();
if ( ! empty( $_GET['filename'] ) ) { // WPCS: input var ok.
$exporter->set_filename( wp_unslash( $_GET['filename'] ) ); // WPCS: input var ok, sanitization ok.
}
$exporter->export();
}
}
@ -130,14 +133,20 @@ class WC_Admin_Exporters {
$exporter->set_product_types_to_export( wp_unslash( $_POST['export_types'] ) ); // WPCS: input var ok, sanitization ok.
}
if ( ! empty( $_POST['filename'] ) ) { // WPCS: input var ok.
$exporter->set_filename( wp_unslash( $_POST['filename'] ) ); // WPCS: input var ok, sanitization ok.
}
$exporter->set_page( $step );
$exporter->generate_file();
$query_args = apply_filters( 'woocommerce_export_get_ajax_query_args', array( 'nonce' => wp_create_nonce( 'product-csv' ), 'action' => 'download_product_csv', 'filename' => $exporter->get_filename() ) );
if ( 100 === $exporter->get_percent_complete() ) {
wp_send_json_success( array(
'step' => 'done',
'percentage' => 100,
'url' => add_query_arg( array( 'nonce' => wp_create_nonce( 'product-csv' ), 'action' => 'download_product_csv' ), admin_url( 'edit.php?post_type=product&page=product_exporter' ) ),
'url' => add_query_arg( $query_args, admin_url( 'edit.php?post_type=product&page=product_exporter' ) ),
) );
} else {
wp_send_json_success( array(

View File

@ -83,7 +83,6 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
// Clear any unwanted data and flush rules.
add_option( 'woocommerce_queue_flush_rewrite_rules', 'true' );
delete_transient( 'woocommerce_cache_excluded_uris' );
WC()->query->init_query_vars();
WC()->query->add_endpoints();
@ -727,7 +726,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
}
break;
case 'select':
$allowed_values = empty( $option['options'] ) ? array() : array_keys( $option['options'] );
$allowed_values = empty( $option['options'] ) ? array() : array_map( 'strval', array_keys( $option['options'] ) );
if ( empty( $option['default'] ) && empty( $allowed_values ) ) {
$value = null;
break;

View File

@ -72,11 +72,23 @@ class WC_Admin_Setup_Wizard {
* and the store doesn't already have a WooCommerce compatible theme.
*/
protected function should_show_theme_extra() {
$is_default_theme = wc_is_active_theme( array(
'twentyseventeen',
'twentysixteen',
'twentyfifteen',
'twentyfourteen',
'twentythirteen',
'twentyeleven',
'twentytwelve',
'twentyten',
) );
$support_woocommerce = current_theme_supports( 'woocommerce' ) && ! $is_default_theme;
return (
current_user_can( 'install_themes' ) &&
current_user_can( 'switch_themes' ) &&
! is_multisite() &&
! current_theme_supports( 'woocommerce' )
! $support_woocommerce
);
}
@ -1056,7 +1068,7 @@ class WC_Admin_Setup_Wizard {
'US',
'CA',
'JP',
'UK',
'GB',
'AU',
);
return in_array( $country_code, $square_supported_countries, true );
@ -1075,16 +1087,11 @@ class WC_Admin_Setup_Wizard {
}
/**
* Simple array of "in cart" gateways to show in wizard.
* Array of all possible "in cart" gateways that can be offered.
*
* @return array
*/
protected function get_wizard_in_cart_payment_gateways() {
$country = WC()->countries->get_base_country();
$can_stripe = $this->is_stripe_supported_country( $country );
$should_display_klarna_checkout = $this->is_klarna_checkout_supported_country( $country );
$should_display_klarna_payments = $this->is_klarna_payments_supported_country( $country );
$should_display_square = $this->is_square_supported_country( $country ) && get_option( 'woocommerce_sell_in_person' );
protected function get_wizard_available_in_cart_payment_gateways() {
$user_email = $this->get_current_user_email();
$stripe_description = '<p>' . sprintf(
@ -1108,139 +1115,139 @@ class WC_Admin_Setup_Wizard {
'https://woocommerce.com/products/square/'
) . '</p>';
$stripe = array(
'name' => __( 'Stripe', 'woocommerce' ),
'image' => WC()->plugin_url() . '/assets/images/stripe.png',
'description' => $stripe_description,
'class' => $can_stripe ? 'checked' : '',
'repo-slug' => 'woocommerce-gateway-stripe',
'settings' => array(
'create_account' => array(
'label' => __( 'Create a new Stripe account for me', 'woocommerce' ),
'type' => 'checkbox',
'value' => 'yes',
'placeholder' => '',
'required' => false,
),
'email' => array(
'label' => __( 'Stripe email address:', 'woocommerce' ),
'type' => 'email',
'value' => $user_email,
'placeholder' => __( 'Stripe email address', 'woocommerce' ),
'description' => __( "Enter your email address and we'll handle account creation. WooCommerce Services and Jetpack will be installed and activated for you.", 'woocommerce' ),
'required' => true,
return array(
'stripe' => array(
'name' => __( 'Stripe', 'woocommerce' ),
'image' => WC()->plugin_url() . '/assets/images/stripe.png',
'description' => $stripe_description,
'class' => 'checked',
'repo-slug' => 'woocommerce-gateway-stripe',
'settings' => array(
'create_account' => array(
'label' => __( 'Create a new Stripe account for me', 'woocommerce' ),
'type' => 'checkbox',
'value' => 'yes',
'placeholder' => '',
'required' => false,
),
'email' => array(
'label' => __( 'Stripe email address:', 'woocommerce' ),
'type' => 'email',
'value' => $user_email,
'placeholder' => __( 'Stripe email address', 'woocommerce' ),
'description' => __( "Enter your email address and we'll handle account creation. WooCommerce Services and Jetpack will be installed and activated for you.", 'woocommerce' ),
'required' => true,
),
),
),
'enabled' => $can_stripe && ! ( $should_display_klarna_checkout || $should_display_klarna_payments || $should_display_square ),
'featured' => ! ( $should_display_klarna_checkout || $should_display_klarna_payments || $should_display_square ),
);
$ppec_paypal = array(
'name' => __( 'PayPal Express Checkout', 'woocommerce' ),
'image' => WC()->plugin_url() . '/assets/images/paypal.png',
'description' => $paypal_ec_description,
'class' => 'checked paypal-logo',
'repo-slug' => 'woocommerce-gateway-paypal-express-checkout',
'settings' => array(
'reroute_requests' => array(
'label' => __( 'Accept payments without linking a PayPal account', 'woocommerce' ),
'type' => 'checkbox',
'value' => 'yes',
'placeholder' => '',
'required' => false,
),
'api_subject' => array(
'label' => __( 'Direct payments to email address:', 'woocommerce' ),
'type' => 'email',
'value' => $user_email,
'placeholder' => __( 'Email address to receive payments', 'woocommerce' ),
'description' => __( "Enter your email address and we'll authenticate payments for you. WooCommerce Services and Jetpack will be installed and activated for you.", 'woocommerce' ),
'required' => true,
'ppec_paypal' => array(
'name' => __( 'PayPal Express Checkout', 'woocommerce' ),
'image' => WC()->plugin_url() . '/assets/images/paypal.png',
'description' => $paypal_ec_description,
'enabled' => true,
'class' => 'checked paypal-logo',
'repo-slug' => 'woocommerce-gateway-paypal-express-checkout',
'settings' => array(
'reroute_requests' => array(
'label' => __( 'Accept payments without linking a PayPal account', 'woocommerce' ),
'type' => 'checkbox',
'value' => 'yes',
'placeholder' => '',
'required' => false,
),
'email' => array(
'label' => __( 'Direct payments to email address:', 'woocommerce' ),
'type' => 'email',
'value' => $user_email,
'placeholder' => __( 'Email address to receive payments', 'woocommerce' ),
'description' => __( "Enter your email address and we'll authenticate payments for you. WooCommerce Services and Jetpack will be installed and activated for you.", 'woocommerce' ),
'required' => true,
),
),
),
'enabled' => $should_display_klarna_checkout || $should_display_klarna_payments || $should_display_square,
);
$paypal = array(
'name' => __( 'PayPal Standard', 'woocommerce' ),
'description' => __( 'Accept payments via PayPal using account balance or credit card.', 'woocommerce' ),
'image' => '',
'settings' => array(
'email' => array(
'label' => __( 'PayPal email address:', 'woocommerce' ),
'type' => 'email',
'value' => $user_email,
'placeholder' => __( 'PayPal email address', 'woocommerce' ),
'required' => true,
'paypal' => array(
'name' => __( 'PayPal Standard', 'woocommerce' ),
'description' => __( 'Accept payments via PayPal using account balance or credit card.', 'woocommerce' ),
'image' => '',
'settings' => array(
'email' => array(
'label' => __( 'PayPal email address:', 'woocommerce' ),
'type' => 'email',
'value' => $user_email,
'placeholder' => __( 'PayPal email address', 'woocommerce' ),
'required' => true,
),
),
),
'klarna_checkout' => array(
'name' => __( 'Klarna Checkout', 'woocommerce' ),
'description' => $klarna_checkout_description,
'image' => WC()->plugin_url() . '/assets/images/klarna-white.png',
'enabled' => true,
'class' => 'klarna-logo',
'repo-slug' => 'klarna-checkout-for-woocommerce',
),
'klarna_payments' => array(
'name' => __( 'Klarna Payments', 'woocommerce' ),
'description' => $klarna_payments_description,
'image' => WC()->plugin_url() . '/assets/images/klarna-white.png',
'enabled' => true,
'class' => 'klarna-logo',
'repo-slug' => 'klarna-payments-for-woocommerce',
),
'square' => array(
'name' => __( 'Square', 'woocommerce' ),
'description' => $square_description,
'image' => WC()->plugin_url() . '/assets/images/square-white.png',
'class' => 'square-logo',
'enabled' => true,
'repo-slug' => 'woocommerce-square',
),
);
$klarna_checkout = array(
'name' => __( 'Klarna Checkout', 'woocommerce' ),
'description' => $klarna_checkout_description,
'image' => WC()->plugin_url() . '/assets/images/klarna-white.png',
'enabled' => true,
'class' => 'klarna-logo',
'repo-slug' => 'klarna-checkout-for-woocommerce',
);
$klarna_payments = array(
'name' => __( 'Klarna Checkout', 'woocommerce' ),
'description' => $klarna_payments_description,
'image' => WC()->plugin_url() . '/assets/images/klarna-white.png',
'enabled' => true,
'class' => 'klarna-logo',
'repo-slug' => 'klarna-payments-for-woocommerce',
);
$square = array(
'name' => __( 'Square', 'woocommerce' ),
'description' => $square_description,
'image' => WC()->plugin_url() . '/assets/images/square-white.png',
'class' => 'square-logo',
'enabled' => true,
'repo-slug' => 'woocommerce-square',
);
}
$gateways = array(
'stripe' => $stripe,
'ppec_paypal' => $ppec_paypal,
'paypal' => $paypal,
);
if ( ! $can_stripe ) {
unset( $gateways['stripe'] );
}
if ( $should_display_klarna_checkout ) {
$gateways = array(
'klarna_checkout' => $klarna_checkout,
'ppec_paypal' => $ppec_paypal,
'stripe' => $stripe,
);
}
if ( $should_display_klarna_payments ) {
$gateways = array(
'klarna_payments' => $klarna_payments,
'ppec_paypal' => $ppec_paypal,
'stripe' => $stripe,
);
}
if ( $should_display_square ) {
$gateways = array(
'square' => $square,
'ppec_paypal' => $ppec_paypal,
'stripe' => $stripe,
);
}
/**
* Simple array of "in cart" gateways to show in wizard.
*
* @return array
*/
public function get_wizard_in_cart_payment_gateways() {
$gateways = $this->get_wizard_available_in_cart_payment_gateways();
if ( ! current_user_can( 'install_plugins' ) ) {
unset( $gateways['ppec_paypal'] );
unset( $gateways['stripe'] );
unset( $gateways['klarna_checkout'] );
unset( $gateways['klarna_payments'] );
unset( $gateways['square'] );
return array( 'paypal' => $gateways['paypal'] );
}
return $gateways;
$country = WC()->countries->get_base_country();
$can_stripe = $this->is_stripe_supported_country( $country );
if ( $this->is_klarna_checkout_supported_country( $country ) ) {
$spotlight = 'klarna_checkout';
} elseif ( $this->is_klarna_payments_supported_country( $country ) ) {
$spotlight = 'klarna_payments';
} elseif ( $this->is_square_supported_country( $country ) && get_option( 'woocommerce_sell_in_person' ) ) {
$spotlight = 'square';
}
if ( isset( $spotlight ) ) {
$offered_gateways = array(
$spotlight => $gateways[ $spotlight ],
'ppec_paypal' => $gateways['ppec_paypal'],
);
if ( $can_stripe ) {
$offered_gateways += array( 'stripe' => $gateways['stripe'] );
}
return $offered_gateways;
}
$offered_gateways = array();
if ( $can_stripe ) {
$gateways['stripe']['enabled'] = true;
$gateways['stripe']['featured'] = true;
$offered_gateways += array( 'stripe' => $gateways['stripe'] );
}
$offered_gateways += array( 'ppec_paypal' => $gateways['ppec_paypal'] );
return $offered_gateways;
}
/**
@ -1468,7 +1475,7 @@ class WC_Admin_Setup_Wizard {
$this->install_woocommerce_services();
}
$gateways = $this->get_wizard_in_cart_payment_gateways();
$gateways = array_merge( $this->get_wizard_in_cart_payment_gateways(), $this->get_wizard_manual_payment_gateways() );
foreach ( $gateways as $gateway_id => $gateway ) {
// If repo-slug is defined, download and install plugin from .org.

View File

@ -47,6 +47,7 @@ class WC_Admin_List_Table_Coupons extends WC_Admin_List_Table {
echo '<div class="woocommerce-BlankState">';
echo '<h2 class="woocommerce-BlankState-message">' . esc_html__( 'Coupons are a great way to offer discounts and rewards to your customers. They will appear here once created.', 'woocommerce' ) . '</h2>';
echo '<a class="woocommerce-BlankState-cta button-primary button" target="_blank" href="https://docs.woocommerce.com/document/coupon-management/?utm_source=blankslate&utm_medium=product&utm_content=couponsdoc&utm_campaign=woocommerceplugin">' . esc_html__( 'Learn more about coupons', 'woocommerce' ) . '</a>';
echo '<a class="woocommerce-BlankState-cta button-primary button" href="' . esc_url ( admin_url( 'post-new.php?post_type=shop_coupon' ) ) . '">' . esc_html__( 'Create your first coupon', 'woocommerce' ) . '</a>';
echo '</div>';
}

View File

@ -30,6 +30,8 @@ class WC_Meta_Box_Product_Data {
$thepostid = $post->ID;
$product_object = $thepostid ? wc_get_product( $thepostid ) : new WC_Product;
wp_nonce_field( 'woocommerce_save_data', 'woocommerce_meta_nonce' );
include( 'views/html-product-data-panel.php' );
}

View File

@ -25,6 +25,7 @@ class WC_Meta_Box_Product_Images {
* @param WP_Post $post
*/
public static function output( $post ) {
wp_nonce_field( 'woocommerce_save_data', 'woocommerce_meta_nonce' );
?>
<div id="product_images_container">
<ul class="product_images">

View File

@ -39,20 +39,19 @@ if ( ! defined( 'ABSPATH' ) ) {
'email' => urlencode( $download->get_user_email() ),
'key' => $download->get_download_id(),
), trailingslashit( home_url() ) );
echo '<a href="' . esc_url( $download_link ) . '">' . esc_html( $file_count ) . '</a>';
?>
<a id="copy-download-link" class="button" href="<?php echo esc_url( $download_link ) ?>" data-tip="<?php esc_attr_e( 'Copied!', 'woocommerce' ); ?>" data-tip-failed="<?php esc_attr_e( 'Copying to clipboard failed. You should be able to right-click the button and copy.', 'woocommerce' ); ?>"><?php esc_html_e( 'Copy link', 'woocommerce' ); ?></a>
</td>
<td>
<label><?php esc_html_e( 'Downloads completed', 'woocommerce' ); ?></label>
<label><?php esc_html_e( 'Customer download log', 'woocommerce' ); ?></label>
<?php
$report_url = add_query_arg(
'permission_id',
rawurlencode( $download->get_id() ),
admin_url( 'admin.php?page=wc-reports&tab=orders&report=downloads' )
);
echo '<a href="' . esc_url( $report_url ) . '">';
echo esc_html( number_format_i18n( $download->get_download_count() ) );
echo '<a class="button" href="' . esc_url( $report_url ) . '">';
esc_html_e( 'View report', 'woocommerce' );
echo '</a>';
?>
</td>

View File

@ -203,7 +203,9 @@ if ( wc_tax_enabled() ) {
<p class="add-items">
<?php if ( $order->is_editable() ) : ?>
<button type="button" class="button add-line-item"><?php esc_html_e( 'Add item(s)', 'woocommerce' ); ?></button>
<button type="button" class="button add-coupon"><?php esc_html_e( 'Apply coupon', 'woocommerce' ); ?></button>
<?php if ( wc_coupons_enabled() ) : ?>
<button type="button" class="button add-coupon"><?php esc_html_e( 'Apply coupon', 'woocommerce' ); ?></button>
<?php endif; ?>
<?php else : ?>
<span class="description"><?php echo wc_help_tip( __( 'To edit this order change the status back to "Pending"', 'woocommerce' ) ); ?> <?php esc_html_e( 'This order is no longer editable.', 'woocommerce' ); ?></span>
<?php endif; ?>

View File

@ -44,7 +44,6 @@ if ( ! defined( 'ABSPATH' ) ) {
self::output_variations();
do_action( 'woocommerce_product_data_panels' );
wc_do_deprecated_action( 'woocommerce_product_write_panels', array(), '2.6', 'Use woocommerce_product_data_panels action instead.' );
wp_nonce_field( 'woocommerce_save_data', 'woocommerce_meta_nonce' );
?>
<div class="clear"></div>
</div>

View File

@ -109,7 +109,7 @@ if ( ! defined( 'ABSPATH' ) ) {
'wrapper_class' => 'form-row form-row-first',
'placeholder' => __( 'Variation price (required)', 'woocommerce' ),
) );
$label = sprintf(
/* translators: %s: currency symbol */
__( 'Sale price (%s)', 'woocommerce' ),
@ -207,7 +207,7 @@ if ( ! defined( 'ABSPATH' ) ) {
'options' => wc_get_product_stock_status_options(),
'desc_tip' => true,
'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ),
'wrapper_class' => 'form-row form-row-full',
'wrapper_class' => 'form-row form-row-full hide_if_variation_manage_stock',
) );
if ( wc_product_weight_enabled() ) {

View File

@ -115,9 +115,13 @@ class WC_Report_Downloads extends WP_List_Table {
$filter_list[] = $filter_names[ $key ] . ' ' . $display_value . ' <a href="' . esc_url( remove_query_arg( $key ) ) . '" class="woocommerce-reports-remove-filter">&times;</a>';
}
echo $filter_list ? ' - ' . wp_kses_post( implode( ', ', $filter_list ) ) : '';
echo '</h1>';
echo '<div id="active-filters" class="woocommerce-reports-wide"><h2>';
echo esc_html__( 'Active filters', 'woocommerce' ) . ': ';
echo $filter_list ? wp_kses_post( implode( ', ', $filter_list ) ) : '';
echo '</h2></div>';
echo '<div id="poststuff" class="woocommerce-reports-wide">';
$this->display();
echo '</div>';

View File

@ -69,6 +69,7 @@ $total_rows = $product_count->publish + $product_count->private + $variatio
<label for="woocommerce-exporter-meta"><?php esc_html_e( 'Yes, export all custom meta', 'woocommerce' ); ?></label>
</td>
</tr>
<?php do_action( 'woocommerce_product_export_row' ); ?>
</tbody>
</table>
<progress class="woocommerce-exporter-progress" max="100" value="0"></progress>

View File

@ -16,7 +16,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<h2>
<?php echo esc_html( $viewed_log ); ?>
<?php if ( ! empty( $handle ) ) : ?>
<a class="page-title-action" href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'handle' => $handle ), admin_url( 'admin.php?page=wc-status&tab=logs' ) ), 'remove_log' ) ); ?>" class="button"><?php esc_html_e( 'Delete log', 'woocommerce' );?></a>
<a class="page-title-action" href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'handle' => $handle ), admin_url( 'admin.php?page=wc-status&tab=logs' ) ), 'remove_log' ) ); ?>" class="button"><?php esc_html_e( 'Delete log', 'woocommerce' ); ?></a>
<?php endif; ?>
</h2>
</div>
@ -24,7 +24,12 @@ if ( ! defined( 'ABSPATH' ) ) {
<form action="<?php echo esc_url( admin_url( 'admin.php?page=wc-status&tab=logs' ) ); ?>" method="post">
<select name="log_file">
<?php foreach ( $logs as $log_key => $log_file ) : ?>
<option value="<?php echo esc_attr( $log_key ); ?>" <?php selected( sanitize_title( $viewed_log ), $log_key ); ?>><?php echo esc_html( $log_file ); ?> (<?php echo esc_html( date_i18n( get_option( 'date_format' ) ) . ' ' . get_option( 'time_format' ), filemtime( WC_LOG_DIR . $log_file ) ); ?>)</option>
<?php
$timestamp = filemtime( WC_LOG_DIR . $log_file );
/* translators: 1: last access date 2: last access time */
$date = sprintf( __( '%1$s at %2$s', 'woocommerce' ), date_i18n( wc_date_format(), $timestamp ), date_i18n( wc_time_format(), $timestamp ) );
?>
<option value="<?php echo esc_attr( $log_key ); ?>" <?php selected( sanitize_title( $viewed_log ), $log_key ); ?>><?php echo esc_html( $log_file ); ?> (<?php echo esc_html( $date ); ?>)</option>
<?php endforeach; ?>
</select>
<button type="submit" class="button" value="<?php esc_attr_e( 'View', 'woocommerce' ); ?>"><?php esc_html_e( 'View', 'woocommerce' ); ?></button>

View File

@ -475,6 +475,14 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller {
$prepared_review['comment_author_email'] = $request['email'];
}
if ( isset( $request['date_created'] ) ) {
$prepared_review['comment_date'] = $request['date_created'];
}
if ( isset( $request['date_created_gmt'] ) ) {
$prepared_review['comment_date_gmt'] = $request['date_created_gmt'];
}
return apply_filters( 'rest_preprocess_product_review', $prepared_review, $request );
}

View File

@ -45,11 +45,11 @@ class WC_Cart extends WC_Legacy_Cart {
public $applied_coupons = array();
/**
* Are prices in the cart displayed inc or excl tax.
* Are prices in the cart displayed inc or excl tax?
*
* @var string
*/
public $tax_display_cart;
public $tax_display_cart = 'incl';
/**
* This stores the chosen shipping methods for the cart item packages.
@ -357,6 +357,16 @@ class WC_Cart extends WC_Legacy_Cart {
return apply_filters( 'woocommerce_cart_' . __FUNCTION__, $this->get_totals_var( 'fee_taxes' ) );
}
/**
* Return whether or not the cart is displaying prices including tax, rather than excluding tax.
*
* @since 3.3.0
* @return bool
*/
public function display_prices_including_tax() {
return apply_filters( 'woocommerce_cart_' . __FUNCTION__, 'incl' === $this->tax_display_cart );
}
/*
|--------------------------------------------------------------------------
| Setters.
@ -951,7 +961,7 @@ class WC_Cart extends WC_Legacy_Cart {
* @return string
*/
public function get_displayed_subtotal() {
return 'incl' === $this->tax_display_cart ? $this->get_subtotal() + $this->get_subtotal_tax() : $this->get_subtotal();
return $this->display_prices_including_tax() ? $this->get_subtotal() + $this->get_subtotal_tax() : $this->get_subtotal();
}
/**
@ -1393,21 +1403,21 @@ class WC_Cart extends WC_Legacy_Cart {
public function get_cart_shipping_total() {
if ( 0 < $this->get_shipping_total() ) {
if ( 'excl' === $this->tax_display_cart ) {
$return = wc_price( $this->shipping_total );
if ( $this->shipping_tax_total > 0 && wc_prices_include_tax() ) {
$return .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
}
return $return;
} else {
if ( $this->display_prices_including_tax() ) {
$return = wc_price( $this->shipping_total + $this->shipping_tax_total );
if ( $this->shipping_tax_total > 0 && ! wc_prices_include_tax() ) {
$return .= ' <small class="tax_label">' . WC()->countries->inc_tax_or_vat() . '</small>';
}
return $return;
} else {
$return = wc_price( $this->shipping_total );
if ( $this->shipping_tax_total > 0 && wc_prices_include_tax() ) {
$return .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
}
return $return;
}
} else {
@ -1758,18 +1768,18 @@ class WC_Cart extends WC_Legacy_Cart {
if ( $compound ) {
$cart_subtotal = wc_price( $this->get_cart_contents_total() + $this->get_shipping_total() + $this->get_taxes_total( false, false ) );
} elseif ( 'excl' === $this->tax_display_cart ) {
$cart_subtotal = wc_price( $this->get_subtotal() );
if ( $this->get_subtotal_tax() > 0 && wc_prices_include_tax() ) {
$cart_subtotal .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
}
} else {
} elseif ( $this->display_prices_including_tax() ) {
$cart_subtotal = wc_price( $this->get_subtotal() + $this->get_subtotal_tax() );
if ( $this->get_subtotal_tax() > 0 && ! wc_prices_include_tax() ) {
$cart_subtotal .= ' <small class="tax_label">' . WC()->countries->inc_tax_or_vat() . '</small>';
}
} else {
$cart_subtotal = wc_price( $this->get_subtotal() );
if ( $this->get_subtotal_tax() > 0 && wc_prices_include_tax() ) {
$cart_subtotal .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
}
}
return apply_filters( 'woocommerce_cart_subtotal', $cart_subtotal, $compound, $this );
@ -1782,10 +1792,10 @@ class WC_Cart extends WC_Legacy_Cart {
* @return string formatted price
*/
public function get_product_price( $product ) {
if ( 'excl' === $this->tax_display_cart ) {
$product_price = wc_get_price_excluding_tax( $product );
} else {
if ( $this->display_prices_including_tax() ) {
$product_price = wc_get_price_including_tax( $product );
} else {
$product_price = wc_get_price_excluding_tax( $product );
}
return apply_filters( 'woocommerce_cart_product_price', wc_price( $product_price ), $product );
}
@ -1806,22 +1816,20 @@ class WC_Cart extends WC_Legacy_Cart {
if ( $product->is_taxable() ) {
if ( 'excl' === $this->tax_display_cart ) {
$row_price = wc_get_price_excluding_tax( $product, array( 'qty' => $quantity ) );
$product_subtotal = wc_price( $row_price );
if ( wc_prices_include_tax() && $this->get_subtotal_tax() > 0 ) {
$product_subtotal .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
}
} else {
if ( $this->display_prices_including_tax() ) {
$row_price = wc_get_price_including_tax( $product, array( 'qty' => $quantity ) );
$product_subtotal = wc_price( $row_price );
if ( ! wc_prices_include_tax() && $this->get_subtotal_tax() > 0 ) {
$product_subtotal .= ' <small class="tax_label">' . WC()->countries->inc_tax_or_vat() . '</small>';
}
} else {
$row_price = wc_get_price_excluding_tax( $product, array( 'qty' => $quantity ) );
$product_subtotal = wc_price( $row_price );
if ( wc_prices_include_tax() && $this->get_subtotal_tax() > 0 ) {
$product_subtotal .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
}
}
} else {
$row_price = $price * $quantity;

File diff suppressed because it is too large Load Diff

View File

@ -270,7 +270,7 @@ class WC_Customer extends WC_Legacy_Customer {
* @param bool $is_vat_exempt
*/
public function set_is_vat_exempt( $is_vat_exempt ) {
$this->is_vat_exempt = (bool) $is_vat_exempt;
$this->is_vat_exempt = wc_string_to_bool( $is_vat_exempt );
}
/**
@ -279,7 +279,7 @@ class WC_Customer extends WC_Legacy_Customer {
* @param boolean $calculated
*/
public function set_calculated_shipping( $calculated = true ) {
$this->calculated_shipping = (bool) $calculated;
$this->calculated_shipping = wc_string_to_bool( $calculated );
}
/**

View File

@ -817,7 +817,7 @@ class WC_Discounts {
$categories = array();
foreach ( $this->items as $item ) {
if ( $coupon->get_exclude_sale_items() && $item->product && $item->product->is_on_sale() ) {
if ( ! $item->product ) {
continue;
}

View File

@ -925,6 +925,7 @@ class WC_Form_Handler {
* Process the login form.
*/
public static function process_login() {
// The global form-login.php template used `_wpnonce` in template versions < 3.3.0.
$nonce_value = isset( $_POST['_wpnonce'] ) ? $_POST['_wpnonce'] : '';
$nonce_value = isset( $_POST['woocommerce-login-nonce'] ) ? $_POST['woocommerce-login-nonce'] : $nonce_value;

View File

@ -92,7 +92,7 @@ class WC_Geolocation {
} elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) { // WPCS: input var ok, CSRF ok.
// Proxy servers can send through this header like this: X-Forwarded-For: client1, proxy1, proxy2
// Make sure we always only send through the first IP in the list which should always be the client IP.
return (string) rest_is_ip_address( trim( current( explode( ',', sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) ) ) ) ); // WPCS: input var ok, CSRF ok.
return (string) rest_is_ip_address( trim( current( preg_split( '/[,:]/', sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) ) ) ) ); // WPCS: input var ok, CSRF ok.
} elseif ( isset( $_SERVER['REMOTE_ADDR'] ) ) { // @codingStandardsIgnoreLine
return sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ); // @codingStandardsIgnoreLine
}

View File

@ -402,8 +402,6 @@ class WC_Install {
foreach ( $pages as $key => $page ) {
wc_create_page( esc_sql( $page['name'] ), 'woocommerce_' . $key . '_page_id', $page['title'], $page['content'], ! empty( $page['parent'] ) ? wc_get_page_id( $page['parent'] ) : '' );
}
delete_transient( 'woocommerce_cache_excluded_uris' );
}
/**

6
includes/class-wc-order.php Executable file → Normal file
View File

@ -163,16 +163,18 @@ class WC_Order extends WC_Abstract_Order {
// Tax for inclusive prices.
if ( wc_tax_enabled() && 'incl' === $tax_display ) {
$tax_string_array = array();
$tax_totals = $this->get_tax_totals();
if ( 'itemized' === get_option( 'woocommerce_tax_total_display' ) ) {
foreach ( $this->get_tax_totals() as $code => $tax ) {
foreach ( $tax_totals as $code => $tax ) {
$tax_amount = ( $total_refunded && $display_refunded ) ? wc_price( WC_Tax::round( $tax->amount - $this->get_total_tax_refunded_by_rate_id( $tax->rate_id ) ), array( 'currency' => $this->get_currency() ) ) : $tax->formatted_amount;
$tax_string_array[] = sprintf( '%s %s', $tax_amount, $tax->label );
}
} else {
} elseif ( ! empty( $tax_totals ) ) {
$tax_amount = ( $total_refunded && $display_refunded ) ? $this->get_total_tax() - $this->get_total_tax_refunded() : $this->get_total_tax();
$tax_string_array[] = sprintf( '%s %s', wc_price( $tax_amount, array( 'currency' => $this->get_currency() ) ), WC()->countries->tax_or_vat() );
}
if ( ! empty( $tax_string_array ) ) {
/* translators: %s: taxes */
$tax_string = ' <small class="includes_tax">' . sprintf( __( '(includes %s)', 'woocommerce' ), implode( ', ', $tax_string_array ) ) . '</small>';

View File

@ -450,48 +450,44 @@ class WC_Query {
);
switch ( $orderby ) {
case 'menu_order' :
case 'menu_order':
$args['orderby'] = 'menu_order title';
break;
case 'relevance' :
$args['orderby']= 'relevance';
$args['order'] = 'DESC';
case 'title':
$args['orderby'] = 'title';
$args['order'] = ( 'DESC' === $order ) ? 'DESC' : 'ASC';
break;
case 'rand' :
$args['orderby'] = 'rand'; // @codingStandardsIgnoreLine
case 'relevance':
$args['orderby'] = 'relevance';
$args['order'] = 'DESC';
break;
case 'date' :
$args['orderby'] = 'date ID';
$args['order'] = ( 'ASC' === $order ) ? 'ASC' : 'DESC';
case 'rand':
$args['orderby'] = 'rand'; // @codingStandardsIgnoreLine
break;
case 'price' :
case 'date':
$args['orderby'] = 'date ID';
$args['order'] = ( 'ASC' === $order ) ? 'ASC' : 'DESC';
break;
case 'price':
if ( 'DESC' === $order ) {
add_filter( 'posts_clauses', array( $this, 'order_by_price_desc_post_clauses' ) );
} else {
add_filter( 'posts_clauses', array( $this, 'order_by_price_asc_post_clauses' ) );
}
break;
case 'popularity' :
case 'popularity':
$args['meta_key'] = 'total_sales'; // @codingStandardsIgnoreLine
// Sorting handled later though a hook.
add_filter( 'posts_clauses', array( $this, 'order_by_popularity_post_clauses' ) );
break;
case 'rating' :
case 'rating':
$args['meta_key'] = '_wc_average_rating'; // @codingStandardsIgnoreLine
$args['orderby'] = array(
'meta_value_num' => 'DESC',
'ID' => 'ASC',
);
break;
case 'title' :
$args['orderby'] = 'title';
$args['order'] = ( 'DESC' === $order ) ? 'DESC' : 'ASC';
break;
case 'relevance' :
$args['orderby'] = 'relevance';
$args['order'] = 'DESC';
break;
}
return apply_filters( 'woocommerce_get_catalog_ordering_args', $args );
@ -522,7 +518,7 @@ class WC_Query {
} else {
$args['join'] .= " INNER JOIN ( SELECT post_id, min( meta_value+0 ) price FROM $wpdb->postmeta WHERE meta_key='_price' GROUP BY post_id ) as price_query ON $wpdb->posts.ID = price_query.post_id ";
}
$args['orderby'] = ' price_query.price ASC ';
$args['orderby'] = " price_query.price ASC, $wpdb->posts.ID ASC ";
return $args;
}
@ -552,7 +548,7 @@ class WC_Query {
$args['join'] .= " INNER JOIN ( SELECT post_id, max( meta_value+0 ) price FROM $wpdb->postmeta WHERE meta_key='_price' GROUP BY post_id ) as price_query ON $wpdb->posts.ID = price_query.post_id ";
}
$args['orderby'] = ' price_query.price DESC ';
$args['orderby'] = " price_query.price DESC, $wpdb->posts.ID DESC ";
return $args;
}
@ -735,13 +731,16 @@ class WC_Query {
}
/**
* Layered Nav Init.
* Get an array of attributes and terms selected with the layered nav widget.
*
* @return array
*/
public static function get_layered_nav_chosen_attributes() {
if ( ! is_array( self::$_chosen_attributes ) ) {
self::$_chosen_attributes = array();
$attribute_taxonomies = wc_get_attribute_taxonomies();
if ( $attribute_taxonomies = wc_get_attribute_taxonomies() ) {
if ( ! empty( $attribute_taxonomies ) ) {
foreach ( $attribute_taxonomies as $tax ) {
$attribute = wc_sanitize_taxonomy_name( $tax->attribute_name );
$taxonomy = wc_attribute_taxonomy_name( $attribute );

View File

@ -1,8 +1,4 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Handle data for the current customers session.
* Implements the WC_Session abstract class.
@ -13,41 +9,76 @@ if ( ! defined( 'ABSPATH' ) ) {
* @version 2.5.0
* @package WooCommerce/Classes
* @category Class
* @author WooThemes
* @author Automattic
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* WC_Session_Handler
*/
class WC_Session_Handler extends WC_Session {
/** @var string cookie name */
/**
* Cookie name used for the session.
*
* @var string cookie name
*/
protected $_cookie;
/** @var string session due to expire timestamp */
/**
* Stores session expiry.
*
* @var string session due to expire timestamp
*/
protected $_session_expiring;
/** @var string session expiration timestamp */
/**
* Stores session due to expire timestamp.
*
* @var string session expiration timestamp
*/
protected $_session_expiration;
/** $var bool Bool based on whether a cookie exists **/
/**
* True when the cookie exists.
*
* @var bool Based on whether a cookie exists.
*/
protected $_has_cookie = false;
/** @var string Custom session table name */
/**
* Table name for session data.
*
* @var string Custom session table name
*/
protected $_table;
/**
* Constructor for the session class.
*/
public function __construct() {
global $wpdb;
$this->_cookie = apply_filters( 'woocommerce_cookie', 'wp_woocommerce_session_' . COOKIEHASH );
$this->_table = $wpdb->prefix . 'woocommerce_sessions';
$this->_table = $GLOBALS['wpdb']->prefix . 'woocommerce_sessions';
}
if ( $cookie = $this->get_session_cookie() ) {
/**
* Init hooks and session data.
*
* @since 3.3.0
*/
public function init() {
$cookie = $this->get_session_cookie();
if ( $cookie ) {
$this->_customer_id = $cookie[0];
$this->_session_expiration = $cookie[1];
$this->_session_expiring = $cookie[2];
$this->_has_cookie = true;
// Update session if its close to expiring
// Update session if its close to expiring.
if ( time() > $this->_session_expiring ) {
$this->set_session_expiration();
$this->update_session_timestamp( $this->_customer_id, $this->_session_expiration );
@ -59,11 +90,10 @@ class WC_Session_Handler extends WC_Session {
$this->_data = $this->get_session_data();
// Actions
add_action( 'woocommerce_set_cart_cookies', array( $this, 'set_customer_session_cookie' ), 10 );
add_action( 'woocommerce_cleanup_sessions', array( $this, 'cleanup_sessions' ), 10 );
add_action( 'shutdown', array( $this, 'save_data' ), 20 );
add_action( 'wp_logout', array( $this, 'destroy_session' ) );
if ( ! is_user_logged_in() ) {
add_filter( 'nonce_user_logged_out', array( $this, 'nonce_user_logged_out' ) );
}
@ -76,17 +106,15 @@ class WC_Session_Handler extends WC_Session {
*
* Warning: Cookies will only be set if this is called before the headers are sent.
*
* @param bool $set
* @param bool $set Should the session cookie be set.
*/
public function set_customer_session_cookie( $set ) {
if ( $set ) {
// Set/renew our cookie
$to_hash = $this->_customer_id . '|' . $this->_session_expiration;
$cookie_hash = hash_hmac( 'md5', $to_hash, wp_hash( $to_hash ) );
$cookie_value = $this->_customer_id . '||' . $this->_session_expiration . '||' . $this->_session_expiring . '||' . $cookie_hash;
$this->_has_cookie = true;
// Set the cookie
wc_setcookie( $this->_cookie, $cookie_value, $this->_session_expiration, apply_filters( 'wc_session_use_secure_cookie', false ) );
}
}
@ -97,7 +125,7 @@ class WC_Session_Handler extends WC_Session {
* @return bool
*/
public function has_session() {
return isset( $_COOKIE[ $this->_cookie ] ) || $this->_has_cookie || is_user_logged_in();
return isset( $_COOKIE[ $this->_cookie ] ) || $this->_has_cookie || is_user_logged_in(); // @codingStandardsIgnoreLine.
}
/**
@ -119,7 +147,7 @@ class WC_Session_Handler extends WC_Session {
if ( is_user_logged_in() ) {
return get_current_user_id();
} else {
require_once( ABSPATH . 'wp-includes/class-phpass.php' );
require_once ABSPATH . 'wp-includes/class-phpass.php';
$hasher = new PasswordHash( 8, false );
return md5( $hasher->get_random_bytes( 32 ) );
}
@ -131,13 +159,15 @@ class WC_Session_Handler extends WC_Session {
* @return bool|array
*/
public function get_session_cookie() {
if ( empty( $_COOKIE[ $this->_cookie ] ) || ! is_string( $_COOKIE[ $this->_cookie ] ) ) {
$cookie_value = isset( $_COOKIE[ $this->_cookie ] ) ? wp_unslash( $_COOKIE[ $this->_cookie ] ) : false; // @codingStandardsIgnoreLine.
if ( empty( $cookie_value ) || ! is_string( $cookie_value ) ) {
return false;
}
list( $customer_id, $session_expiration, $session_expiring, $cookie_hash ) = explode( '||', $_COOKIE[ $this->_cookie ] );
list( $customer_id, $session_expiration, $session_expiring, $cookie_hash ) = explode( '||', $cookie_value );
// Validate hash
// Validate hash.
$to_hash = $customer_id . '|' . $session_expiration;
$hash = hash_hmac( 'md5', $to_hash, wp_hash( $to_hash ) );
@ -170,15 +200,15 @@ class WC_Session_Handler extends WC_Session {
* Save data.
*/
public function save_data() {
// Dirty if something changed - prevents saving nothing new
// Dirty if something changed - prevents saving nothing new.
if ( $this->_dirty && $this->has_session() ) {
global $wpdb;
$wpdb->replace(
$wpdb->replace( // @codingStandardsIgnoreLine.
$this->_table,
array(
'session_key' => $this->_customer_id,
'session_value' => maybe_serialize( $this->_data ),
'session_key' => $this->_customer_id,
'session_value' => maybe_serialize( $this->_data ),
'session_expiry' => $this->_session_expiration,
),
array(
@ -188,10 +218,7 @@ class WC_Session_Handler extends WC_Session {
)
);
// Set cache
wp_cache_set( $this->get_cache_prefix() . $this->_customer_id, $this->_data, WC_SESSION_CACHE_GROUP, $this->_session_expiration - time() );
// Mark session clean after saving
$this->_dirty = false;
}
}
@ -200,15 +227,12 @@ class WC_Session_Handler extends WC_Session {
* Destroy all session data.
*/
public function destroy_session() {
// Clear cookie
wc_setcookie( $this->_cookie, '', time() - YEAR_IN_SECONDS, apply_filters( 'wc_session_use_secure_cookie', false ) );
$this->delete_session( $this->_customer_id );
// Clear cart
wc_empty_cart();
// Clear data
$this->_data = array();
$this->_dirty = false;
$this->_customer_id = $this->generate_customer_id();
@ -217,8 +241,7 @@ class WC_Session_Handler extends WC_Session {
/**
* When a user is logged out, ensure they have a unique nonce by using the customer/session ID.
*
* @param int $uid
*
* @param int $uid User ID.
* @return string
*/
public function nonce_user_logged_out( $uid ) {
@ -226,17 +249,14 @@ class WC_Session_Handler extends WC_Session {
}
/**
* Cleanup sessions.
* Cleanup session data from the database and clear caches.
*/
public function cleanup_sessions() {
global $wpdb;
if ( ! defined( 'WP_SETUP_CONFIG' ) && ! defined( 'WP_INSTALLING' ) ) {
$wpdb->query( $wpdb->prepare( "DELETE FROM $this->_table WHERE session_expiry < %d", time() ) ); // @codingStandardsIgnoreLine.
// Delete expired sessions
$wpdb->query( $wpdb->prepare( "DELETE FROM $this->_table WHERE session_expiry < %d", time() ) );
// Invalidate cache
if ( class_exists( 'WC_Cache_Helper' ) ) {
WC_Cache_Helper::incr_cache_prefix( WC_SESSION_CACHE_GROUP );
}
}
@ -244,8 +264,8 @@ class WC_Session_Handler extends WC_Session {
/**
* Returns the session.
*
* @param string $customer_id
* @param mixed $default
* @param string $customer_id Custo ID.
* @param mixed $default Default session value.
* @return string|array
*/
public function get_session( $customer_id, $default = false ) {
@ -255,11 +275,11 @@ class WC_Session_Handler extends WC_Session {
return false;
}
// Try get it from the cache, it will return false if not present or if object cache not in use
// Try to get it from the cache, it will return false if not present or if object cache not in use.
$value = wp_cache_get( $this->get_cache_prefix() . $customer_id, WC_SESSION_CACHE_GROUP );
if ( false === $value ) {
$value = $wpdb->get_var( $wpdb->prepare( "SELECT session_value FROM $this->_table WHERE session_key = %s", $customer_id ) );
$value = $wpdb->get_var( $wpdb->prepare( "SELECT session_value FROM $this->_table WHERE session_key = %s", $customer_id ) ); // @codingStandardsIgnoreLine.
if ( is_null( $value ) ) {
$value = $default;
@ -274,14 +294,14 @@ class WC_Session_Handler extends WC_Session {
/**
* Delete the session from the cache and database.
*
* @param int $customer_id
* @param int $customer_id Customer ID.
*/
public function delete_session( $customer_id ) {
global $wpdb;
wp_cache_delete( $this->get_cache_prefix() . $customer_id, WC_SESSION_CACHE_GROUP );
$wpdb->delete(
$wpdb->delete( // @codingStandardsIgnoreLine.
$this->_table,
array(
'session_key' => $customer_id,
@ -292,12 +312,13 @@ class WC_Session_Handler extends WC_Session {
/**
* Update the session expiry timestamp.
*
* @param string $customer_id
* @param int $timestamp
* @param string $customer_id Customer ID.
* @param int $timestamp Timestamp to expire the cookie.
*/
public function update_session_timestamp( $customer_id, $timestamp ) {
global $wpdb;
// @codingStandardsIgnoreStart.
$wpdb->update(
$this->_table,
array(
@ -310,5 +331,6 @@ class WC_Session_Handler extends WC_Session {
'%d'
)
);
// @codingStandardsIgnoreEnd.
}
}

View File

@ -247,17 +247,6 @@ final class WooCommerce {
}
}
/**
* Check the active theme.
*
* @since 2.6.9
* @param string $theme Theme slug to check.
* @return bool
*/
private function is_active_theme( $theme ) {
return is_array( $theme ) ? in_array( get_template(), $theme, true ) : get_template() === $theme;
}
/**
* Include required core files used in admin and on the frontend.
*/
@ -389,10 +378,6 @@ final class WooCommerce {
$this->frontend_includes();
}
if ( $this->is_request( 'frontend' ) || $this->is_request( 'cron' ) ) {
include_once( WC_ABSPATH . 'includes/class-wc-session-handler.php' );
}
if ( $this->is_request( 'cron' ) && 'yes' === get_option( 'woocommerce_allow_tracking', 'no' ) ) {
include_once( WC_ABSPATH . 'includes/class-wc-tracker.php' );
}
@ -408,7 +393,7 @@ final class WooCommerce {
* @since 3.3.0
*/
private function theme_support_includes() {
if ( $this->is_active_theme( array( 'twentyseventeen', 'twentysixteen', 'twentyfifteen', 'twentyfourteen', 'twentythirteen', 'twentyeleven', 'twentytwelve', 'twentyten' ) ) ) {
if ( wc_is_active_theme( array( 'twentyseventeen', 'twentysixteen', 'twentyfifteen', 'twentyfourteen', 'twentythirteen', 'twentyeleven', 'twentytwelve', 'twentyten' ) ) ) {
switch ( get_template() ) {
case 'twentyten':
include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-ten.php' );
@ -455,6 +440,7 @@ final class WooCommerce {
include_once( WC_ABSPATH . 'includes/class-wc-shortcodes.php' ); // Shortcodes class.
include_once( WC_ABSPATH . 'includes/class-wc-embed.php' ); // Embeds.
include_once( WC_ABSPATH . 'includes/class-wc-structured-data.php' ); // Structured Data class.
include_once( WC_ABSPATH . 'includes/class-wc-session-handler.php' ); // Session handler class.
}
/**
@ -483,17 +469,17 @@ final class WooCommerce {
$this->deprecated_hook_handlers['actions'] = new WC_Deprecated_Action_Hooks();
$this->deprecated_hook_handlers['filters'] = new WC_Deprecated_Filter_Hooks();
// Session class, handles session data for users - can be overwritten if custom handler is needed.
if ( $this->is_request( 'frontend' ) || $this->is_request( 'cron' ) ) {
$session_class = apply_filters( 'woocommerce_session_handler', 'WC_Session_Handler' );
$this->session = new $session_class();
}
// Classes/actions loaded for the frontend and for ajax requests.
if ( $this->is_request( 'frontend' ) ) {
$this->cart = new WC_Cart(); // Cart class, stores the cart contents.
$this->customer = new WC_Customer( get_current_user_id(), true ); // Customer class, handles data such as customer location.
add_action( 'shutdown', array( $this->customer, 'save' ), 10 ); // Customer should be saved during shutdown.
// Session class, handles session data for users - can be overwritten if custom handler is needed.
$session_class = apply_filters( 'woocommerce_session_handler', 'WC_Session_Handler' );
$this->session = new $session_class();
$this->session->init();
$this->cart = new WC_Cart(); // Cart class, stores the cart contents.
$this->customer = new WC_Customer( get_current_user_id(), true ); // Customer class, handles data such as customer location.
add_action( 'shutdown', array( $this->customer, 'save' ), 10 ); // Customer should be saved during shutdown.
}
$this->load_webhooks();

View File

@ -39,7 +39,7 @@ class WC_Shop_Customizer {
) );
$this->add_store_notice_section( $wp_customize );
$this->add_product_grid_section( $wp_customize );
$this->add_product_catalog_section( $wp_customize );
$this->add_product_images_section( $wp_customize );
}
@ -209,18 +209,18 @@ class WC_Shop_Customizer {
}
/**
* Product grid section.
* Product catalog section.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function add_product_grid_section( $wp_customize ) {
public function add_product_catalog_section( $wp_customize ) {
$theme_support = get_theme_support( 'woocommerce' );
$theme_support = is_array( $theme_support ) ? $theme_support[0] : false;
$wp_customize->add_section(
'woocommerce_product_grid',
'woocommerce_product_catalog',
array(
'title' => __( 'Product Grid', 'woocommerce' ),
'title' => __( 'Product Catalog', 'woocommerce' ),
'priority' => 10,
'active_callback' => array( $this, 'is_products_archive' ),
'panel' => 'woocommerce',
@ -241,8 +241,8 @@ class WC_Shop_Customizer {
'woocommerce_shop_page_display',
array(
'label' => __( 'Shop page display', 'woocommerce' ),
'description' => __( 'This controls what is shown on the product archive.', 'woocommerce' ),
'section' => 'woocommerce_product_grid',
'description' => __( 'Choose what to display on the main shop page.', 'woocommerce' ),
'section' => 'woocommerce_product_catalog',
'settings' => 'woocommerce_shop_page_display',
'type' => 'select',
'choices' => array(
@ -266,14 +266,14 @@ class WC_Shop_Customizer {
$wp_customize->add_control(
'woocommerce_category_archive_display',
array(
'label' => __( 'Default category display', 'woocommerce' ),
'description' => __( 'This controls what is shown on category archives.', 'woocommerce' ),
'section' => 'woocommerce_product_grid',
'label' => __( 'Category display', 'woocommerce' ),
'description' => __( 'Choose what to display on product category pages.', 'woocommerce' ),
'section' => 'woocommerce_product_catalog',
'settings' => 'woocommerce_category_archive_display',
'type' => 'select',
'choices' => array(
'' => __( 'Show products', 'woocommerce' ),
'subcategories' => __( 'Show categories', 'woocommerce' ),
'subcategories' => __( 'Show subcategories', 'woocommerce' ),
'both' => __( 'Show subcategories &amp; products', 'woocommerce' ),
),
)
@ -282,7 +282,7 @@ class WC_Shop_Customizer {
$wp_customize->add_setting(
'woocommerce_default_catalog_orderby',
array(
'default' => '',
'default' => 'menu_order',
'type' => 'option',
'capability' => 'manage_woocommerce',
'sanitize_callback' => array( $this, 'sanitize_default_catalog_orderby' ),
@ -293,8 +293,8 @@ class WC_Shop_Customizer {
'woocommerce_default_catalog_orderby',
array(
'label' => __( 'Default product sorting', 'woocommerce' ),
'description' => __( 'This controls the default sort order of the catalog.', 'woocommerce' ),
'section' => 'woocommerce_product_grid',
'description' => __( 'How should products by sorted in the catalog by default?', 'woocommerce' ),
'section' => 'woocommerce_product_catalog',
'settings' => 'woocommerce_default_catalog_orderby',
'type' => 'select',
'choices' => apply_filters( 'woocommerce_default_catalog_orderby_options', array(
@ -329,7 +329,7 @@ class WC_Shop_Customizer {
array(
'label' => __( 'Products per row', 'woocommerce' ),
'description' => __( 'How many products should be shown per row?', 'woocommerce' ),
'section' => 'woocommerce_product_grid',
'section' => 'woocommerce_product_catalog',
'settings' => 'woocommerce_catalog_columns',
'type' => 'number',
'input_attrs' => array(
@ -356,7 +356,7 @@ class WC_Shop_Customizer {
array(
'label' => __( 'Rows per page', 'woocommerce' ),
'description' => __( 'How many rows of products should be shown per page?', 'woocommerce' ),
'section' => 'woocommerce_product_grid',
'section' => 'woocommerce_product_catalog',
'settings' => 'woocommerce_catalog_rows',
'type' => 'number',
'input_attrs' => array(
@ -389,7 +389,7 @@ class WC_Shop_Customizer {
if ( ! isset( $theme_support['single_image_width'] ) ) {
$wp_customize->add_setting(
'single_image_width',
'woocommerce_single_image_width',
array(
'default' => 600,
'type' => 'option',
@ -400,12 +400,12 @@ class WC_Shop_Customizer {
);
$wp_customize->add_control(
'single_image_width',
'woocommerce_single_image_width',
array(
'label' => __( 'Main image width', 'woocommerce' ),
'description' => __( 'This is the width used by the main image on single product pages. These images will remain uncropped.', 'woocommerce' ),
'description' => __( 'Image size used for the main image on single product pages. These images will remain uncropped.', 'woocommerce' ),
'section' => 'woocommerce_product_images',
'settings' => 'single_image_width',
'settings' => 'woocommerce_single_image_width',
'type' => 'number',
'input_attrs' => array(
'min' => 0,
@ -417,7 +417,7 @@ class WC_Shop_Customizer {
if ( ! isset( $theme_support['thumbnail_image_width'] ) ) {
$wp_customize->add_setting(
'thumbnail_image_width',
'woocommerce_thumbnail_image_width',
array(
'default' => 300,
'type' => 'option',
@ -428,12 +428,12 @@ class WC_Shop_Customizer {
);
$wp_customize->add_control(
'thumbnail_image_width',
'woocommerce_thumbnail_image_width',
array(
'label' => __( 'Thumbnail width', 'woocommerce' ),
'description' => __( 'This size is used for product archives and product listings.', 'woocommerce' ),
'description' => __( 'Image size used for products in the catalog and product gallery thumbnails.', 'woocommerce' ),
'section' => 'woocommerce_product_images',
'settings' => 'thumbnail_image_width',
'settings' => 'woocommerce_thumbnail_image_width',
'type' => 'number',
'input_attrs' => array(
'min' => 0,

View File

@ -18,6 +18,7 @@ class WC_Customer_Data_Store_Session extends WC_Data_Store_WP implements WC_Cust
*/
protected $session_keys = array(
'id',
'date_modified',
'billing_postcode',
'billing_city',
'billing_address_1',
@ -74,11 +75,9 @@ class WC_Customer_Data_Store_Session extends WC_Data_Store_WP implements WC_Cust
if ( 'billing_' === substr( $session_key, 0, 8 ) ) {
$session_key = str_replace( 'billing_', '', $session_key );
}
$data[ $session_key ] = $customer->{"get_$function_key"}( 'edit' );
}
if ( WC()->session->get( 'customer' ) !== $data ) {
WC()->session->set( 'customer', $data );
$data[ $session_key ] = (string) $customer->{"get_$function_key"}( 'edit' );
}
WC()->session->set( 'customer', $data );
}
/**
@ -90,8 +89,17 @@ class WC_Customer_Data_Store_Session extends WC_Data_Store_WP implements WC_Cust
*/
public function read( &$customer ) {
$data = (array) WC()->session->get( 'customer' );
if ( ! empty( $data ) && isset( $data['id'] ) && $data['id'] === $customer->get_id() ) {
/**
* There is a valid session if $data is not empty, and the ID matches the logged in user ID.
*
* If the user object has been updated since the session was created (based on date_modified) we should not load the session - data should be reloaded.
*/
if ( isset( $data['id'], $data['date_modified'] ) && $data['id'] === (string) $customer->get_id() && $data['date_modified'] === (string) $customer->get_date_modified( 'edit' ) ) {
foreach ( $this->session_keys as $session_key ) {
if ( in_array( $session_key, array( 'id', 'date_modified' ), true ) ) {
continue;
}
$function_key = $session_key;
if ( 'billing_' === substr( $session_key, 0, 8 ) ) {
$session_key = str_replace( 'billing_', '', $session_key );

View File

@ -1015,7 +1015,17 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
*/
public function get_related_products( $cats_array, $tags_array, $exclude_ids, $limit, $product_id ) {
global $wpdb;
return $wpdb->get_col( implode( ' ', apply_filters( 'woocommerce_product_related_posts_query', $this->get_related_products_query( $cats_array, $tags_array, $exclude_ids, $limit + 10 ), $product_id ) ) );
$args = array(
'categories' => $cats_array,
'tags' => $tags_array,
'exclude_ids' => $exclude_ids,
'limit' => $limit + 10,
);
$related_product_query = (array) apply_filters( 'woocommerce_product_related_posts_query', $this->get_related_products_query( $cats_array, $tags_array, $exclude_ids, $limit + 10 ), $product_id, $args );
return $wpdb->get_col( implode( ' ', $related_product_query ) );
}
/**

View File

@ -4,8 +4,6 @@
*
* Based on https://pippinsplugins.com/batch-processing-for-big-data/
*
* @author Automattic
* @category Admin
* @package WooCommerce/Export
* @version 3.1.0
*/
@ -25,13 +23,6 @@ if ( ! class_exists( 'WC_CSV_Exporter', false ) ) {
*/
abstract class WC_CSV_Batch_Exporter extends WC_CSV_Exporter {
/**
* The file being exported to.
*
* @var string
*/
protected $file;
/**
* Page being exported
*
@ -43,11 +34,19 @@ abstract class WC_CSV_Batch_Exporter extends WC_CSV_Exporter {
* Constructor.
*/
public function __construct() {
$upload_dir = wp_upload_dir();
$this->file = trailingslashit( $upload_dir['basedir'] ) . $this->get_filename();
$this->column_names = $this->get_default_column_names();
}
/**
* Get file path to export to.
*
* @return string
*/
protected function get_file_path() {
$upload_dir = wp_upload_dir();
return trailingslashit( $upload_dir['basedir'] ) . $this->get_filename();
}
/**
* Get the file contents.
*
@ -56,11 +55,11 @@ abstract class WC_CSV_Batch_Exporter extends WC_CSV_Exporter {
*/
public function get_file() {
$file = '';
if ( @file_exists( $this->file ) ) {
$file = @file_get_contents( $this->file );
if ( @file_exists( $this->get_file_path() ) ) {
$file = @file_get_contents( $this->get_file_path() );
} else {
@file_put_contents( $this->file, '' );
@chmod( $this->file, 0664 );
@file_put_contents( $this->get_file_path(), '' );
@chmod( $this->get_file_path(), 0664 );
}
return $file;
}
@ -73,7 +72,7 @@ abstract class WC_CSV_Batch_Exporter extends WC_CSV_Exporter {
public function export() {
$this->send_headers();
$this->send_content( $this->get_file() );
@unlink( $this->file );
@unlink( $this->get_file_path() );
die();
}
@ -84,7 +83,7 @@ abstract class WC_CSV_Batch_Exporter extends WC_CSV_Exporter {
*/
public function generate_file() {
if ( 1 === $this->get_page() ) {
@unlink( $this->file );
@unlink( $this->get_file_path() );
}
$this->prepare_data_to_export();
$this->write_csv_data( $this->get_csv_data() );
@ -105,7 +104,7 @@ abstract class WC_CSV_Batch_Exporter extends WC_CSV_Exporter {
}
$file .= $data;
@file_put_contents( $this->file, $file );
@file_put_contents( $this->get_file_path(), $file );
}
/**

View File

@ -2,8 +2,6 @@
/**
* Handles CSV export.
*
* @author Automattic
* @category Admin
* @package WooCommerce/Export
* @version 3.1.0
*/
@ -24,6 +22,13 @@ abstract class WC_CSV_Exporter {
*/
protected $export_type = '';
/**
* Filename to export to.
*
* @var string
*/
protected $filename = 'wc-export.csv';
/**
* Batch limit.
*
@ -183,13 +188,23 @@ abstract class WC_CSV_Exporter {
header( 'Expires: 0' );
}
/**
* Set filename to export to.
*
* @param string $filename Filename to export to.
* @return string
*/
public function set_filename( $filename ) {
$this->filename = sanitize_file_name( str_replace( '.csv', '', $filename ) . '.csv' );
}
/**
* Generate and return a filename.
*
* @return string
*/
public function get_filename() {
return sanitize_file_name( 'wc-' . $this->export_type . '-export-' . date_i18n( 'Y-m-d', current_time( 'timestamp' ) ) . '.csv' );
return sanitize_file_name( apply_filters( "woocommerce_{$this->export_type}_export_get_filename", $this->filename ) );
}
/**
@ -296,7 +311,7 @@ abstract class WC_CSV_Exporter {
* @return int
*/
public function get_limit() {
return $this->limit;
return apply_filters( "woocommerce_{$this->export_type}_export_batch_limit", $this->limit, $this );
}
/**
@ -363,9 +378,14 @@ abstract class WC_CSV_Exporter {
$data = $data ? 1 : 0;
}
$use_mb = function_exists( 'mb_convert_encoding' );
$data = (string) urldecode( $data );
$encoding = mb_detect_encoding( $data, 'UTF-8, ISO-8859-1', true );
$data = 'UTF-8' === $encoding ? $data : utf8_encode( $data );
if ( $use_mb ) {
$encoding = mb_detect_encoding( $data, 'UTF-8, ISO-8859-1', true );
$data = 'UTF-8' === $encoding ? $data : utf8_encode( $data );
}
return $this->escape_data( $data );
}

View File

@ -2,8 +2,6 @@
/**
* Handles product CSV export.
*
* @author Automattic
* @category Admin
* @package WooCommerce/Export
* @version 3.1.0
*/
@ -16,7 +14,7 @@ if ( ! defined( 'ABSPATH' ) ) {
* Include dependencies.
*/
if ( ! class_exists( 'WC_CSV_Batch_Exporter', false ) ) {
include_once( WC_ABSPATH . 'includes/export/abstract-wc-csv-batch-exporter.php' );
include_once WC_ABSPATH . 'includes/export/abstract-wc-csv-batch-exporter.php';
}
/**
@ -98,9 +96,13 @@ class WC_Product_CSV_Exporter extends WC_CSV_Batch_Exporter {
'stock' => __( 'Stock', 'woocommerce' ),
'backorders' => __( 'Backorders allowed?', 'woocommerce' ),
'sold_individually' => __( 'Sold individually?', 'woocommerce' ),
/* translators: %s: weight */
'weight' => sprintf( __( 'Weight (%s)', 'woocommerce' ), get_option( 'woocommerce_weight_unit' ) ),
/* translators: %s: length */
'length' => sprintf( __( 'Length (%s)', 'woocommerce' ), get_option( 'woocommerce_dimension_unit' ) ),
/* translators: %s: width */
'width' => sprintf( __( 'Width (%s)', 'woocommerce' ), get_option( 'woocommerce_dimension_unit' ) ),
/* translators: %s: Height */
'height' => sprintf( __( 'Height (%s)', 'woocommerce' ), get_option( 'woocommerce_dimension_unit' ) ),
'reviews_allowed' => __( 'Allow customer reviews?', 'woocommerce' ),
'purchase_note' => __( 'Purchase note', 'woocommerce' ),
@ -129,13 +131,13 @@ class WC_Product_CSV_Exporter extends WC_CSV_Batch_Exporter {
*/
public function prepare_data_to_export() {
$columns = $this->get_column_names();
$args = apply_filters( "woocommerce_product_export_{$this->export_type}_query_args", array(
$args = apply_filters( "woocommerce_product_export_{$this->export_type}_query_args", array(
'status' => array( 'private', 'publish', 'draft' ),
'type' => $this->product_types_to_export,
'limit' => $this->get_limit(),
'page' => $this->get_page(),
'orderby' => array(
'ID' => 'ASC',
'ID' => 'ASC',
),
'return' => 'objects',
'paginate' => true,
@ -199,6 +201,26 @@ class WC_Product_CSV_Exporter extends WC_CSV_Batch_Exporter {
return isset( $statuses[ $status ] ) ? $statuses[ $status ] : -1;
}
/**
* Get formatted sale price.
*
* @param WC_Product $product Product being exported.
* @return string
*/
protected function get_column_value_sale_price( $product ) {
return wc_format_localized_price( $product->get_sale_price( 'view' ) );
}
/**
* Get formatted regular price.
*
* @param WC_Product $product Product being exported.
* @return string
*/
protected function get_column_value_regular_price( $product ) {
return wc_format_localized_price( $product->get_regular_price() );
}
/**
* Get product_cat value.
*
@ -247,7 +269,7 @@ class WC_Product_CSV_Exporter extends WC_CSV_Batch_Exporter {
$images = array();
foreach ( $image_ids as $image_id ) {
$image = wp_get_attachment_image_src( $image_id, 'full' );
$image = wp_get_attachment_image_src( $image_id, 'full' );
if ( $image ) {
$images[] = $image[0];
@ -332,7 +354,7 @@ class WC_Product_CSV_Exporter extends WC_CSV_Batch_Exporter {
}
$grouped_products = array();
$child_ids = $product->get_children( 'edit' );
$child_ids = $product->get_children( 'edit' );
foreach ( $child_ids as $child_id ) {
$child = wc_get_product( $child_id );
if ( ! $child ) {
@ -414,9 +436,9 @@ class WC_Product_CSV_Exporter extends WC_CSV_Batch_Exporter {
$backorders = $product->get_backorders( 'edit' );
switch ( $backorders ) {
case 'notify' :
case 'notify':
return 'notify';
default :
default:
return wc_string_to_bool( $backorders ) ? 1 : 0;
}
}
@ -457,10 +479,12 @@ class WC_Product_CSV_Exporter extends WC_CSV_Batch_Exporter {
if ( $downloads ) {
$i = 1;
foreach ( $downloads as $download ) {
/* translators: %s: download number */
$this->column_names[ 'downloads:name' . $i ] = sprintf( __( 'Download %d name', 'woocommerce' ), $i );
$this->column_names[ 'downloads:url' . $i ] = sprintf( __( 'Download %d URL', 'woocommerce' ), $i );
$row[ 'downloads:name' . $i ] = $download->get_name();
$row[ 'downloads:url' . $i ] = $download->get_file();
/* translators: %s: download number */
$this->column_names[ 'downloads:url' . $i ] = sprintf( __( 'Download %d URL', 'woocommerce' ), $i );
$row[ 'downloads:name' . $i ] = $download->get_name();
$row[ 'downloads:url' . $i ] = $download->get_file();
$i++;
}
}
@ -482,9 +506,13 @@ class WC_Product_CSV_Exporter extends WC_CSV_Batch_Exporter {
if ( count( $attributes ) ) {
$i = 1;
foreach ( $attributes as $attribute_name => $attribute ) {
$this->column_names[ 'attributes:name' . $i ] = sprintf( __( 'Attribute %d name', 'woocommerce' ), $i );
$this->column_names[ 'attributes:value' . $i ] = sprintf( __( 'Attribute %d value(s)', 'woocommerce' ), $i );
$this->column_names[ 'attributes:visible' . $i ] = sprintf( __( 'Attribute %d visible', 'woocommerce' ), $i );
/* translators: %s: attribute number */
$this->column_names[ 'attributes:name' . $i ] = sprintf( __( 'Attribute %d name', 'woocommerce' ), $i );
/* translators: %s: attribute number */
$this->column_names[ 'attributes:value' . $i ] = sprintf( __( 'Attribute %d value(s)', 'woocommerce' ), $i );
/* translators: %s: attribute number */
$this->column_names[ 'attributes:visible' . $i ] = sprintf( __( 'Attribute %d visible', 'woocommerce' ), $i );
/* translators: %s: attribute number */
$this->column_names[ 'attributes:taxonomy' . $i ] = sprintf( __( 'Attribute %d global', 'woocommerce' ), $i );
if ( is_a( $attribute, 'WC_Product_Attribute' ) ) {
@ -522,12 +550,13 @@ class WC_Product_CSV_Exporter extends WC_CSV_Batch_Exporter {
}
if ( $product->is_type( 'variable' ) && isset( $default_attributes[ sanitize_title( $attribute_name ) ] ) ) {
/* translators: %s: attribute number */
$this->column_names[ 'attributes:default' . $i ] = sprintf( __( 'Attribute %d default', 'woocommerce' ), $i );
$default_value = $default_attributes[ sanitize_title( $attribute_name ) ];
if ( 0 === strpos( $attribute_name, 'pa_' ) ) {
$option_term = get_term_by( 'slug', $default_value, $attribute_name ); // @codingStandardsIgnoreLine.
$row[ 'attributes:default' . $i ] = $option_term && ! is_wp_error( $option_term ) ? $option_term->name : $default_value;
$row[ 'attributes:default' . $i ] = $option_term && ! is_wp_error( $option_term ) ? $option_term->name : $default_value;
} else {
$row[ 'attributes:default' . $i ] = $default_value;
}
@ -565,7 +594,8 @@ class WC_Product_CSV_Exporter extends WC_CSV_Batch_Exporter {
continue;
}
$column_key = 'meta:' . esc_attr( $meta->key );
$column_key = 'meta:' . esc_attr( $meta->key );
/* translators: %s: meta data name */
$this->column_names[ $column_key ] = sprintf( __( 'Meta: %s', 'woocommerce' ), $meta->key );
$row[ $column_key ] = $meta_value;
$i ++;

View File

@ -7,6 +7,7 @@
* @package WooCommerce/Import
* @version 3.1.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -15,7 +16,7 @@ if ( ! defined( 'ABSPATH' ) ) {
* Include dependencies.
*/
if ( ! class_exists( 'WC_Importer_Interface', false ) ) {
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-importer-interface.php' );
include_once WC_ABSPATH . 'includes/interfaces/class-wc-importer-interface.php';
}
/**
@ -182,11 +183,19 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
}
$product = new $classname( $id );
} elseif ( isset( $data['id'] ) ) {
} elseif ( ! empty( $data['id'] ) ) {
$product = wc_get_product( $id );
if ( ! $product ) {
return new WP_Error( 'woocommerce_product_csv_importer_invalid_id', sprintf( __( 'Invalid product ID %d.', 'woocommerce' ), $id ), array( 'id' => $id, 'status' => 401 ) );
return new WP_Error(
'woocommerce_product_csv_importer_invalid_id',
/* translators: %d: product ID */
sprintf( __( 'Invalid product ID %d.', 'woocommerce' ), $id ),
array(
'id' => $id,
'status' => 401,
)
);
}
} else {
$product = new WC_Product_Simple( $id );
@ -198,6 +207,7 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
/**
* Process a single item and save.
*
* @throws Exception If item cannot be processed.
* @param array $data Raw CSV data.
* @return array|WC_Error
*/
@ -206,8 +216,12 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
do_action( 'woocommerce_product_import_before_process_item', $data );
// Get product ID from SKU if created during the importation.
if ( empty( $data['id'] ) && ! empty( $data['sku'] ) && ( $product_id = wc_get_product_id_by_sku( $data['sku'] ) ) ) {
$data['id'] = $product_id;
if ( empty( $data['id'] ) && ! empty( $data['sku'] ) ) {
$product_id = wc_get_product_id_by_sku( $data['sku'] );
if ( $product_id ) {
$data['id'] = $product_id;
}
}
$object = $this->get_product_object( $data );
@ -301,8 +315,7 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
*
* @param WC_Product $product Product instance.
* @param array $data Item data.
*
* @throws Exception
* @throws Exception If data cannot be set.
*/
protected function set_product_data( &$product, $data ) {
if ( isset( $data['raw_attributes'] ) ) {
@ -338,7 +351,7 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
}
// Check for default attributes and set "is_variation".
if ( ! empty( $attribute['default'] ) && in_array( $attribute['default'], $options ) ) {
if ( ! empty( $attribute['default'] ) && in_array( $attribute['default'], $options, true ) ) {
$default_term = get_term_by( 'name', $attribute['default'], $attribute_name );
if ( $default_term && ! is_wp_error( $default_term ) ) {
@ -348,7 +361,7 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
}
$default_attributes[ $attribute_name ] = $default;
$is_variation = 1;
$is_variation = 1;
}
if ( ! empty( $options ) ) {
@ -363,7 +376,7 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
}
} elseif ( isset( $attribute['value'] ) ) {
// Check for default attributes and set "is_variation".
if ( ! empty( $attribute['default'] ) && in_array( $attribute['default'], $attribute['value'] ) ) {
if ( ! empty( $attribute['default'] ) && in_array( $attribute['default'], $attribute['value'], true ) ) {
$default_attributes[ sanitize_title( $attribute['name'] ) ] = $attribute['default'];
$is_variation = 1;
}
@ -392,9 +405,8 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
*
* @param WC_Product $variation Product instance.
* @param array $data Item data.
*
* @return WC_Product|WP_Error
* @throws Exception
* @throws Exception If data cannot be set.
*/
protected function set_variation_data( &$variation, $data ) {
$parent = false;
@ -506,6 +518,7 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
* @param string $url Attachment URL.
* @param int $product_id Product ID.
* @return int
* @throws Exception If attachment cannot be loaded.
*/
public function get_attachment_id_from_url( $url, $product_id ) {
if ( empty( $url ) ) {
@ -524,7 +537,7 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
'post_type' => 'attachment',
'post_status' => 'any',
'fields' => 'ids',
'meta_query' => array(
'meta_query' => array( // @codingStandardsIgnoreLine.
'relation' => 'OR',
array(
'key' => '_wp_attached_file',
@ -549,7 +562,7 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
'post_type' => 'attachment',
'post_status' => 'any',
'fields' => 'ids',
'meta_query' => array(
'meta_query' => array( // @codingStandardsIgnoreLine.
array(
'value' => $url,
'key' => '_wc_attachment_source',
@ -558,7 +571,9 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
);
}
if ( $ids = get_posts( $args ) ) {
$ids = get_posts( $args ); // @codingStandardsIgnoreLine.
if ( $ids ) {
$id = current( $ids );
}
@ -573,6 +588,7 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
$id = wc_rest_set_uploaded_image_as_attachment( $upload, $product_id );
if ( ! wp_attachment_is_image( $id ) ) {
/* translators: %s: image URL */
throw new Exception( sprintf( __( 'Not able to attach "%s".', 'woocommerce' ), $url ), 400 );
}
@ -581,6 +597,7 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
}
if ( ! $id ) {
/* translators: %s: image URL */
throw new Exception( sprintf( __( 'Unable to use image "%s".', 'woocommerce' ), $url ), 400 );
}
@ -593,20 +610,23 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
*
* @param string $raw_name Attribute name.
* @return int
* @throws Exception If taxonomy cannot be loaded.
*/
public function get_attribute_taxonomy_id( $raw_name ) {
global $wpdb, $wc_product_attributes;
// These are exported as labels, so convert the label to a name if possible first.
$attribute_labels = wp_list_pluck( wc_get_attribute_taxonomies(), 'attribute_label', 'attribute_name' );
$attribute_name = '';
$attribute_name = array_search( $raw_name, $attribute_labels, true );
if ( ! $attribute_name = array_search( $raw_name, $attribute_labels ) ) {
if ( ! $attribute_name ) {
$attribute_name = wc_sanitize_taxonomy_name( $raw_name );
}
$attribute_id = wc_attribute_taxonomy_id_by_name( $attribute_name );
// Get the ID from the name.
if ( $attribute_id = wc_attribute_taxonomy_id_by_name( $attribute_name ) ) {
if ( $attribute_id ) {
return $attribute_id;
}
@ -709,7 +729,7 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
* separators.
*
* @since 3.2.0
* @param string $value
* @param string $value Value to explode.
* @return array
*/
protected function explode_values( $value ) {
@ -724,7 +744,7 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
* Remove formatting and trim each value.
*
* @since 3.2.0
* @param string $value
* @param string $value Value to format.
* @return string
*/
protected function explode_values_formatter( $value ) {

View File

@ -115,7 +115,7 @@ abstract class WC_Legacy_Cart {
break;
case 'display_totals_ex_tax' :
case 'display_cart_ex_tax' :
$value = 'excl' === $this->tax_display_cart;
$value = ! $this->display_prices_including_tax();
break;
case 'cart_contents_weight' :
$value = $this->get_cart_contents_weight();

View File

@ -162,7 +162,7 @@ class WC_Shipping_Free_Shipping extends WC_Shipping_Method {
if ( in_array( $this->requires, array( 'min_amount', 'either', 'both' ) ) ) {
$total = WC()->cart->get_displayed_subtotal();
if ( 'incl' === WC()->cart->tax_display_cart ) {
if ( WC()->cart->display_prices_including_tax() ) {
$total = round( $total - ( WC()->cart->get_discount_total() + WC()->cart->get_discount_tax() ), wc_get_price_decimals() );
} else {
$total = round( $total - WC()->cart->get_discount_total(), wc_get_price_decimals() );

View File

@ -176,7 +176,7 @@ class WC_Shipping_Legacy_Free_Shipping extends WC_Shipping_Method {
if ( in_array( $this->requires, array( 'min_amount', 'either', 'both' ) ) ) {
$total = WC()->cart->get_displayed_subtotal();
if ( 'incl' === WC()->cart->tax_display_cart ) {
if ( WC()->cart->display_prices_including_tax() ) {
$total = round( $total - ( WC()->cart->get_discount_total() + WC()->cart->get_discount_tax() ), wc_get_price_decimals() );
} else {
$total = round( $total - WC()->cart->get_discount_total(), wc_get_price_decimals() );

View File

@ -299,7 +299,7 @@ function wc_cart_totals_order_total_html() {
$value = '<strong>' . WC()->cart->get_total() . '</strong> ';
// If prices are tax inclusive, show taxes here.
if ( wc_tax_enabled() && WC()->cart->tax_display_cart == 'incl' ) {
if ( wc_tax_enabled() && WC()->cart->display_prices_including_tax() ) {
$tax_string_array = array();
$cart_tax_totals = WC()->cart->get_tax_totals();
@ -329,7 +329,7 @@ function wc_cart_totals_order_total_html() {
* @param object $fee
*/
function wc_cart_totals_fee_html( $fee ) {
$cart_totals_fee_html = ( 'excl' == WC()->cart->tax_display_cart ) ? wc_price( $fee->total ) : wc_price( $fee->total + $fee->tax );
$cart_totals_fee_html = WC()->cart->display_prices_including_tax() ? wc_price( $fee->total + $fee->tax ) : wc_price( $fee->total );
echo apply_filters( 'woocommerce_cart_totals_fee_html', $cart_totals_fee_html, $fee );
}
@ -343,16 +343,16 @@ function wc_cart_totals_shipping_method_label( $method ) {
$label = $method->get_label();
if ( $method->cost > 0 ) {
if ( WC()->cart->tax_display_cart == 'excl' ) {
$label .= ': ' . wc_price( $method->cost );
if ( $method->get_shipping_tax() > 0 && wc_prices_include_tax() ) {
$label .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
}
} else {
if ( WC()->cart->display_prices_including_tax() ) {
$label .= ': ' . wc_price( $method->cost + $method->get_shipping_tax() );
if ( $method->get_shipping_tax() > 0 && ! wc_prices_include_tax() ) {
$label .= ' <small class="tax_label">' . WC()->countries->inc_tax_or_vat() . '</small>';
}
} else {
$label .= ': ' . wc_price( $method->cost );
if ( $method->get_shipping_tax() > 0 && wc_prices_include_tax() ) {
$label .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
}
}
}

View File

@ -53,6 +53,7 @@ add_filter( 'woocommerce_short_description', 'prepend_attachment' );
add_filter( 'woocommerce_short_description', 'do_shortcode', 11 ); // After wpautop().
add_filter( 'woocommerce_short_description', 'wc_format_product_short_description', 9999999 );
add_filter( 'woocommerce_short_description', 'wc_do_oembeds' );
add_filter( 'woocommerce_short_description', array( $GLOBALS['wp_embed'], 'run_shortcode' ), 8 ); // Before wpautop().
/**
* Define a constant if it is not already defined.
@ -1830,7 +1831,7 @@ function wc_make_phone_clickable( $phone ) {
* @return mixed Value sanitized by wc_clean.
*/
function wc_get_post_data_by_key( $key, $default = '' ) {
return wc_clean( wc_get_var( wp_unslash( $_POST[ $key ] ), $default ) ); // @codingStandardsIgnoreLine
return wc_clean( wp_unslash( wc_get_var( $_POST[ $key ], $default ) ) ); // @codingStandardsIgnoreLine
}
/**
@ -1947,3 +1948,29 @@ function wc_is_external_resource( $url ) {
return strstr( $url, '://' ) && strstr( $wp_base, $url );
}
/**
* See if theme/s is activate or not.
*
* @since 3.3.0
* @param string|array $theme Theme name or array of theme names to check.
* @return boolean
*/
function wc_is_active_theme( $theme ) {
return is_array( $theme ) ? in_array( get_template(), $theme, true ) : get_template() === $theme;
}
/**
* Cleans up session data - cron callback.
*
* @since 3.3.0
*/
function wc_cleanup_session_data() {
$session_class = apply_filters( 'woocommerce_session_handler', 'WC_Session_Handler' );
$session = new $session_class();
if ( is_callable( array( $session, 'cleanup_sessions' ) ) ) {
$session->cleanup_sessions();
}
}
add_action( 'woocommerce_cleanup_sessions', 'wc_cleanup_session_data' );

View File

@ -812,6 +812,27 @@ if ( ! function_exists( 'wc_hex_lighter' ) ) {
}
}
if ( ! function_exists( 'wc_is_light' ) ) {
/**
* Determine whether a hex color is light.
*
* @param mixed $color Color.
* @return bool True if a light color.
*/
function wc_hex_is_light( $color ) {
$hex = str_replace( '#', '', $color );
$c_r = hexdec( substr( $hex, 0, 2 ) );
$c_g = hexdec( substr( $hex, 2, 2 ) );
$c_b = hexdec( substr( $hex, 4, 2 ) );
$brightness = ( ( $c_r * 299 ) + ( $c_g * 587 ) + ( $c_b * 114 ) ) / 1000;
return $brightness > 155;
}
}
if ( ! function_exists( 'wc_light_or_dark' ) ) {
/**
@ -825,15 +846,7 @@ if ( ! function_exists( 'wc_light_or_dark' ) ) {
* @return string
*/
function wc_light_or_dark( $color, $dark = '#000000', $light = '#FFFFFF' ) {
$hex = str_replace( '#', '', $color );
$c_r = hexdec( substr( $hex, 0, 2 ) );
$c_g = hexdec( substr( $hex, 2, 2 ) );
$c_b = hexdec( substr( $hex, 4, 2 ) );
$brightness = ( ( $c_r * 299 ) + ( $c_g * 587 ) + ( $c_b * 114 ) ) / 1000;
return $brightness > 155 ? $dark : $light;
return wc_hex_is_light( $color ) ? $dark : $light;
}
}

View File

@ -391,6 +391,7 @@ function wc_scheduled_sales() {
// Sales which are due to start.
$product_ids = $data_store->get_starting_sales();
if ( $product_ids ) {
do_action( 'wc_before_products_starting_sales', $product_ids );
foreach ( $product_ids as $product_id ) {
if ( $product = wc_get_product( $product_id ) ) {
$sale_price = $product->get_sale_price();
@ -406,6 +407,7 @@ function wc_scheduled_sales() {
$product->save();
}
}
do_action( 'wc_after_products_starting_sales', $product_ids );
delete_transient( 'wc_products_onsale' );
}
@ -413,6 +415,7 @@ function wc_scheduled_sales() {
// Sales which are due to end.
$product_ids = $data_store->get_ending_sales();
if ( $product_ids ) {
do_action( 'wc_before_products_ending_sales', $product_ids );
foreach ( $product_ids as $product_id ) {
if ( $product = wc_get_product( $product_id ) ) {
$regular_price = $product->get_regular_price();
@ -423,6 +426,7 @@ function wc_scheduled_sales() {
$product->save();
}
}
do_action( 'wc_after_products_ending_sales', $product_ids );
WC_Cache_Helper::get_transient_version( 'product', true );
delete_transient( 'wc_products_onsale' );
@ -746,20 +750,22 @@ function wc_get_min_max_price_meta_query( $args ) {
/**
* Adjust if the store taxes are not displayed how they are stored.
* Max is left alone because the filter was already increased.
* Kicks in when prices excluding tax are displayed including tax.
*/
if ( wc_tax_enabled() && 'incl' === get_option( 'woocommerce_tax_display_shop' ) && ! wc_prices_include_tax() ) {
$tax_classes = array_merge( array( '' ), WC_Tax::get_tax_classes() );
$class_min = $min;
$class_max = $max;
foreach ( $tax_classes as $tax_class ) {
if ( $tax_rates = WC_Tax::get_rates( $tax_class ) ) {
$class_min = $min - WC_Tax::get_tax_total( WC_Tax::calc_exclusive_tax( $min, $tax_rates ) );
$class_min = $min + WC_Tax::get_tax_total( WC_Tax::calc_exclusive_tax( $min, $tax_rates ) );
$class_max = $max - WC_Tax::get_tax_total( WC_Tax::calc_exclusive_tax( $max, $tax_rates ) );
}
}
$min = $class_min;
$max = $class_max;
}
return array(
@ -849,6 +855,11 @@ function wc_get_related_products( $product_id, $limit = 5, $exclude_ids = array(
set_transient( $transient_name, $related_posts, DAY_IN_SECONDS );
}
$related_posts = apply_filters( 'woocommerce_related_products', $related_posts, $product_id, array(
'limit' => $limit,
'excluded_ids' => $exclude_ids,
) );
shuffle( $related_posts );
return array_slice( $related_posts, 0, $limit );

View File

@ -371,7 +371,7 @@ function wc_reset_product_grid_settings() {
delete_option( 'woocommerce_catalog_rows' );
}
if ( isset( $theme_support['product_grid']['default_rows'] ) ) {
if ( isset( $theme_support['product_grid']['default_columns'] ) ) {
update_option( 'woocommerce_catalog_columns', absint( $theme_support['product_grid']['default_columns'] ) );
} else {
delete_option( 'woocommerce_catalog_columns' );
@ -778,7 +778,11 @@ if ( ! function_exists( 'woocommerce_template_loop_product_link_open' ) ) {
* Insert the opening anchor tag for products in the loop.
*/
function woocommerce_template_loop_product_link_open() {
echo '<a href="' . esc_url( get_the_permalink() ) . '" class="woocommerce-LoopProduct-link woocommerce-loop-product__link">';
global $product;
$link = apply_filters( 'woocommerce_loop_product_link', get_the_permalink(), $product );
echo '<a href="' . esc_url( $link ) . '" class="woocommerce-LoopProduct-link woocommerce-loop-product__link">';
}
}

View File

@ -50,7 +50,7 @@ class WC_Widget_Layered_Nav_Filters extends WC_Widget {
$min_price = isset( $_GET['min_price'] ) ? wc_clean( $_GET['min_price'] ) : 0;
$max_price = isset( $_GET['max_price'] ) ? wc_clean( $_GET['max_price'] ) : 0;
$rating_filter = isset( $_GET['rating_filter'] ) ? array_filter( array_map( 'absint', explode( ',', $_GET['rating_filter'] ) ) ) : array();
$base_link = $this->get_page_base_url();
$base_link = $this->get_current_page_url();
if ( 0 < count( $_chosen_attributes ) || 0 < $min_price || 0 < $max_price || ! empty( $rating_filter ) ) {

View File

@ -424,7 +424,7 @@ class WC_Widget_Layered_Nav extends WC_Widget {
$current_filter[] = $term->slug;
}
$link = remove_query_arg( $filter_name, $this->get_page_base_url() );
$link = remove_query_arg( $filter_name, $this->get_current_page_url() );
// Add current filters to URL.
foreach ( $current_filter as $key => $value ) {

View File

@ -89,24 +89,6 @@ class WC_Widget_Price_Filter extends WC_Widget {
$form_action = preg_replace( '%\/page/[0-9]+%', '', home_url( trailingslashit( $wp->request ) ) );
}
/**
* Adjust max if the store taxes are not displayed how they are stored.
* Min is left alone because the product may not be taxable.
* Kicks in when prices excluding tax are displayed including tax.
*/
if ( wc_tax_enabled() && 'incl' === get_option( 'woocommerce_tax_display_shop' ) && ! wc_prices_include_tax() ) {
$tax_classes = array_merge( array( '' ), WC_Tax::get_tax_classes() );
$class_max = $max;
foreach ( $tax_classes as $tax_class ) {
if ( $tax_rates = WC_Tax::get_rates( $tax_class ) ) {
$class_max = $max + WC_Tax::get_tax_total( WC_Tax::calc_exclusive_tax( $max, $tax_rates ) );
}
}
$max = $class_max;
}
$min_price = isset( $_GET['min_price'] ) ? esc_attr( $_GET['min_price'] ) : apply_filters( 'woocommerce_price_filter_widget_min_amount', $min );
$max_price = isset( $_GET['max_price'] ) ? esc_attr( $_GET['max_price'] ) : apply_filters( 'woocommerce_price_filter_widget_max_amount', $max );

View File

@ -112,7 +112,7 @@ class WC_Widget_Rating_Filter extends WC_Widget {
continue;
}
$found = true;
$link = $this->get_page_base_url();
$link = $this->get_current_page_url();
if ( in_array( $rating, $rating_filter ) ) {
$link_ratings = implode( ',', array_diff( $rating_filter, array( $rating ) ) );

6295
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
{
"name": "woocommerce",
"title": "WooCommerce",
"version": "3.1.0",
"version": "3.3.0",
"homepage": "https://woocommerce.com/",
"repository": {
"type": "git",
@ -47,10 +47,10 @@
"istanbul": "^1.0.0-alpha",
"mocha": "^3.0.2",
"stylelint": "~8.2.0",
"wc-e2e-page-objects": "0.5.0"
"wc-e2e-page-objects": "0.6.0"
},
"engines": {
"node": ">=6.9.4",
"npm": ">=1.1.0"
"node": ">=8.9.3",
"npm": ">=5.5.1"
}
}

View File

@ -20,7 +20,8 @@
<config name="testVersion" value="5.2-"/>
<!-- Rules -->
<rule ref="PHPCompatibility"/>
<rule ref="WooCommerce-Core" />
<rule ref="PHPCompatibility" />
<rule ref="WordPress">
<exclude name="WordPress.VIP.DirectDatabaseQuery.NoCaching" />

View File

@ -22,11 +22,11 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php do_action( 'woocommerce_auth_page_header' ); ?>
<h1><?php printf( __( '%s would like to connect to your store' , 'woocommerce' ), esc_html( $app_name ) ); ?></h1>
<h1><?php printf( __( '%s would like to connect to your store', 'woocommerce' ), esc_html( $app_name ) ); ?></h1>
<?php wc_print_notices(); ?>
<p><?php printf( __( 'This will give "%1$s" %2$s access which will allow it to:' , 'woocommerce' ), '<strong>' . esc_html( $app_name ) . '</strong>', '<strong>' . esc_html( $scope ) . '</strong>' ); ?></p>
<p><?php printf( __( 'This will give "%1$s" %2$s access which will allow it to:', 'woocommerce' ), '<strong>' . esc_html( $app_name ) . '</strong>', '<strong>' . esc_html( $scope ) . '</strong>' ); ?></p>
<ul class="wc-auth-permissions">
<?php foreach ( $permissions as $permission ) : ?>

View File

@ -65,7 +65,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</tr>
<?php endforeach; ?>
<?php if ( wc_tax_enabled() && 'excl' === WC()->cart->tax_display_cart ) :
<?php if ( wc_tax_enabled() && ! WC()->cart->display_prices_including_tax() ) :
$taxable_address = WC()->customer->get_taxable_address();
$estimated_text = WC()->customer->is_customer_outside_base() && ! WC()->customer->has_calculated_shipping()
? sprintf( ' <small>' . __( '(estimated for %s)', 'woocommerce' ) . '</small>', WC()->countries->estimated_for_prefix( $taxable_address[0] ) . WC()->countries->countries[ $taxable_address[0] ] )

View File

@ -84,7 +84,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</tr>
<?php endforeach; ?>
<?php if ( wc_tax_enabled() && 'excl' === WC()->cart->tax_display_cart ) : ?>
<?php if ( wc_tax_enabled() && ! WC()->cart->display_prices_including_tax() ) : ?>
<?php if ( 'itemized' === get_option( 'woocommerce_tax_total_display' ) ) : ?>
<?php foreach ( WC()->cart->get_tax_totals() as $code => $tax ) : ?>
<tr class="tax-rate tax-rate-<?php echo sanitize_title( $code ); ?>">

View File

@ -13,20 +13,26 @@
* @see https://docs.woocommerce.com/document/template-structure/
* @author WooThemes
* @package WooCommerce/Templates/Emails
* @version 2.3.0
* @version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
exit;
}
// Load colors
// Load colors.
$bg = get_option( 'woocommerce_email_background_color' );
$body = get_option( 'woocommerce_email_body_background_color' );
$base = get_option( 'woocommerce_email_base_color' );
$base_text = wc_light_or_dark( $base, '#202020', '#ffffff' );
$text = get_option( 'woocommerce_email_text_color' );
// Pick a contrasting color for links.
$link = wc_hex_is_light( $base ) ? $base : $base_text;
if ( wc_hex_is_light( $body ) ) {
$link = wc_hex_is_light( $base ) ? $base_text : $base;
}
$bg_darker_10 = wc_hex_darker( $bg, 10 );
$body_darker_10 = wc_hex_darker( $body, 10 );
$base_lighter_20 = wc_hex_lighter( $base, 20 );
@ -185,7 +191,7 @@ h3 {
}
a {
color: <?php echo esc_attr( $base_text ); ?>;
color: <?php echo esc_attr( $link ); ?>;
font-weight: normal;
text-decoration: underline;
}

View File

@ -44,7 +44,7 @@ if ( is_user_logged_in() ) {
<?php do_action( 'woocommerce_login_form' ); ?>
<p class="form-row">
<?php wp_nonce_field( 'woocommerce-login' ); ?>
<?php wp_nonce_field( 'woocommerce-login', 'woocommerce-login-nonce' ); ?>
<button type="submit" class="button" name="login" value="<?php esc_attr_e( 'Login', 'woocommerce' ); ?>"><?php esc_html_e( 'Login', 'woocommerce' ); ?></button>
<input type="hidden" name="redirect" value="<?php echo esc_url( $redirect ) ?>" />
<label class="woocommerce-form__label woocommerce-form__label-for-checkbox inline">

View File

@ -52,7 +52,7 @@ do_action( 'woocommerce_before_add_to_cart_form' ); ?>
case 'quantity' :
ob_start();
if ( ! $grouped_product->is_purchasable() || $grouped_product->has_options() ) {
if ( ! $grouped_product->is_purchasable() || $grouped_product->has_options() || ! $grouped_product->is_in_stock() ) {
woocommerce_template_loop_add_to_cart();
} elseif ( $grouped_product->is_sold_individually() ) {
echo '<input type="checkbox" name="' . esc_attr( 'quantity[' . $grouped_product->get_id() . ']' ) . '" value="1" class="wc-grouped-product-add-to-cart-checkbox" />';

View File

@ -10,23 +10,25 @@
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see https://docs.woocommerce.com/document/template-structure/
* @author WooThemes
* @package WooCommerce/Templates
* @version 1.6.4
* @see https://docs.woocommerce.com/document/template-structure/
* @author Automattic
* @package WooCommerce/Templates
* @version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
exit; // Exit if accessed directly.
}
global $post;
if ( ! $post->post_excerpt ) {
$short_description = apply_filters( 'woocommerce_short_description', $post->post_excerpt );
if ( ! $short_description ) {
return;
}
?>
<div class="woocommerce-product-details__short-description">
<?php echo apply_filters( 'woocommerce_short_description', $post->post_excerpt ); ?>
<?php echo $short_description; // WPCS: XSS ok. ?>
</div>

View File

@ -6,6 +6,6 @@ if [[ ${RUN_PHPCS} == 1 ]]; then
if [ "$CHANGED_FILES" != "" ]; then
echo "Running Code Sniffer."
./vendor/bin/phpcs --ignore=$IGNORE --standard=./phpcs.ruleset.xml --encoding=utf-8 -n -p $CHANGED_FILES
./vendor/bin/phpcs --ignore=$IGNORE --encoding=utf-8 -n -p $CHANGED_FILES
fi
fi

View File

@ -4,6 +4,10 @@
"admin": {
"username": "admin",
"password": "password"
},
"customer": {
"username": "Customer",
"password": "password"
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,122 @@
/**
* External dependencies
*/
import config from 'config';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import test from 'selenium-webdriver/testing';
import { WebDriverManager, WebDriverHelper as helper } from 'wp-e2e-webdriver';
import { CustomerFlow, MyAccountPage, PageMap } from 'wc-e2e-page-objects';
chai.use( chaiAsPromised );
const assert = chai.assert;
let manager;
let driver;
test.describe( 'My account page', function() {
const loginAsCustomer = () => {
return new CustomerFlow( driver, {
baseUrl: config.get( 'url' ),
username: config.get( 'users.customer.username' ),
password: config.get( 'users.customer.password' )
} );
};
const getMyAccountSubPageUrl = path => {
return PageMap.getPageUrl( config.get( 'url' ), {
path: '/my-account/%s'
}, path );
};
const untrailingslashit = url => {
return url.endsWith( '/' ) ? url.substring( 0, url.length - 1 ) : url;
};
// open browser
test.before( function() {
this.timeout( config.get( 'startBrowserTimeoutMs' ) );
manager = new WebDriverManager( 'chrome', { baseUrl: config.get( 'url' ) } );
driver = manager.getDriver();
helper.clearCookiesAndDeleteLocalStorage( driver );
} );
this.timeout( config.get( 'mochaTimeoutMs' ) );
test.it( 'allows customer to login', () => {
loginAsCustomer();
const myAccount = new MyAccountPage( driver, {
baseUrl: config.get( 'url' ),
visit: false
} );
assert.eventually.ok( myAccount.hasText( 'Hello Customer' ), 'see "Hello Customer" text' );
assert.eventually.ok( myAccount.hasMenu( 'Dashboard' ), 'see Dashboard menu.' );
assert.eventually.ok( myAccount.hasMenu( 'Orders' ), 'see Orders menu' );
} );
test.it( 'allows customer to see orders', () => {
loginAsCustomer();
const myAccount = new MyAccountPage( driver, {
baseUrl: config.get( 'url' ),
visit: false
} );
myAccount.clickMenu( 'Orders' );
assert.eventually.equal(
driver.getCurrentUrl().then( untrailingslashit ),
untrailingslashit( getMyAccountSubPageUrl( 'orders' ) )
);
assert.eventually.ok( myAccount.hasText( 'Orders' ), 'see "Orders" text' );
} );
test.it( 'allows customer to see downloads', () => {
loginAsCustomer();
const myAccount = new MyAccountPage( driver, {
baseUrl: config.get( 'url' ),
visit: false
} );
myAccount.clickMenu( 'Downloads' );
assert.eventually.equal(
driver.getCurrentUrl().then( untrailingslashit ),
untrailingslashit( getMyAccountSubPageUrl( 'downloads' ) )
);
assert.eventually.ok( myAccount.hasText( 'Downloads' ), 'see "Downloads" text' );
} );
test.it( 'allows customer to edit addresses', () => {
loginAsCustomer();
const myAccount = new MyAccountPage( driver, {
baseUrl: config.get( 'url' ),
visit: false
} );
myAccount.clickMenu( 'Addresses' );
assert.eventually.equal(
driver.getCurrentUrl().then( untrailingslashit ),
untrailingslashit( getMyAccountSubPageUrl( 'edit-address' ) )
);
assert.eventually.ok( myAccount.hasText( 'Addresses' ), 'see "Addresses" text' );
} );
test.it( 'allows customer to edit account details', () => {
loginAsCustomer();
const myAccount = new MyAccountPage( driver, {
baseUrl: config.get( 'url' ),
visit: false
} );
myAccount.clickMenu( 'Account details' );
assert.eventually.equal(
driver.getCurrentUrl().then( untrailingslashit ),
untrailingslashit( getMyAccountSubPageUrl( 'edit-account' ) )
);
assert.eventually.ok( myAccount.hasText( 'Account details' ), 'see "Account details" text' );
} );
// quit browser
test.after( () => {
manager.quitBrowser();
} );
} );

View File

@ -16,6 +16,13 @@ let manager;
let driver;
test.describe( 'Single Product Page', function() {
const visitProductByPath = path => {
return new SingleProductPage( driver, { url: manager.getPageUrl( path ) } );
};
const visitCart = () => {
return new CartPage( driver, { url: manager.getPageUrl( '/cart' ) } );
};
// open browser
test.before( function() {
this.timeout( config.get( 'startBrowserTimeoutMs' ) );
@ -29,28 +36,29 @@ test.describe( 'Single Product Page', function() {
this.timeout( config.get( 'mochaTimeoutMs' ) );
test.it( 'should be able to add simple products to the cart', () => {
const productPage = new SingleProductPage( driver, { url: manager.getPageUrl( '/product/t-shirt' ) } );
const productPage = visitProductByPath( '/product/t-shirt' );
productPage.setQuantity( 5 );
productPage.addToCart();
const cartPage = new CartPage( driver, { url: manager.getPageUrl( '/cart' ) } );
assert.eventually.equal( cartPage.hasItem( 'T-Shirt', { qty: 5 } ), true );
assert.eventually.equal( visitCart().hasItem( 'T-Shirt', { qty: 5 } ), true );
} );
test.it( 'should be able to add variation products to the cart', () => {
const variableProductPage = new SingleProductPage( driver, { url: manager.getPageUrl( '/product/hoodie' ) } );
let variableProductPage;
variableProductPage = visitProductByPath( '/product/hoodie' );
variableProductPage.selectVariation( 'Color', 'Blue' );
variableProductPage.addToCart();
// Pause for a half-second. Driver goes too fast and makes wrong selections otherwise.
variableProductPage.selectVariation( 'Logo', 'Yes' );
driver.sleep( 500 );
variableProductPage.selectVariation( 'Color', 'Green' );
variableProductPage.addToCart();
assert.eventually.ok( visitCart().hasItem( 'Hoodie - Blue, Yes' ), '"Hoodie - Blue, Yes" in the cart' );
const cartPage = new CartPage( driver, { url: manager.getPageUrl( '/cart' ) } );
assert.eventually.equal( cartPage.hasItem( 'Hoodie - Blue' ), true );
assert.eventually.equal( cartPage.hasItem( 'Hoodie - Green' ), true );
variableProductPage = visitProductByPath( '/product/hoodie' );
variableProductPage.selectVariation( 'Color', 'Green' );
variableProductPage.selectVariation( 'Logo', 'No' );
driver.sleep( 500 );
variableProductPage.addToCart();
assert.eventually.ok( visitCart().hasItem( 'Hoodie - Green, No' ), '"Hoodie - Green, No" in the cart' );
} );
// quit browser

View File

@ -13,9 +13,9 @@ class WC_Helper_Customer {
* @return WC_Customer
*/
public static function create_mock_customer() {
$customer_data = array(
'id' => 0,
'date_modified' => null,
'country' => 'US',
'state' => 'PA',
'postcode' => '19123',
@ -35,6 +35,7 @@ class WC_Helper_Customer {
WC_Helper_Customer::set_customer_details( $customer_data );
$customer = new WC_Customer( 0, true );
return $customer;
}
@ -105,7 +106,7 @@ class WC_Helper_Customer {
* @param string $default_shipping_method Shipping Method slug
*/
public static function set_customer_details( $customer_details ) {
WC()->session->set( 'customer', $customer_details );
WC()->session->set( 'customer', array_map( 'strval', $customer_details ) );
}
/**

View File

@ -330,6 +330,92 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case {
WC_Helper_Order::delete_order( $order->get_id() );
}
/**
* Tests updating an order and adding a coupon.
*
* @since 3.3.0
*/
public function test_update_order_add_coupons() {
wp_set_current_user( $this->user );
$order = WC_Helper_Order::create_order();
$order_item = current( $order->get_items() );
$coupon = WC_Helper_Coupon::create_coupon( 'fake-coupon' );
$coupon->set_amount( 5 );
$coupon->save();
$request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() );
$request->set_body_params( array(
'coupon_lines' => array(
array(
'code' => 'fake-coupon',
'discount_total' => '5',
'discount_tax' => '0',
),
),
'line_items' => array(
array(
'id' => $order_item->get_id(),
'product_id' => $order_item->get_product_id(),
'total' => '35.00',
),
),
) );
$response = $this->server->dispatch( $request );
$data = $response->get_data();
$this->assertEquals( 200, $response->get_status() );
$this->assertCount( 1, $data['coupon_lines'] );
$this->assertEquals( '45.00', $data['total'] );
WC_Helper_Order::delete_order( $order->get_id() );
}
/**
* Tests updating an order and removing a coupon.
*
* @since 3.3.0
*/
public function test_update_order_remove_coupons() {
wp_set_current_user( $this->user );
$order = WC_Helper_Order::create_order();
$order_item = current( $order->get_items() );
$coupon = WC_Helper_Coupon::create_coupon( 'fake-coupon' );
$coupon->set_amount( 5 );
$coupon->save();
$order->apply_coupon( $coupon );
$order->save();
// Check that the coupon is applied.
$this->assertEquals( '45.00', $order->get_total() );
$request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() );
$coupon_data = current( $order->get_items( 'coupon' ) );
$request->set_body_params( array(
'coupon_lines' => array(
array(
'id' => $coupon_data->get_id(),
'code' => null,
),
),
'line_items' => array(
array(
'id' => $order_item->get_id(),
'product_id' => $order_item->get_product_id(),
'total' => '40.00',
),
),
) );
$response = $this->server->dispatch( $request );
$data = $response->get_data();
$this->assertEquals( 200, $response->get_status() );
$this->assertTrue( empty( $data['coupon_lines'] ) );
$this->assertEquals( '50.00', $data['total'] );
WC_Helper_Order::delete_order( $order->get_id() );
}
/**
* Tests updating an order without the correct permissions.
*

View File

@ -1,55 +0,0 @@
<?php
/**
* Class Functions.
*
* @package WooCommerce\Tests\Core
* @since 3.2.0
*/
class WC_Tests_WooCommerce_Functions extends WC_Unit_Test_Case {
/**
* Tests wc_maybe_define_constant().
*
* @since 3.2.0
*/
public function test_wc_maybe_define_constant() {
$this->assertFalse( defined( 'WC_TESTING_DEFINE_FUNCTION' ) );
// Check if defined.
wc_maybe_define_constant( 'WC_TESTING_DEFINE_FUNCTION', true );
$this->assertTrue( defined( 'WC_TESTING_DEFINE_FUNCTION' ) );
// Check value.
wc_maybe_define_constant( 'WC_TESTING_DEFINE_FUNCTION', false );
$this->assertTrue( WC_TESTING_DEFINE_FUNCTION );
}
/**
* Tests wc_create_order() and wc_update_order() currency handling.
*
* @since 3.2.0
*/
public function test_wc_create_update_order_currency() {
$old_currency = get_woocommerce_currency();
$new_currency = 'BGN';
update_option( 'woocommerce_currency', $new_currency );
// New order should be created using shop currency.
$order = wc_create_order( array(
'status' => 'pending',
'customer_id' => 1,
) );
$this->assertEquals( $new_currency, $order->get_currency() );
update_option( 'woocommerce_currency', $old_currency );
// Currency should not change when order is updated.
$order = wc_update_order( array(
'customer_id' => 2,
'order_id' => $order->get_id(),
) );
$this->assertEquals( $new_currency, $order->get_currency() );
}
}

View File

@ -442,8 +442,7 @@ class WC_Tests_CustomerCRUD extends WC_Unit_Test_Case {
* @since 3.0.0
*/
public function test_customer_sessions() {
$customer = WC_Helper_Customer::create_customer();
$session = WC_Helper_Customer::create_mock_customer(); // set into session....
$session = WC_Helper_Customer::create_mock_customer(); // set into session....
$this->assertEquals( '19123', $session->get_billing_postcode() );
$this->assertEquals( '123 South Street', $session->get_billing_address() );

View File

@ -0,0 +1,284 @@
<?php
/**
* Unit tests for the WC_Order_Item_Product class.
*
* @package WooCommerce\Tests\Order_Items
* @since 3.2.0
*/
/**
* Order Item Product unit tests.
*/
class WC_Tests_Order_Item_Product extends WC_Unit_Test_Case {
/**
* Test generic setters and getters for WC_Order_Item_Product.
*
* @since 3.2.0
*/
public function test_generic_setters_getters() {
$simple_product = new WC_Product_Simple();
$simple_product->save();
$variation_product = new WC_Product_Variation();
$variation_product->save();
$product_item = new WC_Order_Item_Product();
$product_item->set_quantity( 3 );
$this->assertEquals( 3, $product_item->get_quantity() );
$product_item->set_tax_class( 'reduced-rate' );
$this->assertEquals( 'reduced-rate', $product_item->get_tax_class() );
$product_item->set_product_id( $simple_product->get_id() );
$this->assertEquals( $simple_product->get_id(), $product_item->get_product_id() );
$product_item->set_variation_id( $variation_product->get_id() );
$this->assertEquals( $variation_product->get_id(), $product_item->get_variation_id() );
$product_item->set_subtotal( '12.00' );
$this->assertEquals( '12.00', $product_item->get_subtotal() );
$product_item->set_total( '10.00' );
$this->assertEquals( '10.00', $product_item->get_total() );
$product_item->set_subtotal_tax( '0.50' );
$this->assertEquals( '0.50', $product_item->get_subtotal_tax() );
$product_item->set_total_tax( '0.30' );
$this->assertEquals( '0.30', $product_item->get_total_tax() );
}
/**
* Test set_taxes and get_taxes for WC_Order_Item_Product.
*
* @since 3.2.0
*/
public function test_set_get_taxes() {
$product_item = new WC_Order_Item_Product();
$taxes = array(
'total' => array( '10', '2.4' ),
'subtotal' => array( '12', '3.1' ),
);
$product_item->set_taxes( $taxes );
$this->assertEquals( $taxes, $product_item->get_taxes() );
$this->assertEquals( '12.4', $product_item->get_total_tax() );
$this->assertEquals( '15.1', $product_item->get_subtotal_tax() );
}
/**
* Test set_product and get_product for WC_Order_Item_Product.
*
* @since 3.2.0
*/
public function test_set_get_product() {
$simple_product = new WC_Product_Simple();
$simple_product->set_name( 'Test Simple' );
$simple_product->set_tax_class( 'reduced-rate' );
$simple_product->save();
$parent_product = new WC_Product_Variable();
$parent_product->set_name( 'Test Parent' );
$parent_product->save();
$variation_product = new WC_Product_Variation();
$variation_product->set_name( 'Test Variation' );
$variation_product->set_parent_id( $parent_product->get_id() );
$variation_product->set_attributes( array( 'color' => 'Green' ) );
$variation_product->save();
// Simple product.
$product_item = new WC_Order_Item_Product();
$product_item->set_product( $simple_product );
$this->assertEquals( 'Test Simple', $product_item->get_name() );
$this->assertEquals( $simple_product->get_id(), $product_item->get_product_id() );
$this->assertEquals( 0, $product_item->get_variation_id() );
$this->assertEquals( 'reduced-rate', $product_item->get_tax_class() );
$retrieved = $product_item->get_product();
$this->assertEquals( $simple_product->get_id(), $retrieved->get_id() );
// Variation product.
$product_item = new WC_Order_Item_Product();
$product_item->set_product( $variation_product );
$this->assertEquals( 'Test Parent - Green', $product_item->get_name() );
$this->assertEquals( $parent_product->get_id(), $product_item->get_product_id() );
$this->assertEquals( $variation_product->get_id(), $product_item->get_variation_id() );
$this->assertEquals( '', $product_item->get_tax_class() );
$this->assertEquals( 'Green', $product_item->get_meta( 'color' ) );
$retrieved = $product_item->get_product();
$this->assertEquals( $variation_product->get_id(), $retrieved->get_id() );
}
/**
* Test get_item_download_url method for WC_Order_Item_Product.
*
* @since 3.2.0
*/
public function test_get_item_download_url() {
$product = new WC_Product_Simple();
$product->save();
$order = new WC_Order();
$order->set_billing_email( 'test@woocommerce.com' );
$order->save();
$product_item = new WC_Order_Item_Product();
$product_item->set_product( $product );
$product_item->set_order_id( $order->get_id() );
$expected_regex = '/download_file=.*&order=wc_order_.*&email=test%40woocommerce.com&key=100/';
$this->assertRegexp( $expected_regex, $product_item->get_item_download_url( 100 ) );
}
/**
* Test the get_formatted_meta_data method.
*
* @since 3.3.0
*/
public function test_get_formatted_meta_data() {
$parent_product = new WC_Product_Variable();
$parent_product->set_name( 'Test Parent' );
$parent_product->save();
$variation_product = new WC_Product_Variation();
$variation_product->set_name( 'Test Variation' );
$variation_product->set_parent_id( $parent_product->get_id() );
$variation_product->set_attributes( array(
'color' => 'Green',
'size' => 'Large',
) );
$variation_product->save();
$product_item = new WC_Order_Item_Product();
$product_item->set_product( $variation_product );
$product_item->add_meta_data( 'testkey', 'testval', true );
$product_item->save();
// Test with show_all on.
$formatted = $product_item->get_formatted_meta_data( '_', true );
$formatted_as_array = array();
foreach ( $formatted as $f ) {
$formatted_as_array[] = (array) $f;
}
$this->assertEquals(
array(
array(
'key' => 'color',
'value' => 'Green',
'display_key' => 'color',
'display_value' => "<p>Green</p>\n",
),
array(
'key' => 'size',
'value' => 'Large',
'display_key' => 'size',
'display_value' => "<p>Large</p>\n",
),
array(
'key' => 'testkey',
'value' => 'testval',
'display_key' => 'testkey',
'display_value' => "<p>testval</p>\n",
),
),
$formatted_as_array
);
// Test with show_all off.
$formatted = $product_item->get_formatted_meta_data( '_', false );
$formatted_as_array = array();
foreach ( $formatted as $f ) {
$formatted_as_array[] = (array) $f;
}
$this->assertEquals(
array(
array(
'key' => 'testkey',
'value' => 'testval',
'display_key' => 'testkey',
'display_value' => "<p>testval</p>\n",
),
),
$formatted_as_array
);
// Test with an exclude prefix. Should exclude everything since they're either in the title or in the exclude prefix.
$formatted = $product_item->get_formatted_meta_data( 'test', false );
$this->assertEmpty( $formatted );
}
/**
* Test the Array Access methods.
*
* @since 3.3.0
*/
public function test_arrayaccess() {
$item = new WC_Order_Item_Product();
// Test line_subtotal.
$this->assertTrue( isset( $item['line_subtotal'] ) );
$item['line_subtotal'] = 50;
$this->assertEquals( 50, $item->get_subtotal() );
$this->assertEquals( $item->get_subtotal(), $item['line_subtotal'] );
// Test line_subtotal_tax.
$this->assertTrue( isset( $item['line_subtotal_tax'] ) );
$item['line_subtotal_tax'] = 5;
$this->assertEquals( 5, $item->get_subtotal_tax() );
$this->assertEquals( $item->get_subtotal_tax(), $item['line_subtotal_tax'] );
// Test line_total.
$this->assertTrue( isset( $item['line_total'] ) );
$item['line_total'] = 55;
$this->assertEquals( 55, $item->get_total() );
$this->assertEquals( $item->get_total(), $item['line_total'] );
// Test line_tax.
$this->assertTrue( isset( $item['line_tax'] ) );
$item['line_tax'] = 5;
$this->assertEquals( 5, $item->get_total_tax() );
$this->assertEquals( $item->get_total_tax(), $item['line_tax'] );
// Test line_tax_data.
$this->assertTrue( isset( $item['line_tax_data'] ) );
$item['line_tax_data'] = array(
'total' => array( 5 ),
'subtotal' => array( 5 ),
);
$this->assertEquals(
array(
'total' => array( 5 ),
'subtotal' => array( 5 ),
),
$item->get_taxes()
);
$this->assertEquals( $item->get_taxes(), $item['line_tax_data'] );
// Test qty.
$this->assertTrue( isset( $item['qty'] ) );
$item['qty'] = 150;
$this->assertEquals( 150, $item->get_quantity() );
$this->assertEquals( $item->get_quantity(), $item['qty'] );
// Test item_meta_array.
$this->assertTrue( isset( $item['item_meta_array'] ) );
$item['item_meta_array'] = array(
0 => (object) array(
'key' => 'test',
'value' => 'val',
),
);
$this->assertInstanceOf( 'WC_Meta_Data', current( $item->get_meta_data() ) );
$this->assertEquals( current( $item->get_meta_data() ), $item['item_meta_array'][''] );
unset( $item['item_meta_array'] );
$this->assertEquals( array(), $item->get_meta_data() );
// Test default.
$this->assertFalse( isset( $item['foo'] ) );
$item['foo'] = 'bar';
$this->assertEquals( 'bar', $item->get_meta( 'foo' ) );
}
}

View File

@ -1,130 +0,0 @@
<?php
/**
* Order Item Product Tests.
* @package WooCommerce\Tests\Order_Items
* @since 3.2.0
*/
class WC_Tests_Order_Item_Product extends WC_Unit_Test_Case {
/**
* Test generic setters and getters for WC_Order_Item_Product.
*
* @since 3.2.0
*/
public function test_generic_setters_getters() {
$simple_product = new WC_Product_Simple;
$simple_product->save();
$variation_product = new WC_Product_Variation;
$variation_product->save();
$product_item = new WC_Order_Item_Product;
$product_item->set_quantity( 3 );
$this->assertEquals( 3, $product_item->get_quantity() );
$product_item->set_tax_class( 'reduced-rate' );
$this->assertEquals( 'reduced-rate', $product_item->get_tax_class() );
$product_item->set_product_id( $simple_product->get_id() );
$this->assertEquals( $simple_product->get_id(), $product_item->get_product_id() );
$product_item->set_variation_id( $variation_product->get_id() );
$this->assertEquals( $variation_product->get_id(), $product_item->get_variation_id() );
$product_item->set_subtotal( '12.00' );
$this->assertEquals( '12.00', $product_item->get_subtotal() );
$product_item->set_total( '10.00' );
$this->assertEquals( '10.00', $product_item->get_total() );
$product_item->set_subtotal_tax( '0.50' );
$this->assertEquals( '0.50', $product_item->get_subtotal_tax() );
$product_item->set_total_tax( '0.30' );
$this->assertEquals( '0.30', $product_item->get_total_tax() );
}
/**
* Test set_taxes and get_taxes for WC_Order_Item_Product.
*
* @since 3.2.0
*/
public function test_set_get_taxes() {
$product_item = new WC_Order_Item_Product;
$taxes = array(
'total' => array( '10', '2.4' ),
'subtotal' => array( '12', '3.1' ),
);
$product_item->set_taxes( $taxes );
$this->assertEquals( $taxes, $product_item->get_taxes() );
$this->assertEquals( '12.4', $product_item->get_total_tax() );
$this->assertEquals( '15.1', $product_item->get_subtotal_tax() );
}
/**
* Test set_product and get_product for WC_Order_Item_Product.
*
* @since 3.2.0
*/
public function test_set_get_product() {
$simple_product = new WC_Product_Simple;
$simple_product->set_name( 'Test Simple' );
$simple_product->set_tax_class( 'reduced-rate' );
$simple_product->save();
$parent_product = new WC_Product_Variable;
$parent_product->set_name( 'Test Parent' );
$parent_product->save();
$variation_product = new WC_Product_Variation;
$variation_product->set_name( 'Test Variation' );
$variation_product->set_parent_id( $parent_product->get_id() );
$variation_product->save();
// Simple product.
$product_item = new WC_Order_Item_Product;
$product_item->set_product( $simple_product );
$this->assertEquals( 'Test Simple', $product_item->get_name() );
$this->assertEquals( $simple_product->get_id(), $product_item->get_product_id() );
$this->assertEquals( 0, $product_item->get_variation_id() );
$this->assertEquals( 'reduced-rate', $product_item->get_tax_class() );
$retrieved = $product_item->get_product();
$this->assertEquals( $simple_product->get_id(), $retrieved->get_id() );
// Variation product.
$product_item = new WC_Order_Item_Product;
$product_item->set_product( $variation_product );
$this->assertEquals( 'Test Parent', $product_item->get_name() );
$this->assertEquals( $parent_product->get_id(), $product_item->get_product_id() );
$this->assertEquals( $variation_product->get_id(), $product_item->get_variation_id() );
$this->assertEquals( '', $product_item->get_tax_class() );
$retrieved = $product_item->get_product();
$this->assertEquals( $variation_product->get_id(), $retrieved->get_id() );
}
/**
* Test get_item_download_url method for WC_Order_Item_Product.
*
* @since 3.2.0
*/
public function test_get_item_download_url() {
$product = new WC_Product_Simple;
$product->save();
$order = new WC_Order;
$order->set_billing_email( 'test@woocommerce.com' );
$order->save();
$product_item = new WC_Order_Item_Product;
$product_item->set_product( $product );
$product_item->set_order_id( $order->get_id() );
$expected_regex = '/download_file=.*&order=wc_order_.*&email=test%40woocommerce.com&key=100/';
$this->assertRegexp( $expected_regex, $product_item->get_item_download_url( 100 ) );
}
}

View File

@ -0,0 +1,69 @@
<?php
/**
* Class Functions.
* @package WooCommerce\Tests\Setup
*/
class WC_Tests_Setup_Functions extends WC_Unit_Test_Case {
/**
* Test get_wizard_in_cart_payment_gateways.
* Verifies contents, order, and default enabled state of offered gateways.
*
* @since 3.3
*/
public function test_wizard_in_cart_payment_gateways() {
$setup_wizard = new WC_Admin_Setup_Wizard();
function get_enabled( $gateway ) {
return isset( $gateway['enabled'] ) && $gateway['enabled'];
}
function gateways( $setup_wizard ) {
return array_map( 'get_enabled', $setup_wizard->get_wizard_in_cart_payment_gateways() );
}
// non-admin user
$this->user_id = $this->factory->user->create( array( 'role' => 'shop_manager' ) );
wp_set_current_user( $this->user_id );
$this->assertEquals( gateways( $setup_wizard ), array(
'paypal' => false,
) );
// set admin user
$this->user_id = $this->factory->user->create( array( 'role' => 'administrator' ) );
wp_set_current_user( $this->user_id );
update_option( 'woocommerce_default_country', 'US' );
$this->assertEquals( gateways( $setup_wizard ), array(
'stripe' => true,
'ppec_paypal' => true,
) );
update_option( 'woocommerce_default_country', 'CN' );
$this->assertEquals( gateways( $setup_wizard ), array(
'ppec_paypal' => true,
) );
update_option( 'woocommerce_default_country', 'SE' );
$this->assertEquals( gateways( $setup_wizard ), array(
'klarna_checkout' => true,
'ppec_paypal' => true,
'stripe' => false,
) );
update_option( 'woocommerce_default_country', 'DE' );
$this->assertEquals( gateways( $setup_wizard ), array(
'klarna_payments' => true,
'ppec_paypal' => true,
'stripe' => false,
) );
update_option( 'woocommerce_default_country', 'GB' );
update_option( 'woocommerce_sell_in_person', 'yes' );
$this->assertEquals( gateways( $setup_wizard ), array(
'square' => true,
'ppec_paypal' => true,
'stripe' => false,
) );
}
}

View File

@ -1,10 +1,14 @@
<?php
/**
* Class Core_Functions.
* Unit tests for the core functions.
*
* @package WooCommerce\Tests\Util
* @since 2.2
*/
/**
* Core function unit tests.
*/
class WC_Tests_Core_Functions extends WC_Unit_Test_Case {
/**
@ -199,13 +203,13 @@ class WC_Tests_Core_Functions extends WC_Unit_Test_Case {
*/
public function test_get_woocommerce_currency_symbol() {
// default currency
// Default currency.
$this->assertEquals( '&pound;', get_woocommerce_currency_symbol() );
// given specific currency
// Given specific currency.
$this->assertEquals( '&#36;', get_woocommerce_currency_symbol( 'USD' ) );
// each case
// Each case.
foreach ( array_keys( get_woocommerce_currencies() ) as $currency_code ) {
$this->assertInternalType( 'string', get_woocommerce_currency_symbol( $currency_code ) );
}
@ -220,10 +224,10 @@ class WC_Tests_Core_Functions extends WC_Unit_Test_Case {
$base_uri = get_home_url();
// base uri
// Base URI.
$this->assertEquals( "$base_uri/wc-api/v3/", get_woocommerce_api_url( null ) );
// path
// Path.
$this->assertEquals( "$base_uri/wc-api/v3/orders", get_woocommerce_api_url( 'orders' ) );
}
@ -245,7 +249,7 @@ class WC_Tests_Core_Functions extends WC_Unit_Test_Case {
* @since 3.0.0
*/
public function test_wc_get_logger() {
// This filter should have no effect because the class does not implement WC_Logger_Interface
// This filter should have no effect because the class does not implement WC_Logger_Interface.
add_filter( 'woocommerce_logging_class', array( $this, 'return_bad_logger' ) );
$this->setExpectedIncorrectUsage( 'wc_get_logger' );
@ -287,9 +291,22 @@ class WC_Tests_Core_Functions extends WC_Unit_Test_Case {
*/
public function test_wc_format_country_state_string() {
// Test with correct values.
$this->assertEquals( array( 'country' => 'US', 'state' => 'CA' ), wc_format_country_state_string( 'US:CA' ) );
$this->assertEquals(
array(
'country' => 'US',
'state' => 'CA',
),
wc_format_country_state_string( 'US:CA' )
);
// Test what happens when we pass an incorrect value.
$this->assertEquals( array( 'country' => 'US-CA', 'state' => '' ), wc_format_country_state_string( 'US-CA' ) );
$this->assertEquals(
array(
'country' => 'US-CA',
'state' => '',
),
wc_format_country_state_string( 'US-CA' )
);
}
/**
@ -311,7 +328,13 @@ class WC_Tests_Core_Functions extends WC_Unit_Test_Case {
* @since 3.0.0
*/
public function test_wc_print_r() {
$arr = array( 1, 2, 'a', 'b', 'c' => 'd' );
$arr = array(
1,
2,
'a',
'b',
'c' => 'd',
);
// This filter will sequentially remove handlers, allowing us to test as though our
// functions were accumulatively blacklisted, adding one on each call.
@ -352,7 +375,7 @@ class WC_Tests_Core_Functions extends WC_Unit_Test_Case {
$this->assertFalse( $return_value );
ob_clean();
// Reset filter to include all handlers
// Reset filter to include all handlers.
$this->filter_wc_print_r_alternatives( array(), true );
$this->assertEquals( print_r( $arr, true ), wc_print_r( $arr, true ) );
@ -372,7 +395,7 @@ class WC_Tests_Core_Functions extends WC_Unit_Test_Case {
* Eventually, no handlers are returned.
*
* @param array $alternatives Input array of alternatives.
* @param bool $reset Optional. Default false. True to reset excluded alternatives.
* @param bool $reset Optional. Default false. True to reset excluded alternatives.
* @return array|bool Alternatives. True on reset.
*/
public function filter_wc_print_r_alternatives( $alternatives, $reset = false ) {
@ -398,4 +421,228 @@ class WC_Tests_Core_Functions extends WC_Unit_Test_Case {
$wildcards = array( 'GIJóN', 'GIJÓN', 'GIJÓN*', 'GIJÓ*', 'GIJ*', 'GI*', 'G*', '*' );
$this->assertEquals( $wildcards, wc_get_wildcard_postcodes( $postcode, $country ) );
}
/**
* Tests wc_maybe_define_constant().
*
* @since 3.2.0
*/
public function test_wc_maybe_define_constant() {
$this->assertFalse( defined( 'WC_TESTING_DEFINE_FUNCTION' ) );
// Check if defined.
wc_maybe_define_constant( 'WC_TESTING_DEFINE_FUNCTION', true );
$this->assertTrue( defined( 'WC_TESTING_DEFINE_FUNCTION' ) );
// Check value.
wc_maybe_define_constant( 'WC_TESTING_DEFINE_FUNCTION', false );
$this->assertTrue( WC_TESTING_DEFINE_FUNCTION );
}
/**
* Tests wc_create_order() and wc_update_order() currency handling.
*
* @since 3.2.0
*/
public function test_wc_create_update_order_currency() {
$old_currency = get_woocommerce_currency();
$new_currency = 'BGN';
update_option( 'woocommerce_currency', $new_currency );
// New order should be created using shop currency.
$order = wc_create_order( array(
'status' => 'pending',
'customer_id' => 1,
'created_via' => 'unit tests',
'cart_hash' => '',
) );
$this->assertEquals( $new_currency, $order->get_currency() );
update_option( 'woocommerce_currency', $old_currency );
// Currency should not change when order is updated.
$order = wc_update_order( array(
'customer_id' => 2,
'order_id' => $order->get_id(),
) );
$this->assertEquals( $new_currency, $order->get_currency() );
$order = wc_update_order( array(
'customer_id' => 2,
) );
$this->assertInstanceOf( 'WP_Error', $order );
}
/**
* Test the wc_is_active_theme function.
*
* @return void
*/
public function test_wc_is_active_theme() {
$current_theme = get_template();
$this->assertTrue( wc_is_active_theme( $current_theme ) );
$this->assertFalse( wc_is_active_theme( 'somegiberish' ) );
$this->assertTrue( wc_is_active_theme( array( $current_theme, 'somegiberish' ) ) );
}
/**
* Test the wc_get_template function.
*
* @return void
*/
public function test_wc_get_template_part() {
$this->assertEmpty( wc_get_template_part( 'nothinghere' ) );
}
/**
* Test wc_get_image_size function.
*
* @return void
*/
public function test_wc_get_image_size() {
$this->assertArrayHasKey( 'width', wc_get_image_size( array( 100, 100, 1 ) ) );
$this->assertArrayHasKey( 'height', wc_get_image_size( 'shop_single' ) );
update_option( 'woocommerce_thumbnail_cropping', 'uncropped' );
$this->assertArrayHasKey( 'crop', wc_get_image_size( 'shop_thumbnail' ) );
update_option( 'woocommerce_thumbnail_cropping', 'custom' );
$this->assertArrayHasKey( 'crop', wc_get_image_size( 'shop_thumbnail' ) );
}
/**
* Test wc_enqueue_js and wc_print_js functions.
*
* @return void
*/
public function test_wc_enqueue_js_wc_print_js() {
$js = 'alert( "test" );';
ob_start();
wc_print_js();
$printed_js = ob_get_clean();
$this->assertNotContains( $js, $printed_js );
wc_enqueue_js( $js );
ob_start();
wc_print_js();
$printed_js = ob_get_clean();
$this->assertContains( $js, $printed_js );
}
/**
* Test wc_get_log_file_name function.
*
* @return void
*/
public function test_wc_get_log_file_name() {
$this->assertNotEmpty( wc_get_log_file_name( 'test' ) );
}
/**
* Test wc_get_page_children function.
*
* @return void
*/
public function test_wc_get_page_children() {
$page_id = wp_insert_post( array(
'post_title' => 'Parent Page',
'post_type' => 'page',
'post_name' => 'parent-page',
'post_status' => 'publish',
'post_author' => 1,
'menu_order' => 0,
) );
$child_page_id = wp_insert_post( array(
'post_parent' => $page_id,
'post_title' => 'Parent Page',
'post_type' => 'page',
'post_name' => 'parent-page',
'post_status' => 'publish',
'post_author' => 1,
'menu_order' => 0,
) );
$children = wc_get_page_children( $page_id );
$this->assertEquals( $child_page_id, $children[0] );
wp_delete_post( $page_id, true );
wp_delete_post( $child_page_id, true );
}
/**
* Test hash_equals function.
*
* @return void
*/
public function test_hash_equals() {
$this->assertTrue( hash_equals( 'abc', 'abc' ) ); // @codingStandardsIgnoreLine.
$this->assertFalse( hash_equals( 'abcd', 'abc' ) ); // @codingStandardsIgnoreLine.
}
/**
* Test wc_rand_hash function.
*
* @return void
*/
public function test_wc_rand_hash() {
$this->assertNotEquals( wc_rand_hash(), wc_rand_hash() );
}
/**
* Test wc_transaction_query function.
*/
public function test_wc_transaction_query() {
global $wpdb;
$wpdb->insert(
$wpdb->prefix . 'options',
array(
'option_name' => 'transaction_test',
'option_value' => '1',
),
array(
'%s',
'%s',
)
);
wc_transaction_query( 'start' );
$this->assertTrue( WC_USE_TRANSACTIONS );
$wpdb->update(
$wpdb->prefix . 'options',
array(
'option_value' => '0',
),
array(
'option_name' => 'transaction_test',
)
);
$col = $wpdb->get_col( "SElECT option_value FROM {$wpdb->prefix}options WHERE option_name = 'transaction_test'" );
$this->assertEquals( '0', $col[0] );
wc_transaction_query( 'rollback' );
$col = $wpdb->get_col( "SElECT option_value FROM {$wpdb->prefix}options WHERE option_name = 'transaction_test'" );
$this->assertEquals( '1', $col[0] );
wc_transaction_query( 'start' );
$wpdb->update(
$wpdb->prefix . 'options',
array(
'option_value' => '0',
),
array(
'option_name' => 'transaction_test',
)
);
wc_transaction_query( 'commit' );
$col = $wpdb->get_col( "SElECT option_value FROM {$wpdb->prefix}options WHERE option_name = 'transaction_test'" );
$this->assertEquals( '0', $col[0] );
$wpdb->delete(
$wpdb->prefix . 'options',
array(
'option_name' => 'transaction_test',
)
);
}
}

View File

@ -0,0 +1,368 @@
<?php
/**
* Tests for the WC_Query class.
*
* @package WooCommerce\Tests\Util
* @since 3.3.0
*/
/**
* WC_Query tests.
*/
class WC_Tests_WC_Query extends WC_Unit_Test_Case {
/**
* Test WC_Query gets initialized properly.
*/
public function test_instance() {
$this->assertInstanceOf( 'WC_Query', WC()->query );
}
/**
* Test the get_errors method.
*/
public function test_get_errors() {
$_GET['wc_error'] = 'test';
WC()->query->get_errors();
$this->assertTrue( wc_has_notice( 'test', 'error' ) );
// Clean up.
unset( $_GET['wc_error'] );
wc_clear_notices();
WC()->query->get_errors();
$this->assertFalse( wc_has_notice( 'test', 'error' ) );
}
/**
* Test the init_query_vars and get_query_vars methods.
*/
public function test_init_query_vars_get_query_vars() {
// Test the default options are present.
WC()->query->init_query_vars();
$default_vars = WC()->query->get_query_vars();
$expected = array(
'product-page' => '',
'order-pay' => 'order-pay',
'order-received' => 'order-received',
'orders' => 'orders',
'view-order' => 'view-order',
'downloads' => 'downloads',
'edit-account' => 'edit-account',
'edit-address' => 'edit-address',
'payment-methods' => 'payment-methods',
'lost-password' => 'lost-password',
'customer-logout' => 'customer-logout',
'add-payment-method' => 'add-payment-method',
'delete-payment-method' => 'delete-payment-method',
'set-default-payment-method' => 'set-default-payment-method',
);
$this->assertEquals( $expected, $default_vars );
// Test updating a setting works.
update_option( 'woocommerce_checkout_pay_endpoint', 'order-pay-new' );
WC()->query->init_query_vars();
$updated_vars = WC()->query->get_query_vars();
$this->assertEquals( 'order-pay-new', $updated_vars['order-pay'] );
// Clean up.
update_option( 'woocommerce_checkout_pay_endpoint', 'order-pay' );
}
/**
* Test the get_endpoint_title method.
*/
public function test_get_endpoint_title() {
$endpoints = array(
'order-pay',
'order-received',
'orders',
'downloads',
'edit-account',
'edit-address',
'payment-methods',
'add-payment-method',
'lost-password',
);
foreach ( $endpoints as $endpoint ) {
$this->assertNotEquals( '', WC()->query->get_endpoint_title( $endpoint ) );
}
$this->assertEquals( '', WC()->query->get_endpoint_title( 'not-real-endpoint' ) );
}
/**
* Test the get_endpoint_mask method.
*/
public function test_get_endpoint_mask() {
$this->assertEquals( EP_PAGES, WC()->query->get_endpoints_mask() );
update_option( 'show_on_front', 'page' );
update_option( 'page_on_front', 999 );
update_option( 'woocommerce_checkout_page_id', 999 );
$this->assertEquals( EP_ROOT | EP_PAGES, WC()->query->get_endpoints_mask() );
}
/**
* Test the add_query_vars method.
*/
public function test_add_query_vars() {
WC()->query->init_query_vars();
$vars = array(
'test1',
'test2',
);
$added = WC()->query->add_query_vars( $vars );
$this->assertContains( 'test1', $added );
$this->assertContains( 'test2', $added );
$this->assertContains( 'order-pay', $added );
$this->assertContains( 'customer-logout', $added );
}
/**
* Test the get_current_endpoint method.
*/
public function test_get_current_endpoint() {
global $wp;
$this->assertEquals( '', WC()->query->get_current_endpoint() );
$wp->query_vars['order-pay'] = 'order-pay';
$this->assertEquals( 'order-pay', WC()->query->get_current_endpoint() );
}
/**
* Test the parse_request method.
*/
public function test_parse_request() {
global $wp;
// Test with $_GET.
WC()->query->init_query_vars();
$_GET['order-pay'] = 'order-pay';
WC()->query->parse_request();
$this->assertEquals( 'order-pay', $wp->query_vars['order-pay'] );
unset( $_GET['order-pay'] );
// Test with query var.
update_option( 'woocommerce_checkout_pay_endpoint', 'order-pay-new' );
WC()->query->init_query_vars();
$wp->query_vars['order-pay-new'] = 'order-pay-new';
WC()->query->parse_request();
$this->assertEquals( 'order-pay-new', $wp->query_vars['order-pay'] );
}
/**
* Test the remove_product_query method.
*/
public function test_remove_product_query() {
$this->assertTrue( (bool) has_filter( 'pre_get_posts', array( WC()->query, 'pre_get_posts' ) ) );
WC()->query->remove_product_query();
$this->assertFalse( (bool) has_filter( 'pre_get_posts', array( WC()->query, 'pre_get_posts' ) ) );
}
/**
* Test the remove_ordering_args method.
*/
public function test_remove_ordering_args() {
WC()->query->get_catalog_ordering_args( 'price', 'DESC' );
$this->assertTrue( (bool) has_filter( 'posts_clauses', array( WC()->query, 'order_by_price_desc_post_clauses' ) ) );
WC()->query->remove_ordering_args();
$this->assertFalse( (bool) has_filter( 'posts_clauses', array( WC()->query, 'order_by_price_desc_post_clauses' ) ) );
}
/**
* Test the get_catalog_ordering_args method.
*/
public function test_get_catalog_ordering_args() {
$data = array(
array(
'orderby' => 'menu_order',
'order' => 'ASC',
'expected' => array(
'orderby' => 'menu_order title',
'order' => 'ASC',
'meta_key' => '',
),
),
array(
'orderby' => 'title',
'order' => 'DESC',
'expected' => array(
'orderby' => 'title',
'order' => 'DESC',
'meta_key' => '',
),
),
array(
'orderby' => 'relevance',
'order' => 'ASC',
'expected' => array(
'orderby' => 'relevance',
'order' => 'DESC', // Relevance is always DESC order.
'meta_key' => '',
),
),
array(
'orderby' => 'rand',
'order' => '',
'expected' => array(
'orderby' => 'rand',
'order' => 'ASC',
'meta_key' => '',
),
),
array(
'orderby' => 'date',
'order' => 'DESC',
'expected' => array(
'orderby' => 'date ID',
'order' => 'DESC',
'meta_key' => '',
),
),
array(
'orderby' => 'price',
'order' => 'ASC',
'expected' => array(
'orderby' => 'price',
'order' => 'ASC',
'meta_key' => '',
),
),
array(
'orderby' => 'price',
'order' => 'DESC',
'expected' => array(
'orderby' => 'price',
'order' => 'DESC',
'meta_key' => '',
),
),
array(
'orderby' => 'popularity',
'order' => 'DESC',
'expected' => array(
'orderby' => 'popularity',
'order' => 'DESC',
'meta_key' => 'total_sales',
),
),
array(
'orderby' => 'rating',
'order' => 'ASC',
'expected' => array(
'orderby' => array(
'meta_value_num' => 'DESC',
'ID' => 'ASC',
),
'order' => 'ASC',
'meta_key' => '_wc_average_rating',
),
),
array(
'orderby' => 'unknownkey',
'order' => 'ASC',
'expected' => array(
'orderby' => 'unknownkey',
'order' => 'ASC',
'meta_key' => '',
),
),
array(
'orderby' => 'date',
'order' => 'INVALIDORDER',
'expected' => array(
'orderby' => 'date ID',
'order' => 'DESC',
'meta_key' => '',
),
),
);
foreach ( $data as $test ) {
$result = WC()->query->get_catalog_ordering_args( $test['orderby'], $test['order'] );
$this->assertEquals( $test['expected'], $result );
}
}
/**
* Test the get_catalog_ordering_args method with $_GET param.
*/
public function test_get_catalog_ordering_args_GET() {
$_GET['orderby'] = 'price-desc';
$expected = array(
'orderby' => 'price',
'order' => 'DESC',
'meta_key' => '',
);
$this->assertEquals( $expected, WC()->query->get_catalog_ordering_args() );
unset( $_GET['orderby'] );
}
/**
* Test the get_main_query method.
*/
public function test_get_main_query() {
WC()->query->product_query( new WP_Query() );
$this->assertInstanceOf( 'WP_Query', WC_Query::get_main_query() );
}
/**
* Test the get_main_tax_query method.
*/
public function test_get_main_tax_query() {
$tax_query = array(
'taxonomy' => 'product_tag',
'field' => 'slug',
'terms' => array( 'test' ),
'operator' => 'IN',
'include_children' => true,
);
$query_args = array(
'tax_query' => array( $tax_query ),
);
WC()->query->product_query( new WP_Query( $query_args ) );
$tax_queries = WC_Query::get_main_tax_query();
$this->assertContains( $tax_query, $tax_queries );
}
/**
* Test the get_main_meta_query method.
*/
public function test_get_main_meta_query() {
$meta_query = array(
'key' => '_stock',
'value' => 10,
'compare' => '=',
);
$query_args = array(
'meta_query' => array( $meta_query ),
);
WC()->query->product_query( new WP_Query( $query_args ) );
$meta_queries = WC_Query::get_main_meta_query();
$this->assertContains( $meta_query, $meta_queries );
}
/**
* Test the remove_add_to_cart_pagination method.
*/
public function test_remove_add_to_cart_pagination() {
$url = 'http://example.com/shop/page/2/?add-to-cart=1';
$this->assertEquals( 'http://example.com/shop/page/2/', WC()->query->remove_add_to_cart_pagination( $url ) );
}
}

View File

@ -0,0 +1,29 @@
<?php
/**
* Dummy widget class extending WC_Widget.
*/
class Dummy_Widget extends WC_Widget {
/**
* Constructor.
*/
public function __construct() {
$this->widget_cssclass = 'widget_dummy';
$this->widget_description = __( 'A dummy widget', 'woocommerce' );
$this->widget_id = 'wc_dummy_widget';
$this->widget_name = __( 'Dummy Widget', 'woocommerce' );
parent::__construct();
}
/**
* Output widget.
*
* @param mixed $args Arguments.
* @param WP_Widget $instance Intance of WP_Widget.
* @return void
*/
public function widget( $args, $instance ) {
ob_start();
echo 'Dummy';
echo $this->cache_widget( $args, ob_get_clean() );
}
}

View File

@ -0,0 +1,67 @@
<?php
/**
* Testing WC_Widget functionality.
*
* @package WooCommerce/Tests/Widgets
*/
/**
* Class for testing WC_Widget functionality.
*/
class WC_Tests_Widget extends WC_Unit_Test_Case {
/**
* Test intance creation
*
* @return void
*/
public function test_instance() {
require_once 'class-dummy-widget.php';
$dummy_widget = new Dummy_Widget();
$this->assertTrue( property_exists( $dummy_widget, 'widget_id' ) );
}
/**
* Test widget caching.
*
* @return void
*/
public function test_caching() {
global $wp_widget_factory;
require_once 'class-dummy-widget.php';
register_widget( 'Dummy_Widget' );
$dummy_widget = $wp_widget_factory->widgets['Dummy_Widget'];
// Uncached widget.
ob_start();
$cache_hit = $dummy_widget->get_cached_widget( array( 'widget_id' => $dummy_widget->widget_id ) );
$output = ob_get_clean();
$this->assertFalse( $cache_hit );
$this->assertEmpty( $output );
// Render widget to prime the cache.
ob_start();
$dummy_widget->widget( array( 'widget_id' => $dummy_widget->widget_id ), array() );
ob_get_clean();
// Cached widget.
ob_start();
$cache_hit = $dummy_widget->get_cached_widget( array( 'widget_id' => $dummy_widget->widget_id ) );
$output = ob_get_clean();
$this->assertTrue( $cache_hit );
$this->assertEquals( 'Dummy', $output );
}
/**
* Test widget form.
*
* @return void
*/
public function test_form() {
global $wp_widget_factory;
require_once 'class-dummy-widget.php';
register_widget( 'Dummy_Widget' );
$dummy_widget = $wp_widget_factory->widgets['Dummy_Widget'];
$this->assertEmpty( $dummy_widget->form( array( 'widget_id' => $dummy_widget->widget_id ) ) );
}
}

View File

@ -2,7 +2,7 @@
/**
* Plugin Name: WooCommerce
* Plugin URI: https://woocommerce.com/
* Description: An e-commerce toolkit that helps you sell anything. Beautifully.
* Description: An eCommerce toolkit that helps you sell anything. Beautifully.
* Version: 3.3.0-beta.1
* Author: Automattic
* Author URI: https://woocommerce.com