Merge pull request #30900 from woocommerce/update/marketplace-featured-page
Revamp Featured page in WooCommerce Marketplace
This commit is contained in:
commit
d5b874a7fe
|
@ -194,14 +194,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
h1.search-form-title {
|
||||
clear: left;
|
||||
font-size: 20px;
|
||||
line-height: 1.2;
|
||||
margin: 48px 0 16px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.update-plugins .update-count {
|
||||
background-color: #d54e21;
|
||||
border-radius: 10px;
|
||||
|
@ -215,6 +207,26 @@
|
|||
vertical-align: text-top;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marketplace related variables
|
||||
*/
|
||||
$font-sf-pro-text:
|
||||
helveticaneue-light,
|
||||
"Helvetica Neue Light",
|
||||
"Helvetica Neue",
|
||||
sans-serif;
|
||||
|
||||
$font-sf-pro-display: sans-serif;
|
||||
|
||||
h1.search-form-title {
|
||||
clear: left;
|
||||
font-size: 20px;
|
||||
font-family: $font-sf-pro-display;
|
||||
line-height: 1.2;
|
||||
margin: 48px 0 16px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.addons-featured {
|
||||
margin: 0;
|
||||
}
|
||||
|
@ -243,82 +255,15 @@
|
|||
width: 124px;
|
||||
}
|
||||
|
||||
.addons-banner-block-item-icon,
|
||||
.addons-column-block-item-icon {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.addons-banner-block,
|
||||
.addons-wcs-banner-block {
|
||||
align-items: center;
|
||||
background: #fff;
|
||||
border: 1px solid #ddd;
|
||||
display: flex;
|
||||
margin: 0 0 1em 0;
|
||||
padding: 2em 2em 1em;
|
||||
}
|
||||
|
||||
.addons-banner-block img {
|
||||
height: 62px;
|
||||
}
|
||||
|
||||
.addons-banner-block p {
|
||||
margin: 0 0 20px;
|
||||
}
|
||||
|
||||
.addons-banner-block-items {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
margin: 0 -10px 0 -10px;
|
||||
}
|
||||
|
||||
.addons-banner-block-item {
|
||||
border: 1px solid #e6e6e6;
|
||||
border-radius: 3px;
|
||||
flex: 1;
|
||||
margin: 1em;
|
||||
min-width: 200px;
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.addons-banner-block-item-icon {
|
||||
background: #f7f7f7;
|
||||
height: 143px;
|
||||
}
|
||||
|
||||
.addons-banner-block-item-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 184px;
|
||||
justify-content: space-between;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.addons-banner-block-item-content h3 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.addons-banner-block-item-content p {
|
||||
margin: 0 0 auto;
|
||||
}
|
||||
|
||||
.addons-wcs-banner-block {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.addons-promotion-block {
|
||||
display: flex;
|
||||
padding: 20px;
|
||||
|
||||
.addons-img {
|
||||
height: auto;
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
.addons-wcs-banner-block-image {
|
||||
background: #f7f7f7;
|
||||
border: 1px solid #e6e6e6;
|
||||
|
@ -343,33 +288,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.addons-promotion-block-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-left: 24px;
|
||||
}
|
||||
|
||||
.addons-promotion-block-description {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.addons-promotion-block-title {
|
||||
margin: 0 0 16px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.addons-promotion-block-buttons {
|
||||
margin-top: auto;
|
||||
|
||||
.addons-button {
|
||||
margin-right: 8px;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.addons-shipping-methods .addons-wcs-banner-block {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
|
@ -415,13 +333,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.addons-column-section {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.addons-column {
|
||||
flex: 1;
|
||||
width: 50%;
|
||||
|
@ -432,90 +343,6 @@
|
|||
margin-right: 0;
|
||||
}
|
||||
|
||||
.addons-small-light-block,
|
||||
.addons-small-dark-block,
|
||||
.addons-column-block {
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #ddd;
|
||||
margin: 0 0 1em;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.addons-column-block img {
|
||||
max-height: 50px;
|
||||
max-width: 50px;
|
||||
}
|
||||
|
||||
.addons-small-light-block,
|
||||
.addons-column-block {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.addons-column-block-left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.addons-column-block-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.addons-column-block-item {
|
||||
border-top: 2px solid #f9f9f9;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
margin: 0 -20px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.addons-column-block-item-icon {
|
||||
background: #f7f7f7;
|
||||
border: 1px solid #e6e6e6;
|
||||
height: 100px;
|
||||
margin: 0 10px 10px 0;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.addons-column-block-item-content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-wrap: wrap;
|
||||
height: 20%;
|
||||
justify-content: space-between;
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.addons-column-block-item-content h2 {
|
||||
float: left;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.addons-column-block-item-content a {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.addons-column-block-item-content p {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.addons-banner-block-item,
|
||||
.addons-column-block-item {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.addons-banner-block-item:nth-child(-n + 3) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.addons-column-block-item:nth-of-type(-n + 3) {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.addons-small-dark-block {
|
||||
background-color: #54687d;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.addons-small-dark-items {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
@ -526,14 +353,6 @@
|
|||
margin: 0 0 20px;
|
||||
}
|
||||
|
||||
.addons-small-dark-block h1 {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.addons-small-dark-block p {
|
||||
color: #fafafa;
|
||||
}
|
||||
|
||||
.addons-small-dark-item-icon img {
|
||||
height: 30px;
|
||||
}
|
||||
|
@ -542,40 +361,6 @@
|
|||
margin: 28px auto 0;
|
||||
}
|
||||
|
||||
.addons-small-light-block {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.addons-small-light-block h1 {
|
||||
margin-top: -12px;
|
||||
}
|
||||
|
||||
.addons-small-light-block p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.addons-small-light-block img {
|
||||
height: 225px;
|
||||
margin: 0 0 0 -20px;
|
||||
}
|
||||
|
||||
.addons-small-light-block-content {
|
||||
display: flex;
|
||||
flex: 1 1 100px;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.addons-small-light-block-buttons {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.addons-small-light-block-content a {
|
||||
width: 48%;
|
||||
}
|
||||
|
||||
.addons-button-solid {
|
||||
background-color: #674399;
|
||||
color: #fff;
|
||||
|
@ -645,31 +430,64 @@
|
|||
.addons-small-dark-item {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.addons-column-block-item-icon {
|
||||
background: none;
|
||||
border: none;
|
||||
height: 75px;
|
||||
margin: 0 10px 10px 0;
|
||||
width: 75px;
|
||||
}
|
||||
}
|
||||
|
||||
.marketplace-content-wrapper {
|
||||
font-family: $font-sf-pro-text;
|
||||
margin: 0 auto;
|
||||
max-width: 1032px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.addon-product-group-title {
|
||||
font-family: $font-sf-pro-display;
|
||||
letter-spacing: 0.38px;
|
||||
}
|
||||
|
||||
.addon-product-group-description-container {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
font-size: 14px;
|
||||
justify-content: space-between;
|
||||
line-height: 20px;
|
||||
|
||||
.addon-product-group-see-more,
|
||||
.addon-product-group-see-more:visited {
|
||||
color: #007cba; /* Primary / Blue */
|
||||
display: block;
|
||||
font-size: 13px;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.products {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
flex-wrap: wrap;
|
||||
font-weight: normal;
|
||||
justify-content: space-between;
|
||||
margin: 0;
|
||||
max-width: 1032px;
|
||||
overflow: hidden;
|
||||
|
||||
.product.addons-product-banner,
|
||||
.product.addons-buttons-banner {
|
||||
max-width: calc(100% - 2px);
|
||||
}
|
||||
|
||||
@media screen and (min-width: 960px) {
|
||||
// Adjust heading titles font for three-column product groups
|
||||
&.addons-products-three-column li.product {
|
||||
max-width: calc(33.33% - 12px);
|
||||
|
||||
h2,
|
||||
h3 {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
background: #fff;
|
||||
border: 1px solid #dcdcde;
|
||||
|
@ -697,11 +515,15 @@
|
|||
|
||||
.product-details {
|
||||
padding: 24px;
|
||||
position: relative;
|
||||
|
||||
/* Display an image (product's icon) top right */
|
||||
.product-img-wrap {
|
||||
display: block;
|
||||
float: right;
|
||||
margin-left: 24px;
|
||||
position: absolute;
|
||||
right: 24px;
|
||||
top: 24px;
|
||||
|
||||
img {
|
||||
border-radius: 3px;
|
||||
|
@ -712,24 +534,62 @@
|
|||
}
|
||||
}
|
||||
|
||||
/* Align aproduct-related banner image vertically centered */
|
||||
&.addon-product-banner-details {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
|
||||
.product-img-wrap {
|
||||
position: unset;
|
||||
|
||||
img {
|
||||
max-width: 150px;
|
||||
max-height: 150px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h2,
|
||||
h3 {
|
||||
color: #007cba;
|
||||
font-family:
|
||||
HelveticaNeue-Light,
|
||||
"Helvetica Neue Light",
|
||||
"Helvetica Neue",
|
||||
sans-serif;
|
||||
font-size: 20px;
|
||||
font-weight: 400;
|
||||
letter-spacing: -0.32px;
|
||||
line-height: 28px;
|
||||
margin: 0 !important;
|
||||
// Don't cover a product icon
|
||||
max-width: calc(100% - 48px);
|
||||
}
|
||||
|
||||
.addons-buttons-banner-details h2 {
|
||||
color: #1d2327; // Gray / Gray 90
|
||||
}
|
||||
|
||||
p {
|
||||
color: #2c3338;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
margin: 14px 64px 0 0;
|
||||
max-width: 389px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.addons-buttons-banner-details p {
|
||||
font-size: 14px;
|
||||
margin-bottom: 14px;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.product-developed-by {
|
||||
color: #50575e; /* Gray 60 */
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
margin-top: 4px;
|
||||
|
||||
.product-vendor-link {
|
||||
color: #50575e; /* Gray 60 */
|
||||
}
|
||||
}
|
||||
|
||||
.product-developed-by {
|
||||
|
@ -802,7 +662,48 @@
|
|||
border-color: #007cba;
|
||||
color: #007cba;
|
||||
float: right;
|
||||
height: 22px;
|
||||
font-size: 13px;
|
||||
height: 36px;
|
||||
line-height: 30px;
|
||||
padding: 2px 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.addons-buttons-banner {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.addons-buttons-banner-image {
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
height: 190px;
|
||||
margin: 24px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.addons-buttons-banner-details-container {
|
||||
padding-left: 0;
|
||||
width: calc(100% - 198px - 24px - 24px);
|
||||
}
|
||||
|
||||
.addons-buttons-banner-details-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.button.addons-buttons-banner-button,
|
||||
.button.addons-buttons-banner-button:hover {
|
||||
background: #fff;
|
||||
border: 1.5px solid #624594;
|
||||
color: #624594;
|
||||
padding: 4px 12px;
|
||||
margin-right: 16px;
|
||||
|
||||
&.addons-buttons-banner-button-primary {
|
||||
background-color: #624594;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3016,30 +2917,6 @@ ul.wc_coupon_list_block {
|
|||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
.wc-addons-wrap {
|
||||
|
||||
.addons-promotion-block {
|
||||
flex-direction: column;
|
||||
padding: 24px;
|
||||
|
||||
.addons-img {
|
||||
height: auto;
|
||||
width: 100%;
|
||||
max-width: 240px;
|
||||
margin: 0 auto 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.addons-promotion-block-content {
|
||||
display: block;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.addons-promotion-block-title {
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.column-customer_message .note-on {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "ed397d52c25da204154232b3dd4b529f",
|
||||
"content-hash": "f694e88349087e677d5ae262107235de",
|
||||
"packages": [
|
||||
{
|
||||
"name": "automattic/jetpack-autoloader",
|
||||
|
|
|
@ -21,6 +21,8 @@ class WC_Admin_Addons {
|
|||
/**
|
||||
* Get featured for the addons screen
|
||||
*
|
||||
* @deprecated 5.9.0 No longer used in In-App Marketplace
|
||||
*
|
||||
* @return array of objects
|
||||
*/
|
||||
public static function get_featured() {
|
||||
|
@ -55,6 +57,49 @@ class WC_Admin_Addons {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render featured products and banners using WCCOM's the Featured 2.0 Endpoint
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function render_featured() {
|
||||
$featured = get_transient( 'wc_addons_featured' );
|
||||
if ( false === $featured ) {
|
||||
$headers = array();
|
||||
$auth = WC_Helper_Options::get( 'auth' );
|
||||
|
||||
if ( ! empty( $auth['access_token'] ) ) {
|
||||
$headers['Authorization'] = 'Bearer ' . $auth['access_token'];
|
||||
}
|
||||
|
||||
$parameter_string = '';
|
||||
$country = WC()->countries->get_base_country();
|
||||
if ( ! empty( $country ) ) {
|
||||
$parameter_string = '?' . http_build_query( array( 'country' => $country ) );
|
||||
}
|
||||
|
||||
// Important: WCCOM Extensions API v2.0 is used.
|
||||
$raw_featured = wp_safe_remote_get(
|
||||
'https://woocommerce.com/wp-json/wccom-extensions/2.0/featured' . $parameter_string,
|
||||
array(
|
||||
'headers' => $headers,
|
||||
'user-agent' => 'WooCommerce Addons Page',
|
||||
)
|
||||
);
|
||||
|
||||
if ( ! is_wp_error( $raw_featured ) ) {
|
||||
$featured = json_decode( wp_remote_retrieve_body( $raw_featured ) );
|
||||
if ( $featured ) {
|
||||
set_transient( 'wc_addons_featured', $featured, DAY_IN_SECONDS );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $featured ) ) {
|
||||
self::output_featured( $featured );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build url parameter string
|
||||
*
|
||||
|
@ -141,9 +186,12 @@ class WC_Admin_Addons {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get section content for the addons screen.
|
||||
*
|
||||
* @deprecated 5.9.0 No longer used in In-App Marketplace
|
||||
*
|
||||
* @param string $section_id Required section ID.
|
||||
*
|
||||
* @return array
|
||||
|
@ -172,6 +220,8 @@ class WC_Admin_Addons {
|
|||
|
||||
/**
|
||||
* Handles the outputting of a contextually aware Storefront link (points to child themes if Storefront is already active).
|
||||
*
|
||||
* @deprecated 5.9.0 No longer used in In-App Marketplace
|
||||
*/
|
||||
public static function output_storefront_button() {
|
||||
$template = get_option( 'template' );
|
||||
|
@ -209,6 +259,8 @@ class WC_Admin_Addons {
|
|||
/**
|
||||
* Handles the outputting of a banner block.
|
||||
*
|
||||
* @deprecated 5.9.0 No longer used in In-App Marketplace
|
||||
*
|
||||
* @param object $block Banner data.
|
||||
*/
|
||||
public static function output_banner_block( $block ) {
|
||||
|
@ -246,6 +298,8 @@ class WC_Admin_Addons {
|
|||
/**
|
||||
* Handles the outputting of a column.
|
||||
*
|
||||
* @deprecated 5.9.0 No longer used in In-App Marketplace
|
||||
*
|
||||
* @param object $block Column data.
|
||||
*/
|
||||
public static function output_column( $block ) {
|
||||
|
@ -273,6 +327,8 @@ class WC_Admin_Addons {
|
|||
/**
|
||||
* Handles the outputting of a column block.
|
||||
*
|
||||
* @deprecated 5.9.0 No longer used in In-App Marketplace
|
||||
*
|
||||
* @param object $block Column block data.
|
||||
*/
|
||||
public static function output_column_block( $block ) {
|
||||
|
@ -309,6 +365,8 @@ class WC_Admin_Addons {
|
|||
/**
|
||||
* Handles the outputting of a small light block.
|
||||
*
|
||||
* @deprecated 5.9.0 No longer used in In-App Marketplace
|
||||
*
|
||||
* @param object $block Block data.
|
||||
*/
|
||||
public static function output_small_light_block( $block ) {
|
||||
|
@ -337,6 +395,8 @@ class WC_Admin_Addons {
|
|||
/**
|
||||
* Handles the outputting of a small dark block.
|
||||
*
|
||||
* @deprecated 5.9.0 No longer used in In-App Marketplace
|
||||
*
|
||||
* @param object $block Block data.
|
||||
*/
|
||||
public static function output_small_dark_block( $block ) {
|
||||
|
@ -369,6 +429,8 @@ class WC_Admin_Addons {
|
|||
/**
|
||||
* Handles the outputting of the WooCommerce Services banner block.
|
||||
*
|
||||
* @deprecated 5.9.0 No longer used in In-App Marketplace
|
||||
*
|
||||
* @param object $block Block data.
|
||||
*/
|
||||
public static function output_wcs_banner_block( $block = array() ) {
|
||||
|
@ -464,6 +526,8 @@ class WC_Admin_Addons {
|
|||
/**
|
||||
* Handles the outputting of the WooCommerce Pay banner block.
|
||||
*
|
||||
* @deprecated 5.9.0 No longer used in In-App Marketplace
|
||||
*
|
||||
* @param object $block Block data.
|
||||
*/
|
||||
public static function output_wcpay_banner_block( $block = array() ) {
|
||||
|
@ -523,6 +587,7 @@ class WC_Admin_Addons {
|
|||
<?php
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Output the HTML for the promotion block.
|
||||
*
|
||||
|
@ -554,9 +619,12 @@ class WC_Admin_Addons {
|
|||
<?php
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles the output of a full-width block.
|
||||
*
|
||||
* @deprecated 5.9.0 No longer used in In-App Marketplace
|
||||
*
|
||||
* @param array $section Section data.
|
||||
*/
|
||||
public static function output_promotion_block( $section ) {
|
||||
|
@ -658,6 +726,115 @@ class WC_Admin_Addons {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the outputting of featured page
|
||||
*
|
||||
* @param array $blocks Featured page's blocks.
|
||||
*/
|
||||
private static function output_featured( $blocks ) {
|
||||
foreach ( $blocks as $block ) {
|
||||
$block_type = $block->type ?? null;
|
||||
switch ( $block_type ) {
|
||||
case 'group':
|
||||
self::output_group( $block );
|
||||
break;
|
||||
case 'banner':
|
||||
self::output_banner( $block );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a group block including products
|
||||
*
|
||||
* @param mixed $block Block of the page for rendering.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function output_group( $block ) {
|
||||
$capacity = $block->capacity ?? 3;
|
||||
$product_list_classes = 3 === $capacity ? 'three-column' : 'two-column';
|
||||
$product_list_classes = 'products addons-products-' . $product_list_classes;
|
||||
?>
|
||||
<section class="addon-product-group">
|
||||
<h1 class="addon-product-group-title"><?php echo esc_html( $block->title ); ?></h1>
|
||||
<div class="addon-product-group-description-container">
|
||||
<?php if ( ! empty( $block->description ) ) : ?>
|
||||
<div class="addon-product-group-description">
|
||||
<?php echo esc_html( $block->description ); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ( null !== $block->url ) : ?>
|
||||
<a class="addon-product-group-see-more" href="<?php echo esc_url( $block->url ); ?>">
|
||||
<?php esc_html_e( 'See more', 'woocommerce' ); ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="addon-product-group__items">
|
||||
<ul class="<?php echo esc_attr( $product_list_classes ); ?>">
|
||||
<?php
|
||||
$products = array_slice( $block->items, 0, $capacity );
|
||||
foreach ( $products as $item ) {
|
||||
self::render_product_card( $item );
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
<div>
|
||||
</section>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a banner contains a product
|
||||
*
|
||||
* @param mixed $block Block of the page for rendering.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function output_banner( $block ) {
|
||||
if ( empty( $block->buttons ) ) {
|
||||
// Render a product-like banner.
|
||||
?>
|
||||
<ul class="products">
|
||||
<?php self::render_product_card( $block, $block->type ); ?>
|
||||
</ul>
|
||||
<?php
|
||||
} else {
|
||||
// Render a banner with buttons.
|
||||
?>
|
||||
<ul class="products">
|
||||
<li class="product addons-buttons-banner">
|
||||
<div class="addons-buttons-banner-image"
|
||||
style="background-image:url(<?php echo esc_url( $block->image ); ?>)"
|
||||
title="<?php echo esc_attr( $block->image_alt ); ?>"></div>
|
||||
<div class="product-details addons-buttons-banner-details-container">
|
||||
<div class="addons-buttons-banner-details">
|
||||
<h2><?php echo esc_html( $block->title ); ?></h2>
|
||||
<p><?php echo wp_kses( $block->description, array() ); ?></p>
|
||||
</div>
|
||||
<div class="addons-buttons-banner-button-container">
|
||||
<?php
|
||||
foreach ( $block->buttons as $button ) {
|
||||
$button_classes = array( 'button', 'addons-buttons-banner-button' );
|
||||
$type = $button->type ?? null;
|
||||
if ( 'primary' === $type ) {
|
||||
$button_classes[] = 'addons-buttons-banner-button-primary';
|
||||
}
|
||||
?>
|
||||
<a class="<?php echo esc_attr( implode( ' ', $button_classes ) ); ?>"
|
||||
href="<?php echo esc_url( $button->href ); ?>">
|
||||
<?php echo esc_html( $button->title ); ?>
|
||||
</a>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns in-app-purchase URL params.
|
||||
*/
|
||||
|
@ -843,29 +1020,6 @@ class WC_Admin_Addons {
|
|||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should an extension be shown on the featured page.
|
||||
*
|
||||
* @param object $item Item data.
|
||||
* @return boolean
|
||||
*/
|
||||
public static function show_extension( $item ) {
|
||||
$location = WC()->countries->get_base_country();
|
||||
if ( isset( $item->geowhitelist ) && ! in_array( $location, $item->geowhitelist, true ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( isset( $item->geoblacklist ) && in_array( $location, $item->geoblacklist, true ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( is_plugin_active( $item->plugin ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* We're displaying page=wc-addons and page=wc-addons§ion=helper as two separate pages.
|
||||
* When we're on those pages, add body classes to distinguishe them.
|
||||
|
@ -984,4 +1138,171 @@ class WC_Admin_Addons {
|
|||
}
|
||||
return $formatted_promotions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map data from different endpoints to a universal format
|
||||
*
|
||||
* Search and featured products has a slightly different products' field names.
|
||||
* Mapping converts different data structures into a universal one for further processing.
|
||||
*
|
||||
* @param mixed $data Product Card Data.
|
||||
*
|
||||
* @return object Converted data.
|
||||
*/
|
||||
public static function map_product_card_data( $data ) {
|
||||
$mapped = (object) null;
|
||||
|
||||
$type = $data->type ?? null;
|
||||
|
||||
// Icon.
|
||||
$mapped->icon = $data->icon ?? null;
|
||||
if ( null === $mapped->icon && 'banner' === $type ) {
|
||||
// For product-related banners icon is a product's image.
|
||||
$mapped->icon = $data->image ?? null;
|
||||
}
|
||||
// URL.
|
||||
$mapped->url = $data->link ?? null;
|
||||
if ( empty( $mapped->url ) ) {
|
||||
$mapped->url = $data->url ?? null;
|
||||
}
|
||||
// Title.
|
||||
$mapped->title = $data->title ?? null;
|
||||
// Vendor Name.
|
||||
$mapped->vendor_name = $data->vendor_name ?? null;
|
||||
if ( empty( $mapped->vendor_name ) ) {
|
||||
$mapped->vendor_name = $data->vendorName ?? null; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
||||
}
|
||||
// Vendor URL.
|
||||
$mapped->vendor_url = $data->vendor_url ?? null;
|
||||
if ( empty( $mapped->vendor_url ) ) {
|
||||
$mapped->vendor_url = $data->vendorUrl ?? null; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
||||
}
|
||||
// Description.
|
||||
$mapped->description = $data->excerpt ?? null;
|
||||
if ( empty( $mapped->description ) ) {
|
||||
$mapped->description = $data->description ?? null;
|
||||
}
|
||||
$has_currency = ! empty( $data->currency ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
||||
|
||||
// Is Free.
|
||||
if ( $has_currency ) {
|
||||
$mapped->is_free = 0 === (int) $data->price;
|
||||
} else {
|
||||
$mapped->is_free = '$0.00' === $data->price;
|
||||
}
|
||||
// Price.
|
||||
if ( $has_currency ) {
|
||||
$mapped->price = wc_price( $data->price, array( 'currency' => $data->currency ) );
|
||||
} else {
|
||||
$mapped->price = $data->price;
|
||||
}
|
||||
// Rating.
|
||||
$mapped->rating = $data->rating ?? null;
|
||||
if ( null === $mapped->rating ) {
|
||||
$mapped->rating = $data->averageRating ?? null; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
||||
}
|
||||
// Reviews Count.
|
||||
$mapped->reviews_count = $data->reviews_count ?? null;
|
||||
if ( null === $mapped->reviews_count ) {
|
||||
$mapped->reviews_count = $data->reviewsCount ?? null; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
||||
}
|
||||
|
||||
return $mapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a product card
|
||||
*
|
||||
* There's difference in data structure (e.g. field names) between endpoints such as search and
|
||||
* featured. Inner mapping helps to use universal field names for further work.
|
||||
*
|
||||
* @param mixed $data Product data.
|
||||
* @param string $block_type Block type that's different from the default product card, e.g. a banner.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function render_product_card( $data, $block_type = null ) {
|
||||
$mapped = self::map_product_card_data( $data );
|
||||
$product_url = self::add_in_app_purchase_url_params( $mapped->url );
|
||||
$class_names = array( 'product' );
|
||||
// Specify a class name according to $block_type (if it's specified).
|
||||
if ( null !== $block_type ) {
|
||||
$class_names[] = 'addons-product-' . $block_type;
|
||||
}
|
||||
|
||||
$product_details_classes = 'product-details';
|
||||
if ( 'banner' === $block_type ) {
|
||||
$product_details_classes .= ' addon-product-banner-details';
|
||||
}
|
||||
?>
|
||||
<li class="<?php echo esc_attr( implode( ' ', $class_names ) ); ?>">
|
||||
<div class="<?php echo esc_attr( $product_details_classes ); ?>">
|
||||
<div class="product-text-container">
|
||||
<a href="<?php echo esc_url( $product_url ); ?>">
|
||||
<h2><?php echo esc_html( $mapped->title ); ?></h2>
|
||||
</a>
|
||||
<?php if ( ! empty( $mapped->vendor_name ) && ! empty( $mapped->vendor_url ) ) : ?>
|
||||
<div class="product-developed-by">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s vendor link */
|
||||
esc_html__( 'Developed by %s', 'woocommerce' ),
|
||||
sprintf(
|
||||
'<a class="product-vendor-link" href="%1$s" target="_blank">%2$s</a>',
|
||||
esc_url_raw( $mapped->vendor_url ),
|
||||
esc_html( $mapped->vendor_name )
|
||||
)
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<p><?php echo wp_kses_post( $mapped->description ); ?></p>
|
||||
</div>
|
||||
<?php if ( ! empty( $mapped->icon ) ) : ?>
|
||||
<span class="product-img-wrap">
|
||||
<?php /* Show an icon if it exists */ ?>
|
||||
<img src="<?php echo esc_url( $mapped->icon ); ?>" />
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="product-footer">
|
||||
<div class="product-price-and-reviews-container">
|
||||
<div class="product-price-block">
|
||||
<?php if ( $mapped->is_free ) : ?>
|
||||
<span class="price"><?php esc_html_e( 'Free', 'woocommerce' ); ?></span>
|
||||
<?php else : ?>
|
||||
<span class="price">
|
||||
<?php
|
||||
echo wp_kses(
|
||||
$mapped->price,
|
||||
array(
|
||||
'span' => array(
|
||||
'class' => array(),
|
||||
),
|
||||
'bdi' => array(),
|
||||
)
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<span class="price-suffix"><?php esc_html_e( 'per year', 'woocommerce' ); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if ( ! empty( $mapped->reviews_count ) && ! empty( $mapped->rating ) ) : ?>
|
||||
<?php /* Show rating and the number of reviews */ ?>
|
||||
<div class="product-reviews-block">
|
||||
<?php for ( $index = 1; $index <= 5; ++$index ) : ?>
|
||||
<?php $rating_star_class = 'product-rating-star product-rating-star__' . self::get_star_class( $mapped->rating, $index ); ?>
|
||||
<div class="<?php echo esc_attr( $rating_star_class ); ?>"></div>
|
||||
<?php endfor; ?>
|
||||
<span class="product-reviews-count">(<?php echo (int) $mapped->reviews_count; ?>)</span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<a class="button" href="<?php echo esc_url( $product_url ); ?>">
|
||||
<?php esc_html_e( 'View details', 'woocommerce' ); ?>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ $current_section_name = __( 'Browse Categories', 'woocommerce' );
|
|||
|
||||
<div class="wrap">
|
||||
<div class="marketplace-content-wrapper">
|
||||
<?php if ( count( $addons ) == 0 ) : ?>
|
||||
<?php if ( ! empty( $search ) && 0 === count( $addons ) ) : ?>
|
||||
<h1 class="search-form-title">
|
||||
<?php esc_html_e( 'Sorry, could not find anything. Try searching again using a different term.', 'woocommerce' ); ?></p>
|
||||
</h1>
|
||||
|
@ -78,9 +78,7 @@ $current_section_name = __( 'Browse Categories', 'woocommerce' );
|
|||
|
||||
<?php if ( '_featured' === $current_section ) : ?>
|
||||
<div class="addons-featured">
|
||||
<?php
|
||||
$featured = WC_Admin_Addons::get_featured();
|
||||
?>
|
||||
<?php WC_Admin_Addons::render_featured(); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ( '_featured' !== $current_section && $addons ) : ?>
|
||||
|
@ -115,81 +113,7 @@ $current_section_name = __( 'Browse Categories', 'woocommerce' );
|
|||
}
|
||||
}
|
||||
?>
|
||||
<li class="product">
|
||||
<div class="product-details">
|
||||
<?php if ( ! empty( $addon->icon ) ) : ?>
|
||||
<span class="product-img-wrap">
|
||||
<?php /* Show an icon if it exists */ ?>
|
||||
<img src="<?php echo esc_url( $addon->icon ); ?>" />
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
<a href="<?php echo esc_url( WC_Admin_Addons::add_in_app_purchase_url_params( $addon->link ) ); ?>">
|
||||
<h2><?php echo esc_html( $addon->title ); ?></h2>
|
||||
</a>
|
||||
<?php if ( ! empty( $addon->vendor_name ) && ! empty( $addon->vendor_url ) ) : ?>
|
||||
<div class="product-developed-by">
|
||||
<?php
|
||||
$parsed_vendor_url = parse_url( $addon->vendor_url );
|
||||
if ( null == $parsed_vendor_url['path'] ) {
|
||||
$addon->vendor_url .= '/';
|
||||
}
|
||||
$separator = ( null == $parsed_vendor_url['query'] ) ? '?' : '&';
|
||||
$query = http_build_query(
|
||||
array(
|
||||
'utm_source' => 'extensionsscreen',
|
||||
'utm_medium' => 'product',
|
||||
'utm_campaign' => 'wcaddons',
|
||||
'utm_content' => 'devpartner',
|
||||
)
|
||||
);
|
||||
$addon->vendor_url .= $separator . $query;
|
||||
|
||||
printf(
|
||||
/* translators: %s vendor link */
|
||||
esc_html__( 'Developed by %s', 'woocommerce' ),
|
||||
sprintf(
|
||||
'<a class="product-vendor-link" href="%1$s" target="_blank">%2$s</a>',
|
||||
esc_url_raw( $addon->vendor_url ),
|
||||
wp_kses_post( $addon->vendor_name )
|
||||
)
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<p><?php echo wp_kses_post( $addon->excerpt ); ?></p>
|
||||
</div>
|
||||
<div class="product-footer">
|
||||
<div class="product-price-and-reviews-container">
|
||||
<div class="product-price-block">
|
||||
<?php if ( '$0.00' === $addon->price ) : ?>
|
||||
<span class="price"><?php esc_html_e( 'Free', 'woocommerce' ); ?></span>
|
||||
<?php else : ?>
|
||||
<?php
|
||||
$price_suffix = __( 'per year', 'woocommerce' );
|
||||
if ( ! empty( $addon->price_suffix ) ) {
|
||||
$price_suffix = $addon->price_suffix;
|
||||
}
|
||||
?>
|
||||
<span class="price"><?php echo wp_kses_post( $addon->price ); ?></span>
|
||||
<span class="price-suffix"><?php echo esc_html( $price_suffix ); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if ( ! empty( $addon->reviews_count ) && ! empty( $addon->rating ) ) : ?>
|
||||
<?php /* Show rating and the number of reviews */ ?>
|
||||
<div class="product-reviews-block">
|
||||
<?php for ( $index = 1; $index <= 5; ++$index ) : ?>
|
||||
<?php $rating_star_class = 'product-rating-star product-rating-star__' . WC_Admin_Addons::get_star_class( $addon->rating, $index ); ?>
|
||||
<div class="<?php echo esc_attr( $rating_star_class ); ?>"></div>
|
||||
<?php endfor; ?>
|
||||
<span class="product-reviews-count">(<?php echo wp_kses_post( $addon->reviews_count ); ?>)</span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<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>
|
||||
<?php WC_Admin_Addons::render_product_card( $addon ); ?>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
|
|
Loading…
Reference in New Issue