<?php use Automattic\Jetpack\Constants; if (!defined('ABSPATH')) { exit; } class WC_Admin_Addons { public static function get_featured() { $featured = get_transient('wc_addons_featured'); if (false === $featured) { $headers = array(); $auth = WC_Helper_Options::get('auth'); if (!empty($auth['access_token'])) { $headers['Authorization'] = 'Bearer ' . $auth['access_token']; } $raw_featured = wp_safe_remote_get('https://woocommerce.com/wp-json/wccom-extensions/1.0/featured', array('headers' => $headers, 'user-agent' => 'WooCommerce Addons Page')); if (!is_wp_error($raw_featured)) { $featured = json_decode(wp_remote_retrieve_body($raw_featured)); if ($featured) { set_transient('wc_addons_featured', $featured, DAY_IN_SECONDS); } } } if (is_object($featured)) { self::output_featured_sections($featured->sections); return $featured; } } public static function build_parameter_string($category, $term, $country) { $parameters = array('category' => $category, 'term' => $term, 'country' => $country); return '?' . http_build_query($parameters); } public static function get_extension_data($category, $term, $country) { $parameters = self::build_parameter_string($category, $term, $country); $headers = array(); $auth = WC_Helper_Options::get('auth'); if (!empty($auth['access_token'])) { $headers['Authorization'] = 'Bearer ' . $auth['access_token']; } $raw_extensions = wp_safe_remote_get('https://woocommerce.com/wp-json/wccom-extensions/1.0/search' . $parameters, array('headers' => $headers)); if (!is_wp_error($raw_extensions)) { $addons = json_decode(wp_remote_retrieve_body($raw_extensions))->products; } return $addons; } public static function get_sections() { $addon_sections = get_transient('wc_addons_sections'); if (false === $addon_sections) { $raw_sections = wp_safe_remote_get('https://woocommerce.com/wp-json/wccom-extensions/1.0/categories'); if (!is_wp_error($raw_sections)) { $addon_sections = json_decode(wp_remote_retrieve_body($raw_sections)); if ($addon_sections) { set_transient('wc_addons_sections', $addon_sections, WEEK_IN_SECONDS); } } } return apply_filters('woocommerce_addons_sections', $addon_sections); } public static function get_section($section_id) { $sections = self::get_sections(); if (isset($sections[$section_id])) { return $sections[$section_id]; } return false; } public static function get_section_data($section_id) { $section = self::get_section($section_id); $section_data = ''; if (!empty($section->endpoint)) { $section_data = get_transient('wc_addons_section_' . $section_id); if (false === $section_data) { $raw_section = wp_safe_remote_get(esc_url_raw($section->endpoint), array('user-agent' => 'WooCommerce Addons Page')); if (!is_wp_error($raw_section)) { $section_data = json_decode(wp_remote_retrieve_body($raw_section)); if (!empty($section_data->products)) { set_transient('wc_addons_section_' . $section_id, $section_data, WEEK_IN_SECONDS); } } } } return apply_filters('woocommerce_addons_section_data', $section_data->products, $section_id); } public static function output_storefront_button() { $template = get_option('template'); $stylesheet = get_option('stylesheet'); if ('storefront' === $template) { if ('storefront' === $stylesheet) { $url = 'https://woocommerce.com/product-category/themes/storefront-child-theme-themes/'; $text = __('Need a fresh look? Try Storefront child themes', 'woocommerce'); $utm_content = 'nostorefrontchildtheme'; } else { $url = 'https://woocommerce.com/product-category/themes/storefront-child-theme-themes/'; $text = __('View more Storefront child themes', 'woocommerce'); $utm_content = 'hasstorefrontchildtheme'; } } else { $url = 'https://woocommerce.com/storefront/'; $text = __('Need a theme? Try Storefront', 'woocommerce'); $utm_content = 'nostorefront'; } $url = add_query_arg(array('utm_source' => 'addons', 'utm_medium' => 'product', 'utm_campaign' => 'woocommerceplugin', 'utm_content' => $utm_content), $url); echo '<a href="' . esc_url($url) . '" class="add-new-h2">' . esc_html($text) . '</a>' . "\n"; } public static function output_banner_block($block) { ?> <div class="addons-banner-block"> <h1><?php echo esc_html($block->title); ?></h1> <p><?php echo esc_html($block->description); ?></p> <div class="addons-banner-block-items"> <?php foreach ($block->items as $item) { ?> <?php if (self::show_extension($item)) { ?> <div class="addons-banner-block-item"> <div class="addons-banner-block-item-icon"> <img class="addons-img" src="<?php echo esc_url($item->image); ?>" /> </div> <div class="addons-banner-block-item-content"> <h3><?php echo esc_html($item->title); ?></h3> <p><?php echo esc_html($item->description); ?></p> <?php self::output_button($item->href, $item->button, 'addons-button-solid', $item->plugin); ?> </div> </div> <?php } ?> <?php } ?> </div> </div> <?php } public static function output_column($block) { if (isset($block->container) && 'column_container_start' === $block->container) { ?> <div class="addons-column-section"> <?php } if ('column_start' === $block->module) { ?> <div class="addons-column"> <?php } else { ?> </div> <?php } if (isset($block->container) && 'column_container_end' === $block->container) { ?> </div> <?php } } public static function output_column_block($block) { ?> <div class="addons-column-block"> <h1><?php echo esc_html($block->title); ?></h1> <p><?php echo esc_html($block->description); ?></p> <?php foreach ($block->items as $item) { ?> <?php if (self::show_extension($item)) { ?> <div class="addons-column-block-item"> <div class="addons-column-block-item-icon"> <img class="addons-img" src="<?php echo esc_url($item->image); ?>" /> </div> <div class="addons-column-block-item-content"> <h2><?php echo esc_html($item->title); ?></h2> <?php self::output_button($item->href, $item->button, 'addons-button-solid', $item->plugin); ?> <p><?php echo esc_html($item->description); ?></p> </div> </div> <?php } ?> <?php } ?> </div> <?php } public static function output_small_light_block($block) { ?> <div class="addons-small-light-block"> <img class="addons-img" src="<?php echo esc_url($block->image); ?>" /> <div class="addons-small-light-block-content"> <h1><?php echo esc_html($block->title); ?></h1> <p><?php echo esc_html($block->description); ?></p> <div class="addons-small-light-block-buttons"> <?php foreach ($block->buttons as $button) { ?> <?php self::output_button($button->href, $button->text, 'addons-button-solid'); ?> <?php } ?> </div> </div> </div> <?php } public static function output_small_dark_block($block) { ?> <div class="addons-small-dark-block"> <h1><?php echo esc_html($block->title); ?></h1> <p><?php echo esc_html($block->description); ?></p> <div class="addons-small-dark-items"> <?php foreach ($block->items as $item) { ?> <div class="addons-small-dark-item"> <?php if (!empty($item->image)) { ?> <div class="addons-small-dark-item-icon"> <img class="addons-img" src="<?php echo esc_url($item->image); ?>" /> </div> <?php } ?> <?php self::output_button($item->href, $item->button, 'addons-button-outline-white'); ?> </div> <?php } ?> </div> </div> <?php } public static function output_wcs_banner_block($block = array()) { $is_active = is_plugin_active('woocommerce-services/woocommerce-services.php'); $location = wc_get_base_location(); if (!in_array($location['country'], array('US'), true) || $is_active || !current_user_can('install_plugins') || !current_user_can('activate_plugins')) { return; } $button_url = wp_nonce_url(add_query_arg(array('install-addon' => 'woocommerce-services')), 'install-addon_woocommerce-services'); $defaults = array('image' => WC()->plugin_url() . '/assets/images/wcs-extensions-banner-3x.jpg', 'image_alt' => __('WooCommerce Shipping', 'woocommerce'), 'title' => __('Save time and money with WooCommerce Shipping', 'woocommerce'), 'description' => __('Print discounted USPS and DHL labels straight from your WooCommerce dashboard and save on shipping.', 'woocommerce'), 'button' => __('Free - Install now', 'woocommerce'), 'href' => $button_url, 'logos' => array()); switch ($location['country']) { case 'US': $local_defaults = array('logos' => array_merge($defaults['logos'], array(array('link' => WC()->plugin_url() . '/assets/images/wcs-usps-logo.png', 'alt' => 'USPS logo'), array('link' => WC()->plugin_url() . '/assets/images/wcs-dhlexpress-logo.png', 'alt' => 'DHL Express logo')))); break; default: $local_defaults = array(); } $block_data = array_merge($defaults, $local_defaults, $block); ?> <div class="addons-wcs-banner-block"> <div class="addons-wcs-banner-block-image is-full-image"> <img class="addons-img" src="<?php echo esc_url($block_data['image']); ?>" alt="<?php echo esc_attr($block_data['image_alt']); ?>" /> </div> <div class="addons-wcs-banner-block-content"> <h1><?php echo esc_html($block_data['title']); ?></h1> <p><?php echo esc_html($block_data['description']); ?></p> <ul class="wcs-logos-container"> <?php foreach ($block_data['logos'] as $logo) { ?> <li> <img alt="<?php echo esc_attr($logo['alt']); ?>" class="wcs-service-logo" src="<?php echo esc_url($logo['link']); ?>" > </li> <?php } ?> </ul> <?php self::output_button($block_data['href'], $block_data['button'], 'addons-button-outline-purple'); ?> </div> </div> <?php } public static function output_wcpay_banner_block($block = array()) { $is_active = is_plugin_active('woocommerce-payments/woocommerce-payments.php'); $location = wc_get_base_location(); if (!in_array($location['country'], array('US'), true) || $is_active || !current_user_can('install_plugins') || !current_user_can('activate_plugins')) { return; } $button_url = wp_nonce_url(add_query_arg(array('install-addon' => 'woocommerce-payments')), 'install-addon_woocommerce-payments'); $defaults = array('image' => WC()->plugin_url() . '/assets/images/wcpayments-icon-secure.png', 'image_alt' => __('WooCommerce Payments', 'woocommerce'), 'title' => __('Payments made simple, with no monthly fees &mdash; exclusively for WooCommerce stores.', 'woocommerce'), 'description' => __('Securely accept cards in your store. See payments, track cash flow into your bank account, and stay on top of disputes – right from your dashboard.', 'woocommerce'), 'button' => __('Free - Install now', 'woocommerce'), 'href' => $button_url, 'logos' => array()); $block_data = array_merge($defaults, $block); ?> <div class="addons-wcs-banner-block"> <div class="addons-wcs-banner-block-image"> <img class="addons-img" src="<?php echo esc_url($block_data['image']); ?>" alt="<?php echo esc_attr($block_data['image_alt']); ?>" /> </div> <div class="addons-wcs-banner-block-content"> <h1><?php echo esc_html($block_data['title']); ?></h1> <p><?php echo esc_html($block_data['description']); ?></p> <?php self::output_button($block_data['href'], $block_data['button'], 'addons-button-outline-purple'); ?> </div> </div> <?php } public static function output_promotion_block($section) { if (!current_user_can('install_plugins') || !current_user_can('activate_plugins')) { return; } $section_object = (object) $section; if (!empty($section_object->geowhitelist)) { $section_object->geowhitelist = explode(',', $section_object->geowhitelist); } if (!empty($section_object->geoblacklist)) { $section_object->geoblacklist = explode(',', $section_object->geoblacklist); } if (!self::show_extension($section_object)) { return; } ?> <div class="addons-banner-block addons-promotion-block"> <img class="addons-img" src="<?php echo esc_url($section['image']); ?>" alt="<?php echo esc_attr($section['image_alt']); ?>" /> <div class="addons-promotion-block-content"> <h1 class="addons-promotion-block-title"><?php echo esc_html($section['title']); ?></h1> <div class="addons-promotion-block-description"> <?php echo wp_kses_post($section['description']); ?> </div> <div class="addons-promotion-block-buttons"> <?php if ($section['button_1']) { self::output_button($section['button_1_href'], $section['button_1'], 'addons-button-expandable addons-button-solid', $section['plugin']); } if ($section['button_2']) { self::output_button($section['button_2_href'], $section['button_2'], 'addons-button-expandable addons-button-outline-purple', $section['plugin']); } ?> </div> </div> </div> <?php } public static function output_featured_sections($sections) { foreach ($sections as $section) { switch ($section->module) { case 'banner_block': self::output_banner_block($section); break; case 'column_start': self::output_column($section); break; case 'column_end': self::output_column($section); break; case 'column_block': self::output_column_block($section); break; case 'small_light_block': self::output_small_light_block($section); break; case 'small_dark_block': self::output_small_dark_block($section); break; case 'wcs_banner_block': self::output_wcs_banner_block((array) $section); break; case 'wcpay_banner_block': self::output_wcpay_banner_block((array) $section); break; case 'promotion_block': self::output_promotion_block((array) $section); break; } } } public static function get_in_app_purchase_url_params() { $back_admin_path = add_query_arg(array()); return array('wccom-site' => site_url(), 'wccom-back' => rawurlencode($back_admin_path), 'wccom-woo-version' => Constants::get_constant('WC_VERSION'), 'wccom-connect-nonce' => wp_create_nonce('connect')); } public static function add_in_app_purchase_url_params($url) { return add_query_arg(self::get_in_app_purchase_url_params(), $url); } public static function output_button($url, $text, $style, $plugin = '') { $style = __('Free', 'woocommerce') === $text ? 'addons-button-outline-purple' : $style; $style = is_plugin_active($plugin) ? 'addons-button-installed' : $style; $text = is_plugin_active($plugin) ? __('Installed', 'woocommerce') : $text; $url = self::add_in_app_purchase_url_params($url); ?> <a class="addons-button <?php echo esc_attr($style); ?>" href="<?php echo esc_url($url); ?>"> <?php echo esc_html($text); ?> </a> <?php } public static function output() { $section = isset($_GET['section']) ? sanitize_text_field(wp_unslash($_GET['section'])) : '_featured'; $search = isset($_GET['search']) ? sanitize_text_field(wp_unslash($_GET['search'])) : ''; if (isset($_GET['section']) && 'helper' === $_GET['section']) { do_action('woocommerce_helper_output'); return; } if (isset($_GET['install-addon'])) { switch ($_GET['install-addon']) { case 'woocommerce-services': self::install_woocommerce_services_addon(); break; case 'woocommerce-payments': self::install_woocommerce_payments_addon($section); break; default: break; } } $sections = self::get_sections(); $theme = wp_get_theme(); $current_section = isset($_GET['section']) ? $section : '_featured'; $addons = array(); if ('_featured' !== $current_section) { $category = $section ? $section : null; $term = $search ? $search : null; $country = WC()->countries->get_base_country(); $addons = self::get_extension_data($category, $term, $country); } include_once dirname(__FILE__) . '/views/html-admin-page-addons.php'; } public static function install_woocommerce_services_addon() { check_admin_referer('install-addon_woocommerce-services'); $services_plugin_id = 'woocommerce-services'; $services_plugin = array('name' => __('WooCommerce Services', 'woocommerce'), 'repo-slug' => 'woocommerce-services'); WC_Install::background_installer($services_plugin_id, $services_plugin); wp_safe_redirect(remove_query_arg(array('install-addon', '_wpnonce'))); exit; } public static function install_woocommerce_payments_addon($section = '_featured') { check_admin_referer('install-addon_woocommerce-payments'); $wcpay_plugin_id = 'woocommerce-payments'; $wcpay_plugin = array('name' => __('WooCommerce Payments', 'woocommerce'), 'repo-slug' => 'woocommerce-payments'); WC_Install::background_installer($wcpay_plugin_id, $wcpay_plugin); do_action('woocommerce_addon_installed', $wcpay_plugin_id, $section); wp_safe_redirect(remove_query_arg(array('install-addon', '_wpnonce'))); exit; } public static function show_extension($item) { $location = WC()->countries->get_base_country(); if (isset($item->geowhitelist) && !in_array($location, $item->geowhitelist, true)) { return false; } if (isset($item->geoblacklist) && in_array($location, $item->geoblacklist, true)) { return false; } if (is_plugin_active($item->plugin)) { return false; } return true; } public static function filter_admin_body_classes(string $admin_body_class = '') : string { if (isset($_GET['section']) && 'helper' === $_GET['section']) { return " {$admin_body_class} woocommerce-page-wc-subscriptions "; } return " {$admin_body_class} woocommerce-page-wc-marketplace "; } }