fix merge conflict

This commit is contained in:
Ron Rennick 2021-08-19 11:19:26 -03:00
commit e02bd1ba56
23 changed files with 829 additions and 356 deletions

View File

@ -1,4 +1,3 @@
/** /**
* admin.scss * admin.scss
* General WooCommerce admin styles. Settings, product data tabs, reports, etc. * General WooCommerce admin styles. Settings, product data tabs, reports, etc.
@ -20,26 +19,51 @@
@include loader(); @include loader();
} }
.wc_addons_wrap { .wc-addons-wrap {
max-width: 1200px;
h1.search-form-title { .marketplace-header {
clear: left; background-image: url(../images/marketplace-header-bg@2x.png);
background-position: right;
background-size: cover;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: center;
min-height: 216px;
padding: 24px 16px;
width: 100%;
&__title {
color: #fff;
font-size: 32px;
font-style: normal;
font-weight: 400;
line-height: 1.15;
margin-bottom: 8px;
padding: 0; padding: 0;
} }
form.search-form { &__description {
color: #fff;
font-size: 16px;
line-height: 24px;
margin-bottom: 24px;
margin-top: 0;
}
&__search-form {
clear: both; clear: both;
display: block; display: block;
max-width: 318px;
position: relative; position: relative;
margin-top: 1em;
margin-bottom: 1em;
input { input {
border: 1px solid #ddd; border: 1px solid #ddd;
box-shadow: none; box-shadow: none;
height: 53px; font-size: 13px;
padding-left: 50px; height: 48px;
padding-left: 16px;
padding-right: 50px;
width: 100%; width: 100%;
margin: 0; margin: 0;
} }
@ -48,11 +72,136 @@
background: none; background: none;
border: none; border: none;
cursor: pointer; cursor: pointer;
height: 53px; height: 48px;
position: absolute; position: absolute;
right: 0;
width: 53px; width: 53px;
} }
} }
}
.top-bar {
background: #fff;
box-shadow: inset 0 -1px 0 #ccc;
display: block;
height: 60px;
margin: 0 0 16px;
@media only screen and ( min-width: 768px ) {
margin-bottom: 24px;
}
.current-section-dropdown {
position: relative;
width: 100%;
@media only screen and ( min-width: 600px ) {
margin-left: 70px;
width: 288px;
}
}
.current-section-name {
cursor: pointer;
font-weight: 600;
font-size: 14px;
line-height: 20px;
padding: 20px 16px;
position: relative;
}
.current-section-name::after {
background-image: url(../images/icons/gridicons-chevron-down.svg);
background-size: contain;
content: "";
display: block;
height: 20px;
position: absolute;
right: 20px;
top: 20px;
width: 20px;
}
ul {
background: #fff;
border-radius: 2px;
display: none;
flex-direction: column;
justify-content: left;
left: 0;
margin: 0;
padding: 14px 0;
position: absolute;
top: 50px;
width: 100%;
z-index: 10;
@media only screen and ( min-width: 600px ) {
border: 1px solid #1e1e1e;
}
@media only screen and ( min-width: 1100px ) {
justify-content: center;
}
li {
font-size: 13px;
line-height: 16px;
margin: 0;
}
a,
a:visited,
a:hover,
a:focus {
border: none;
box-shadow: none;
box-sizing: border-box;
color: #1e1e1e;
display: inline-block;
text-decoration: none;
outline: none;
padding: 14px 18px;
position: relative;
width: 100%;
@media only screen and ( min-width: 600px ) {
padding: 10px 18px;
}
}
a.current::after {
background-image: url(../images/icons/gridicons-checkmark.svg);
content: "";
display: block;
height: 20px;
position: absolute;
right: 20px;
top: 7px;
width: 20px;
}
}
.current-section-dropdown:hover,
.current-section-dropdown.is-open {
ul {
display: flex;
}
.current-section-name::after {
transform: rotate(0.5turn);
}
}
}
h1.search-form-title {
clear: left;
font-size: 20px;
line-height: 1.2;
margin: 48px 0 16px;
padding: 0;
}
.update-plugins .update-count { .update-plugins .update-count {
background-color: #d54e21; background-color: #d54e21;
@ -83,6 +232,18 @@
content: ""; content: "";
} }
.addons-button {
border-radius: 3px;
cursor: pointer;
display: block;
height: 37px;
line-height: 37px;
margin-top: 16px;
text-align: center;
text-decoration: none;
width: 124px;
}
.addons-banner-block-item-icon, .addons-banner-block-item-icon,
.addons-column-block-item-icon { .addons-column-block-item-icon {
align-items: center; align-items: center;
@ -149,6 +310,16 @@
align-items: center; align-items: center;
} }
.addons-promotion-block {
display: flex;
padding: 20px;
.addons-img {
height: auto;
width: 200px;
}
}
.addons-wcs-banner-block-image { .addons-wcs-banner-block-image {
background: #f7f7f7; background: #f7f7f7;
border: 1px solid #e6e6e6; border: 1px solid #e6e6e6;
@ -173,16 +344,6 @@
} }
} }
.addons-promotion-block {
display: flex;
padding: 20px;
.addons-img {
height: auto;
width: 200px;
}
}
.addons-promotion-block-content { .addons-promotion-block-content {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -416,17 +577,6 @@
width: 48%; width: 48%;
} }
.addons-button {
border-radius: 3px;
cursor: pointer;
display: block;
height: 37px;
line-height: 37px;
text-align: center;
text-decoration: none;
width: 124px;
}
.addons-button-solid { .addons-button-solid {
background-color: #674399; background-color: #674399;
color: #fff; color: #fff;
@ -506,81 +656,105 @@
} }
} }
.marketplace-content-wrapper {
margin: 0 auto;
max-width: 1032px;
width: 100%;
}
.products { .products {
overflow: hidden;
display: flex; display: flex;
flex-flow: row; flex-flow: row;
flex-wrap: wrap; flex-wrap: wrap;
margin: 0 -0.5em; justify-content: space-between;
margin: 0;
max-width: 1032px;
overflow: hidden;
li { li {
float: left; background: #fff;
border: 1px solid #ddd; border: 1px solid #dcdcde;
margin: 0 0.5em 1em !important; border-radius: 2px;
padding: 0; display: flex;
vertical-align: top; flex: 1 0 auto;
width: 25%; flex-direction: column;
justify-content: space-between;
margin: 12px 0;
max-width: calc(50% - 12px);
min-width: 280px; min-width: 280px;
min-height: 220px; min-height: 220px;
flex: 1;
overflow: hidden; overflow: hidden;
background: #f5f5f5; padding: 0;
box-shadow: vertical-align: top;
inset 0 1px 0 rgba(255, 255, 255, 0.2),
inset 0 -1px 0 rgba(0, 0, 0, 0.1); @media only screen and ( max-width: 768px ) {
max-width: none;
width: 100%;
}
a { a {
text-decoration: none; text-decoration: none;
color: inherit; }
display: block;
height: 100%; .product-details {
padding: 24px;
.product-img-wrap { .product-img-wrap {
background: #fff;
display: block; display: block;
} float: right;
margin-left: 24px;
img { img {
max-width: 258px; border-radius: 3px;
max-height: 24px;
padding: 17px 20px;
display: block; display: block;
margin: 0; margin: 0;
background: #fff; max-width: 48px;
border-right: 260px solid #fff; max-height: 48px;
} }
img.extension-thumb + h3 {
display: none;
}
.price {
display: none;
} }
h2, h2,
h3 { h3 {
color: #007cba;
font-family:
HelveticaNeue-Light,
"Helvetica Neue Light",
"Helvetica Neue",
sans-serif;
font-size: 20px;
font-weight: 400;
line-height: 28px;
margin: 0 !important; margin: 0 !important;
padding: 20px !important;
background: #fff;
} }
p { p {
padding: 20px !important; color: #2c3338;
margin: 0 !important; margin: 14px 64px 0 0;
border-top: 1px solid #f1f1f1; max-width: 389px;
}
} }
&:hover, .product-footer {
&:focus { border-top: 1px solid #dcdcde;
padding: 24px;
.price {
font-size: 16px;
color: #1d2327;
}
.button {
background-color: #fff; background-color: #fff;
border-color: #007cba;
color: #007cba;
float: right;
} }
} }
} }
} }
.storefront { .storefront {
background: url("../images/storefront-bg.jpg") bottom right #f6f6f6; background: url(../images/storefront-bg.jpg) bottom right #f6f6f6;
border: 1px solid #ddd; border: 1px solid #ddd;
margin-top: 1em; margin-top: 1em;
padding: 20px; padding: 20px;
@ -601,6 +775,43 @@
} }
} }
.wc-subscriptions-wrap {
max-width: 1200px;
}
.woocommerce-page-wc-marketplace {
.notice {
margin-left: 20px;
margin-right: 20px;
}
&.woocommerce-page {
.wrap {
margin-top: 32px;
}
}
}
.woocommerce-page-wc-subscriptions {
#wpbody-content {
.screen-reader-text + .notice {
margin-top: 32px;
}
}
}
.woocommerce-embed-page.woocommerce-page-wc-marketplace {
#screen-meta-links {
position: absolute;
right: 0;
}
}
.woocommerce-message, .woocommerce-message,
.woocommerce-BlankState { .woocommerce-BlankState {
@ -610,7 +821,11 @@
border-color: #a36597; border-color: #a36597;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 0 #a36597; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 0 #a36597;
color: #fff; color: #fff;
text-shadow: 0 -1px 1px #a36597, 1px 0 1px #a36597, 0 1px 1px #a36597, -1px 0 1px #a36597; text-shadow:
0 -1px 1px #a36597,
1px 0 1px #a36597,
0 1px 1px #a36597,
-1px 0 1px #a36597;
display: inline-block; display: inline-block;
&:hover, &:hover,
@ -845,7 +1060,6 @@ table.wc_status_table--tools {
} }
} }
/** /**
* DB log viewer * DB log viewer
*/ */
@ -1162,7 +1376,11 @@ ul.wc_coupon_list_block {
h2 { h2 {
margin: 0; margin: 0;
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", sans-serif; font-family:
"HelveticaNeue-Light",
"Helvetica Neue Light",
"Helvetica Neue",
sans-serif;
font-size: 21px; font-size: 21px;
font-weight: normal; font-weight: normal;
line-height: 1.2; line-height: 1.2;
@ -1186,7 +1404,11 @@ ul.wc_coupon_list_block {
p.order_number { p.order_number {
margin: 0; margin: 0;
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", sans-serif; font-family:
"HelveticaNeue-Light",
"Helvetica Neue Light",
"Helvetica Neue",
sans-serif;
font-weight: normal; font-weight: normal;
line-height: 1.6em; line-height: 1.6em;
font-size: 16px; font-size: 16px;
@ -2432,7 +2654,6 @@ ul.wc_coupon_list_block {
font-size: 14px; font-size: 14px;
vertical-align: middle; vertical-align: middle;
top: 4px; top: 4px;
} }
&:hover { &:hover {
@ -2717,7 +2938,7 @@ ul.wc_coupon_list_block {
} }
} }
.wc_addons_wrap { .wc-addons-wrap {
.addons-promotion-block { .addons-promotion-block {
flex-direction: column; flex-direction: column;
@ -3155,8 +3376,8 @@ table.wc_input_table {
background: #fff; background: #fff;
cursor: default; cursor: default;
input[type=text], input[type="text"],
input[type=number] { input[type="number"] {
width: 100% !important; width: 100% !important;
min-width: 100px; min-width: 100px;
padding: 8px 10px; padding: 8px 10px;
@ -3600,10 +3821,16 @@ table.wc-shipping-classes {
.button-primary { .button-primary {
background-color: #804877; background-color: #804877;
border-color: #804877; border-color: #804877;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 0 rgba(0, 0, 0, 0.15); box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.2),
0 1px 0 rgba(0, 0, 0, 0.15);
margin: 0; margin: 0;
opacity: 1; opacity: 1;
text-shadow: 0 -1px 1px #8a4f7f, 1px 0 1px #8a4f7f, 0 1px 1px #8a4f7f, -1px 0 1px #8a4f7f; text-shadow:
0 -1px 1px #8a4f7f,
1px 0 1px #8a4f7f,
0 1px 1px #8a4f7f,
-1px 0 1px #8a4f7f;
font-size: 1.5em; font-size: 1.5em;
padding: 0.75em 1em; padding: 0.75em 1em;
height: auto; height: auto;
@ -4260,7 +4487,6 @@ img.help_tip {
} }
table.form-table { table.form-table {
// Give regular settings inputs a standard width and padding. // Give regular settings inputs a standard width and padding.
textarea, textarea,
input[type="text"], input[type="text"],
@ -4692,8 +4918,8 @@ img.help_tip {
*/ */
.woocommerce_page_wc-settings { .woocommerce_page_wc-settings {
input[type=url], input[type="url"],
input[type=email] { input[type="email"] {
direction: ltr; direction: ltr;
} }
@ -5450,7 +5676,7 @@ img.help_tip {
padding: 4px 1em 2px 0; padding: 4px 1em 2px 0;
} }
input[type=checkbox] { input[type="checkbox"] {
margin: 0 5px 0 0.5em !important; margin: 0 5px 0 0.5em !important;
vertical-align: middle; vertical-align: middle;
} }
@ -5549,7 +5775,6 @@ img.tips {
/*rtl:ignore*/ /*rtl:ignore*/
left: 0; left: 0;
&.tip_top { &.tip_top {
padding-bottom: 5px; padding-bottom: 5px;
@ -5991,7 +6216,11 @@ img.ui-datepicker-trigger {
color: #464646; color: #464646;
font-weight: normal; font-weight: normal;
display: block; display: block;
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", sans-serif; font-family:
"HelveticaNeue-Light",
"Helvetica Neue Light",
"Helvetica Neue",
sans-serif;
del { del {
color: #e74c3c; color: #e74c3c;
@ -6238,7 +6467,9 @@ table.bar_chart {
&::before { &::before {
color: #ddd; color: #ddd;
text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.8); text-shadow:
0 -1px 1px rgba(0, 0, 0, 0.2),
0 1px 0 rgba(255, 255, 255, 0.8);
font-size: 8em; font-size: 8em;
display: block; display: block;
position: relative !important; position: relative !important;
@ -6325,7 +6556,6 @@ table.bar_chart {
} }
} }
.woocommerce_variations, .woocommerce_variations,
.woocommerce_options_panel { .woocommerce_options_panel {
@ -6513,7 +6743,7 @@ table.bar_chart {
flex-direction: column; flex-direction: column;
} }
.wc_addons_wrap { .wc-addons-wrap {
.addons-wcs-banner-block { .addons-wcs-banner-block {
padding: 40px; padding: 40px;
@ -6911,7 +7141,9 @@ table.bar_chart {
right: 1px; right: 1px;
height: 28px; height: 28px;
width: 23px; width: 23px;
background: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23555%22%2F%3E%3C%2Fsvg%3E") no-repeat right 5px top 55%; background:
url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23555%22%2F%3E%3C%2Fsvg%3E")
no-repeat right 5px top 55%;
background-size: 16px 16px; background-size: 16px 16px;
@media only screen and (max-width: 782px) { @media only screen and (max-width: 782px) {
@ -6941,7 +7173,6 @@ table.bar_chart {
padding: 0 0 0 3px; padding: 0 0 0 3px;
min-height: 28px; min-height: 28px;
} }
} }
.woocommerce table.form-table .select2-container { .woocommerce table.form-table .select2-container {
@ -6980,11 +7211,10 @@ table.bar_chart {
midnight: #e14d43, midnight: #e14d43,
ocean: #9ebaa0, ocean: #9ebaa0,
sunrise: #dd823b, sunrise: #dd823b,
light: #04a4cc light: #04a4cc,
); );
@each $name, $color in $wp_admin_colors { @each $name, $color in $wp_admin_colors {
&-#{$name}.wc-wp-version-gte-53 { &-#{$name}.wc-wp-version-gte-53 {
.select2-dropdown { .select2-dropdown {
@ -7003,22 +7233,26 @@ table.bar_chart {
color: $color; color: $color;
} }
.select2-container.select2-container--focus .select2-selection--single, .select2-container.select2-container--focus
.select2-container.select2-container--open .select2-selection--single, .select2-selection--single,
.select2-container.select2-container--open .select2-selection--multiple { .select2-container.select2-container--open
.select2-selection--single,
.select2-container.select2-container--open
.select2-selection--multiple {
border-color: $color; border-color: $color;
box-shadow: 0 0 0 1px $color; box-shadow: 0 0 0 1px $color;
} }
.select2-container--default .select2-results__option--highlighted[aria-selected], .select2-container--default
.select2-container--default .select2-results__option--highlighted[data-selected] { .select2-results__option--highlighted[aria-selected],
.select2-container--default
.select2-results__option--highlighted[data-selected] {
background-color: $color; background-color: $color;
} }
} }
} }
} }
.post-type-product .tablenav, .post-type-product .tablenav,
.post-type-shop_order .tablenav { .post-type-shop_order .tablenav {
@ -7117,9 +7351,15 @@ table.bar_chart {
border-radius: 4px; border-radius: 4px;
background-color: #bb77ae; background-color: #bb77ae;
border-color: #a36597; border-color: #a36597;
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 0 #a36597; -webkit-box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.25),
0 1px 0 #a36597;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 0 #a36597; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 0 #a36597;
text-shadow: 0 -1px 1px #a36597, 1px 0 1px #a36597, 0 1px 1px #a36597, -1px 0 1px #a36597; text-shadow:
0 -1px 1px #a36597,
1px 0 1px #a36597,
0 1px 1px #a36597,
-1px 0 1px #a36597;
margin: 0; margin: 0;
opacity: 1; opacity: 1;
@ -7128,7 +7368,9 @@ table.bar_chart {
&:active { &:active {
background: #a36597; background: #a36597;
border-color: #a36597; border-color: #a36597;
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 0 #a36597; -webkit-box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.25),
0 1px 0 #a36597;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 0 #a36597; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 0 #a36597;
} }
} }
@ -7423,3 +7665,13 @@ table.bar_chart {
color: darkred; color: darkred;
font-weight: bold; font-weight: bold;
} }
@media screen and (min-width: 600px) {
.wc-addons-wrap {
.marketplace-header {
padding-left: 84px;
}
}
}

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><rect x="0" fill="none" width="24" height="24"/><g><path d="M9 19.414l-6.707-6.707 1.414-1.414L9 16.586 20.293 5.293l1.414 1.414"/></g></svg>

After

Width:  |  Height:  |  Size: 201 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><rect x="0" fill="none" width="24" height="24"/><g><path d="M20 9l-8 8-8-8 1.414-1.414L12 14.172l6.586-6.586"/></g></svg>

After

Width:  |  Height:  |  Size: 181 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 KiB

View File

@ -406,6 +406,43 @@
return window.confirm( woocommerce_admin.i18n_remove_personal_data_notice ); return window.confirm( woocommerce_admin.i18n_remove_personal_data_notice );
} }
}); });
var marketplaceSectionDropdown = $( '#marketplace-current-section-dropdown' );
var marketplaceSectionName = $( '#marketplace-current-section-name' );
var marketplaceMenuIsOpen = false;
// Add event listener to toggle Marketplace menu on touch devices
if ( marketplaceSectionDropdown.length && isTouchDevice() ) {
marketplaceSectionName.on( 'click', function() {
marketplaceMenuIsOpen = ! marketplaceMenuIsOpen;
if ( marketplaceMenuIsOpen ) {
marketplaceSectionDropdown.addClass( 'is-open' );
$( document ).on( 'click', maybeToggleMarketplaceMenu );
} else {
marketplaceSectionDropdown.removeClass( 'is-open' );
$( document ).off( 'click', maybeToggleMarketplaceMenu );
}
} );
}
// Close menu if the user clicks outside it
function maybeToggleMarketplaceMenu( e ) {
if (
! marketplaceSectionDropdown.is( e.target )
&& marketplaceSectionDropdown.has( e.target ).length === 0
) {
marketplaceSectionDropdown.removeClass( 'is-open' );
marketplaceMenuIsOpen = false;
$( document ).off( 'click', maybeToggleMarketplaceMenu );
}
}
function isTouchDevice() {
return ( ( 'ontouchstart' in window ) ||
( navigator.maxTouchPoints > 0 ) ||
( navigator.msMaxTouchPoints > 0 ) );
}
}); });
})( jQuery, woocommerce_admin ); })( jQuery, woocommerce_admin );

View File

@ -723,6 +723,7 @@ class WC_Admin_Addons {
* Addon page view. * Addon page view.
* *
* @uses $addons * @uses $addons
* @uses $search
* @uses $sections * @uses $sections
* @uses $theme * @uses $theme
* @uses $current_section * @uses $current_section
@ -794,4 +795,20 @@ class WC_Admin_Addons {
return true; return true;
} }
/**
* We're displaying page=wc-addons and page=wc-addons&section=helper as two separate pages.
* When we're on those pages, add body classes to distinguishe them.
*
* @param string $admin_body_class Unfiltered body class.
*
* @return string Body class with added class for Marketplace or My Subscriptions page.
*/
public static function filter_admin_body_classes( string $admin_body_class = '' ): string {
if ( isset( $_GET['section'] ) && 'helper' === $_GET['section'] ) {
return " $admin_body_class woocommerce-page-wc-subscriptions ";
}
return " $admin_body_class woocommerce-page-wc-marketplace ";
}
} }

View File

@ -36,6 +36,8 @@ class WC_Admin_Menus {
add_filter( 'menu_order', array( $this, 'menu_order' ) ); add_filter( 'menu_order', array( $this, 'menu_order' ) );
add_filter( 'custom_menu_order', array( $this, 'custom_menu_order' ) ); add_filter( 'custom_menu_order', array( $this, 'custom_menu_order' ) );
add_filter( 'set-screen-option', array( $this, 'set_screen_option' ), 10, 3 ); add_filter( 'set-screen-option', array( $this, 'set_screen_option' ), 10, 3 );
add_filter( 'submenu_file', array( $this, 'update_menu_highlight' ), 10, 2 );
add_filter( 'admin_title', array( $this, 'update_my_subscriptions_title' ) );
// Add endpoints custom URLs in Appearance > Menus > Pages. // Add endpoints custom URLs in Appearance > Menus > Pages.
add_action( 'admin_head-nav-menus.php', array( $this, 'add_nav_menu_meta_boxes' ) ); add_action( 'admin_head-nav-menus.php', array( $this, 'add_nav_menu_meta_boxes' ) );
@ -149,8 +151,9 @@ class WC_Admin_Menus {
public function addons_menu() { public function addons_menu() {
$count_html = WC_Helper_Updater::get_updates_count_html(); $count_html = WC_Helper_Updater::get_updates_count_html();
/* translators: %s: extensions count */ /* translators: %s: extensions count */
$menu_title = sprintf( __( 'Extensions %s', 'woocommerce' ), $count_html ); $menu_title = sprintf( __( 'My Subscriptions %s', 'woocommerce' ), $count_html );
add_submenu_page( 'woocommerce', __( 'WooCommerce extensions', 'woocommerce' ), $menu_title, 'manage_woocommerce', 'wc-addons', array( $this, 'addons_page' ) ); add_submenu_page( 'woocommerce', __( 'WooCommerce Marketplace', 'woocommerce' ), __( 'Marketplace', 'woocommerce' ), 'manage_woocommerce', 'wc-addons', array( $this, 'addons_page' ) );
add_submenu_page( 'woocommerce', __( 'My WooCommerce.com Subscriptions', 'woocommerce' ), $menu_title, 'manage_woocommerce', 'wc-addons&section=helper', array( $this, 'addons_page' ) );
} }
/** /**
@ -387,6 +390,39 @@ class WC_Admin_Menus {
) )
); );
} }
/**
* Highlight the My Subscriptions menu item when on that page
*
* @param string $submenu_file The submenu file.
* @param string $parent_file currently opened page.
*
* @return string
*/
public function update_menu_highlight( $submenu_file, $parent_file ) {
if ( 'woocommerce' === $parent_file && isset( $_GET['section'] ) && 'helper' === $_GET['section'] ) {
$submenu_file = 'wc-addons&section=helper';
}
return $submenu_file;
}
/**
* Update the My Subscriptions document title when on that page.
* We want to maintain existing page URL but add it as a separate page,
* which requires updating it manually.
*
* @param string $admin_title existing page title.
* @return string
*/
public function update_my_subscriptions_title( $admin_title ) {
if (
isset( $_GET['page'] ) && 'wc-addons' === $_GET['page'] &&
isset( $_GET['section'] ) && 'helper' === $_GET['section']
) {
$admin_title = 'My WooCommerce.com Subscriptions';
}
return $admin_title;
}
} }
return new WC_Admin_Menus(); return new WC_Admin_Menus();

View File

@ -35,6 +35,11 @@ class WC_Admin {
// Add body class for WP 5.3+ compatibility. // Add body class for WP 5.3+ compatibility.
add_filter( 'admin_body_class', array( $this, 'include_admin_body_class' ), 9999 ); add_filter( 'admin_body_class', array( $this, 'include_admin_body_class' ), 9999 );
// Add body class for Marketplace and My Subscriptions pages.
if ( isset( $_GET['page'] ) && 'wc-addons' === $_GET['page'] ) {
add_filter( 'admin_body_class', array( 'WC_Admin_Addons', 'filter_admin_body_classes' ) );
}
} }
/** /**

View File

@ -1,19 +1,46 @@
<?php defined( 'ABSPATH' ) or exit(); ?> <?php
/**
* Helper main view
*
* @package WooCommerce\Helper
*/
<div class="wrap woocommerce wc_addons_wrap wc-helper"> ?>
<?php require WC_Helper::get_view_filename( 'html-section-nav.php' ); ?> <?php defined( 'ABSPATH' ) || exit(); ?>
<h1 class="screen-reader-text"><?php _e( 'WooCommerce Extensions', 'woocommerce' ); ?></h1>
<div class="wrap woocommerce wc-subscriptions-wrap wc-helper">
<h1 class="screen-reader-text"><?php esc_html_e( 'My Subscriptions', 'woocommerce' ); ?></h1>
<?php require WC_Helper::get_view_filename( 'html-section-notices.php' ); ?> <?php require WC_Helper::get_view_filename( 'html-section-notices.php' ); ?>
<div class="subscriptions-header"> <div class="subscriptions-header">
<h2><?php _e( 'Subscriptions', 'woocommerce' ); ?></h2> <h2><?php esc_html_e( 'Subscriptions', 'woocommerce' ); ?></h2>
<?php require WC_Helper::get_view_filename( 'html-section-account.php' ); ?> <?php require WC_Helper::get_view_filename( 'html-section-account.php' ); ?>
<p><?php printf( __( 'Below is a list of extensions available on your WooCommerce.com account. To receive extension updates please make sure the extension is installed, and its subscription activated and connected to your WooCommerce.com account. Extensions can be activated from the <a href="%s">Plugins</a> screen.', 'woocommerce' ), admin_url( 'plugins.php' ) ); ?></p> <p>
<?php
printf(
wp_kses(
/* translators: Introduction to list of WooCommerce.com extensions the merchant has subscriptions for. */
__(
'Below is a list of extensions available on your WooCommerce.com account. To receive extension updates please make sure the extension is installed, and its subscription activated and connected to your WooCommerce.com account. Extensions can be activated from the <a href="%s">Plugins</a> screen.',
'woocommerce'
),
array(
'a' => array(
'href' => array(),
),
)
),
esc_url(
admin_url( 'plugins.php' )
)
);
?>
</p>
</div> </div>
<ul class="subscription-filter"> <ul class="subscription-filter">
<label><?php _e( 'Sort by:', 'woocommerce' ); ?> <span class="chevron dashicons dashicons-arrow-up-alt2"></span></label> <label><?php esc_html_e( 'Sort by:', 'woocommerce' ); ?> <span class="chevron dashicons dashicons-arrow-up-alt2"></span></label>
<?php <?php
$filters = array_keys( WC_Helper::get_filters() ); $filters = array_keys( WC_Helper::get_filters() );
$last_filter = array_pop( $filters ); $last_filter = array_pop( $filters );
@ -32,7 +59,7 @@
$class_html = $current_filter === $key ? 'class="current"' : ''; $class_html = $current_filter === $key ? 'class="current"' : '';
?> ?>
<li> <li>
<a <?php echo $class_html; ?> href="<?php echo esc_url( $url ); ?>"> <a <?php echo esc_html( $class_html ); ?> href="<?php echo esc_url( $url ); ?>">
<?php echo esc_html( $label ); ?> <?php echo esc_html( $label ); ?>
<span class="count">(<?php echo absint( $counts[ $key ] ); ?>)</span> <span class="count">(<?php echo absint( $counts[ $key ] ); ?>)</span>
</a> </a>
@ -55,27 +82,27 @@
<div class="wp-list-table__ext-description"> <div class="wp-list-table__ext-description">
<?php if ( $subscription['lifetime'] ) : ?> <?php if ( $subscription['lifetime'] ) : ?>
<span class="renews"> <span class="renews">
<?php _e( 'Lifetime Subscription', 'woocommerce' ); ?> <?php esc_html_e( 'Lifetime Subscription', 'woocommerce' ); ?>
</span> </span>
<?php elseif ( $subscription['expired'] ) : ?> <?php elseif ( $subscription['expired'] ) : ?>
<span class="renews"> <span class="renews">
<strong><?php _e( 'Expired :(', 'woocommerce' ); ?></strong> <strong><?php esc_html_e( 'Expired :(', 'woocommerce' ); ?></strong>
<?php echo date_i18n( 'F jS, Y', $subscription['expires'] ); ?> <?php echo esc_html( date_i18n( 'F jS, Y', $subscription['expires'] ) ); ?>
</span> </span>
<?php elseif ( $subscription['autorenew'] ) : ?> <?php elseif ( $subscription['autorenew'] ) : ?>
<span class="renews"> <span class="renews">
<?php _e( 'Auto renews on:', 'woocommerce' ); ?> <?php esc_html_e( 'Auto renews on:', 'woocommerce' ); ?>
<?php echo date_i18n( 'F jS, Y', $subscription['expires'] ); ?> <?php echo esc_html( date_i18n( 'F jS, Y', $subscription['expires'] ) ); ?>
</span> </span>
<?php elseif ( $subscription['expiring'] ) : ?> <?php elseif ( $subscription['expiring'] ) : ?>
<span class="renews"> <span class="renews">
<strong><?php _e( 'Expiring soon!', 'woocommerce' ); ?></strong> <strong><?php esc_html_e( 'Expiring soon!', 'woocommerce' ); ?></strong>
<?php echo date_i18n( 'F jS, Y', $subscription['expires'] ); ?> <?php echo esc_html( date_i18n( 'F jS, Y', $subscription['expires'] ) ); ?>
</span> </span>
<?php else : ?> <?php else : ?>
<span class="renews"> <span class="renews">
<?php _e( 'Expires on:', 'woocommerce' ); ?> <?php esc_html_e( 'Expires on:', 'woocommerce' ); ?>
<?php echo date_i18n( 'F jS, Y', $subscription['expires'] ); ?> <?php echo esc_html( date_i18n( 'F jS, Y', $subscription['expires'] ) ); ?>
</span> </span>
<?php endif; ?> <?php endif; ?>
@ -84,19 +111,21 @@
<?php <?php
if ( ! $subscription['active'] && $subscription['maxed'] ) { if ( ! $subscription['active'] && $subscription['maxed'] ) {
/* translators: %1$d: sites active, %2$d max sites active */ /* translators: %1$d: sites active, %2$d max sites active */
printf( __( 'Subscription: Not available - %1$d of %2$d already in use', 'woocommerce' ), absint( $subscription['sites_active'] ), absint( $subscription['sites_max'] ) ); printf( esc_html__( 'Subscription: Not available - %1$d of %2$d already in use', 'woocommerce' ), absint( $subscription['sites_active'] ), absint( $subscription['sites_max'] ) );
} elseif ( $subscription['sites_max'] > 0 ) { } elseif ( $subscription['sites_max'] > 0 ) {
/* translators: %1$d: sites active, %2$d max sites active */ /* translators: %1$d: sites active, %2$d max sites active */
printf( __( 'Subscription: Using %1$d of %2$d sites available', 'woocommerce' ), absint( $subscription['sites_active'] ), absint( $subscription['sites_max'] ) ); printf( esc_html__( 'Subscription: Using %1$d of %2$d sites available', 'woocommerce' ), absint( $subscription['sites_active'] ), absint( $subscription['sites_max'] ) );
} else { } else {
_e( 'Subscription: Unlimited', 'woocommerce' ); esc_html_e( 'Subscription: Unlimited', 'woocommerce' );
} }
// Check shared. // Check shared.
if ( ! empty( $subscription['is_shared'] ) && ! empty( $subscription['owner_email'] ) ) { if ( ! empty( $subscription['is_shared'] ) && ! empty( $subscription['owner_email'] ) ) {
printf( '</br>' . __( 'Shared by %s', 'woocommerce' ), esc_html( $subscription['owner_email'] ) ); /* translators: Email address of person who shared the subscription. */
printf( '</br>' . esc_html__( 'Shared by %s', 'woocommerce' ), esc_html( $subscription['owner_email'] ) );
} elseif ( isset( $subscription['master_user_email'] ) ) { } elseif ( isset( $subscription['master_user_email'] ) ) {
printf( '</br>' . __( 'Shared by %s', 'woocommerce' ), esc_html( $subscription['master_user_email'] ) ); /* translators: Email address of person who shared the subscription. */
printf( '</br>' . esc_html__( 'Shared by %s', 'woocommerce' ), esc_html( $subscription['master_user_email'] ) );
} }
?> ?>
</span> </span>
@ -104,35 +133,35 @@
</td> </td>
<td class="wp-list-table__ext-actions"> <td class="wp-list-table__ext-actions">
<?php if ( ! $subscription['active'] && $subscription['maxed'] ) : ?> <?php if ( ! $subscription['active'] && $subscription['maxed'] ) : ?>
<a class="button" href="https://woocommerce.com/my-account/my-subscriptions/" target="_blank"><?php _e( 'Upgrade', 'woocommerce' ); ?></a> <a class="button" href="https://woocommerce.com/my-account/my-subscriptions/" target="_blank"><?php esc_html_e( 'Upgrade', 'woocommerce' ); ?></a>
<?php elseif ( ! $subscription['local']['installed'] && ! $subscription['expired'] ) : ?> <?php elseif ( ! $subscription['local']['installed'] && ! $subscription['expired'] ) : ?>
<a class="button <?php echo empty( $subscription['download_primary'] ) ? 'button-secondary' : ''; ?>" href="<?php echo esc_url( $subscription['download_url'] ); ?>" target="_blank"><?php _e( 'Download', 'woocommerce' ); ?></a> <a class="button <?php echo empty( $subscription['download_primary'] ) ? 'button-secondary' : ''; ?>" href="<?php echo esc_url( $subscription['download_url'] ); ?>" target="_blank"><?php esc_html_e( 'Download', 'woocommerce' ); ?></a>
<?php elseif ( $subscription['active'] ) : ?> <?php elseif ( $subscription['active'] ) : ?>
<span class="form-toggle__wrapper"> <span class="form-toggle__wrapper">
<a href="<?php echo esc_url( $subscription['deactivate_url'] ); ?>" class="form-toggle active is-compact" role="link" aria-checked="true"><?php _e( 'Active', 'woocommerce' ); ?></a> <a href="<?php echo esc_url( $subscription['deactivate_url'] ); ?>" class="form-toggle active is-compact" role="link" aria-checked="true"><?php esc_html_e( 'Active', 'woocommerce' ); ?></a>
<label class="form-toggle__label" for="activate-extension"> <label class="form-toggle__label" for="activate-extension">
<span class="form-toggle__label-content"> <span class="form-toggle__label-content">
<label for="activate-extension"><?php _e( 'Active', 'woocommerce' ); ?></label> <label for="activate-extension"><?php esc_html_e( 'Active', 'woocommerce' ); ?></label>
</span> </span>
<span class="form-toggle__switch"></span> <span class="form-toggle__switch"></span>
</label> </label>
</span> </span>
<?php elseif ( ! $subscription['expired'] ) : ?> <?php elseif ( ! $subscription['expired'] ) : ?>
<span class="form-toggle__wrapper"> <span class="form-toggle__wrapper">
<a href="<?php echo esc_url( $subscription['activate_url'] ); ?>" class="form-toggle is-compact" role="link" aria-checked="false"><?php _e( 'Inactive', 'woocommerce' ); ?></a> <a href="<?php echo esc_url( $subscription['activate_url'] ); ?>" class="form-toggle is-compact" role="link" aria-checked="false"><?php esc_html_e( 'Inactive', 'woocommerce' ); ?></a>
<label class="form-toggle__label" for="activate-extension"> <label class="form-toggle__label" for="activate-extension">
<span class="form-toggle__label-content"> <span class="form-toggle__label-content">
<label for="activate-extension"><?php _e( 'Inactive', 'woocommerce' ); ?></label> <label for="activate-extension"><?php esc_html_e( 'Inactive', 'woocommerce' ); ?></label>
</span> </span>
<span class="form-toggle__switch"></span> <span class="form-toggle__switch"></span>
</label> </label>
</span> </span>
<?php else : ?> <?php else : ?>
<span class="form-toggle__wrapper"> <span class="form-toggle__wrapper">
<span class="form-toggle disabled is-compact"><?php _e( 'Inactive', 'woocommerce' ); ?></span> <span class="form-toggle disabled is-compact"><?php esc_html_e( 'Inactive', 'woocommerce' ); ?></span>
<label class="form-toggle__label" for="activate-extension"> <label class="form-toggle__label" for="activate-extension">
<span class="form-toggle__label-content"> <span class="form-toggle__label-content">
<label for="activate-extension"><?php _e( 'Inactive', 'woocommerce' ); ?></label> <label for="activate-extension"><?php esc_html_e( 'Inactive', 'woocommerce' ); ?></label>
</span> </span>
</label> </label>
</span> </span>
@ -140,16 +169,16 @@
</td> </td>
</tr> </tr>
<?php foreach ( $subscription['actions'] as $action ) : ?> <?php foreach ( $subscription['actions'] as $subscription_action ) : ?>
<tr class="wp-list-table__row wp-list-table__ext-updates"> <tr class="wp-list-table__row wp-list-table__ext-updates">
<td class="wp-list-table__ext-status <?php echo sanitize_html_class( $action['status'] ); ?>"> <td class="wp-list-table__ext-status <?php echo sanitize_html_class( $subscription_action['status'] ); ?>">
<p><span class="dashicons <?php echo sanitize_html_class( $action['icon'] ); ?>"></span> <p><span class="dashicons <?php echo sanitize_html_class( $subscription_action['icon'] ); ?>"></span>
<?php echo $action['message']; ?> <?php echo wp_kses_post( $subscription_action['message'] ); ?>
</p> </p>
</td> </td>
<td class="wp-list-table__ext-actions"> <td class="wp-list-table__ext-actions">
<?php if ( ! empty( $action['button_label'] ) && ! empty( $action['button_url'] ) ) : ?> <?php if ( ! empty( $subscription_action['button_label'] ) && ! empty( $subscription_action['button_url'] ) ) : ?>
<a class="button <?php echo empty( $action['primary'] ) ? 'button-secondary' : ''; ?>" href="<?php echo esc_url( $action['button_url'] ); ?>"><?php echo esc_html( $action['button_label'] ); ?></a> <a class="button <?php echo empty( $subscription_action['primary'] ) ? 'button-secondary' : ''; ?>" href="<?php echo esc_url( $subscription_action['button_url'] ); ?>"><?php echo esc_html( $subscription_action['button_label'] ); ?></a>
<?php endif; ?> <?php endif; ?>
</td> </td>
</tr> </tr>
@ -159,14 +188,14 @@
<?php endforeach; ?> <?php endforeach; ?>
<?php else : ?> <?php else : ?>
<tr> <tr>
<td colspan="3"><em><?php _e( 'Could not find any subscriptions on your WooCommerce.com account', 'woocommerce' ); ?></td> <td colspan="3"><em><?php esc_html_e( 'Could not find any subscriptions on your WooCommerce.com account', 'woocommerce' ); ?></td>
</tr> </tr>
<?php endif; ?> <?php endif; ?>
</tbody> </tbody>
</table> </table>
<?php if ( ! empty( $no_subscriptions ) ) : ?> <?php if ( ! empty( $no_subscriptions ) ) : ?>
<h2><?php _e( 'Installed Extensions without a Subscription', 'woocommerce' ); ?></h2> <h2><?php esc_html_e( 'Installed Extensions without a Subscription', 'woocommerce' ); ?></h2>
<p>Below is a list of WooCommerce.com products available on your site - but are either out-dated or do not have a valid subscription.</p> <p>Below is a list of WooCommerce.com products available on your site - but are either out-dated or do not have a valid subscription.</p>
<table class="wp-list-table widefat fixed striped"> <table class="wp-list-table widefat fixed striped">
@ -183,25 +212,25 @@
</td> </td>
<td class="wp-list-table__ext-actions"> <td class="wp-list-table__ext-actions">
<span class="form-toggle__wrapper"> <span class="form-toggle__wrapper">
<span class="form-toggle disabled is-compact" ><?php _e( 'Inactive', 'woocommerce' ); ?></span> <span class="form-toggle disabled is-compact" ><?php esc_html_e( 'Inactive', 'woocommerce' ); ?></span>
<label class="form-toggle__label" for="activate-extension"> <label class="form-toggle__label" for="activate-extension">
<span class="form-toggle__label-content"> <span class="form-toggle__label-content">
<label for="activate-extension"><?php _e( 'Inactive', 'woocommerce' ); ?></label> <label for="activate-extension"><?php esc_html_e( 'Inactive', 'woocommerce' ); ?></label>
</span> </span>
</label> </label>
</span> </span>
</td> </td>
</tr> </tr>
<?php foreach ( $data['_actions'] as $action ) : ?> <?php foreach ( $data['_actions'] as $subscription_action ) : ?>
<tr class="wp-list-table__row wp-list-table__ext-updates"> <tr class="wp-list-table__row wp-list-table__ext-updates">
<td class="wp-list-table__ext-status <?php echo sanitize_html_class( $action['status'] ); ?>"> <td class="wp-list-table__ext-status <?php echo sanitize_html_class( $subscription_action['status'] ); ?>">
<p><span class="dashicons <?php echo sanitize_html_class( $action['icon'] ); ?>"></span> <p><span class="dashicons <?php echo sanitize_html_class( $subscription_action['icon'] ); ?>"></span>
<?php echo $action['message']; ?> <?php echo esc_html( $subscription_action['message'] ); ?>
</p> </p>
</td> </td>
<td class="wp-list-table__ext-actions"> <td class="wp-list-table__ext-actions">
<a class="button" href="<?php echo esc_url( $action['button_url'] ); ?>" target="_blank"><?php echo esc_html( $action['button_label'] ); ?></a> <a class="button" href="<?php echo esc_url( $subscription_action['button_url'] ); ?>" target="_blank"><?php echo esc_html( $subscription_action['button_label'] ); ?></a>
</td> </td>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>

View File

@ -9,8 +9,7 @@ defined( 'ABSPATH' ) || exit();
?> ?>
<div class="wrap woocommerce wc_addons_wrap wc-helper"> <div class="wrap woocommerce wc-addons-wrap wc-helper">
<?php require WC_Helper::get_view_filename( 'html-section-nav.php' ); ?>
<h1 class="screen-reader-text"><?php esc_html_e( 'WooCommerce Extensions', 'woocommerce' ); ?></h1> <h1 class="screen-reader-text"><?php esc_html_e( 'WooCommerce Extensions', 'woocommerce' ); ?></h1>
<?php require WC_Helper::get_view_filename( 'html-section-notices.php' ); ?> <?php require WC_Helper::get_view_filename( 'html-section-notices.php' ); ?>

View File

@ -3,6 +3,8 @@
* Helper admin navigation. * Helper admin navigation.
* *
* @package WooCommerce\Helper * @package WooCommerce\Helper
*
* @deprecated 5.7.0
*/ */
defined( 'ABSPATH' ) || exit(); ?> defined( 'ABSPATH' ) || exit(); ?>

View File

@ -11,24 +11,40 @@ if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
} }
?> $current_section_name = __( 'Browse Categories', 'woocommerce' );
<div class="wrap woocommerce wc_addons_wrap">
<nav class="nav-tab-wrapper woo-nav-tab-wrapper">
<a href="<?php echo esc_url( admin_url( 'admin.php?page=wc-addons' ) ); ?>" class="nav-tab nav-tab-active"><?php esc_html_e( 'Browse Extensions', 'woocommerce' ); ?></a>
<?php
$count_html = WC_Helper_Updater::get_updates_count_html();
// translators: Count of updates for WooCommerce.com subscriptions.
$menu_title = sprintf( __( 'WooCommerce.com Subscriptions %s', 'woocommerce' ), $count_html );
?> ?>
<a href="<?php echo esc_url( admin_url( 'admin.php?page=wc-addons&section=helper' ) ); ?>" class="nav-tab"><?php echo wp_kses_post( $menu_title ); ?></a> <div class="woocommerce wc-addons-wrap">
</nav> <h1 class="screen-reader-text"><?php esc_html_e( 'Marketplace', 'woocommerce' ); ?></h1>
<h1 class="screen-reader-text"><?php esc_html_e( 'WooCommerce Extensions', 'woocommerce' ); ?></h1>
<?php if ( $sections ) : ?> <?php if ( $sections ) : ?>
<ul class="subsubsub"> <div class="marketplace-header">
<h1 class="marketplace-header__title"><?php esc_html_e( 'WooCommerce Marketplace', 'woocommerce' ); ?></h1>
<p class="marketplace-header__description"><?php esc_html_e( 'Grow your business with hundreds of free and paid WooCommerce extensions.', 'woocommerce' ); ?></p>
<form class="marketplace-header__search-form" method="GET">
<input
type="text"
name="search"
value="<?php echo esc_attr( ! empty( $search ) ? sanitize_text_field( wp_unslash( $search ) ) : '' ); ?>"
placeholder="<?php esc_attr_e( 'Search for extensions', 'woocommerce' ); ?>"
/>
<button type="submit">
<span class="dashicons dashicons-search"></span>
</button>
<input type="hidden" name="page" value="wc-addons">
<input type="hidden" name="section" value="_all">
</form>
</div>
<div class="top-bar">
<div id="marketplace-current-section-dropdown" class="current-section-dropdown">
<ul>
<?php foreach ( $sections as $section ) : ?> <?php foreach ( $sections as $section ) : ?>
<?php
if ( $current_section === $section->slug && '_featured' !== $section->slug ) {
$current_section_name = $section->label;
}
?>
<li> <li>
<a <a
class="<?php echo $current_section === $section->slug ? 'current' : ''; ?>" class="<?php echo $current_section === $section->slug ? 'current' : ''; ?>"
@ -38,26 +54,21 @@ if ( ! defined( 'ABSPATH' ) ) {
</li> </li>
<?php endforeach; ?> <?php endforeach; ?>
</ul> </ul>
<div id="marketplace-current-section-name" class="current-section-name"><?php echo esc_html( $current_section_name ); ?></div>
</div>
</div>
<?php if ( isset( $_GET['search'] ) ) : // phpcs:ignore WordPress.Security.NonceVerification.Recommended ?> <div class="wp-header-end"></div>
<div class="wrap">
<div class="marketplace-content-wrapper">
<?php if ( ! empty( $search ) ) : ?>
<h1 class="search-form-title"> <h1 class="search-form-title">
<?php // translators: search keyword. ?> <?php // translators: search keyword. ?>
<?php printf( esc_html__( 'Showing search results for: %s', 'woocommerce' ), '<strong>' . esc_html( sanitize_text_field( wp_unslash( $_GET['search'] ) ) ) . '</strong>' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended ?> <?php printf( esc_html__( 'Search results for "%s"', 'woocommerce' ), esc_html( sanitize_text_field( wp_unslash( $search ) ) ) ); ?>
</h1> </h1>
<?php endif; ?> <?php endif; ?>
<form class="search-form" method="GET">
<button type="submit">
<span class="dashicons dashicons-search"></span>
</button>
<input
type="text"
name="search"
value="<?php echo esc_attr( isset( $_GET['search'] ) ? sanitize_text_field( wp_unslash( $_GET['search'] ) ) : '' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended ?>"
placeholder="<?php esc_attr_e( 'Enter a search term and press enter', 'woocommerce' ); ?>">
<input type="hidden" name="page" value="wc-addons">
<input type="hidden" name="section" value="_all">
</form>
<?php if ( '_featured' === $current_section ) : ?> <?php if ( '_featured' === $current_section ) : ?>
<div class="addons-featured"> <div class="addons-featured">
<?php <?php
@ -101,19 +112,31 @@ if ( ! defined( 'ABSPATH' ) ) {
} }
?> ?>
<li class="product"> <li class="product">
<a href="<?php echo esc_attr( WC_Admin_Addons::add_in_app_purchase_url_params( $addon->link ) ); ?>"> <div class="product-details">
<?php if ( ! empty( $addon->image ) ) : ?> <?php if ( ! empty( $addon->image ) ) : ?>
<span class="product-img-wrap"><img src="<?php echo esc_url( $addon->image ); ?>" /></span> <span class="product-img-wrap"><img src="<?php echo esc_url( $addon->image ); ?>" /></span>
<?php else : ?>
<h2><?php echo esc_html( $addon->title ); ?></h2>
<?php endif; ?> <?php endif; ?>
<span class="price"><?php echo wp_kses_post( $addon->price ); ?></span> <a href="<?php echo esc_url( WC_Admin_Addons::add_in_app_purchase_url_params( $addon->link ) ); ?>">
<p><?php echo wp_kses_post( $addon->excerpt ); ?></p> <h2><?php echo esc_html( $addon->title ); ?></h2>
</a> </a>
<p><?php echo wp_kses_post( $addon->excerpt ); ?></p>
</div>
<div class="product-footer">
<?php if ( '&#36;0.00' === $addon->price ) : ?>
<span class="price"><?php esc_html_e( 'Free', 'woocommerce' ); ?></span>
<?php else : ?>
<span class="price"><?php echo wp_kses_post( $addon->price ); ?></span>
<span class="price_suffix"><?php esc_html_e( 'per year', 'woocommerce' ); ?></span>
<?php endif; ?>
<a class="button" href="<?php echo esc_url( WC_Admin_Addons::add_in_app_purchase_url_params( $addon->link ) ); ?>">
<?php esc_html_e( 'View details', 'woocommerce' ); ?>
</a>
</div>
</li> </li>
<?php endforeach; ?> <?php endforeach; ?>
</ul> </ul>
<?php endif; ?> <?php endif; ?>
</div>
<?php else : ?> <?php else : ?>
<?php /* translators: a url */ ?> <?php /* translators: a url */ ?>
<p><?php printf( wp_kses_post( __( 'Our catalog of WooCommerce Extensions can be found on WooCommerce.com here: <a href="%s">WooCommerce Extensions Catalog</a>', 'woocommerce' ) ), 'https://woocommerce.com/product-category/woocommerce-extensions/' ); ?></p> <p><?php printf( wp_kses_post( __( 'Our catalog of WooCommerce Extensions can be found on WooCommerce.com here: <a href="%s">WooCommerce Extensions Catalog</a>', 'woocommerce' ) ), 'https://woocommerce.com/product-category/woocommerce-extensions/' ); ?></p>
@ -132,3 +155,4 @@ if ( ! defined( 'ABSPATH' ) ) {
</div> </div>
<?php endif; ?> <?php endif; ?>
</div> </div>
</div>

View File

@ -29,11 +29,15 @@ class WC_Extensions_Tracking {
*/ */
public function track_extensions_page() { public function track_extensions_page() {
// phpcs:disable WordPress.Security.NonceVerification.Recommended // phpcs:disable WordPress.Security.NonceVerification.Recommended
$event = 'extensions_view';
$properties = array( $properties = array(
'section' => empty( $_REQUEST['section'] ) ? '_featured' : wc_clean( wp_unslash( $_REQUEST['section'] ) ), 'section' => empty( $_REQUEST['section'] ) ? '_featured' : wc_clean( wp_unslash( $_REQUEST['section'] ) ),
); );
$event = 'extensions_view';
if ( 'helper' === $properties['section'] ) {
$event = 'subscriptions_view';
}
if ( ! empty( $_REQUEST['search'] ) ) { if ( ! empty( $_REQUEST['search'] ) ) {
$event = 'extensions_view_search'; $event = 'extensions_view_search';
$properties['search_term'] = wc_clean( wp_unslash( $_REQUEST['search'] ) ); $properties['search_term'] = wc_clean( wp_unslash( $_REQUEST['search'] ) );

View File

@ -20,14 +20,8 @@ const runInitiateWccomConnectionTest = () => {
await merchant.login(); await merchant.login();
}); });
it.skip('can initiate WCCOM connection', async () => { it('can initiate WCCOM connection', async () => {
await merchant.openExtensions(); await merchant.openHelper();
// Click on a tab to choose WooCommerce Subscriptions extension
await Promise.all([
expect(page).toClick('a.nav-tab', {text: "WooCommerce.com Subscriptions"}),
page.waitForNavigation({waitUntil: 'networkidle0'}),
]);
// Click on Connect button to initiate a WCCOM connection // Click on Connect button to initiate a WCCOM connection
await Promise.all([ await Promise.all([

View File

@ -1,5 +1,3 @@
/* eslint-disable jest/no-export, jest/no-disabled-tests */
/** /**
* Internal dependencies * Internal dependencies
*/ */
@ -10,7 +8,7 @@ const {
addShippingZoneAndMethod, addShippingZoneAndMethod,
clearAndFillInput, clearAndFillInput,
selectOptionInSelect2, selectOptionInSelect2,
deleteAllShippingZones, withRestApi,
} = require( '@woocommerce/e2e-utils' ); } = require( '@woocommerce/e2e-utils' );
/** /**
@ -35,8 +33,8 @@ const runAddNewShippingZoneTest = () => {
describe('WooCommerce Shipping Settings - Add new shipping zone', () => { describe('WooCommerce Shipping Settings - Add new shipping zone', () => {
beforeAll(async () => { beforeAll(async () => {
await createSimpleProduct(); await createSimpleProduct();
await withRestApi.deleteAllShippingZones();
await merchant.login(); await merchant.login();
await deleteAllShippingZones();
}); });
it('add shipping zone for San Francisco with free Local pickup', async () => { it('add shipping zone for San Francisco with free Local pickup', async () => {

View File

@ -1,16 +1,12 @@
/* eslint-disable jest/no-export, jest/no-disabled-tests, jest/expect-expect */
/** /**
* Internal dependencies * Internal dependencies
*/ */
const { const {
shopper, shopper,
merchant,
createSimpleProduct, createSimpleProduct,
addShippingZoneAndMethod,
clearAndFillInput,
uiUnblocked, uiUnblocked,
selectOptionInSelect2, selectOptionInSelect2,
withRestApi,
} = require( '@woocommerce/e2e-utils' ); } = require( '@woocommerce/e2e-utils' );
/** /**
@ -43,29 +39,21 @@ const runCartCalculateShippingTest = () => {
await createSimpleProduct(firstProductName); await createSimpleProduct(firstProductName);
await createSimpleProduct(secondProductName, secondProductPrice); await createSimpleProduct(secondProductName, secondProductPrice);
await merchant.login(); await withRestApi.resetSettingsGroupToDefault( 'general' );
await merchant.openNewShipping();
// Add a new shipping zone Germany with Free shipping // Add a new shipping zone Germany with Free shipping
await addShippingZoneAndMethod(shippingZoneNameDE, shippingCountryDE, ' ', 'free_shipping'); await withRestApi.addShippingZoneAndMethod(shippingZoneNameDE, shippingCountryDE, ' ', 'free_shipping');
// Add a new shipping zone for France with Flat rate & Local pickup // Add a new shipping zone for France with Flat rate & Local pickup
await addShippingZoneAndMethod(shippingZoneNameFR, shippingCountryFR, ' ', 'flat_rate'); await withRestApi.addShippingZoneAndMethod(shippingZoneNameFR, shippingCountryFR, ' ', 'flat_rate', '5', ['local_pickup']);
await page.waitFor(1000); // to avoid flakiness in headless
await page.click('a.wc-shipping-zone-method-settings', {text: 'Flat rate'});
await clearAndFillInput('#woocommerce_flat_rate_cost', '5');
await page.click('.wc-backbone-modal-main button#btn-ok');
// Add additional method Local pickup for the same location
await page.waitFor(1000); // to avoid flakiness in headless
await page.click('button.wc-shipping-zone-add-method', {text:'Add shipping method'});
await page.waitForSelector('.wc-shipping-zone-method-selector');
await page.select('select[name="add_method_id"]', 'local_pickup');
await page.click('button#btn-ok');
await page.waitForSelector('#zone_locations');
await merchant.logout();
await shopper.emptyCart(); await shopper.emptyCart();
}); });
afterAll(async () => {
await withRestApi.deleteAllShippingZones();
});
it('allows customer to calculate Free Shipping if in Germany', async () => { it('allows customer to calculate Free Shipping if in Germany', async () => {
await shopper.goToShop(); await shopper.goToShop();
await shopper.addToCartFromShopPage(firstProductName); await shopper.addToCartFromShopPage(firstProductName);
@ -76,6 +64,7 @@ const runCartCalculateShippingTest = () => {
await expect(page).toClick('#select2-calc_shipping_country-container'); await expect(page).toClick('#select2-calc_shipping_country-container');
await selectOptionInSelect2('Germany'); await selectOptionInSelect2('Germany');
await expect(page).toClick('button[name="calc_shipping"]'); await expect(page).toClick('button[name="calc_shipping"]');
await uiUnblocked();
// Verify shipping costs // Verify shipping costs
await page.waitForSelector('.order-total'); await page.waitForSelector('.order-total');
@ -84,13 +73,14 @@ const runCartCalculateShippingTest = () => {
}); });
it('allows customer to calculate Flat rate and Local pickup if in France', async () => { it('allows customer to calculate Flat rate and Local pickup if in France', async () => {
await page.reload(); await page.reload( { waitUntil: ['networkidle0', 'domcontentloaded'] } );
// Set shipping country to France // Set shipping country to France
await expect(page).toClick('a.shipping-calculator-button'); await expect(page).toClick('a.shipping-calculator-button');
await expect(page).toClick('#select2-calc_shipping_country-container'); await expect(page).toClick('#select2-calc_shipping_country-container');
await selectOptionInSelect2('France'); await selectOptionInSelect2('France');
await expect(page).toClick('button[name="calc_shipping"]'); await expect(page).toClick('button[name="calc_shipping"]');
await uiUnblocked();
// Verify shipping costs // Verify shipping costs
await page.waitForSelector('.order-total'); await page.waitForSelector('.order-total');
@ -119,13 +109,14 @@ const runCartCalculateShippingTest = () => {
}); });
it('should show correct total cart price with 2 products without flat rate', async () => { it('should show correct total cart price with 2 products without flat rate', async () => {
await page.reload(); await page.reload( { waitUntil: ['networkidle0', 'domcontentloaded'] } );
// Set shipping country to Spain // Set shipping country to Spain
await expect(page).toClick('a.shipping-calculator-button'); await expect(page).toClick('a.shipping-calculator-button');
await expect(page).toClick('#select2-calc_shipping_country-container'); await expect(page).toClick('#select2-calc_shipping_country-container');
await selectOptionInSelect2('Spain'); await selectOptionInSelect2('Spain');
await expect(page).toClick('button[name="calc_shipping"]'); await expect(page).toClick('button[name="calc_shipping"]');
await uiUnblocked();
// Verify shipping costs // Verify shipping costs
await page.waitForSelector('.order-total'); await page.waitForSelector('.order-total');

View File

@ -9,8 +9,9 @@
- Added `getLatestReleaseZipUrl( owner, repository, getPrerelease, perPage )` util function to get the latest release zip from a GitHub repository. - Added `getLatestReleaseZipUrl( owner, repository, getPrerelease, perPage )` util function to get the latest release zip from a GitHub repository.
- Added `DEFAULT_TIMEOUT_OVERRIDE` that allows passing in a time in milliseconds to override the default Jest and Puppeteer timeouts. - Added `DEFAULT_TIMEOUT_OVERRIDE` that allows passing in a time in milliseconds to override the default Jest and Puppeteer timeouts.
- Fix latest version tag search paging logic - Fix latest version tag search paging logic
- Bump PHP fallback version to 7.4.22 - Update fallback PHP version to 7.4.22
- Bump MariahDB fallback version to 10.6.4 - Update fallback MariahDB version to 10.6.4
- Update fallback WordPress version to 5.8.0.
# 0.2.2 # 0.2.2

View File

@ -10,7 +10,7 @@ if [[ $1 ]]; then
if [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+ ]]; then if [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+ ]]; then
export WORDPRESS_VERSION=$WP_VERSION export WORDPRESS_VERSION=$WP_VERSION
else else
export WORDPRESS_VERSION="5.5.1" export WORDPRESS_VERSION="5.8.0"
fi fi
if ! [[ $TRAVIS_PHP_VERSION =~ ^[0-9]+\.[0-9]+ ]]; then if ! [[ $TRAVIS_PHP_VERSION =~ ^[0-9]+\.[0-9]+ ]]; then

View File

@ -16,6 +16,7 @@
- Added `deleteAllOrders()` that goes through and deletes all orders - Added `deleteAllOrders()` that goes through and deletes all orders
- Added `deleteAllShippingClasses()` which permanently deletes all shipping classes using the API - Added `deleteAllShippingClasses()` which permanently deletes all shipping classes using the API
- Added `statuses` optional parameter to `deleteAllRepositoryObjects()` to delete on specific statuses - Added `statuses` optional parameter to `deleteAllRepositoryObjects()` to delete on specific statuses
- Updated `addShippingZoneAndMethod` to use the API instead of UI to create shipping zones
# 0.1.5 # 0.1.5

View File

@ -41,6 +41,7 @@ export const WP_ADMIN_ANALYTICS_PAGES = WP_ADMIN_WC_HOME + '&path=%2Fanalytics%2
export const WP_ADMIN_WC_SETTINGS = WP_ADMIN_PLUGIN_PAGE + 'wc-settings&tab='; export const WP_ADMIN_WC_SETTINGS = WP_ADMIN_PLUGIN_PAGE + 'wc-settings&tab=';
export const WP_ADMIN_NEW_SHIPPING_ZONE = WP_ADMIN_WC_SETTINGS + 'shipping&zone_id=new'; export const WP_ADMIN_NEW_SHIPPING_ZONE = WP_ADMIN_WC_SETTINGS + 'shipping&zone_id=new';
export const WP_ADMIN_WC_EXTENSIONS = WP_ADMIN_PLUGIN_PAGE + 'wc-addons'; export const WP_ADMIN_WC_EXTENSIONS = WP_ADMIN_PLUGIN_PAGE + 'wc-addons';
export const WP_ADMIN_WC_HELPER = WP_ADMIN_PLUGIN_PAGE + 'wc-addons&section=helper';
/** /**
* Shop pages. * Shop pages.

View File

@ -21,6 +21,7 @@ const {
WP_ADMIN_WC_HOME, WP_ADMIN_WC_HOME,
WP_ADMIN_WC_SETTINGS, WP_ADMIN_WC_SETTINGS,
WP_ADMIN_WC_EXTENSIONS, WP_ADMIN_WC_EXTENSIONS,
WP_ADMIN_WC_HELPER,
WP_ADMIN_NEW_SHIPPING_ZONE, WP_ADMIN_NEW_SHIPPING_ZONE,
WP_ADMIN_ANALYTICS_PAGES, WP_ADMIN_ANALYTICS_PAGES,
WP_ADMIN_ALL_USERS_VIEW, WP_ADMIN_ALL_USERS_VIEW,
@ -134,6 +135,12 @@ const merchant = {
} ); } );
}, },
openHelper: async () => {
await page.goto( WP_ADMIN_WC_HELPER, {
waitUntil: 'networkidle0',
} );
},
runSetupWizard: async () => { runSetupWizard: async () => {
const setupWizard = IS_RETEST_MODE ? WP_ADMIN_SETUP_WIZARD : WP_ADMIN_WC_HOME; const setupWizard = IS_RETEST_MODE ? WP_ADMIN_SETUP_WIZARD : WP_ADMIN_WC_HOME;
await page.goto( setupWizard, { await page.goto( setupWizard, {

View File

@ -92,6 +92,79 @@ export const withRestApi = {
const orderStatuses = ['pending', 'processing', 'on-hold', 'completed', 'cancelled', 'refunded', 'failed', 'trash']; const orderStatuses = ['pending', 'processing', 'on-hold', 'completed', 'cancelled', 'refunded', 'failed', 'trash'];
const repository = Order.restRepository( client ); const repository = Order.restRepository( client );
await deleteAllRepositoryObjects( repository, null, orderStatuses ); await deleteAllRepositoryObjects( repository, null, orderStatuses );
},
/**
* Adds a shipping zone along with a shipping method using the API.
*
* @param zoneName Shipping zone name.
* @param zoneLocation Shiping zone location. Defaults to country:US. For states use: state:US:CA.
* @param zipCode Shipping zone zip code. Default is no zip code.
* @param zoneMethod Shipping method type. Defaults to flat_rate (use also: free_shipping or local_pickup).
* @param cost Shipping method cost. Default is no cost.
* @param additionalZoneMethods Array of additional zone methods to add to the shipping zone.
*/
addShippingZoneAndMethod: async (
zoneName,
zoneLocation = 'country:US',
zipCode = '',
zoneMethod = 'flat_rate',
cost = '',
additionalZoneMethods = [] ) => {
const path = 'wc/v3/shipping/zones';
const response = await client.post( path, { name: zoneName } );
expect(response.statusCode).toEqual(201);
let zoneId = response.data.id;
// Select shipping zone location
let [ zoneType, zoneCode ] = zoneLocation.split(/:(.+)/);
let zoneLocationPayload = [
{
code: zoneCode,
type: zoneType,
}
];
// Fill shipping zone postcode if provided
if ( zipCode ) {
zoneLocationPayload.push( {
code: zipCode,
type: "postcode",
} );
}
const locationResponse = await client.put( path + `/${zoneId}/locations`, zoneLocationPayload );
expect(locationResponse.statusCode).toEqual(200);
// Add shipping zone method
let methodPayload = {
method_id: zoneMethod
}
const methodsResponse = await client.post( path + `/${zoneId}/methods`, methodPayload );
expect(methodsResponse.statusCode).toEqual(200);
let methodId = methodsResponse.data.id;
// Add in cost, if provided
if ( cost ) {
let costPayload = {
settings: {
cost: cost
}
}
const costResponse = await client.put( path + `/${zoneId}/methods/${methodId}`, costPayload );
expect(costResponse.statusCode).toEqual(200);
}
// Add any additional zones, if provided
if (additionalZoneMethods.length > 0) {
for ( let z = 0; z < additionalZoneMethods.length; z++ ) {
let response = await client.post( path + `/${zoneId}/methods`, { method_id: additionalZoneMethods[z] } );
expect(response.statusCode).toEqual(200);
}
}
}, },
/** /**
* Use api package to delete shipping zones. * Use api package to delete shipping zones.