2017-04-21 12:05:44 +00:00
< ? php
if ( ! defined ( 'ABSPATH' ) ) {
exit ;
}
2017-04-26 15:50:38 +00:00
/**
* WC_Helper Class
*
* The main entry - point for all things related to the Helper .
*/
2017-04-21 12:05:44 +00:00
class WC_Helper {
2017-05-03 11:37:36 +00:00
/**
* A log object returned by wc_get_logger () .
*/
2017-04-21 12:05:44 +00:00
public static $log ;
2017-04-26 15:50:38 +00:00
/**
* Get an absolute path to the requested helper view .
*
* @ param string $view The requested view file .
*
* @ return string The absolute path to the view file .
*/
2017-04-21 12:05:44 +00:00
public static function get_view_filename ( $view ) {
return __DIR__ . " /views/ $view " ;
}
2017-04-26 15:50:38 +00:00
/**
* Loads the helper class , runs on init .
*/
2017-04-21 12:05:44 +00:00
public static function load () {
add_action ( 'current_screen' , array ( __CLASS__ , 'current_screen' ) );
2017-05-30 16:46:26 +00:00
add_action ( 'woocommerce_helper_output' , array ( __CLASS__ , 'render_helper_output' ) );
2017-04-21 12:05:44 +00:00
add_action ( 'admin_enqueue_scripts' , array ( __CLASS__ , 'admin_enqueue_scripts' ) );
add_filter ( 'extra_plugin_headers' , array ( __CLASS__ , 'extra_headers' ) );
add_filter ( 'extra_theme_headers' , array ( __CLASS__ , 'extra_headers' ) );
2017-05-03 11:37:36 +00:00
// Attempt to toggle subscription state upon plugin activation/deactivation
add_action ( 'activated_plugin' , array ( __CLASS__ , 'activated_plugin' ) );
add_action ( 'deactivated_plugin' , array ( __CLASS__ , 'deactivated_plugin' ) );
2017-05-24 11:54:39 +00:00
// Add some nags about extension updates
add_action ( 'admin_notices' , array ( __CLASS__ , 'admin_notices' ) );
2017-06-14 13:12:53 +00:00
do_action ( 'woocommerce_helper_loaded' );
2017-04-21 12:05:44 +00:00
}
/**
* Render the helper section content based on context .
*/
2017-05-30 16:46:26 +00:00
public static function render_helper_output () {
2018-03-05 18:59:17 +00:00
$auth = WC_Helper_Options :: get ( 'auth' );
2017-04-21 12:05:44 +00:00
$auth_user_data = WC_Helper_Options :: get ( 'auth_user_data' );
// Return success/error notices.
$notices = self :: _get_return_notices ();
// No active connection.
if ( empty ( $auth [ 'access_token' ] ) ) {
2018-03-05 18:59:17 +00:00
$connect_url = add_query_arg (
array (
'page' => 'wc-addons' ,
'section' => 'helper' ,
'wc-helper-connect' => 1 ,
'wc-helper-nonce' => wp_create_nonce ( 'connect' ),
), admin_url ( 'admin.php' )
);
include self :: get_view_filename ( 'html-oauth-start.php' );
2017-04-21 12:05:44 +00:00
return ;
}
2018-03-05 18:59:17 +00:00
$disconnect_url = add_query_arg (
array (
'page' => 'wc-addons' ,
'section' => 'helper' ,
'wc-helper-disconnect' => 1 ,
'wc-helper-nonce' => wp_create_nonce ( 'disconnect' ),
), admin_url ( 'admin.php' )
);
2017-04-21 12:05:44 +00:00
2017-08-28 08:53:31 +00:00
$current_filter = self :: get_current_filter ();
2018-03-05 18:59:17 +00:00
$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' )
);
2017-04-21 12:05:44 +00:00
// Installed plugins and themes, with or without an active subscription.
$woo_plugins = self :: get_local_woo_plugins ();
2018-03-05 18:59:17 +00:00
$woo_themes = self :: get_local_woo_themes ();
2017-04-21 12:05:44 +00:00
2018-03-05 18:59:17 +00:00
$site_id = absint ( $auth [ 'site_id' ] );
$subscriptions = self :: get_subscriptions ();
$updates = WC_Helper_Updater :: get_update_data ();
2017-04-21 12:05:44 +00:00
$subscriptions_product_ids = wp_list_pluck ( $subscriptions , 'product_id' );
foreach ( $subscriptions as & $subscription ) {
$subscription [ 'active' ] = in_array ( $site_id , $subscription [ 'connections' ] );
2018-03-05 18:59:17 +00:00
$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' ],
'wc-helper-nonce' => wp_create_nonce ( 'activate:' . $subscription [ 'product_key' ] ),
), admin_url ( 'admin.php' )
);
$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' ],
'wc-helper-nonce' => wp_create_nonce ( 'deactivate:' . $subscription [ 'product_key' ] ),
), admin_url ( 'admin.php' )
);
2017-04-21 12:05:44 +00:00
$subscription [ 'local' ] = array (
'installed' => false ,
2018-03-05 18:59:17 +00:00
'active' => false ,
'version' => null ,
2017-04-21 12:05:44 +00:00
);
2017-05-24 15:11:37 +00:00
$subscription [ 'update_url' ] = admin_url ( 'update-core.php' );
2017-04-21 12:05:44 +00:00
$local = wp_list_filter ( array_merge ( $woo_plugins , $woo_themes ), array ( '_product_id' => $subscription [ 'product_id' ] ) );
if ( ! empty ( $local ) ) {
2018-03-05 18:59:17 +00:00
$local = array_shift ( $local );
2017-04-21 12:05:44 +00:00
$subscription [ 'local' ][ 'installed' ] = true ;
2018-03-05 18:59:17 +00:00
$subscription [ 'local' ][ 'version' ] = $local [ 'Version' ];
2017-04-21 12:05:44 +00:00
2017-04-21 12:35:27 +00:00
if ( 'plugin' == $local [ '_type' ] ) {
2017-04-21 12:05:44 +00:00
if ( is_plugin_active ( $local [ '_filename' ] ) ) {
$subscription [ 'local' ][ 'active' ] = true ;
} elseif ( is_multisite () && is_plugin_active_for_network ( $local [ '_filename' ] ) ) {
$subscription [ 'local' ][ 'active' ] = true ;
}
2017-05-24 15:11:37 +00:00
// A magic update_url.
$subscription [ 'update_url' ] = wp_nonce_url ( self_admin_url ( 'update.php?action=upgrade-plugin&plugin=' ) . $local [ '_filename' ], 'upgrade-plugin_' . $local [ '_filename' ] );
2017-04-21 12:35:27 +00:00
} elseif ( 'theme' == $local [ '_type' ] ) {
2017-04-21 12:05:44 +00:00
if ( in_array ( $local [ '_stylesheet' ], array ( get_stylesheet (), get_template () ) ) ) {
$subscription [ 'local' ][ 'active' ] = true ;
}
2017-05-24 15:15:07 +00:00
// Another magic update_url.
$subscription [ 'update_url' ] = wp_nonce_url ( self_admin_url ( 'update.php?action=upgrade-theme&theme=' . $local [ '_stylesheet' ] ), 'upgrade-theme_' . $local [ '_stylesheet' ] );
2017-04-21 12:05:44 +00:00
}
}
2017-06-14 13:12:53 +00:00
$subscription [ 'has_update' ] = false ;
if ( $subscription [ 'local' ][ 'installed' ] && ! empty ( $updates [ $subscription [ 'product_id' ] ] ) ) {
$subscription [ 'has_update' ] = version_compare ( $updates [ $subscription [ 'product_id' ] ][ 'version' ], $subscription [ 'local' ][ 'version' ], '>' );
}
2017-06-21 15:15:45 +00:00
$subscription [ 'download_primary' ] = true ;
2018-03-05 18:59:17 +00:00
$subscription [ 'download_url' ] = $subscription [ 'product_url' ];
2017-06-14 13:12:53 +00:00
if ( ! $subscription [ 'local' ][ 'installed' ] && ! empty ( $updates [ $subscription [ 'product_id' ] ] ) ) {
$subscription [ 'download_url' ] = $updates [ $subscription [ 'product_id' ] ][ 'package' ];
}
$subscription [ 'actions' ] = array ();
if ( $subscription [ 'has_update' ] && ! $subscription [ 'expired' ] ) {
$action = array (
/* translators: %s: version number */
2018-03-05 18:59:17 +00:00
'message' => sprintf ( __ ( 'Version %s is <strong>available</strong>.' , 'woocommerce' ), esc_html ( $updates [ $subscription [ 'product_id' ] ][ 'version' ] ) ),
2017-06-14 13:12:53 +00:00
'button_label' => __ ( 'Update' , 'woocommerce' ),
2018-03-05 18:59:17 +00:00
'button_url' => $subscription [ 'update_url' ],
'status' => 'update-available' ,
'icon' => 'dashicons-update' ,
2017-06-14 13:12:53 +00:00
);
// Subscription is not active on this site.
if ( ! $subscription [ 'active' ] ) {
2018-03-05 18:59:17 +00:00
$action [ 'message' ] .= ' ' . __ ( 'To enable this update you need to <strong>activate</strong> this subscription.' , 'woocommerce' );
2017-06-14 13:12:53 +00:00
$action [ 'button_label' ] = null ;
2018-03-05 18:59:17 +00:00
$action [ 'button_url' ] = null ;
2017-06-14 13:12:53 +00:00
}
$subscription [ 'actions' ][] = $action ;
}
if ( $subscription [ 'has_update' ] && $subscription [ 'expired' ] ) {
$action = array (
/* translators: %s: version number */
'message' => sprintf ( __ ( 'Version %s is <strong>available</strong>.' , 'woocommerce' ), esc_html ( $updates [ $subscription [ 'product_id' ] ][ 'version' ] ) ),
2018-03-05 18:59:17 +00:00
'status' => 'expired' ,
'icon' => 'dashicons-info' ,
2017-06-14 13:12:53 +00:00
);
2018-03-05 18:59:17 +00:00
$action [ 'message' ] .= ' ' . __ ( 'To enable this update you need to <strong>purchase</strong> a new subscription.' , 'woocommerce' );
2017-06-14 13:12:53 +00:00
$action [ 'button_label' ] = __ ( 'Purchase' , 'woocommerce' );
2018-03-05 18:59:17 +00:00
$action [ 'button_url' ] = $subscription [ 'product_url' ];
2017-06-14 13:12:53 +00:00
2017-06-21 14:45:41 +00:00
$subscription [ 'actions' ][] = $action ;
2017-06-22 09:10:33 +00:00
} elseif ( $subscription [ 'expired' ] && ! empty ( $subscription [ 'master_user_email' ] ) ) {
2017-06-21 14:45:41 +00:00
$action = array (
'message' => sprintf ( __ ( 'This subscription has expired. Contact the owner to <strong>renew</strong> the subscription to receive updates and support.' , 'woocommerce' ) ),
2018-03-05 18:59:17 +00:00
'status' => 'expired' ,
'icon' => 'dashicons-info' ,
2017-06-21 14:45:41 +00:00
);
2017-06-14 13:12:53 +00:00
$subscription [ 'actions' ][] = $action ;
} elseif ( $subscription [ 'expired' ] ) {
$action = array (
2018-03-05 18:59:17 +00:00
'message' => sprintf ( __ ( 'This subscription has expired. Please <strong>renew</strong> to receive updates and support.' , 'woocommerce' ) ),
2017-06-14 13:12:53 +00:00
'button_label' => __ ( 'Renew' , 'woocommerce' ),
2018-03-05 18:59:17 +00:00
'button_url' => 'https://woocommerce.com/my-account/my-subscriptions/' ,
'status' => 'expired' ,
'icon' => 'dashicons-info' ,
2017-06-14 13:12:53 +00:00
);
$subscription [ 'actions' ][] = $action ;
}
if ( $subscription [ 'expiring' ] && ! $subscription [ 'autorenew' ] ) {
$action = array (
2018-03-05 18:59:17 +00:00
'message' => __ ( 'Subscription is <strong>expiring</strong> soon.' , 'woocommerce' ),
2017-06-14 13:12:53 +00:00
'button_label' => __ ( 'Enable auto-renew' , 'woocommerce' ),
2018-03-05 18:59:17 +00:00
'button_url' => 'https://woocommerce.com/my-account/my-subscriptions/' ,
'status' => 'expired' ,
'icon' => 'dashicons-info' ,
2017-06-14 13:12:53 +00:00
);
2017-06-21 15:15:45 +00:00
$subscription [ 'download_primary' ] = false ;
2018-03-05 18:59:17 +00:00
$subscription [ 'actions' ][] = $action ;
2017-06-14 13:12:53 +00:00
} elseif ( $subscription [ 'expiring' ] ) {
$action = array (
2018-03-05 18:59:17 +00:00
'message' => sprintf ( __ ( 'This subscription is expiring soon. Please <strong>renew</strong> to continue receiving updates and support.' , 'woocommerce' ) ),
2017-06-14 13:12:53 +00:00
'button_label' => __ ( 'Renew' , 'woocommerce' ),
2018-03-05 18:59:17 +00:00
'button_url' => 'https://woocommerce.com/my-account/my-subscriptions/' ,
'status' => 'expired' ,
'icon' => 'dashicons-info' ,
2017-06-14 13:12:53 +00:00
);
2017-06-21 15:15:45 +00:00
$subscription [ 'download_primary' ] = false ;
2018-03-05 18:59:17 +00:00
$subscription [ 'actions' ][] = $action ;
2017-06-14 13:12:53 +00:00
}
// Mark the first action primary.
foreach ( $subscription [ 'actions' ] as $key => $action ) {
if ( ! empty ( $action [ 'button_label' ] ) ) {
$subscription [ 'actions' ][ $key ][ 'primary' ] = true ;
break ;
}
}
2017-04-21 12:05:44 +00:00
}
// Break the by-ref.
unset ( $subscription );
// Installed products without a subscription.
$no_subscriptions = array ();
foreach ( array_merge ( $woo_plugins , $woo_themes ) as $filename => $data ) {
if ( in_array ( $data [ '_product_id' ], $subscriptions_product_ids ) ) {
continue ;
}
2017-06-14 13:12:53 +00:00
$data [ '_product_url' ] = '#' ;
2018-03-05 18:59:17 +00:00
$data [ '_has_update' ] = false ;
2017-06-14 13:12:53 +00:00
if ( ! empty ( $updates [ $data [ '_product_id' ] ] ) ) {
$data [ '_has_update' ] = version_compare ( $updates [ $data [ '_product_id' ] ][ 'version' ], $data [ 'Version' ], '>' );
if ( ! empty ( $updates [ $data [ '_product_id' ] ][ 'url' ] ) ) {
$data [ '_product_url' ] = $updates [ $data [ '_product_id' ] ][ 'url' ];
} elseif ( ! empty ( $data [ 'PluginURI' ] ) ) {
$data [ '_product_url' ] = $data [ 'PluginURI' ];
}
}
$data [ '_actions' ] = array ();
if ( $data [ '_has_update' ] ) {
$action = array (
2018-03-05 18:59:17 +00:00
'message' => sprintf ( __ ( 'Version %s is <strong>available</strong>. To enable this update you need to <strong>purchase</strong> a new subscription.' , 'woocommerce' ), esc_html ( $updates [ $data [ '_product_id' ] ][ 'version' ] ) ),
2017-06-14 13:12:53 +00:00
'button_label' => __ ( 'Purchase' , 'woocommerce' ),
2018-03-05 18:59:17 +00:00
'button_url' => $data [ '_product_url' ],
'status' => 'expired' ,
'icon' => 'dashicons-info' ,
2017-06-14 13:12:53 +00:00
);
$data [ '_actions' ][] = $action ;
} else {
$action = array (
2018-01-31 17:25:38 +00:00
/* translators: 1: subscriptions docs 2: subscriptions docs */
2018-03-05 18:59:17 +00:00
'message' => sprintf ( __ ( 'To receive updates and support for this extension, you need to <strong>purchase</strong> a new subscription or consolidate your extensions to one connected account by <strong><a href="%1$s" title="Sharing Docs">sharing</a> or <a href="%2$s" title="Transferring Docs">transferring</a></strong> this extension to this connected account.' , 'woocommerce' ), 'https://docs.woocommerce.com/document/managing-woocommerce-com-subscriptions/#section-10' , 'https://docs.woocommerce.com/document/managing-woocommerce-com-subscriptions/#section-5' ),
2017-06-14 13:12:53 +00:00
'button_label' => __ ( 'Purchase' , 'woocommerce' ),
2018-03-05 18:59:17 +00:00
'button_url' => $data [ '_product_url' ],
'status' => 'expired' ,
'icon' => 'dashicons-info' ,
2017-06-14 13:12:53 +00:00
);
$data [ '_actions' ][] = $action ;
}
2017-04-21 12:05:44 +00:00
$no_subscriptions [ $filename ] = $data ;
}
2017-06-14 13:12:53 +00:00
// Update the user id if it came from a migrated connection.
if ( empty ( $auth [ 'user_id' ] ) ) {
$auth [ 'user_id' ] = get_current_user_id ();
WC_Helper_Options :: update ( 'auth' , $auth );
}
2017-06-21 15:43:19 +00:00
// Sort alphabetically
2017-06-22 13:47:07 +00:00
uasort ( $subscriptions , array ( __CLASS__ , '_sort_by_product_name' ) );
uasort ( $no_subscriptions , array ( __CLASS__ , '_sort_by_name' ) );
2017-06-21 15:43:19 +00:00
2017-08-28 08:39:41 +00:00
// Filters
2017-08-30 14:39:02 +00:00
self :: get_filters_counts ( $subscriptions ); // Warm it up.
2017-08-28 08:53:31 +00:00
self :: _filter ( $subscriptions , self :: get_current_filter () );
2017-08-28 08:39:41 +00:00
2017-04-21 12:05:44 +00:00
// We have an active connection.
2018-03-05 18:59:17 +00:00
include self :: get_view_filename ( 'html-main.php' );
2017-04-21 12:05:44 +00:00
return ;
}
2017-08-28 08:39:41 +00:00
/**
* Get available subscriptions filters .
*
* @ return array An array of filter keys and labels .
*/
2017-11-23 11:49:12 +00:00
public static function get_filters () {
2017-08-28 08:39:41 +00:00
$filters = array (
2018-03-05 18:59:17 +00:00
'all' => __ ( 'All' , 'woocommerce' ),
'active' => __ ( 'Active' , 'woocommerce' ),
'inactive' => __ ( 'Inactive' , 'woocommerce' ),
'installed' => __ ( 'Installed' , 'woocommerce' ),
2017-08-30 14:39:02 +00:00
'update-available' => __ ( 'Update Available' , 'woocommerce' ),
2018-03-05 18:59:17 +00:00
'expiring' => __ ( 'Expiring Soon' , 'woocommerce' ),
'expired' => __ ( 'Expired' , 'woocommerce' ),
'download' => __ ( 'Download' , 'woocommerce' ),
2017-08-28 08:39:41 +00:00
);
2017-08-30 14:39:02 +00:00
return $filters ;
2017-08-28 08:53:31 +00:00
}
2017-08-30 14:39:02 +00:00
/**
* 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 ;
}
2017-08-28 08:53:31 +00:00
/**
* Get current filter .
*
* @ return string The current filter .
*/
public static function get_current_filter () {
$current_filter = 'all' ;
2018-03-05 18:59:17 +00:00
$valid_filters = array_keys ( self :: get_filters () );
2017-08-28 08:53:31 +00:00
if ( ! empty ( $_GET [ 'filter' ] ) && in_array ( $_GET [ 'filter' ], $valid_filters ) ) {
$current_filter = $_GET [ 'filter' ];
}
return $current_filter ;
2017-08-28 08:39:41 +00:00
}
/**
* Filter an array of subscriptions by $filter .
*
2018-03-05 18:59:17 +00:00
* @ param array $subscriptions The subscriptions array , passed by ref .
2017-08-28 08:39:41 +00:00
* @ param string $filter The filter .
*/
private static function _filter ( & $subscriptions , $filter ) {
2017-08-29 07:23:34 +00:00
switch ( $filter ) {
2017-08-28 08:39:41 +00:00
case 'active' :
$subscriptions = wp_list_filter ( $subscriptions , array ( 'active' => true ) );
break ;
case 'inactive' :
$subscriptions = wp_list_filter ( $subscriptions , array ( 'active' => false ) );
break ;
2017-09-27 12:17:24 +00:00
case 'installed' :
foreach ( $subscriptions as $key => $subscription ) {
if ( empty ( $subscription [ 'local' ][ 'installed' ] ) ) {
unset ( $subscriptions [ $key ] );
}
}
break ;
2017-08-28 08:39:41 +00:00
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 ;
}
}
2017-04-21 12:05:44 +00:00
/**
* Enqueue admin scripts and styles .
*/
public static function admin_enqueue_scripts () {
2017-07-10 15:29:06 +00:00
$screen = get_current_screen ();
$screen_id = $screen ? $screen -> id : '' ;
$wc_screen_id = sanitize_title ( __ ( 'WooCommerce' , 'woocommerce' ) );
2017-05-30 16:46:26 +00:00
2017-07-10 15:29:06 +00:00
if ( $wc_screen_id . '_page_wc-addons' === $screen_id && isset ( $_GET [ 'section' ] ) && 'helper' === $_GET [ 'section' ] ) {
2017-04-21 12:05:44 +00:00
wp_enqueue_style ( 'woocommerce-helper' , WC () -> plugin_url () . '/assets/css/helper.css' , array (), WC_VERSION );
}
}
/**
* Various success / error notices .
*
* Runs during admin page render , so no headers / redirects here .
*
* @ return array Array pairs of message / type strings with notices .
*/
private static function _get_return_notices () {
$return_status = isset ( $_GET [ 'wc-helper-status' ] ) ? $_GET [ 'wc-helper-status' ] : null ;
2018-03-05 18:59:17 +00:00
$notices = array ();
2017-04-21 12:05:44 +00:00
switch ( $return_status ) {
case 'activate-success' :
2017-05-03 11:37:36 +00:00
$subscription = self :: _get_subscriptions_from_product_id ( absint ( $_GET [ 'wc-helper-product-id' ] ) );
2018-03-05 18:59:17 +00:00
$notices [] = array (
'type' => 'updated' ,
2017-04-26 15:36:20 +00:00
/* translators: %s: product name */
2018-03-05 18:59:17 +00:00
'message' => sprintf (
__ ( '%s activated successfully. You will now receive updates for this product.' , 'woocommerce' ),
'<strong>' . esc_html ( $subscription [ 'product_name' ] ) . '</strong>'
),
2017-04-21 12:05:44 +00:00
);
break ;
case 'activate-error' :
2017-05-03 11:37:36 +00:00
$subscription = self :: _get_subscriptions_from_product_id ( absint ( $_GET [ 'wc-helper-product-id' ] ) );
2018-03-05 18:59:17 +00:00
$notices [] = array (
'type' => 'error' ,
2017-04-26 15:36:20 +00:00
/* translators: %s: product name */
2018-03-05 18:59:17 +00:00
'message' => sprintf (
__ ( 'An error has occurred when activating %s. Please try again later.' , 'woocommerce' ),
'<strong>' . esc_html ( $subscription [ 'product_name' ] ) . '</strong>'
),
2017-04-21 12:05:44 +00:00
);
break ;
case 'deactivate-success' :
2017-05-03 11:37:36 +00:00
$subscription = self :: _get_subscriptions_from_product_id ( absint ( $_GET [ 'wc-helper-product-id' ] ) );
2018-03-05 18:59:17 +00:00
$local = self :: _get_local_from_product_id ( absint ( $_GET [ 'wc-helper-product-id' ] ) );
2017-04-26 15:36:20 +00:00
/* translators: %s: product name */
2018-03-05 18:59:17 +00:00
$message = sprintf (
__ ( 'Subscription for %s deactivated successfully. You will no longer receive updates for this product.' , 'woocommerce' ),
'<strong>' . esc_html ( $subscription [ 'product_name' ] ) . '</strong>'
);
2017-04-21 12:05:44 +00:00
if ( $local && is_plugin_active ( $local [ '_filename' ] ) && current_user_can ( 'activate_plugins' ) ) {
2018-03-05 18:59:17 +00:00
$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' ] ),
), admin_url ( 'admin.php' )
);
2017-04-21 12:05:44 +00:00
2017-04-26 15:36:20 +00:00
/* translators: %1$s: product name, %2$s: deactivate url */
2018-03-05 18:59:17 +00:00
$message = sprintf (
__ ( 'Subscription for %1$s deactivated successfully. You will no longer receive updates for this product. <a href="%2$s">Click here</a> if you wish to deactivate the plugin as well.' , 'woocommerce' ),
'<strong>' . esc_html ( $subscription [ 'product_name' ] ) . '</strong>' , esc_url ( $deactivate_plugin_url )
);
2017-04-21 12:05:44 +00:00
}
$notices [] = array (
'message' => $message ,
2018-03-05 18:59:17 +00:00
'type' => 'updated' ,
2017-04-21 12:05:44 +00:00
);
break ;
case 'deactivate-error' :
2017-05-03 11:37:36 +00:00
$subscription = self :: _get_subscriptions_from_product_id ( absint ( $_GET [ 'wc-helper-product-id' ] ) );
2018-03-05 18:59:17 +00:00
$notices [] = array (
'type' => 'error' ,
2017-04-26 15:36:20 +00:00
/* translators: %s: product name */
2018-03-05 18:59:17 +00:00
'message' => sprintf (
__ ( 'An error has occurred when deactivating the subscription for %s. Please try again later.' , 'woocommerce' ),
'<strong>' . esc_html ( $subscription [ 'product_name' ] ) . '</strong>'
),
2017-04-21 12:05:44 +00:00
);
break ;
case 'deactivate-plugin-success' :
2017-05-03 11:37:36 +00:00
$subscription = self :: _get_subscriptions_from_product_id ( absint ( $_GET [ 'wc-helper-product-id' ] ) );
2018-03-05 18:59:17 +00:00
$notices [] = array (
'type' => 'updated' ,
2017-04-26 15:36:20 +00:00
/* translators: %s: product name */
2018-03-05 18:59:17 +00:00
'message' => sprintf (
__ ( 'The extension %s has been deactivated successfully.' , 'woocommerce' ),
'<strong>' . esc_html ( $subscription [ 'product_name' ] ) . '</strong>'
),
2017-04-21 12:05:44 +00:00
);
break ;
case 'deactivate-plugin-error' :
2017-05-03 11:37:36 +00:00
$subscription = self :: _get_subscriptions_from_product_id ( absint ( $_GET [ 'wc-helper-product-id' ] ) );
2018-03-05 18:59:17 +00:00
$notices [] = array (
'type' => 'error' ,
2017-04-26 15:36:20 +00:00
/* translators: %1$s: product name, %2$s: plugins screen url */
2018-03-05 18:59:17 +00:00
'message' => sprintf (
__ ( 'An error has occurred when deactivating the extension %1$s. Please proceed to the <a href="%2$s">Plugins screen</a> to deactivate it manually.' , 'woocommerce' ),
'<strong>' . esc_html ( $subscription [ 'product_name' ] ) . '</strong>' , admin_url ( 'plugins.php' )
),
2017-04-21 12:05:44 +00:00
);
break ;
case 'helper-connected' :
$notices [] = array (
2017-04-26 15:36:20 +00:00
'message' => __ ( 'You have successfully connected your store to WooCommerce.com' , 'woocommerce' ),
2018-03-05 18:59:17 +00:00
'type' => 'updated' ,
2017-04-21 12:05:44 +00:00
);
break ;
case 'helper-disconnected' :
$notices [] = array (
2017-04-26 15:36:20 +00:00
'message' => __ ( 'You have successfully disconnected your store from WooCommerce.com' , 'woocommerce' ),
2018-03-05 18:59:17 +00:00
'type' => 'updated' ,
2017-04-21 12:05:44 +00:00
);
break ;
case 'helper-refreshed' :
$notices [] = array (
2017-04-26 15:36:20 +00:00
'message' => __ ( 'Authentication and subscription caches refreshed successfully.' , 'woocommerce' ),
2018-03-05 18:59:17 +00:00
'type' => 'updated' ,
2017-04-21 12:05:44 +00:00
);
break ;
}
return $notices ;
}
/**
* Various early - phase actions with possible redirects .
*/
public static function current_screen ( $screen ) {
2017-07-10 15:29:06 +00:00
$wc_screen_id = sanitize_title ( __ ( 'WooCommerce' , 'woocommerce' ) );
if ( $wc_screen_id . '_page_wc-addons' !== $screen -> id ) {
2017-05-30 16:46:26 +00:00
return ;
}
if ( empty ( $_GET [ 'section' ] ) || 'helper' !== $_GET [ 'section' ] ) {
2017-04-21 12:05:44 +00:00
return ;
}
if ( ! empty ( $_GET [ 'wc-helper-connect' ] ) ) {
return self :: _helper_auth_connect ();
}
if ( ! empty ( $_GET [ 'wc-helper-return' ] ) ) {
return self :: _helper_auth_return ();
}
if ( ! empty ( $_GET [ 'wc-helper-disconnect' ] ) ) {
return self :: _helper_auth_disconnect ();
}
if ( ! empty ( $_GET [ 'wc-helper-refresh' ] ) ) {
return self :: _helper_auth_refresh ();
}
if ( ! empty ( $_GET [ 'wc-helper-activate' ] ) ) {
return self :: _helper_subscription_activate ();
}
if ( ! empty ( $_GET [ 'wc-helper-deactivate' ] ) ) {
return self :: _helper_subscription_deactivate ();
}
if ( ! empty ( $_GET [ 'wc-helper-deactivate-plugin' ] ) ) {
return self :: _helper_plugin_deactivate ();
}
}
/**
* Initiate a new OAuth connection .
*/
private static function _helper_auth_connect () {
if ( empty ( $_GET [ 'wc-helper-nonce' ] ) || ! wp_verify_nonce ( $_GET [ 'wc-helper-nonce' ], 'connect' ) ) {
self :: log ( 'Could not verify nonce in _helper_auth_connect' );
wp_die ( 'Could not verify nonce' );
}
2018-03-05 18:59:17 +00:00
$redirect_uri = add_query_arg (
array (
'page' => 'wc-addons' ,
'section' => 'helper' ,
'wc-helper-return' => 1 ,
'wc-helper-nonce' => wp_create_nonce ( 'connect' ),
), admin_url ( 'admin.php' )
);
2017-04-21 12:05:44 +00:00
2018-03-05 18:59:17 +00:00
$request = WC_Helper_API :: post (
'oauth/request_token' , array (
'body' => array (
'home_url' => home_url (),
'redirect_uri' => $redirect_uri ,
),
)
);
2017-04-21 12:05:44 +00:00
$code = wp_remote_retrieve_response_code ( $request );
2017-04-21 12:35:27 +00:00
if ( 200 !== $code ) {
2017-04-21 12:05:44 +00:00
self :: log ( sprintf ( 'Call to oauth/request_token returned a non-200 response code (%d)' , $code ) );
wp_die ( 'Something went wrong' );
}
$secret = json_decode ( wp_remote_retrieve_body ( $request ) );
if ( empty ( $secret ) ) {
self :: log ( sprintf ( 'Call to oauth/request_token returned an invalid body: %s' , wp_remote_retrieve_body ( $request ) ) );
wp_die ( 'Something went wrong' );
}
2018-03-05 18:59:17 +00:00
$connect_url = add_query_arg (
array (
'home_url' => rawurlencode ( home_url () ),
'redirect_uri' => rawurlencode ( $redirect_uri ),
'secret' => rawurlencode ( $secret ),
), WC_Helper_API :: url ( 'oauth/authorize' )
);
2017-04-21 12:05:44 +00:00
wp_redirect ( esc_url_raw ( $connect_url ) );
die ();
}
/**
* Return from WooCommerce . com OAuth flow .
*/
private static function _helper_auth_return () {
if ( empty ( $_GET [ 'wc-helper-nonce' ] ) || ! wp_verify_nonce ( $_GET [ 'wc-helper-nonce' ], 'connect' ) ) {
self :: log ( 'Could not verify nonce in _helper_auth_return' );
wp_die ( 'Something went wrong' );
}
// Bail if the user clicked deny.
if ( ! empty ( $_GET [ 'deny' ] ) ) {
2017-05-30 16:46:26 +00:00
wp_safe_redirect ( admin_url ( 'admin.php?page=wc-addons§ion=helper' ) );
2017-04-21 12:05:44 +00:00
die ();
}
// We do need a request token...
if ( empty ( $_GET [ 'request_token' ] ) ) {
self :: log ( 'Request token not found in _helper_auth_return' );
wp_die ( 'Something went wrong' );
}
// Obtain an access token.
2018-03-05 18:59:17 +00:00
$request = WC_Helper_API :: post (
'oauth/access_token' , array (
'body' => array (
'request_token' => $_GET [ 'request_token' ],
'home_url' => home_url (),
),
)
);
2017-04-21 12:05:44 +00:00
$code = wp_remote_retrieve_response_code ( $request );
2017-04-21 12:35:27 +00:00
if ( 200 !== $code ) {
2017-04-21 12:05:44 +00:00
self :: log ( sprintf ( 'Call to oauth/access_token returned a non-200 response code (%d)' , $code ) );
wp_die ( 'Something went wrong' );
}
$access_token = json_decode ( wp_remote_retrieve_body ( $request ), true );
if ( ! $access_token ) {
self :: log ( sprintf ( 'Call to oauth/access_token returned an invalid body: %s' , wp_remote_retrieve_body ( $request ) ) );
wp_die ( 'Something went wrong' );
}
2018-03-05 18:59:17 +00:00
WC_Helper_Options :: update (
'auth' , array (
'access_token' => $access_token [ 'access_token' ],
'access_token_secret' => $access_token [ 'access_token_secret' ],
'site_id' => $access_token [ 'site_id' ],
'user_id' => get_current_user_id (),
'updated' => time (),
)
);
2017-04-21 12:05:44 +00:00
// Obtain the connected user info.
if ( ! self :: _flush_authentication_cache () ) {
self :: log ( 'Could not obtain connected user info in _helper_auth_return' );
WC_Helper_Options :: update ( 'auth' , array () );
wp_die ( 'Something went wrong.' );
}
self :: _flush_subscriptions_cache ();
2018-04-24 14:43:52 +00:00
self :: _flush_updates_cache ();
2017-04-21 12:05:44 +00:00
2017-06-14 13:12:53 +00:00
// Enable tracking when connected.
if ( class_exists ( 'WC_Tracker' ) ) {
update_option ( 'woocommerce_allow_tracking' , 'yes' );
WC_Tracker :: send_tracking_data ( true );
}
2018-03-05 18:59:17 +00:00
wp_safe_redirect (
add_query_arg (
array (
'page' => 'wc-addons' ,
'section' => 'helper' ,
'wc-helper-status' => 'helper-connected' ,
), admin_url ( 'admin.php' )
)
);
2017-04-21 12:05:44 +00:00
die ();
}
/**
* Disconnect from WooCommerce . com , clear OAuth tokens .
*/
private static function _helper_auth_disconnect () {
if ( empty ( $_GET [ 'wc-helper-nonce' ] ) || ! wp_verify_nonce ( $_GET [ 'wc-helper-nonce' ], 'disconnect' ) ) {
self :: log ( 'Could not verify nonce in _helper_auth_disconnect' );
wp_die ( 'Could not verify nonce' );
}
2018-03-05 18:59:17 +00:00
$redirect_uri = add_query_arg (
array (
'page' => 'wc-addons' ,
'section' => 'helper' ,
'wc-helper-status' => 'helper-disconnected' ,
), admin_url ( 'admin.php' )
);
2017-04-21 12:05:44 +00:00
2018-03-05 18:59:17 +00:00
WC_Helper_API :: post (
'oauth/invalidate_token' , array (
'authenticated' => true ,
)
);
2017-04-21 12:05:44 +00:00
WC_Helper_Options :: update ( 'auth' , array () );
WC_Helper_Options :: update ( 'auth_user_data' , array () );
self :: _flush_subscriptions_cache ();
self :: _flush_updates_cache ();
2017-06-14 13:12:53 +00:00
// Disable tracking when disconnected.
update_option ( 'woocommerce_allow_tracking' , 'no' );
2017-04-21 12:05:44 +00:00
wp_safe_redirect ( $redirect_uri );
die ();
}
/**
* User hit the Refresh button , clear all caches .
*/
private static function _helper_auth_refresh () {
if ( empty ( $_GET [ 'wc-helper-nonce' ] ) || ! wp_verify_nonce ( $_GET [ 'wc-helper-nonce' ], 'refresh' ) ) {
self :: log ( 'Could not verify nonce in _helper_auth_refresh' );
wp_die ( 'Could not verify nonce' );
}
2018-03-05 18:59:17 +00:00
$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' )
);
2017-04-21 12:05:44 +00:00
self :: _flush_authentication_cache ();
self :: _flush_subscriptions_cache ();
self :: _flush_updates_cache ();
wp_safe_redirect ( $redirect_uri );
die ();
}
/**
* Active a product subscription .
*/
private static function _helper_subscription_activate () {
$product_key = $_GET [ 'wc-helper-product-key' ];
2018-03-05 18:59:17 +00:00
$product_id = absint ( $_GET [ 'wc-helper-product-id' ] );
2017-04-21 12:05:44 +00:00
if ( empty ( $_GET [ 'wc-helper-nonce' ] ) || ! wp_verify_nonce ( $_GET [ 'wc-helper-nonce' ], 'activate:' . $product_key ) ) {
self :: log ( 'Could not verify nonce in _helper_subscription_activate' );
wp_die ( 'Could not verify nonce' );
}
2018-03-05 18:59:17 +00:00
$request = WC_Helper_API :: post (
'activate' , array (
'authenticated' => true ,
'body' => json_encode (
array (
'product_key' => $product_key ,
)
),
)
);
2017-04-21 12:05:44 +00:00
2017-05-03 11:37:36 +00:00
$activated = wp_remote_retrieve_response_code ( $request ) === 200 ;
2018-03-05 18:59:17 +00:00
$body = json_decode ( wp_remote_retrieve_body ( $request ), true );
2017-04-21 12:35:27 +00:00
if ( ! $activated && ! empty ( $body [ 'code' ] ) && 'already_connected' == $body [ 'code' ] ) {
2017-04-21 12:05:44 +00:00
$activated = true ;
}
// Attempt to activate this plugin.
$local = self :: _get_local_from_product_id ( $product_id );
2017-04-21 12:35:27 +00:00
if ( $local && 'plugin' == $local [ '_type' ] && current_user_can ( 'activate_plugins' ) && ! is_plugin_active ( $local [ '_filename' ] ) ) {
2017-04-21 12:05:44 +00:00
activate_plugin ( $local [ '_filename' ] );
}
self :: _flush_subscriptions_cache ();
2018-04-24 14:43:52 +00:00
self :: _flush_updates_cache ();
2018-03-05 18:59:17 +00:00
$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' )
);
2017-04-21 12:05:44 +00:00
wp_safe_redirect ( $redirect_uri );
die ();
}
/**
* Deactivate a product subscription .
*/
private static function _helper_subscription_deactivate () {
$product_key = $_GET [ 'wc-helper-product-key' ];
2018-03-05 18:59:17 +00:00
$product_id = absint ( $_GET [ 'wc-helper-product-id' ] );
2017-04-21 12:05:44 +00:00
if ( empty ( $_GET [ 'wc-helper-nonce' ] ) || ! wp_verify_nonce ( $_GET [ 'wc-helper-nonce' ], 'deactivate:' . $product_key ) ) {
self :: log ( 'Could not verify nonce in _helper_subscription_deactivate' );
wp_die ( 'Could not verify nonce' );
}
2018-03-05 18:59:17 +00:00
$request = WC_Helper_API :: post (
'deactivate' , array (
'authenticated' => true ,
'body' => json_encode (
array (
'product_key' => $product_key ,
)
),
)
);
2017-04-21 12:05:44 +00:00
2018-03-05 18:59:17 +00:00
$code = wp_remote_retrieve_response_code ( $request );
2017-05-03 11:37:36 +00:00
$deactivated = 200 === $code ;
2017-04-21 12:05:44 +00:00
if ( ! $deactivated ) {
self :: log ( sprintf ( 'Deactivate API call returned a non-200 response code (%d)' , $code ) );
}
self :: _flush_subscriptions_cache ();
2018-03-05 18:59:17 +00:00
$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' )
);
2017-04-21 12:05:44 +00:00
wp_safe_redirect ( $redirect_uri );
die ();
}
/**
* Deactivate a plugin .
*/
private static function _helper_plugin_deactivate () {
2018-03-05 18:59:17 +00:00
$product_id = absint ( $_GET [ 'wc-helper-product-id' ] );
2017-04-21 12:05:44 +00:00
$deactivated = false ;
if ( empty ( $_GET [ 'wc-helper-nonce' ] ) || ! wp_verify_nonce ( $_GET [ 'wc-helper-nonce' ], 'deactivate-plugin:' . $product_id ) ) {
self :: log ( 'Could not verify nonce in _helper_plugin_deactivate' );
wp_die ( 'Could not verify nonce' );
}
if ( ! current_user_can ( 'activate_plugins' ) ) {
wp_die ( 'You are not allowed to manage plugins on this site.' );
}
2018-03-05 18:59:17 +00:00
$local = wp_list_filter (
array_merge (
self :: get_local_woo_plugins (),
self :: get_local_woo_themes ()
), array ( '_product_id' => $product_id )
);
2017-04-21 12:05:44 +00:00
// Attempt to deactivate this plugin or theme.
if ( ! empty ( $local ) ) {
$local = array_shift ( $local );
if ( is_plugin_active ( $local [ '_filename' ] ) ) {
deactivate_plugins ( $local [ '_filename' ] );
}
$deactivated = ! is_plugin_active ( $local [ '_filename' ] );
}
2018-03-05 18:59:17 +00:00
$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' )
);
2017-04-21 12:05:44 +00:00
wp_safe_redirect ( $redirect_uri );
die ();
}
/**
* Get a local plugin / theme entry from product_id .
*
* @ param int $product_id The product id .
*
* @ return array | bool The array containing the local plugin / theme data or false .
*/
private static function _get_local_from_product_id ( $product_id ) {
2018-03-05 18:59:17 +00:00
$local = wp_list_filter (
array_merge (
self :: get_local_woo_plugins (),
self :: get_local_woo_themes ()
), array ( '_product_id' => $product_id )
);
2017-04-21 12:05:44 +00:00
if ( ! empty ( $local ) ) {
return array_shift ( $local );
}
return false ;
}
/**
* Get a subscription entry from product_id . If multiple subscriptions are
2017-05-03 11:37:36 +00:00
* found with the same product id and $single is set to true , will return the
* first one in the list , so you can use this method to get things like extension
* name , version , etc .
2017-04-21 12:05:44 +00:00
*
2018-03-05 18:59:17 +00:00
* @ param int $product_id The product id .
2017-05-03 11:37:36 +00:00
* @ param bool $single Whether to return a single subscription or all matching a product id .
2017-04-21 12:05:44 +00:00
*
* @ return array | bool The array containing sub data or false .
*/
2017-05-03 11:37:36 +00:00
private static function _get_subscriptions_from_product_id ( $product_id , $single = true ) {
2017-04-21 12:05:44 +00:00
$subscriptions = wp_list_filter ( self :: get_subscriptions (), array ( 'product_id' => $product_id ) );
if ( ! empty ( $subscriptions ) ) {
2017-05-03 11:37:36 +00:00
return $single ? array_shift ( $subscriptions ) : $subscriptions ;
2017-04-21 12:05:44 +00:00
}
return false ;
}
/**
* Additional theme style . css and plugin file headers .
*
* Format : Woo : product_id : file_id
*/
public static function extra_headers ( $headers ) {
$headers [] = 'Woo' ;
return $headers ;
}
/**
* Obtain a list of locally installed Woo extensions .
*/
public static function get_local_woo_plugins () {
if ( ! function_exists ( 'get_plugins' ) ) {
2018-03-05 18:59:17 +00:00
require_once ABSPATH . 'wp-admin/includes/plugin.php' ;
2017-04-21 12:05:44 +00:00
}
2018-03-05 18:59:17 +00:00
$plugins = get_plugins ();
2017-04-21 12:05:44 +00:00
$woo_plugins = array ();
2017-07-17 10:10:52 +00:00
// Backwards compatibility for woothemes_queue_update().
2017-04-21 12:05:44 +00:00
$_compat = array ();
if ( ! empty ( $GLOBALS [ 'woothemes_queued_updates' ] ) ) {
2017-04-21 12:35:27 +00:00
foreach ( $GLOBALS [ 'woothemes_queued_updates' ] as $_compat_plugin ) {
2017-04-21 12:05:44 +00:00
$_compat [ $_compat_plugin -> file ] = array (
'product_id' => $_compat_plugin -> product_id ,
2018-03-05 18:59:17 +00:00
'file_id' => $_compat_plugin -> file_id ,
2017-04-21 12:05:44 +00:00
);
}
}
foreach ( $plugins as $filename => $data ) {
if ( empty ( $data [ 'Woo' ] ) && ! empty ( $_compat [ $filename ] ) ) {
$data [ 'Woo' ] = sprintf ( '%d:%s' , $_compat [ $filename ][ 'product_id' ], $_compat [ $filename ][ 'file_id' ] );
}
if ( empty ( $data [ 'Woo' ] ) ) {
continue ;
}
list ( $product_id , $file_id ) = explode ( ':' , $data [ 'Woo' ] );
if ( empty ( $product_id ) || empty ( $file_id ) ) {
continue ;
}
2018-03-05 18:59:17 +00:00
$data [ '_filename' ] = $filename ;
$data [ '_product_id' ] = absint ( $product_id );
$data [ '_file_id' ] = $file_id ;
$data [ '_type' ] = 'plugin' ;
2017-04-21 12:05:44 +00:00
$woo_plugins [ $filename ] = $data ;
}
return $woo_plugins ;
}
/**
* Get locally installed Woo themes .
*/
public static function get_local_woo_themes () {
2018-03-05 18:59:17 +00:00
$themes = wp_get_themes ();
2017-04-21 12:05:44 +00:00
$woo_themes = array ();
foreach ( $themes as $theme ) {
$header = $theme -> get ( 'Woo' );
2017-07-17 10:10:52 +00:00
// Backwards compatibility for theme_info.txt
2017-04-21 12:05:44 +00:00
if ( ! $header ) {
$txt = $theme -> get_stylesheet_directory () . '/theme_info.txt' ;
if ( is_readable ( $txt ) ) {
$txt = file_get_contents ( $txt );
2018-03-05 18:59:17 +00:00
$txt = preg_split ( '#\s#' , $txt );
2017-04-21 12:05:44 +00:00
if ( count ( $txt ) >= 2 ) {
$header = sprintf ( '%d:%s' , $txt [ 0 ], $txt [ 1 ] );
}
}
}
if ( empty ( $header ) ) {
continue ;
}
list ( $product_id , $file_id ) = explode ( ':' , $header );
if ( empty ( $product_id ) || empty ( $file_id ) ) {
continue ;
}
$data = array (
2018-03-05 18:59:17 +00:00
'Name' => $theme -> get ( 'Name' ),
'Version' => $theme -> get ( 'Version' ),
'Woo' => $header ,
2017-04-21 12:05:44 +00:00
2018-03-05 18:59:17 +00:00
'_filename' => $theme -> get_stylesheet () . '/style.css' ,
2017-04-21 12:05:44 +00:00
'_stylesheet' => $theme -> get_stylesheet (),
'_product_id' => absint ( $product_id ),
2018-03-05 18:59:17 +00:00
'_file_id' => $file_id ,
'_type' => 'theme' ,
2017-04-21 12:05:44 +00:00
);
$woo_themes [ $data [ '_filename' ] ] = $data ;
}
return $woo_themes ;
}
/**
* Get the connected user ' s subscriptions .
*
* @ return array
*/
public static function get_subscriptions () {
$cache_key = '_woocommerce_helper_subscriptions' ;
if ( false !== ( $data = get_transient ( $cache_key ) ) ) {
return $data ;
}
// Obtain the connected user info.
2018-03-05 18:59:17 +00:00
$request = WC_Helper_API :: get (
'subscriptions' , array (
'authenticated' => true ,
)
);
2017-04-21 12:05:44 +00:00
2017-05-03 11:37:36 +00:00
if ( wp_remote_retrieve_response_code ( $request ) !== 200 ) {
2017-04-21 12:05:44 +00:00
set_transient ( $cache_key , array (), 15 * MINUTE_IN_SECONDS );
return array ();
}
$data = json_decode ( wp_remote_retrieve_body ( $request ), true );
if ( empty ( $data ) || ! is_array ( $data ) ) {
$data = array ();
}
set_transient ( $cache_key , $data , 1 * HOUR_IN_SECONDS );
return $data ;
}
2017-05-03 11:37:36 +00:00
/**
* Runs when any plugin is activated .
*
* Depending on the activated plugin attempts to look through available
* subscriptions and auto - activate one if possible , so the user does not
* need to visit the Helper UI at all after installing a new extension .
*
* @ param string $filename The filename of the activated plugin .
*/
public static function activated_plugin ( $filename ) {
$plugins = self :: get_local_woo_plugins ();
// Not a local woo plugin
if ( empty ( $plugins [ $filename ] ) ) {
return ;
}
// Make sure we have a connection.
$auth = WC_Helper_Options :: get ( 'auth' );
if ( empty ( $auth ) ) {
return ;
}
2018-03-05 18:59:17 +00:00
$plugin = $plugins [ $filename ];
2017-05-03 11:37:36 +00:00
$subscriptions = self :: _get_subscriptions_from_product_id ( $plugin [ '_product_id' ], false );
// No valid subscriptions for this product
if ( empty ( $subscriptions ) ) {
return ;
}
$subscription = null ;
foreach ( $subscriptions as $_sub ) {
// Don't attempt to activate expired subscriptions.
if ( $_sub [ 'expired' ] ) {
continue ;
}
// No more sites available in this subscription.
2017-10-06 14:12:55 +00:00
if ( $_sub [ 'sites_max' ] && $_sub [ 'sites_active' ] >= $_sub [ 'sites_max' ] ) {
2017-05-03 11:37:36 +00:00
continue ;
}
// Looks good.
$subscription = $_sub ;
break ;
}
// No valid subscription found.
if ( ! $subscription ) {
return ;
}
2018-03-05 18:59:17 +00:00
$request = WC_Helper_API :: post (
'activate' , array (
'authenticated' => true ,
'body' => json_encode (
array (
'product_key' => $subscription [ 'product_key' ],
)
),
)
);
2017-05-03 11:37:36 +00:00
$activated = wp_remote_retrieve_response_code ( $request ) === 200 ;
2018-03-05 18:59:17 +00:00
$body = json_decode ( wp_remote_retrieve_body ( $request ), true );
2017-05-03 11:37:36 +00:00
if ( ! $activated && ! empty ( $body [ 'code' ] ) && 'already_connected' == $body [ 'code' ] ) {
$activated = true ;
}
if ( ! $activated ) {
2018-04-30 15:23:49 +00:00
self :: log ( 'Could not activate a subscription upon plugin activation: ' . $filename );
2017-05-03 11:37:36 +00:00
return ;
}
2017-07-10 05:56:28 +00:00
self :: log ( 'Auto-activated a subscription for ' . $filename );
2017-05-03 11:37:36 +00:00
self :: _flush_subscriptions_cache ();
2018-04-24 14:43:52 +00:00
self :: _flush_updates_cache ();
2017-05-03 11:37:36 +00:00
}
/**
* Runs when any plugin is deactivated .
*
* When a user deactivates a plugin , attempt to deactivate any subscriptions
* associated with the extension .
*
* @ param string $filename The filename of the deactivated plugin .
*/
public static function deactivated_plugin ( $filename ) {
$plugins = self :: get_local_woo_plugins ();
// Not a local woo plugin
if ( empty ( $plugins [ $filename ] ) ) {
return ;
}
// Make sure we have a connection.
$auth = WC_Helper_Options :: get ( 'auth' );
if ( empty ( $auth ) ) {
return ;
}
2018-03-05 18:59:17 +00:00
$plugin = $plugins [ $filename ];
2017-05-03 11:37:36 +00:00
$subscriptions = self :: _get_subscriptions_from_product_id ( $plugin [ '_product_id' ], false );
2018-03-05 18:59:17 +00:00
$site_id = absint ( $auth [ 'site_id' ] );
2017-05-03 11:37:36 +00:00
// No valid subscriptions for this product
if ( empty ( $subscriptions ) ) {
return ;
}
$deactivated = 0 ;
foreach ( $subscriptions as $subscription ) {
// Don't touch subscriptions that aren't activated on this site.
if ( ! in_array ( $site_id , $subscription [ 'connections' ] ) ) {
continue ;
}
2018-03-05 18:59:17 +00:00
$request = WC_Helper_API :: post (
'deactivate' , array (
'authenticated' => true ,
'body' => json_encode (
array (
'product_key' => $subscription [ 'product_key' ],
)
),
)
);
2017-05-03 11:37:36 +00:00
if ( wp_remote_retrieve_response_code ( $request ) === 200 ) {
$deactivated ++ ;
}
}
if ( $deactivated ) {
2017-07-10 05:56:28 +00:00
self :: log ( sprintf ( 'Auto-deactivated %d subscription(s) for %s' , $deactivated , $filename ) );
2017-05-03 11:37:36 +00:00
self :: _flush_subscriptions_cache ();
2018-04-24 14:43:52 +00:00
self :: _flush_updates_cache ();
2017-05-03 11:37:36 +00:00
}
}
2017-05-24 11:54:39 +00:00
/**
2017-12-13 16:31:38 +00:00
* Various Helper - related admin notices .
2017-05-24 11:54:39 +00:00
*/
public static function admin_notices () {
2017-12-13 16:31:38 +00:00
if ( apply_filters ( 'woocommerce_helper_suppress_admin_notices' , false ) ) {
return ;
}
2017-07-10 15:29:06 +00:00
$screen = get_current_screen ();
$screen_id = $screen ? $screen -> id : '' ;
2017-12-13 16:31:38 +00:00
self :: _prompt_helper_connect ( $screen_id );
2017-07-10 15:29:06 +00:00
if ( 'update-core' !== $screen_id ) {
2017-05-24 11:54:39 +00:00
return ;
}
// Don't nag if Woo doesn't have an update available.
if ( ! self :: _woo_core_update_available () ) {
return ;
}
2017-12-13 16:31:38 +00:00
// Add a note about available extension updates if Woo core has an update available.
2017-05-24 11:54:39 +00:00
$notice = self :: _get_extensions_update_notice ();
if ( ! empty ( $notice ) ) {
echo '<div class="updated woocommerce-message"><p>' . $notice . '</p></div>' ;
}
}
2017-12-13 16:31:38 +00:00
/**
* Prompt a Helper connection if the user has WooCommerce . com extensions .
2018-01-22 15:43:23 +00:00
*
* @ param string $screen_id Current screen ID .
2017-12-13 16:31:38 +00:00
*/
private static function _prompt_helper_connect ( $screen_id ) {
2018-04-03 18:42:01 +00:00
if ( apply_filters ( 'woocommerce_helper_suppress_connect_notice' , false ) ) {
return ;
}
2018-01-22 15:43:23 +00:00
$screens = wc_get_screen_ids ();
2018-01-19 17:58:36 +00:00
$screens [] = 'plugins' ;
2018-01-18 09:28:00 +00:00
2018-01-19 17:58:36 +00:00
if ( ! in_array ( $screen_id , $screens , true ) ) {
2018-01-18 09:28:00 +00:00
return ;
}
2017-12-13 16:31:38 +00:00
// Don't show the notice on the Helper screens.
2018-01-19 17:58:36 +00:00
$screen_addons = sanitize_title ( __ ( 'WooCommerce' , 'woocommerce' ) ) . '_page_wc-addons' ;
2018-01-22 15:43:23 +00:00
if ( $screen_addons === $screen_id && ! empty ( $_REQUEST [ 'section' ] ) && 'helper' === $_REQUEST [ 'section' ] ) {
2017-12-13 16:31:38 +00:00
return ;
}
2018-01-22 15:43:23 +00:00
// We believe we have an active connection.
2017-12-13 16:31:38 +00:00
$auth = WC_Helper_Options :: get ( 'auth' );
if ( ! empty ( $auth [ 'access_token' ] ) ) {
return ;
}
$active_plugins = apply_filters ( 'active_plugins' , get_option ( 'active_plugins' ) );
if ( empty ( $active_plugins ) ) {
return ;
}
$woo_plugins = self :: get_local_woo_plugins ();
if ( empty ( $woo_plugins ) ) {
return ;
}
$active_woo_plugins = array_intersect_key ( $woo_plugins , array_flip ( $active_plugins ) );
if ( count ( $active_woo_plugins ) > 0 ) {
/* translators: %s: helper screen url */
$notice = __ ( '<a href="%s">Connect your store</a> to WooCommerce.com to receive extensions updates and support.' , 'woocommerce' );
$notice = sprintf ( $notice , admin_url ( 'admin.php?page=wc-addons§ion=helper' ) );
echo '<div class="updated woocommerce-message"><p>' . $notice . '</p></div>' ;
}
}
2017-05-24 11:54:39 +00:00
/**
* Get an update notice if one or more Woo extensions has an update available .
*
* @ return string | null The update notice or null if everything is up to date .
*/
private static function _get_extensions_update_notice () {
2018-03-05 18:59:17 +00:00
$plugins = self :: get_local_woo_plugins ();
$updates = WC_Helper_Updater :: get_update_data ();
2017-05-24 11:54:39 +00:00
$available = 0 ;
foreach ( $plugins as $data ) {
if ( empty ( $updates [ $data [ '_product_id' ] ] ) ) {
continue ;
}
$product_id = $data [ '_product_id' ];
if ( version_compare ( $updates [ $product_id ][ 'version' ], $data [ 'Version' ], '>' ) ) {
$available ++ ;
}
}
if ( ! $available ) {
return ;
}
/* translators: %1$s: helper url, %2$d: number of extensions */
2018-03-05 18:59:17 +00:00
return sprintf (
_n ( 'Note: You currently have <a href="%1$s">%2$d paid extension</a> which should be updated first before updating WooCommerce.' , 'Note: You currently have <a href="%1$s">%2$d paid extensions</a> which should be updated first before updating WooCommerce.' , $available , 'woocommerce' ),
admin_url ( 'admin.php?page=wc-addons§ion=helper' ), $available
);
2017-05-24 11:54:39 +00:00
}
/**
* Whether WooCommerce has an update available .
*
* @ return bool True if a Woo core update is available .
*/
private static function _woo_core_update_available () {
$updates = get_site_transient ( 'update_plugins' );
if ( empty ( $updates -> response ) ) {
return false ;
}
if ( empty ( $updates -> response [ 'woocommerce/woocommerce.php' ] ) ) {
return false ;
}
$data = $updates -> response [ 'woocommerce/woocommerce.php' ];
if ( version_compare ( WC_VERSION , $data -> new_version , '>=' ) ) {
return false ;
}
return true ;
}
2017-04-26 15:50:38 +00:00
/**
* Flush subscriptions cache .
*/
2017-04-21 12:05:44 +00:00
private static function _flush_subscriptions_cache () {
delete_transient ( '_woocommerce_helper_subscriptions' );
}
2017-04-26 15:50:38 +00:00
/**
* Flush auth cache .
2017-06-14 13:12:53 +00:00
*
* @ access private
2017-04-26 15:50:38 +00:00
*/
2017-06-14 13:12:53 +00:00
public static function _flush_authentication_cache () {
2018-03-05 18:59:17 +00:00
$request = WC_Helper_API :: get (
'oauth/me' , array (
'authenticated' => true ,
)
);
2017-04-21 12:05:44 +00:00
if ( wp_remote_retrieve_response_code ( $request ) !== 200 ) {
return false ;
}
$user_data = json_decode ( wp_remote_retrieve_body ( $request ), true );
if ( ! $user_data ) {
return false ;
}
2018-03-05 18:59:17 +00:00
WC_Helper_Options :: update (
'auth_user_data' , array (
'name' => $user_data [ 'name' ],
'email' => $user_data [ 'email' ],
)
);
2017-04-21 12:05:44 +00:00
return true ;
}
2017-04-26 15:50:38 +00:00
/**
* Flush updates cache .
*/
2017-04-21 12:05:44 +00:00
private static function _flush_updates_cache () {
WC_Helper_Updater :: flush_updates_cache ();
}
2017-06-22 13:47:07 +00:00
/**
* Sort subscriptions by the product_name .
*
* @ param array $a Subscription array
* @ param array $b Subscription array
*
* @ return int
*/
public static function _sort_by_product_name ( $a , $b ) {
return strcmp ( $a [ 'product_name' ], $b [ 'product_name' ] );
}
/**
* Sort subscriptions by the Name .
*
* @ param array $a Product array
* @ param array $b Product array
*
* @ return int
*/
public static function _sort_by_name ( $a , $b ) {
return strcmp ( $a [ 'Name' ], $b [ 'Name' ] );
}
2017-04-21 12:05:44 +00:00
/**
* Log a helper event .
*
* @ param string $message Log message .
* @ param string $level Optional , defaults to info , valid levels :
* emergency | alert | critical | error | warning | notice | info | debug
*/
public static function log ( $message , $level = 'info' ) {
if ( ! defined ( 'WP_DEBUG' ) || ! WP_DEBUG ) {
return ;
}
if ( ! isset ( self :: $log ) ) {
self :: $log = wc_get_logger ();
}
self :: $log -> log ( $level , $message , array ( 'source' => 'helper' ) );
}
}
WC_Helper :: load ();