Add installed themes and WooCommerce support to theme browser (https://github.com/woocommerce/woocommerce-admin/pull/2503)

* Add theme step to onboarding profiler

* Add installed themes to onboarding theme data

* Add theme status for install themes in frontend

* Add regex test to check for WooCommerce theme support

* Add woocommerce not supported icon and tooltips

* Cache installed themes for performance

* Update themes endpoint to use real wccom endpoint

* Update error icon to use info gridicon
This commit is contained in:
Joshua T Flowers 2019-06-28 15:42:20 +08:00 committed by GitHub
parent 54ff76e178
commit 0bc8c96ace
3 changed files with 106 additions and 22 deletions

View File

@ -7,7 +7,8 @@ import { Button } from 'newspack-components';
import { Component, Fragment } from '@wordpress/element';
import { compose } from '@wordpress/compose';
import { decodeEntities } from '@wordpress/html-entities';
import { TabPanel } from '@wordpress/components';
import Gridicon from 'gridicons';
import { TabPanel, Tooltip } from '@wordpress/components';
import { withDispatch } from '@wordpress/data';
/**
@ -55,7 +56,7 @@ class Theme extends Component {
}
renderTheme( theme ) {
const { image, price, slug, title } = theme;
const { demo_url, has_woocommerce_support, image, slug, title } = theme;
return (
<Card className="woocommerce-profile-wizard__theme" key={ theme.slug }>
@ -63,25 +64,56 @@ class Theme extends Component {
<img alt={ title } src={ image } className="woocommerce-profile-wizard__theme-image" />
) }
<div className="woocommerce-profile-wizard__theme-details">
<H className="woocommerce-profile-wizard__theme-name">{ title }</H>
<p className="woocommerce-profile-wizard__theme-price">
{ this.getPriceValue( price ) <= 0
? __( 'Free', 'woocommerce-admin' )
: sprintf( __( '%s per year', 'woocommerce-admin' ), decodeEntities( price ) ) }
<H className="woocommerce-profile-wizard__theme-name">
{ title }
{ ! has_woocommerce_support && (
<Tooltip
text={ __( 'This theme does not support WooCommerce.', 'woocommerce-admin' ) }
>
<span>
<Gridicon icon="info" role="img" aria-hidden="true" focusable="false" />
</span>
</Tooltip>
) }
</H>
<p className="woocommerce-profile-wizard__theme-status">
{ this.getThemeStatus( theme ) }
</p>
<div className="woocommerce-profile-wizard__theme-actions">
<Button isPrimary onClick={ () => this.onChoose( slug ) }>
<Button
isPrimary={ Boolean( demo_url ) }
isDefault={ ! Boolean( demo_url ) }
onClick={ () => this.onChoose( slug ) }
>
{ __( 'Choose', 'woocommerce-admin' ) }
</Button>
<Button isDefault onClick={ () => this.openDemo( slug ) }>
{ __( 'Live Demo', 'woocommerce-admin' ) }
</Button>
{ demo_url && (
<Button isDefault onClick={ () => this.openDemo( slug ) }>
{ __( 'Live Demo', 'woocommerce-admin' ) }
</Button>
) }
</div>
</div>
</Card>
);
}
getThemeStatus( theme ) {
const { installed, price, slug } = theme;
const { activeTheme } = wcSettings.onboarding;
if ( activeTheme === slug ) {
return __( 'Currently active theme', 'woocommerce-admin' );
}
if ( installed ) {
return __( 'Installed', 'woocommerce-admin' );
} else if ( this.getPriceValue( price ) <= 0 ) {
return __( 'Free', 'woocommerce-admin' );
}
return sprintf( __( '%s per year', 'woocommerce-admin' ), decodeEntities( price ) );
}
onSelectTab( tab ) {
this.setState( { activeTab: tab } );
}
@ -137,7 +169,7 @@ class Theme extends Component {
>
{ () => (
<div className="woocommerce-profile-wizard__themes">
{ themes.map( theme => this.renderTheme( theme ) ) }
{ themes && themes.map( theme => this.renderTheme( theme ) ) }
</div>
) }
</TabPanel>

View File

@ -68,6 +68,16 @@
margin-bottom: $gap-smaller;
@include font-size(24);
font-weight: 400;
svg {
max-width: 18px;
height: 18px;
margin-left: $gap-smaller;
path {
fill: $muriel-red-500;
}
}
}
.woocommerce-profile-wizard__theme-details {
@ -77,7 +87,7 @@
height: 100%;
}
.woocommerce-profile-wizard__theme-price {
.woocommerce-profile-wizard__theme-status {
margin: 0;
font-size: 14px;
}

View File

@ -115,18 +115,59 @@ class WC_Admin_Onboarding {
* @return array
*/
public static function get_themes() {
$theme_data_transient_name = 'wc_onboarding_themes';
$theme_data = get_transient( $theme_data_transient_name );
if ( false === $theme_data ) {
// @todo This should be replaced with the real wccom URL once
// https://github.com/Automattic/woocommerce.com/pull/6035 is merged and deployed.
$theme_data = wp_remote_get( 'http://woocommerce.test/wp-json/wccom-extensions/1.0/search?category=themes' );
set_transient( $theme_data_transient_name, $theme_data, DAY_IN_SECONDS );
$themes_transient_name = 'wc_onboarding_themes';
$themes = get_transient( $themes_transient_name );
if ( false === $themes ) {
$theme_data = wp_remote_get( 'http://woocommerce.com/wp-json/wccom-extensions/1.0/search?category=themes' );
$theme_data = json_decode( $theme_data['body'] );
$themes = array();
foreach ( $theme_data->products as $theme ) {
$slug = sanitize_title( $theme->slug );
$themes[ $slug ] = (array) $theme;
$themes[ $slug ]['is_installed'] = false;
$themes[ $slug ]['has_woocommerce_support'] = true;
}
$installed_themes = wp_get_themes();
foreach ( $installed_themes as $slug => $theme ) {
$themes[ $slug ] = array(
'slug' => sanitize_title( $slug ),
'title' => $theme->get( 'Name' ),
'price' => '0.00',
'is_installed' => true,
'image' => $theme->get_screenshot(),
'has_woocommerce_support' => self::has_woocommerce_support( $theme ),
);
}
set_transient( $themes_transient_name, $themes, DAY_IN_SECONDS );
}
$theme_data = json_decode( $theme_data['body'] );
$themes = apply_filters( 'woocommerce_admin_onboarding_themes', $themes );
return array_values( $themes );
}
return apply_filters( 'woocommerce_admin_onboarding_themes', $theme_data->products );
/**
* Check if theme has declared support for WooCommerce
*
* @param WP_Theme $theme Theme to check.
* @return bool
*/
public static function has_woocommerce_support( $theme ) {
$directory = new RecursiveDirectoryIterator( $theme->theme_root . '/' . $theme->stylesheet );
$iterator = new RecursiveIteratorIterator( $directory );
$files = new RegexIterator( $iterator, '/^.+\.php$/i', RecursiveRegexIterator::GET_MATCH );
foreach ( $files as $file ) {
$content = file_get_contents( $file[0] );
if ( preg_match( '/add_theme_support\(([^(]*)(\'|\")woocommerce(\'|\")([^(]*)/si', $content, $matches ) ) {
return true;
}
}
return false;
}
/**
@ -180,6 +221,7 @@ class WC_Admin_Onboarding {
if ( $this->should_show_profiler() ) {
$settings['onboarding']['productTypes'] = self::get_allowed_product_types();
$settings['onboarding']['themes'] = self::get_themes();
$settings['onboarding']['activeTheme'] = get_option( 'stylesheet' );
}
return $settings;