Merge branch 'helper-updates'

This commit is contained in:
Mike Jolley 2017-08-30 21:22:56 +01:00
commit 0ac8744065
13 changed files with 361 additions and 61 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -21,6 +21,19 @@
.wc_addons_wrap {
.update-plugins .update-count {
background-color: #d54e21;
border-radius: 10px;
color: #fff;
display: inline-block;
font-size: 9px;
font-weight: 600;
line-height: 17px;
margin: 1px 0 0 2px;
padding: 0 6px;
vertical-align: text-top;
}
.addons-featured {
max-width: 1140px;
margin: -1%;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -25,11 +25,11 @@ $color_button_secondary: $woo_pink2;
/*------------------------------------------------------------------------------
Tab navigation
------------------------------------------------------------------------------*/
.wc-helper {
.nav-tab-wrapper {
margin-bottom: 22px;
}
@media only screen and (max-width : 784px) {
.nav-tab {
max-width: 40%;
@ -88,24 +88,17 @@ $color_button_secondary: $woo_pink2;
line-height: 1;
padding: 0;
position: absolute;
top: 12px;
right: 12px;
top: 10px;
right: 14px;
}
}
span {
font-weight: bold;
padding-right: 4px;
}
a {
li {
color: #0073AA;
display: inline-block;
padding: 0 4px 0 8px;
position: relative;
text-decoration: none;
&:before {
&::before {
background-color: #979797;
content: " ";
position: absolute;
@ -114,21 +107,50 @@ $color_button_secondary: $woo_pink2;
bottom: 0;
width: 1px;
}
&:first-of-type {
&::before {
display: none;
}
}
}
a{
color: #0073AA;
text-decoration: none;
&.current{
color: #000;
font-weight: 600;
}
}
.count{
color: #555d66;
font-weight: 400;
}
@media only screen and (max-width : 600px) {
background-color: #fff;
border: 1px solid #E1E1E1;
border-radius: 2px;
border-radius: 4px;
font-size: 14px;
label,
span,
a {
border-bottom: 1px solid #E1E1E1;
line-height: 2;
li {
line-height: 21px;
padding: 8px 16px;
margin: 0;
&:last-child {
border-bottom: none;
}
}
span,
li {
border-bottom: 1px solid #E1E1E1;
}
label,
@ -137,26 +159,36 @@ $color_button_secondary: $woo_pink2;
}
span,
a {
li{
display: none;
}
a {
cursor: pointer;
li{
&::before {
display: none;
}
}
a {
cursor: pointer;
}
span.chevron {
transform: rotateX(0deg);
color: #555555;
opacity: 0.5;
transform: rotateX(180deg);
}
&:focus,
&:hover {
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2);
label{
border-bottom: 1px solid #E1E1E1;
}
span,
a {
li{
display: block;
}
@ -447,7 +479,7 @@ $color_button_secondary: $woo_pink2;
.wp-list-table__ext-title {
color: $color_text_blue;
font-size: 18px;
font-weight: 784;
font-weight: 600;
width: 60%;
@media only screen and (max-width : 782px) {
@ -472,7 +504,7 @@ $color_button_secondary: $woo_pink2;
.wp-list-table__ext-status {
position: relative;
&.update-available:after {
&.update-available::after {
background-color: #FFC322;
content: " ";
position: absolute;
@ -482,7 +514,7 @@ $color_button_secondary: $woo_pink2;
width: 5px;
}
&.expired:after {
&.expired::after {
background-color: #B81C23;
content: " ";
position: absolute;
@ -532,7 +564,7 @@ $color_button_secondary: $woo_pink2;
td {
position: relative;
&:before {
&::before {
background-color: #E1E1E1;
content: " ";
height: 1px;
@ -545,13 +577,13 @@ $color_button_secondary: $woo_pink2;
td.wp-list-table__ext-status,
td.wp-list-table__licence-container {
&:before {
&::before {
left: 22px !important;
width: auto !important;
}
}
td.wp-list-table__ext-actions:before {
td.wp-list-table__ext-actions::before {
right: 22px;
}
@ -896,8 +928,8 @@ $color_button_secondary: $woo_pink2;
transition: all .4s ease, box-shadow 0s;
vertical-align: middle;
&:before,
&:after {
&::before,
&::after {
content: "";
display: block;
position: relative;
@ -905,14 +937,14 @@ $color_button_secondary: $woo_pink2;
height: 20px;
}
&:after {
&::after {
border-radius: 50%;
background: $white;
left: 0;
transition: all .2s ease;
}
&:before {
&::before {
display: none;
}
@ -967,7 +999,7 @@ $color_button_secondary: $woo_pink2;
+ .form-toggle__label .form-toggle__switch {
background: $woo_pink1;
&:after {
&::after {
left: 8px;
}
}
@ -1002,15 +1034,15 @@ $color_button_secondary: $woo_pink2;
width: 24px;
height: 16px;
&:before,
&:after {
&::before,
&::after {
height: 12px;
width: 12px;
}
}
&:checked {
+ .form-toggle__label .form-toggle__switch {
&:after {
&::after {
left: 8px;
}
}

View File

@ -124,7 +124,9 @@ class WC_Admin_Menus {
* Addons menu item.
*/
public function addons_menu() {
add_submenu_page( 'woocommerce', __( 'WooCommerce extensions', 'woocommerce' ), __( 'Extensions', 'woocommerce' ) , 'manage_woocommerce', 'wc-addons', array( $this, 'addons_page' ) );
$count_html = WC_Helper_Updater::get_updates_count_html();
$menu_title = sprintf( __( 'Extensions %s', 'woocommerce' ), $count_html );
add_submenu_page( 'woocommerce', __( 'WooCommerce extensions', 'woocommerce' ), $menu_title, 'manage_woocommerce', 'wc-addons', array( $this, 'addons_page' ) );
}
/**

View File

@ -36,25 +36,27 @@ class WC_Helper_Plugin_Info {
return $response;
}
$found_plugin = null;
// Look through local Woo plugins by slugs.
foreach ( WC_Helper::get_local_woo_plugins() as $plugin ) {
if ( dirname( $plugin['_filename'] ) === $args->slug ) {
$plugin['_slug'] = $args->slug;
$found_plugin = $plugin;
break;
}
}
if ( ! $found_plugin ) {
// Only for slugs that start with woo-
if ( 0 !== strpos( $args->slug, 'woocommerce-com-' ) ) {
return $response;
}
$clean_slug = str_replace( 'woocommerce-com-', '', $args->slug );
// Look through update data by slug.
$update_data = WC_Helper_Updater::get_update_data();
$products = wp_list_filter( $update_data, array( 'slug' => $clean_slug ) );
if ( empty( $products ) ) {
return $response;
}
$product_id = array_keys( $products );
$product_id = array_shift( $product_id );
// Fetch the product information from the Helper API.
$request = WC_Helper_API::get( add_query_arg( array(
'product_id' => absint( $plugin['_product_id'] ),
'product_slug' => rawurlencode( $plugin['_slug'] ),
'product_id' => absint( $product_id ),
), 'info' ), array( 'authenticated' => true ) );
$results = json_decode( wp_remote_retrieve_body( $request ), true );

View File

@ -17,6 +17,7 @@ class WC_Helper_Updater {
public static function load() {
add_action( 'pre_set_site_transient_update_plugins', array( __CLASS__, 'transient_update_plugins' ), 21, 1 );
add_action( 'pre_set_site_transient_update_themes', array( __CLASS__, 'transient_update_themes' ), 21, 1 );
add_action( 'upgrader_process_complete', array( __CLASS__, 'upgrader_process_complete' ) );
}
/**
@ -39,8 +40,8 @@ class WC_Helper_Updater {
$filename = $plugin['_filename'];
$item = array(
'id' => 'woo-' . $plugin['_product_id'],
'slug' => $data['slug'],
'id' => 'woocommerce-com-' . $plugin['_product_id'],
'slug' => 'woocommerce-com-' . $data['slug'],
'plugin' => $filename,
'new_version' => $data['version'],
'url' => $data['url'],
@ -229,11 +230,99 @@ class WC_Helper_Updater {
return false;
}
/**
* Get the number of products that have updates.
*
* @return int The number of products with updates.
*/
public static function get_updates_count() {
$cache_key = '_woocommerce_helper_updates_count';
if ( false !== ( $count = get_transient( $cache_key ) ) ) {
return $count;
}
// Don't fetch any new data since this function in high-frequency.
if ( ! get_transient( '_woocommerce_helper_subscriptions' ) ) {
return 0;
}
if ( ! get_transient( '_woocommerce_helper_updates' ) ) {
return 0;
}
$count = 0;
$update_data = self::get_update_data();
if ( empty( $update_data ) ) {
set_transient( $cache_key, $count, 12 * HOUR_IN_SECONDS );
return $count;
}
// Scan local plugins.
foreach ( WC_Helper::get_local_woo_plugins() as $plugin ) {
if ( empty( $update_data[ $plugin['_product_id'] ] ) ) {
continue;
}
if ( version_compare( $plugin['Version'], $update_data[ $plugin['_product_id'] ]['version'], '<' ) ) {
$count++;
}
}
// Scan local themes.
foreach ( WC_Helper::get_local_woo_themes() as $theme ) {
if ( empty( $update_data[ $theme['_product_id'] ] ) ) {
continue;
}
if ( version_compare( $theme['Version'], $update_data[ $theme['_product_id'] ]['version'], '<' ) ) {
$count++;
}
}
set_transient( $cache_key, $count, 12 * HOUR_IN_SECONDS );
return $count;
}
/**
* Return the updates count markup.
*
* @return string Updates count markup, empty string if no updates avairable.
*/
public static function get_updates_count_html() {
$count = self::get_updates_count();
if ( ! $count ) {
return '';
}
$count_html = sprintf( '<span class="update-plugins count-%d"><span class="update-count">%d</span></span>', $count, number_format_i18n( $count ) );
return $count_html;
}
/**
* Flushes cached update data.
*/
public static function flush_updates_cache() {
delete_transient( '_woocommerce_helper_updates' );
delete_transient( '_woocommerce_helper_updates_count' );
// Refresh update transients
$update_plugins = get_site_transient( 'update_plugins' );
if ( ! empty( $update_plugins ) ) {
set_site_transient( 'update_plugins', $update_plugins );
}
$update_themes = get_site_transient( 'update_themes' );
if ( ! empty( $update_themes ) ) {
set_site_transient( 'update_themes', $update_themes );
}
}
/**
* Fires when a user successfully updated a theme or a plugin.
*/
public static function upgrader_process_complete() {
delete_transient( '_woocommerce_helper_updates_count' );
}
}

View File

@ -74,9 +74,11 @@ class WC_Helper {
'wc-helper-nonce' => wp_create_nonce( 'disconnect' ),
), admin_url( 'admin.php' ) );
$current_filter = self::get_current_filter();
$refresh_url = add_query_arg( array(
'page' => 'wc-addons',
'section' => 'helper',
'filter' => $current_filter,
'wc-helper-refresh' => 1,
'wc-helper-nonce' => wp_create_nonce( 'refresh' ),
), admin_url( 'admin.php' ) );
@ -96,6 +98,7 @@ class WC_Helper {
$subscription['activate_url'] = add_query_arg( array(
'page' => 'wc-addons',
'section' => 'helper',
'filter' => $current_filter,
'wc-helper-activate' => 1,
'wc-helper-product-key' => $subscription['product_key'],
'wc-helper-product-id' => $subscription['product_id'],
@ -105,6 +108,7 @@ class WC_Helper {
$subscription['deactivate_url'] = add_query_arg( array(
'page' => 'wc-addons',
'section' => 'helper',
'filter' => $current_filter,
'wc-helper-deactivate' => 1,
'wc-helper-product-key' => $subscription['product_key'],
'wc-helper-product-id' => $subscription['product_id'],
@ -305,11 +309,118 @@ class WC_Helper {
uasort( $subscriptions, array( __CLASS__, '_sort_by_product_name' ) );
uasort( $no_subscriptions, array( __CLASS__, '_sort_by_name' ) );
// Filters
self::get_filters_counts( $subscriptions ); // Warm it up.
self::_filter( $subscriptions, self::get_current_filter() );
// We have an active connection.
include( self::get_view_filename( 'html-main.php' ) );
return;
}
/**
* Get available subscriptions filters.
*
* @param array Optional subscriptions array to generate counts.
*
* @return array An array of filter keys and labels.
*/
public static function get_filters( $subscriptions = null ) {
$filters = array(
'all' => __( 'All', 'woocommerce' ),
'active' => __( 'Active', 'woocommerce' ),
'inactive' => __( 'Inactive', 'woocommerce' ),
'update-available' => __( 'Update Available', 'woocommerce' ),
'expiring' => __( 'Expiring Soon', 'woocommerce' ),
'expired' => __( 'Expired', 'woocommerce' ),
'download' => __( 'Download', 'woocommerce' ),
);
return $filters;
}
/**
* Get counts data for the filters array.
*
* @param array $subscriptions The array of all available subscriptions.
*
* @return array Filter counts (filter => count)
*/
public static function get_filters_counts( $subscriptions = null ) {
static $filters;
if ( isset( $filters ) ) {
return $filters;
}
$filters = array_fill_keys( array_keys( self::get_filters() ), 0 );
if ( empty( $subscriptions ) ) {
return array();
}
foreach ( $filters as $key => $count ) {
$_subs = $subscriptions;
self::_filter( $_subs, $key );
$filters[ $key ] = count( $_subs );
}
return $filters;
}
/**
* Get current filter.
*
* @return string The current filter.
*/
public static function get_current_filter() {
$current_filter = 'all';
$valid_filters = array_keys( self::get_filters() );
if ( ! empty( $_GET['filter'] ) && in_array( $_GET['filter'], $valid_filters ) ) {
$current_filter = $_GET['filter'];
}
return $current_filter;
}
/**
* Filter an array of subscriptions by $filter.
*
* @param array $subscriptions The subscriptions array, passed by ref.
* @param string $filter The filter.
*/
private static function _filter( &$subscriptions, $filter ) {
switch ( $filter ) {
case 'active':
$subscriptions = wp_list_filter( $subscriptions, array( 'active' => true ) );
break;
case 'inactive':
$subscriptions = wp_list_filter( $subscriptions, array( 'active' => false ) );
break;
case 'update-available':
$subscriptions = wp_list_filter( $subscriptions, array( 'has_update' => true ) );
break;
case 'expiring':
$subscriptions = wp_list_filter( $subscriptions, array( 'expiring' => true ) );
break;
case 'expired':
$subscriptions = wp_list_filter( $subscriptions, array( 'expired' => true ) );
break;
case 'download':
foreach ( $subscriptions as $key => $subscription ) {
if ( $subscription['local']['installed'] || $subscription['expired'] ) {
unset( $subscriptions[ $key ] );
}
}
break;
}
}
/**
* Enqueue admin scripts and styles.
*/
@ -367,6 +478,7 @@ class WC_Helper {
$deactivate_plugin_url = add_query_arg( array(
'page' => 'wc-addons',
'section' => 'helper',
'filter' => self::get_current_filter(),
'wc-helper-deactivate-plugin' => 1,
'wc-helper-product-id' => $subscription['product_id'],
'wc-helper-nonce' => wp_create_nonce( 'deactivate-plugin:' . $subscription['product_id'] ),
@ -644,6 +756,7 @@ class WC_Helper {
$redirect_uri = add_query_arg( array(
'page' => 'wc-addons',
'section' => 'helper',
'filter' => self::get_current_filter(),
'wc-helper-status' => 'helper-refreshed',
), admin_url( 'admin.php' ) );
@ -690,6 +803,7 @@ class WC_Helper {
$redirect_uri = add_query_arg( array(
'page' => 'wc-addons',
'section' => 'helper',
'filter' => self::get_current_filter(),
'wc-helper-status' => $activated ? 'activate-success' : 'activate-error',
'wc-helper-product-id' => $product_id,
), admin_url( 'admin.php' ) );
@ -727,6 +841,7 @@ class WC_Helper {
$redirect_uri = add_query_arg( array(
'page' => 'wc-addons',
'section' => 'helper',
'filter' => self::get_current_filter(),
'wc-helper-status' => $deactivated ? 'deactivate-success' : 'deactivate-error',
'wc-helper-product-id' => $product_id,
), admin_url( 'admin.php' ) );
@ -767,6 +882,7 @@ class WC_Helper {
$redirect_uri = add_query_arg( array(
'page' => 'wc-addons',
'section' => 'helper',
'filter' => self::get_current_filter(),
'wc-helper-status' => $deactivated ? 'deactivate-plugin-success' : 'deactivate-plugin-error',
'wc-helper-product-id' => $product_id,
), admin_url( 'admin.php' ) );

View File

@ -12,6 +12,34 @@
<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>
</div>
<ul class="subscription-filter">
<label><?php _e( 'Sort by:', 'woocommerce' ); ?> <span class="chevron dashicons dashicons-arrow-up-alt2"></span></label>
<?php
$filters = array_keys( WC_Helper::get_filters() );
$last_filter = array_pop( $filters );
$current_filter = WC_Helper::get_current_filter();
$counts = WC_Helper::get_filters_counts();
?>
<?php foreach ( WC_Helper::get_filters() as $key => $label ) : ?>
<?php
// Don't show empty filters.
if ( empty( $counts[ $key ] ) ) {
continue;
}
$url = admin_url( 'admin.php?page=wc-addons&section=helper&filter=' . $key );
$class_html = $current_filter === $key ? 'class="current"' : '';
?>
<li>
<a <?php echo $class_html; ?> href="<?php echo esc_url( $url ); ?>">
<?php echo esc_html( $label ); ?>
<span class="count">(<?php echo absint( $counts[ $key ] ); ?>)</span>
</a>
</li>
<?php endforeach; ?>
</ul>
<table class="wp-list-table widefat fixed striped">
<?php if ( ! empty( $subscriptions ) ) : ?>
<?php foreach ( $subscriptions as $subscription ) : ?>
@ -24,7 +52,11 @@
</div>
<div class="wp-list-table__ext-description">
<?php if ( $subscription['expired'] ) : ?>
<?php if ( $subscription['lifetime'] ) : ?>
<span class="renews">
<?php _e( 'Lifetime Subscription', 'woocommerce' ); ?>
</span>
<?php elseif ( $subscription['expired'] ) : ?>
<span class="renews">
<strong><?php _e( 'Expired :(', 'woocommerce' ); ?></strong>
<?php echo date_i18n( 'F jS, Y', $subscription['expires'] ); ?>
@ -58,7 +90,11 @@
} else {
_e( 'Subscription: Unlimited', 'woocommerce' );
}
if ( isset( $subscription['master_user_email'] ) ) {
// Check shared.
if ( ! empty( $subscription['is_shared'] ) && ! empty( $subscription['owner_email'] ) ) {
printf( '</br>' . __( 'Shared by %s', 'woocommerce' ), esc_html( $subscription['owner_email'] ) );
} elseif ( isset( $subscription['master_user_email'] ) ) {
printf( '</br>' . __( 'Shared by %s', 'woocommerce' ), esc_html( $subscription['master_user_email'] ) );
}
?>

View File

@ -2,5 +2,10 @@
<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"><?php _e( 'Browse Extensions', 'woocommerce' ); ?></a>
<a href="<?php echo esc_url( admin_url( 'admin.php?page=wc-addons&section=helper' ) ); ?>" class="nav-tab nav-tab-active"><?php _e( 'WooCommerce.com Subscriptions', 'woocommerce' ); ?></a>
<?php
$count_html = WC_Helper_Updater::get_updates_count_html();
$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 nav-tab-active"><?php echo $menu_title; ?></a>
</nav>

View File

@ -13,7 +13,12 @@ if ( ! defined( 'ABSPATH' ) ) {
<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 _e( 'Browse Extensions', 'woocommerce' ); ?></a>
<a href="<?php echo esc_url( admin_url( 'admin.php?page=wc-addons&section=helper' ) ); ?>" class="nav-tab"><?php _e( 'WooCommerce.com Subscriptions', 'woocommerce' ); ?></a>
<?php
$count_html = WC_Helper_Updater::get_updates_count_html();
$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 $menu_title; ?></a>
</nav>
<h1 class="screen-reader-text"><?php _e( 'WooCommerce Extensions', 'woocommerce' ); ?></h1>