<?php
use Automattic\Jetpack\Constants;
if (!defined('ABSPATH')) {
exit;
}
class WC_Helper
{
public static $log;
public static function get_view_filename($view)
{
return dirname(__FILE__) . "/views/{$view}";
}
public static function load()
{
self::includes();
add_action('current_screen', array(__CLASS__, 'current_screen'));
add_action('woocommerce_helper_output', array(__CLASS__, 'render_helper_output'));
add_action('admin_enqueue_scripts', array(__CLASS__, 'admin_enqueue_scripts'));
add_action('admin_notices', array(__CLASS__, 'admin_notices'));
do_action('woocommerce_helper_loaded');
}
protected static function includes()
{
include_once dirname(__FILE__) . '/class-wc-helper-options.php';
include_once dirname(__FILE__) . '/class-wc-helper-api.php';
include_once dirname(__FILE__) . '/class-wc-helper-updater.php';
include_once dirname(__FILE__) . '/class-wc-helper-plugin-info.php';
include_once dirname(__FILE__) . '/class-wc-helper-compat.php';
}
public static function render_helper_output()
{
$auth = WC_Helper_Options::get('auth');
$auth_user_data = WC_Helper_Options::get('auth_user_data');
$notices = self::_get_return_notices();
if (empty($auth['access_token'])) {
$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');
return;
}
$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'));
$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'));
$woo_plugins = self::get_local_woo_plugins();
$woo_themes = self::get_local_woo_themes();
$site_id = absint($auth['site_id']);
$subscriptions = self::get_subscriptions();
$updates = WC_Helper_Updater::get_update_data();
$subscriptions_product_ids = wp_list_pluck($subscriptions, 'product_id');
foreach ($subscriptions as &$subscription) {
$subscription['active'] = in_array($site_id, $subscription['connections']);
$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'));
$subscription['local'] = array('installed' => false, 'active' => false, 'version' => null);
$subscription['update_url'] = admin_url('update-core.php');
$local = wp_list_filter(array_merge($woo_plugins, $woo_themes), array('_product_id' => $subscription['product_id']));
if (!empty($local)) {
$local = array_shift($local);
$subscription['local']['installed'] = true;
$subscription['local']['version'] = $local['Version'];
if ('plugin' == $local['_type']) {
if (is_plugin_active($local['_filename'])) {
$subscription['local']['active'] = true;
} elseif (is_multisite() && is_plugin_active_for_network($local['_filename'])) {
$subscription['local']['active'] = true;
}
$subscription['update_url'] = wp_nonce_url(self_admin_url('update.php?action=upgrade-plugin&plugin=') . $local['_filename'], 'upgrade-plugin_' . $local['_filename']);
} elseif ('theme' == $local['_type']) {
if (in_array($local['_stylesheet'], array(get_stylesheet(), get_template()))) {
$subscription['local']['active'] = true;
}
$subscription['update_url'] = wp_nonce_url(self_admin_url('update.php?action=upgrade-theme&theme=' . $local['_stylesheet']), 'upgrade-theme_' . $local['_stylesheet']);
}
}
$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'], '>');
}
$subscription['download_primary'] = true;
$subscription['download_url'] = 'https://woocommerce.com/my-account/downloads/';
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('message' => sprintf(__('Version %s is <strong>available</strong>.', 'woocommerce'), esc_html($updates[$subscription['product_id']]['version'])), 'button_label' => __('Update', 'woocommerce'), 'button_url' => $subscription['update_url'], 'status' => 'update-available', 'icon' => 'dashicons-update');
if (!$subscription['active']) {
$action['message'] .= ' ' . __('To enable this update you need to <strong>activate</strong> this subscription.', 'woocommerce');
$action['button_label'] = null;
$action['button_url'] = null;
}
$subscription['actions'][] = $action;
}
if ($subscription['has_update'] && $subscription['expired']) {
$action = array('message' => sprintf(__('Version %s is <strong>available</strong>.', 'woocommerce'), esc_html($updates[$subscription['product_id']]['version'])), 'status' => 'expired', 'icon' => 'dashicons-info');
$action['message'] .= ' ' . __('To enable this update you need to <strong>purchase</strong> a new subscription.', 'woocommerce');
$action['button_label'] = __('Purchase', 'woocommerce');
$action['button_url'] = $subscription['product_url'];
$subscription['actions'][] = $action;
} elseif ($subscription['expired'] && !empty($subscription['master_user_email'])) {
$action = array('message' => sprintf(__('This subscription has expired. Contact the owner to <strong>renew</strong> the subscription to receive updates and support.', 'woocommerce')), 'status' => 'expired', 'icon' => 'dashicons-info');
$subscription['actions'][] = $action;
} elseif ($subscription['expired']) {
$action = array('message' => sprintf(__('This subscription has expired. Please <strong>renew</strong> to receive updates and support.', 'woocommerce')), 'button_label' => __('Renew', 'woocommerce'), 'button_url' => 'https://woocommerce.com/my-account/my-subscriptions/', 'status' => 'expired', 'icon' => 'dashicons-info');
$subscription['actions'][] = $action;
}
if ($subscription['expiring'] && !$subscription['autorenew']) {
$action = array('message' => __('Subscription is <strong>expiring</strong> soon.', 'woocommerce'), 'button_label' => __('Enable auto-renew', 'woocommerce'), 'button_url' => 'https://woocommerce.com/my-account/my-subscriptions/', 'status' => 'expired', 'icon' => 'dashicons-info');
$subscription['download_primary'] = false;
$subscription['actions'][] = $action;
} elseif ($subscription['expiring']) {
$action = array('message' => sprintf(__('This subscription is expiring soon. Please <strong>renew</strong> to continue receiving updates and support.', 'woocommerce')), 'button_label' => __('Renew', 'woocommerce'), 'button_url' => 'https://woocommerce.com/my-account/my-subscriptions/', 'status' => 'expired', 'icon' => 'dashicons-info');
$subscription['download_primary'] = false;
$subscription['actions'][] = $action;
}
foreach ($subscription['actions'] as $key => $action) {
if (!empty($action['button_label'])) {
$subscription['actions'][$key]['primary'] = true;
break;
}
}
}
unset($subscription);
$no_subscriptions = array();
foreach (array_merge($woo_plugins, $woo_themes) as $filename => $data) {
if (in_array($data['_product_id'], $subscriptions_product_ids)) {
continue;
}
$data['_product_url'] = '#';
$data['_has_update'] = false;
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('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'])), 'button_label' => __('Purchase', 'woocommerce'), 'button_url' => $data['_product_url'], 'status' => 'expired', 'icon' => 'dashicons-info');
$data['_actions'][] = $action;
} else {
$action = array('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'), 'button_label' => __('Purchase', 'woocommerce'), 'button_url' => $data['_product_url'], 'status' => 'expired', 'icon' => 'dashicons-info');
$data['_actions'][] = $action;
}
$no_subscriptions[$filename] = $data;
}
if (empty($auth['user_id'])) {
$auth['user_id'] = get_current_user_id();
WC_Helper_Options::update('auth', $auth);
}
uasort($subscriptions, array(__CLASS__, '_sort_by_product_name'));
uasort($no_subscriptions, array(__CLASS__, '_sort_by_name'));
self::get_filters_counts($subscriptions);
self::_filter($subscriptions, self::get_current_filter());
include self::get_view_filename('html-main.php');
return;
}
public static function get_filters()
{
$filters = array('all' => __('All', 'woocommerce'), 'active' => __('Active', 'woocommerce'), 'inactive' => __('Inactive', 'woocommerce'), 'installed' => __('Installed', 'woocommerce'), 'update-available' => __('Update Available', 'woocommerce'), 'expiring' => __('Expiring Soon', 'woocommerce'), 'expired' => __('Expired', 'woocommerce'), 'download' => __('Download', 'woocommerce'));
return $filters;
}
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;
}
public static function get_current_filter()
{
$current_filter = 'all';
$valid_filters = array_keys(self::get_filters());
if (!empty($_GET['filter']) && in_array(wp_unslash($_GET['filter']), $valid_filters)) {
$current_filter = wc_clean(wp_unslash($_GET['filter']));
}
return $current_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 'installed':
foreach ($subscriptions as $key => $subscription) {
if (empty($subscription['local']['installed'])) {
unset($subscriptions[$key]);
}
}
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;
}
}
public static function admin_enqueue_scripts()
{
$screen = get_current_screen();
$screen_id = $screen ? $screen->id : '';
$wc_screen_id = sanitize_title(__('WooCommerce', 'woocommerce'));
if ($wc_screen_id . '_page_wc-addons' === $screen_id && isset($_GET['section']) && 'helper' === $_GET['section']) {
wp_enqueue_style('woocommerce-helper', WC()->plugin_url() . '/assets/css/helper.css', array(), Constants::get_constant('WC_VERSION'));
wp_style_add_data('woocommerce-helper', 'rtl', 'replace');
}
}
private static function _get_return_notices()
{
$return_status = isset($_GET['wc-helper-status']) ? wc_clean(wp_unslash($_GET['wc-helper-status'])) : null;
$notices = array();
switch ($return_status) {
case 'activate-success':
$product_id = isset($_GET['wc-helper-product-id']) ? absint($_GET['wc-helper-product-id']) : 0;
$subscription = self::_get_subscriptions_from_product_id($product_id);
$notices[] = array('type' => 'updated', 'message' => sprintf(__('%s activated successfully. You will now receive updates for this product.', 'woocommerce'), '<strong>' . esc_html($subscription['product_name']) . '</strong>'));
break;
case 'activate-error':
$product_id = isset($_GET['wc-helper-product-id']) ? absint($_GET['wc-helper-product-id']) : 0;
$subscription = self::_get_subscriptions_from_product_id($product_id);
$notices[] = array('type' => 'error', 'message' => sprintf(__('An error has occurred when activating %s. Please try again later.', 'woocommerce'), '<strong>' . esc_html($subscription['product_name']) . '</strong>'));
break;
case 'deactivate-success':
$product_id = isset($_GET['wc-helper-product-id']) ? absint($_GET['wc-helper-product-id']) : 0;
$subscription = self::_get_subscriptions_from_product_id($product_id);
$local = self::_get_local_from_product_id($product_id);
$message = sprintf(__('Subscription for %s deactivated successfully. You will no longer receive updates for this product.', 'woocommerce'), '<strong>' . esc_html($subscription['product_name']) . '</strong>');
if ($local && is_plugin_active($local['_filename']) && current_user_can('activate_plugins')) {
$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'));
$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));
}
$notices[] = array('message' => $message, 'type' => 'updated');
break;
case 'deactivate-error':
$product_id = isset($_GET['wc-helper-product-id']) ? absint($_GET['wc-helper-product-id']) : 0;
$subscription = self::_get_subscriptions_from_product_id($product_id);
$notices[] = array('type' => 'error', 'message' => sprintf(__('An error has occurred when deactivating the subscription for %s. Please try again later.', 'woocommerce'), '<strong>' . esc_html($subscription['product_name']) . '</strong>'));
break;
case 'deactivate-plugin-success':
$product_id = isset($_GET['wc-helper-product-id']) ? absint($_GET['wc-helper-product-id']) : 0;
$subscription = self::_get_subscriptions_from_product_id($product_id);
$notices[] = array('type' => 'updated', 'message' => sprintf(__('The extension %s has been deactivated successfully.', 'woocommerce'), '<strong>' . esc_html($subscription['product_name']) . '</strong>'));
break;
case 'deactivate-plugin-error':
$product_id = isset($_GET['wc-helper-product-id']) ? absint($_GET['wc-helper-product-id']) : 0;
$subscription = self::_get_subscriptions_from_product_id($product_id);
$notices[] = array('type' => 'error', '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')));
break;
case 'helper-connected':
$notices[] = array('message' => __('You have successfully connected your store to WooCommerce.com', 'woocommerce'), 'type' => 'updated');
break;
case 'helper-disconnected':
$notices[] = array('message' => __('You have successfully disconnected your store from WooCommerce.com', 'woocommerce'), 'type' => 'updated');
break;
case 'helper-refreshed':
$notices[] = array('message' => __('Authentication and subscription caches refreshed successfully.', 'woocommerce'), 'type' => 'updated');
break;
}
return $notices;
}
public static function current_screen($screen)
{
$wc_screen_id = sanitize_title(__('WooCommerce', 'woocommerce'));
if ($wc_screen_id . '_page_wc-addons' !== $screen->id) {
return;
}
if (empty($_GET['section']) || 'helper' !== $_GET['section']) {
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();
}
}
private static function _helper_auth_connect()
{
if (empty($_GET['wc-helper-nonce']) || !wp_verify_nonce(wp_unslash($_GET['wc-helper-nonce']), 'connect')) {
self::log('Could not verify nonce in _helper_auth_connect');
wp_die('Could not verify nonce');
}
$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'));
$request = WC_Helper_API::post('oauth/request_token', array('body' => array('home_url' => home_url(), 'redirect_uri' => $redirect_uri)));
$code = wp_remote_retrieve_response_code($request);
if (200 !== $code) {
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');
}
do_action('woocommerce_helper_connect_start');
$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'));
wp_redirect(esc_url_raw($connect_url));
die;
}
private static function _helper_auth_return()
{
if (empty($_GET['wc-helper-nonce']) || !wp_verify_nonce(wp_unslash($_GET['wc-helper-nonce']), 'connect')) {
self::log('Could not verify nonce in _helper_auth_return');
wp_die('Something went wrong');
}
if (!empty($_GET['deny'])) {
do_action('woocommerce_helper_denied');
wp_safe_redirect(admin_url('admin.php?page=wc-addons§ion=helper'));
die;
}
if (empty($_GET['request_token'])) {
self::log('Request token not found in _helper_auth_return');
wp_die('Something went wrong');
}
$request = WC_Helper_API::post('oauth/access_token', array('body' => array('request_token' => wp_unslash($_GET['request_token']), 'home_url' => home_url())));
$code = wp_remote_retrieve_response_code($request);
if (200 !== $code) {
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');
}
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()));
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();
self::_flush_updates_cache();
do_action('woocommerce_helper_connected');
if (class_exists('WC_Tracker')) {
update_option('woocommerce_allow_tracking', 'yes');
WC_Tracker::send_tracking_data(true);
}
if (!empty($_GET['wccom-install-url'])) {
wp_redirect(wp_unslash($_GET['wccom-install-url']));
exit;
}
wp_safe_redirect(add_query_arg(array('page' => 'wc-addons', 'section' => 'helper', 'wc-helper-status' => 'helper-connected'), admin_url('admin.php')));
die;
}
private static function _helper_auth_disconnect()
{
if (empty($_GET['wc-helper-nonce']) || !wp_verify_nonce(wp_unslash($_GET['wc-helper-nonce']), 'disconnect')) {
self::log('Could not verify nonce in _helper_auth_disconnect');
wp_die('Could not verify nonce');
}
do_action('woocommerce_helper_disconnected');
$redirect_uri = add_query_arg(array('page' => 'wc-addons', 'section' => 'helper', 'wc-helper-status' => 'helper-disconnected'), admin_url('admin.php'));
WC_Helper_API::post('oauth/invalidate_token', array('authenticated' => true));
WC_Helper_Options::update('auth', array());
WC_Helper_Options::update('auth_user_data', array());
self::_flush_subscriptions_cache();
self::_flush_updates_cache();
wp_safe_redirect($redirect_uri);
die;
}
private static function _helper_auth_refresh()
{
if (empty($_GET['wc-helper-nonce']) || !wp_verify_nonce(wp_unslash($_GET['wc-helper-nonce']), 'refresh')) {
self::log('Could not verify nonce in _helper_auth_refresh');
wp_die('Could not verify nonce');
}
do_action('woocommerce_helper_subscriptions_refresh');
$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'));
self::_flush_authentication_cache();
self::_flush_subscriptions_cache();
self::_flush_updates_cache();
wp_safe_redirect($redirect_uri);
die;
}
private static function _helper_subscription_activate()
{
$product_key = isset($_GET['wc-helper-product-key']) ? wc_clean(wp_unslash($_GET['wc-helper-product-key'])) : '';
$product_id = isset($_GET['wc-helper-product-id']) ? absint($_GET['wc-helper-product-id']) : 0;
if (empty($_GET['wc-helper-nonce']) || !wp_verify_nonce(wp_unslash($_GET['wc-helper-nonce']), 'activate:' . $product_key)) {
self::log('Could not verify nonce in _helper_subscription_activate');
wp_die('Could not verify nonce');
}
$activation_response = WC_Helper_API::post('activate', array('authenticated' => true, 'body' => wp_json_encode(array('product_key' => $product_key))));
$activated = wp_remote_retrieve_response_code($activation_response) === 200;
$body = json_decode(wp_remote_retrieve_body($activation_response), true);
if (!$activated && !empty($body['code']) && 'already_connected' === $body['code']) {
$activated = true;
}
if ($activated) {
do_action('woocommerce_helper_subscription_activate_success', $product_id, $product_key, $activation_response);
} else {
do_action('woocommerce_helper_subscription_activate_error', $product_id, $product_key, $activation_response);
}
$local = self::_get_local_from_product_id($product_id);
if ($local && 'plugin' == $local['_type'] && current_user_can('activate_plugins') && !is_plugin_active($local['_filename'])) {
activate_plugin($local['_filename']);
}
self::_flush_subscriptions_cache();
self::_flush_updates_cache();
$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'));
wp_safe_redirect($redirect_uri);
die;
}
private static function _helper_subscription_deactivate()
{
$product_key = isset($_GET['wc-helper-product-key']) ? wc_clean(wp_unslash($_GET['wc-helper-product-key'])) : '';
$product_id = isset($_GET['wc-helper-product-id']) ? absint($_GET['wc-helper-product-id']) : 0;
if (empty($_GET['wc-helper-nonce']) || !wp_verify_nonce(wp_unslash($_GET['wc-helper-nonce']), 'deactivate:' . $product_key)) {
self::log('Could not verify nonce in _helper_subscription_deactivate');
wp_die('Could not verify nonce');
}
$deactivation_response = WC_Helper_API::post('deactivate', array('authenticated' => true, 'body' => wp_json_encode(array('product_key' => $product_key))));
$code = wp_remote_retrieve_response_code($deactivation_response);
$deactivated = 200 === $code;
if ($deactivated) {
do_action('woocommerce_helper_subscription_deactivate_success', $product_id, $product_key, $deactivation_response);
} else {
self::log(sprintf('Deactivate API call returned a non-200 response code (%d)', $code));
do_action('woocommerce_helper_subscription_deactivate_error', $product_id, $product_key, $deactivation_response);
}
self::_flush_subscriptions_cache();
$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'));
wp_safe_redirect($redirect_uri);
die;
}
private static function _helper_plugin_deactivate()
{
$product_id = isset($_GET['wc-helper-product-id']) ? absint($_GET['wc-helper-product-id']) : 0;
$deactivated = false;
if (empty($_GET['wc-helper-nonce']) || !wp_verify_nonce(wp_unslash($_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.');
}
$local = wp_list_filter(array_merge(self::get_local_woo_plugins(), self::get_local_woo_themes()), array('_product_id' => $product_id));
if (!empty($local)) {
$local = array_shift($local);
if (is_plugin_active($local['_filename'])) {
deactivate_plugins($local['_filename']);
}
$deactivated = !is_plugin_active($local['_filename']);
}
$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'));
wp_safe_redirect($redirect_uri);
die;
}
private static function _get_local_from_product_id($product_id)
{
$local = wp_list_filter(array_merge(self::get_local_woo_plugins(), self::get_local_woo_themes()), array('_product_id' => $product_id));
if (!empty($local)) {
return array_shift($local);
}
return false;
}
public static function has_product_subscription($product_id)
{
$subscription = self::_get_subscriptions_from_product_id($product_id, true);
return !empty($subscription);
}
private static function _get_subscriptions_from_product_id($product_id, $single = true)
{
$subscriptions = wp_list_filter(self::get_subscriptions(), array('product_id' => $product_id));
if (!empty($subscriptions)) {
return $single ? array_shift($subscriptions) : $subscriptions;
}
return false;
}
public static function get_local_woo_plugins()
{
if (!function_exists('get_plugins')) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
$plugins = get_plugins();
if (!empty($plugins) && !array_key_exists('Woo', current($plugins))) {
wp_clean_plugins_cache(false);
$plugins = get_plugins();
}
$woo_plugins = array();
$_compat = array();
if (!empty($GLOBALS['woothemes_queued_updates'])) {
foreach ($GLOBALS['woothemes_queued_updates'] as $_compat_plugin) {
$_compat[$_compat_plugin->file] = array('product_id' => $_compat_plugin->product_id, 'file_id' => $_compat_plugin->file_id);
}
}
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;
}
$data['_filename'] = $filename;
$data['_product_id'] = absint($product_id);
$data['_file_id'] = $file_id;
$data['_type'] = 'plugin';
$data['slug'] = dirname($filename);
$woo_plugins[$filename] = $data;
}
return $woo_plugins;
}
public static function get_local_woo_themes()
{
$themes = wp_get_themes();
$woo_themes = array();
foreach ($themes as $theme) {
$header = $theme->get('Woo');
if (!$header) {
$txt = $theme->get_stylesheet_directory() . '/theme_info.txt';
if (is_readable($txt)) {
$txt = file_get_contents($txt);
$txt = preg_split('#\\s#', $txt);
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('Name' => $theme->get('Name'), 'Version' => $theme->get('Version'), 'Woo' => $header, '_filename' => $theme->get_stylesheet() . '/style.css', '_stylesheet' => $theme->get_stylesheet(), '_product_id' => absint($product_id), '_file_id' => $file_id, '_type' => 'theme');
$woo_themes[$data['_filename']] = $data;
}
return $woo_themes;
}
public static function get_subscriptions()
{
$cache_key = '_woocommerce_helper_subscriptions';
$data = get_transient($cache_key);
if (false !== $data) {
return $data;
}
$request = WC_Helper_API::get('subscriptions', array('authenticated' => true));
if (wp_remote_retrieve_response_code($request) !== 200) {
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;
}
public static function activated_plugin($filename)
{
$plugins = self::get_local_woo_plugins();
if (empty($plugins[$filename])) {
return;
}
$auth = WC_Helper_Options::get('auth');
if (empty($auth)) {
return;
}
$plugin = $plugins[$filename];
$product_id = $plugin['_product_id'];
$subscriptions = self::_get_subscriptions_from_product_id($product_id, false);
if (empty($subscriptions)) {
return;
}
$subscription = null;
foreach ($subscriptions as $_sub) {
if ($_sub['expired']) {
continue;
}
if ($_sub['sites_max'] && $_sub['sites_active'] >= $_sub['sites_max']) {
continue;
}
$subscription = $_sub;
break;
}
if (!$subscription) {
return;
}
$product_key = $subscription['product_key'];
$activation_response = WC_Helper_API::post('activate', array('authenticated' => true, 'body' => wp_json_encode(array('product_key' => $product_key))));
$activated = wp_remote_retrieve_response_code($activation_response) === 200;
$body = json_decode(wp_remote_retrieve_body($activation_response), true);
if (!$activated && !empty($body['code']) && 'already_connected' === $body['code']) {
$activated = true;
}
if ($activated) {
self::log('Auto-activated a subscription for ' . $filename);
do_action('woocommerce_helper_subscription_activate_success', $product_id, $product_key, $activation_response);
} else {
self::log('Could not activate a subscription upon plugin activation: ' . $filename);
do_action('woocommerce_helper_subscription_activate_error', $product_id, $product_key, $activation_response);
}
self::_flush_subscriptions_cache();
self::_flush_updates_cache();
}
public static function deactivated_plugin($filename)
{
$plugins = self::get_local_woo_plugins();
if (empty($plugins[$filename])) {
return;
}
$auth = WC_Helper_Options::get('auth');
if (empty($auth)) {
return;
}
$plugin = $plugins[$filename];
$product_id = $plugin['_product_id'];
$subscriptions = self::_get_subscriptions_from_product_id($product_id, false);
$site_id = absint($auth['site_id']);
if (empty($subscriptions)) {
return;
}
$deactivated = 0;
foreach ($subscriptions as $subscription) {
if (!in_array($site_id, $subscription['connections'], true)) {
continue;
}
$product_key = $subscription['product_key'];
$deactivation_response = WC_Helper_API::post('deactivate', array('authenticated' => true, 'body' => wp_json_encode(array('product_key' => $product_key))));
if (wp_remote_retrieve_response_code($deactivation_response) === 200) {
$deactivated++;
do_action('woocommerce_helper_subscription_deactivate_success', $product_id, $product_key, $deactivation_response);
} else {
do_action('woocommerce_helper_subscription_deactivate_error', $product_id, $product_key, $deactivation_response);
}
}
if ($deactivated) {
self::log(sprintf('Auto-deactivated %d subscription(s) for %s', $deactivated, $filename));
self::_flush_subscriptions_cache();
self::_flush_updates_cache();
}
}
public static function admin_notices()
{
if (apply_filters('woocommerce_helper_suppress_admin_notices', false)) {
return;
}
$screen = get_current_screen();
$screen_id = $screen ? $screen->id : '';
if ('update-core' !== $screen_id) {
return;
}
if (!self::_woo_core_update_available()) {
return;
}
$notice = self::_get_extensions_update_notice();
if (!empty($notice)) {
echo '<div class="updated woocommerce-message"><p>' . $notice . '</p></div>';
}
}
private static function _get_extensions_update_notice()
{
$plugins = self::get_local_woo_plugins();
$updates = WC_Helper_Updater::get_update_data();
$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;
}
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);
}
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(Constants::get_constant('WC_VERSION'), $data->new_version, '>=')) {
return false;
}
return true;
}
public static function _flush_subscriptions_cache()
{
delete_transient('_woocommerce_helper_subscriptions');
}
public static function _flush_authentication_cache()
{
$request = WC_Helper_API::get('oauth/me', array('authenticated' => true));
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;
}
WC_Helper_Options::update('auth_user_data', array('name' => $user_data['name'], 'email' => $user_data['email']));
return true;
}
private static function _flush_updates_cache()
{
WC_Helper_Updater::flush_updates_cache();
}
public static function _sort_by_product_name($a, $b)
{
return strcmp($a['product_name'], $b['product_name']);
}
public static function _sort_by_name($a, $b)
{
return strcmp($a['Name'], $b['Name']);
}
public static function log($message, $level = 'info')
{
if (!Constants::is_true('WP_DEBUG')) {
return;
}
if (!isset(self::$log)) {
self::$log = wc_get_logger();
}
self::$log->log($level, $message, array('source' => 'helper'));
}
}
WC_Helper::load();