Файловый менеджер - Редактировать - /home/infrafs/INFRABIKEIT/wp-content/plugins/inc.tar
Назад
class-envato-market-github.php 0000644 00000023041 15132720601 0012412 0 ustar 00 <?php /** * Envato Market Github class. * * @package Envato_Market */ if ( ! class_exists( 'Envato_Market_Github' ) ) : /** * Creates the connection between Github to install & update the Envato Market plugin. * * @class Envato_Market_Github * @version 1.0.0 * @since 1.0.0 */ class Envato_Market_Github { /** * Action nonce. * * @type string */ const AJAX_ACTION = 'envato_market_dismiss_notice'; /** * The single class instance. * * @since 1.0.0 * @access private * * @var object */ private static $_instance = null; /** * The API URL. * * @since 1.0.0 * @access private * * @var string */ private static $api_url = 'https://envato.github.io/wp-envato-market/dist/update-check.json'; /** * The Envato_Market_Items Instance * * Ensures only one instance of this class exists in memory at any one time. * * @see Envato_Market_Github() * @uses Envato_Market_Github::init_actions() Setup hooks and actions. * * @since 1.0.0 * @static * @return object The one true Envato_Market_Github. * @codeCoverageIgnore */ public static function instance() { if ( is_null( self::$_instance ) ) { self::$_instance = new self(); self::$_instance->init_actions(); } return self::$_instance; } /** * A dummy constructor to prevent this class from being loaded more than once. * * @see Envato_Market_Github::instance() * * @since 1.0.0 * @access private * @codeCoverageIgnore */ private function __construct() { /* We do nothing here! */ } /** * You cannot clone this class. * * @since 1.0.0 * @codeCoverageIgnore */ public function __clone() { _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'envato-market' ), '1.0.0' ); } /** * You cannot unserialize instances of this class. * * @since 1.0.0 * @codeCoverageIgnore */ public function __wakeup() { _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'envato-market' ), '1.0.0' ); } /** * Setup the actions and filters. * * @uses add_action() To add actions. * @uses add_filter() To add filters. * * @since 1.0.0 */ public function init_actions() { // Bail outside of the WP Admin panel. if ( ! is_admin() ) { return; } add_filter( 'http_request_args', array( $this, 'update_check' ), 5, 2 ); add_filter( 'plugins_api', array( $this, 'plugins_api' ), 10, 3 ); add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'update_plugins' ) ); add_filter( 'pre_set_transient_update_plugins', array( $this, 'update_plugins' ) ); add_filter( 'site_transient_update_plugins', array( $this, 'update_state' ) ); add_filter( 'transient_update_plugins', array( $this, 'update_state' ) ); add_action( 'admin_notices', array( $this, 'notice' ) ); add_action( 'wp_ajax_' . self::AJAX_ACTION, array( $this, 'dismiss_notice' ) ); } /** * Check Github for an update. * * @since 1.0.0 * * @return false|object */ public function api_check() { $raw_response = wp_remote_get( self::$api_url ); if ( is_wp_error( $raw_response ) ) { return false; } if ( ! empty( $raw_response['body'] ) ) { $raw_body = json_decode( $raw_response['body'], true ); if ( $raw_body ) { return (object) $raw_body; } } return false; } /** * Disables requests to the wp.org repository for Envato Market. * * @since 1.0.0 * * @param array $request An array of HTTP request arguments. * @param string $url The request URL. * @return array */ public function update_check( $request, $url ) { // Plugin update request. if ( false !== strpos( $url, '//api.wordpress.org/plugins/update-check/1.1/' ) ) { // Decode JSON so we can manipulate the array. $data = json_decode( $request['body']['plugins'] ); // Remove the Envato Market. unset( $data->plugins->{'envato-market/envato-market.php'} ); // Encode back into JSON and update the response. $request['body']['plugins'] = wp_json_encode( $data ); } return $request; } /** * API check. * * @since 1.0.0 * * @param bool $api Always false. * @param string $action The API action being performed. * @param object $args Plugin arguments. * @return mixed $api The plugin info or false. */ public function plugins_api( $api, $action, $args ) { if ( isset( $args->slug ) && 'envato-market' === $args->slug ) { $api_check = $this->api_check(); if ( is_object( $api_check ) ) { $api = $api_check; } } return $api; } /** * Update check. * * @since 1.0.0 * * @param object $transient The pre-saved value of the `update_plugins` site transient. * @return object */ public function update_plugins( $transient ) { $state = $this->state(); if ( 'activated' === $state ) { $api_check = $this->api_check(); if ( is_object( $api_check ) && version_compare( envato_market()->get_version(), $api_check->version, '<' ) ) { $transient->response['envato-market/envato-market.php'] = (object) array( 'slug' => 'envato-market', 'plugin' => 'envato-market/envato-market.php', 'new_version' => $api_check->version, 'url' => 'https://github.com/envato/wp-envato-market', 'package' => $api_check->download_link, ); } } return $transient; } /** * Set the plugin state. * * @since 1.0.0 * * @return string */ public function state() { $option = 'envato_market_state'; $active_plugins = apply_filters( 'active_plugins', get_option( 'active_plugins' ) ); // We also have to check network activated plugins. Otherwise this plugin won't update on multisite. $active_sitewide_plugins = get_site_option( 'active_sitewide_plugins' ); if ( ! is_array( $active_plugins ) ) { $active_plugins = array(); } if ( ! is_array( $active_sitewide_plugins ) ) { $active_sitewide_plugins = array(); } $active_plugins = array_merge( $active_plugins, array_keys( $active_sitewide_plugins ) ); if ( in_array( 'envato-market/envato-market.php', $active_plugins ) ) { $state = 'activated'; update_option( $option, $state ); } else { $state = 'install'; update_option( $option, $state ); foreach ( array_keys( get_plugins() ) as $plugin ) { if ( strpos( $plugin, 'envato-market.php' ) !== false ) { $state = 'deactivated'; update_option( $option, $state ); } } } return $state; } /** * Force the plugin state to be updated. * * @since 1.0.0 * * @param object $transient The saved value of the `update_plugins` site transient. * @return object */ public function update_state( $transient ) { $state = $this->state(); return $transient; } /** * Admin notices. * * @since 1.0.0 * * @return string */ public function notice() { $screen = get_current_screen(); $slug = 'envato-market'; $state = get_option( 'envato_market_state' ); $notice = get_option( self::AJAX_ACTION ); if ( empty( $state ) ) { $state = $this->state(); } if ( 'activated' === $state || 'update-core' === $screen->id || 'update' === $screen->id || 'plugins' === $screen->id && isset( $_GET['action'] ) && 'delete-selected' === $_GET['action'] || 'dismissed' === $notice ) { return; } if ( 'deactivated' === $state ) { $activate_url = add_query_arg( array( 'action' => 'activate', 'plugin' => urlencode( "$slug/$slug.php" ), '_wpnonce' => urlencode( wp_create_nonce( "activate-plugin_$slug/$slug.php" ) ), ), self_admin_url( 'plugins.php' ) ); $message = sprintf( esc_html__( '%1$sActivate the Envato Market plugin%2$s to get updates for your ThemeForest and CodeCanyon items.', 'envato-market' ), '<a href="' . esc_url( $activate_url ) . '">', '</a>' ); } elseif ( 'install' === $state ) { $install_url = add_query_arg( array( 'action' => 'install-plugin', 'plugin' => $slug, ), self_admin_url( 'update.php' ) ); $message = sprintf( esc_html__( '%1$sInstall the Envato Market plugin%2$s to get updates for your ThemeForest and CodeCanyon items.', 'envato-market' ), '<a href="' . esc_url( wp_nonce_url( $install_url, 'install-plugin_' . $slug ) ) . '">', '</a>' ); } if ( isset( $message ) ) { ?> <div class="updated envato-market-notice notice is-dismissible"> <p><?php echo wp_kses_post( $message ); ?></p> </div> <script> jQuery( document ).ready( function( $ ) { $( document ).on( 'click', '.envato-market-notice .notice-dismiss', function() { $.ajax( { url: ajaxurl, data: { action: '<?php echo self::AJAX_ACTION; ?>', nonce: '<?php echo wp_create_nonce( self::AJAX_ACTION ); ?>' } } ); } ); } ); </script> <?php } } /** * Dismiss admin notice. * * @since 1.0.0 */ public function dismiss_notice() { check_ajax_referer( self::AJAX_ACTION, 'nonce' ); update_option( self::AJAX_ACTION, 'dismissed' ); wp_send_json_success(); } } if ( ! function_exists( 'envato_market_github' ) ) : /** * Envato_Market_Github Instance * * @since 1.0.0 * * @return Envato_Market_Github */ function envato_market_github() { return Envato_Market_Github::instance(); } endif; /** * Loads the main instance of Envato_Market_Github * * @since 1.0.0 */ add_action( 'after_setup_theme', 'envato_market_github', 99 ); endif; class-envato-market.php 0000644 00000023164 15132720601 0011140 0 ustar 00 <?php /** * Envato Market class. * * @package Envato_Market */ if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } if ( ! class_exists( 'Envato_Market' ) ) : /** * It's the main class that does all the things. * * @class Envato_Market * @version 1.0.0 * @since 1.0.0 */ final class Envato_Market { /** * The single class instance. * * @since 1.0.0 * @access private * * @var object */ private static $_instance = null; /** * Plugin data. * * @since 1.0.0 * @access private * * @var object */ private $data; /** * The slug. * * @since 1.0.0 * @access private * * @var string */ private $slug; /** * The version number. * * @since 1.0.0 * @access private * * @var string */ private $version; /** * The web URL to the plugin directory. * * @since 1.0.0 * @access private * * @var string */ private $plugin_url; /** * The server path to the plugin directory. * * @since 1.0.0 * @access private * * @var string */ private $plugin_path; /** * The web URL to the plugin admin page. * * @since 1.0.0 * @access private * * @var string */ private $page_url; /** * The setting option name. * * @since 1.0.0 * @access private * * @var string */ private $option_name; /** * Main Envato_Market Instance * * Ensures only one instance of this class exists in memory at any one time. * * @see Envato_Market() * @uses Envato_Market::init_globals() Setup class globals. * @uses Envato_Market::init_includes() Include required files. * @uses Envato_Market::init_actions() Setup hooks and actions. * * @since 1.0.0 * @static * @return Envato_Market. * @codeCoverageIgnore */ public static function instance() { if ( is_null( self::$_instance ) ) { self::$_instance = new self(); self::$_instance->init_globals(); self::$_instance->init_includes(); self::$_instance->init_actions(); } return self::$_instance; } /** * A dummy constructor to prevent this class from being loaded more than once. * * @see Envato_Market::instance() * * @since 1.0.0 * @access private * @codeCoverageIgnore */ private function __construct() { /* We do nothing here! */ } /** * You cannot clone this class. * * @since 1.0.0 * @codeCoverageIgnore */ public function __clone() { _doing_it_wrong( __FUNCTION__, __( 'Cheatin’ huh?', 'envato-market' ), '1.0.0' ); } /** * You cannot unserialize instances of this class. * * @since 1.0.0 * @codeCoverageIgnore */ public function __wakeup() { _doing_it_wrong( __FUNCTION__, __( 'Cheatin’ huh?', 'envato-market' ), '1.0.0' ); } /** * Setup the class globals. * * @since 1.0.0 * @access private * @codeCoverageIgnore */ private function init_globals() { $this->data = new stdClass(); $this->version = ENVATO_MARKET_VERSION; $this->slug = 'envato-market'; $this->option_name = self::sanitize_key( $this->slug ); $this->plugin_url = ENVATO_MARKET_URI; $this->plugin_path = ENVATO_MARKET_PATH; $this->page_url = ENVATO_MARKET_NETWORK_ACTIVATED ? network_admin_url( 'admin.php?page=' . $this->slug ) : admin_url( 'admin.php?page=' . $this->slug ); $this->data->admin = true; } /** * Include required files. * * @since 1.0.0 * @access private * @codeCoverageIgnore */ private function init_includes() { require $this->plugin_path . '/inc/admin/class-envato-market-admin.php'; require $this->plugin_path . '/inc/admin/functions.php'; require $this->plugin_path . '/inc/class-envato-market-api.php'; require $this->plugin_path . '/inc/class-envato-market-items.php'; require $this->plugin_path . '/inc/class-envato-market-github.php'; } /** * Setup the hooks, actions and filters. * * @uses add_action() To add actions. * @uses add_filter() To add filters. * * @since 1.0.0 * @access private * @codeCoverageIgnore */ private function init_actions() { // Activate plugin. register_activation_hook( ENVATO_MARKET_CORE_FILE, array( $this, 'activate' ) ); // Deactivate plugin. register_deactivation_hook( ENVATO_MARKET_CORE_FILE, array( $this, 'deactivate' ) ); // Load the textdomain. add_action( 'init', array( $this, 'load_textdomain' ) ); // Load OAuth. add_action( 'init', array( $this, 'admin' ) ); // Load Upgrader. add_action( 'init', array( $this, 'items' ) ); } /** * Activate plugin. * * @since 1.0.0 * @codeCoverageIgnore */ public function activate() { self::set_plugin_state( true ); } /** * Deactivate plugin. * * @since 1.0.0 * @codeCoverageIgnore */ public function deactivate() { self::set_plugin_state( false ); } /** * Loads the plugin's translated strings. * * @since 1.0.0 * @codeCoverageIgnore */ public function load_textdomain() { load_plugin_textdomain( 'envato-market', false, ENVATO_MARKET_PATH . 'languages/' ); } /** * Sanitize data key. * * @since 1.0.0 * @access private * * @param string $key An alpha numeric string to sanitize. * @return string */ private function sanitize_key( $key ) { return preg_replace( '/[^A-Za-z0-9\_]/i', '', str_replace( array( '-', ':' ), '_', $key ) ); } /** * Recursively converts data arrays to objects. * * @since 1.0.0 * @access private * * @param array $array An array of data. * @return object */ private function convert_data( $array ) { foreach ( (array) $array as $key => $value ) { if ( is_array( $value ) ) { $array[ $key ] = self::convert_data( $value ); } } return (object) $array; } /** * Set the `is_plugin_active` option. * * This setting helps determine context. Since the plugin can be included in your theme root you * might want to hide the admin UI when the plugin is not activated and implement your own. * * @since 1.0.0 * @access private * * @param bool $value Whether or not the plugin is active. */ private function set_plugin_state( $value ) { self::set_option( 'is_plugin_active', $value ); } /** * Set option value. * * @since 1.0.0 * * @param string $name Option name. * @param mixed $option Option data. */ public function set_option( $name, $option ) { $options = self::get_options(); $name = self::sanitize_key( $name ); $options[ $name ] = esc_html( $option ); $this->set_options( $options ); } /** * Set option. * * @since 2.0.0 * * @param mixed $options Option data. */ public function set_options( $options ) { ENVATO_MARKET_NETWORK_ACTIVATED ? update_site_option( $this->option_name, $options ) : update_option( $this->option_name, $options ); } /** * Return the option settings array. * * @since 1.0.0 */ public function get_options() { return ENVATO_MARKET_NETWORK_ACTIVATED ? get_site_option( $this->option_name, array() ) : get_option( $this->option_name, array() ); } /** * Return a value from the option settings array. * * @since 1.0.0 * * @param string $name Option name. * @param mixed $default The default value if nothing is set. * @return mixed */ public function get_option( $name, $default = '' ) { $options = self::get_options(); $name = self::sanitize_key( $name ); return isset( $options[ $name ] ) ? $options[ $name ] : $default; } /** * Set data. * * @since 1.0.0 * * @param string $key Unique object key. * @param mixed $data Any kind of data. */ public function set_data( $key, $data ) { if ( ! empty( $key ) ) { if ( is_array( $data ) ) { $data = self::convert_data( $data ); } $key = self::sanitize_key( $key ); // @codingStandardsIgnoreStart $this->data->$key = $data; // @codingStandardsIgnoreEnd } } /** * Get data. * * @since 1.0.0 * * @param string $key Unique object key. * @return string|object */ public function get_data( $key ) { return isset( $this->data->$key ) ? $this->data->$key : ''; } /** * Return the plugin slug. * * @since 1.0.0 * * @return string */ public function get_slug() { return $this->slug; } /** * Return the plugin version number. * * @since 1.0.0 * * @return string */ public function get_version() { return $this->version; } /** * Return the plugin URL. * * @since 1.0.0 * * @return string */ public function get_plugin_url() { return $this->plugin_url; } /** * Return the plugin path. * * @since 1.0.0 * * @return string */ public function get_plugin_path() { return $this->plugin_path; } /** * Return the plugin page URL. * * @since 1.0.0 * * @return string */ public function get_page_url() { return $this->page_url; } /** * Return the option settings name. * * @since 1.0.0 * * @return string */ public function get_option_name() { return $this->option_name; } /** * Admin UI class. * * @since 1.0.0 * * @return Envato_Market_Admin */ public function admin() { return Envato_Market_Admin::instance(); } /** * Envato API class. * * @since 1.0.0 * * @return Envato_Market_API */ public function api() { return Envato_Market_API::instance(); } /** * Items class. * * @since 1.0.0 * * @return Envato_Market_Items */ public function items() { return Envato_Market_Items::instance(); } } endif; admin/view/notice/error-permissions.php 0000644 00000001054 15132720601 0014277 0 ustar 00 <?php /** * Error notice * * @package Envato_Market * @since 2.0.1 */ ?> <div class="notice notice-error is-dismissible"> <p><?php printf( esc_html__( 'Incorrect token permissions, please generate another token or fix the permissions on the existing token.' ) ); ?></p> <p><?php printf( esc_html__( 'Please ensure only the following permissions are enabled: ', 'envato-market' ) ); ?></p> <ol> <?php foreach ( $this->get_required_permissions() as $permission ) { ?> <li><?php echo esc_html( $permission ); ?></li> <?php } ?> </ol> </div> admin/view/notice/error-http.php 0000644 00000000741 15132720601 0012705 0 ustar 00 <?php /** * Error notice * * @package Envato_Market * @since 2.0.1 */ ?> <div class="notice notice-error is-dismissible"> <p><?php esc_html_e( 'Failed to connect to the Envato API. Please contact the hosting providier with this message: "The Envato Market WordPress plugin requires TLS version 1.2 or above, please confirm if this hosting account supports TLS version 1.2 and allows connections from WordPress to the host api.envato.com".', 'envato-market' ); ?></p> </div> admin/view/notice/error-missing-zip.php 0000644 00000000645 15132720601 0014202 0 ustar 00 <?php /** * Error notice * * @package Envato_Market * @since 2.0.1 */ ?> <div class="notice notice-error is-dismissible"> <p><?php printf( esc_html__( 'Failed to locate the package file for this item. Please contact the item author for support, or install/upgrade the item manually from the %s.', 'envato-market' ), '<a href="https://themeforest.net/downloads" target="_blank">downloads page</a>' ); ?></p> </div> admin/view/notice/success-no-items.php 0000644 00000000457 15132720601 0014004 0 ustar 00 <?php /** * Success notice * * @package Envato_Market * @since 1.0.0 */ ?> <div class="notice notice-success is-dismissible"> <p><?php esc_html_e( 'Your OAuth Personal Token has been verified. However, there are no WordPress downloadable items in your account.', 'envato-market' ); ?></p> </div> admin/view/notice/error-single-use.php 0000644 00000000424 15132720601 0013777 0 ustar 00 <?php /** * Error notice * * @package Envato_Market * @since 1.0.0 */ ?> <div class="notice notice-error is-dismissible"> <p><?php esc_html_e( 'One or more Single Use OAuth Personal Tokens could not be verified and should be removed.', 'envato-market' ); ?></p> </div> admin/view/notice/error.php 0000644 00000000513 15132720601 0011725 0 ustar 00 <?php /** * Error notice * * @package Envato_Market * @since 1.0.0 */ ?> <div class="notice notice-error is-dismissible"> <p><?php esc_html_e( 'The OAuth Personal Token could not be verified. Please check that the Token has been entered correctly and has the minimum required permissions.', 'envato-market' ); ?></p> </div> admin/view/notice/success-single-use.php 0000644 00000000367 15132720601 0014324 0 ustar 00 <?php /** * Success notice * * @package Envato_Market * @since 1.0.0 */ ?> <div class="notice notice-success is-dismissible"> <p><?php esc_html_e( 'All Single Use OAuth Personal Tokens have been verified.', 'envato-market' ); ?></p> </div> admin/view/notice/success.php 0000644 00000000353 15132720601 0012246 0 ustar 00 <?php /** * Success notice * * @package Envato_Market * @since 1.0.0 */ ?> <div class="notice notice-success is-dismissible"> <p><?php esc_html_e( 'Your OAuth Personal Token has been verified.', 'envato-market' ); ?></p> </div> admin/view/notice/error-details.php 0000644 00000000466 15132720601 0013357 0 ustar 00 <?php /** * Error details * * @package Envato_Market * @since 2.0.2 */ ?> <div class="notice notice-error is-dismissible"> <p><?php printf( '<strong>Additional Error Details:</strong><br/>%s.<br/> %s <br/> %s', esc_html( $title ), esc_html( $message ), esc_html( json_encode( $data ) ) ); ?></p> </div> admin/view/callback/section/items.php 0000644 00000001032 15132720601 0013631 0 ustar 00 <?php /** * Items section * * @package Envato_Market * @since 1.0.0 */ ?> <p><?php esc_html_e( 'Add Envato Market themes & plugins using multiple OAuth tokens. This is especially useful when an item has been purchased on behalf of a third-party. This works similarly to the global OAuth Personal Token, but for individual items and additionally requires the Envato Market item ID.', 'envato-market' ); ?></p> <p><?php esc_html_e( 'Warning: These tokens can be revoked by the account holder at any time.', 'envato-market' ); ?></p> admin/view/callback/section/oauth.php 0000644 00000002737 15132720601 0013645 0 ustar 00 <?php /** * OAuth section * * @package Envato_Market * @since 1.0.0 */ ?> <p> <?php printf( esc_html__( 'This area enables WordPress Theme & Plugin updates from Envato Market. Read more about how this process works at %s.', 'envato-market' ), '<a href="https://envato.com/market-plugin/" target="_blank">' . esc_html__( 'envato.com', 'envato-market' ) . '</a>' ); ?> </p> <p> <?php esc_html_e( 'Please follow the steps below:', 'envato-market' ); ?> </p> <ol> <li><?php printf( esc_html__( 'Generate an Envato API Personal Token by %s.', 'envato-market' ), '<a href="' . envato_market()->admin()->get_generate_token_url() . '" target="_blank">' . esc_html__( 'clicking this link', 'envato-market' ) . '</a>' ); ?></li> <li><?php esc_html_e( 'Name the token eg “My WordPress site”.', 'envato-market' ); ?></li> <li><?php esc_html_e( 'Ensure the following permissions are enabled:', 'envato-market' ); ?> <ul> <li><?php esc_html_e( 'View and search Envato sites', 'envato-market' ); ?></li> <li><?php esc_html_e( 'Download your purchased items', 'envato-market' ); ?></li> <li><?php esc_html_e( 'List purchases you\'ve made', 'envato-market' ); ?></li> </ul> </li> <li><?php esc_html_e( 'Copy the token into the box below.', 'envato-market' ); ?></li> <li><?php esc_html_e( 'Click the "Save Changes" button.', 'envato-market' ); ?></li> <li><?php esc_html_e( 'A list of purchased Themes & Plugins from Envato Market will appear.', 'envato-market' ); ?></li> </ol> admin/view/callback/setting/token.php 0000644 00000000612 15132720601 0013644 0 ustar 00 <?php /** * Token setting * * @package Envato_Market * @since 1.0.0 */ ?> <input type="text" name="<?php echo esc_attr( envato_market()->get_option_name() ); ?>[token]" class="widefat" value="<?php echo esc_html( envato_market()->get_option( 'token' ) ); ?>" autocomplete="off"> <p class="description"><?php esc_html_e( 'Enter your Envato API Personal Token.', 'envato-market' ); ?></p> admin/view/callback/setting/items.php 0000644 00000003531 15132720601 0013650 0 ustar 00 <?php /** * Items setting * * @package Envato_Market * @since 1.0.0 */ $items = envato_market()->get_option( 'items', array() ); ?> <ul id="envato-market-items"> <?php if ( ! empty( $items ) ) { foreach ( $items as $key => $item ) { if ( empty( $item['name'] ) || empty( $item['token'] ) || empty( $item['id'] ) || empty( $item['type'] ) || empty( $item['authorized'] ) ) { continue; } $class = 'success' === $item['authorized'] ? 'is-authorized' : 'not-authorized'; echo ' <li data-id="' . esc_attr( $item['id'] ) . '" class="' . esc_attr( $class ) . '"> <span class="item-name">' . esc_html__( 'ID', 'envato-market' ) . ': ' . esc_html( $item['id'] ) . ' - ' . esc_html( $item['name'] ) . '</span> <button class="item-delete dashicons dashicons-dismiss"> <span class="screen-reader-text">' . esc_html__( 'Delete', 'envato-market' ) . '</span> </button> <input type="hidden" name="' . esc_attr( envato_market()->get_option_name() ) . '[items][' . esc_attr( $key ) . '][name]" value="' . esc_html( $item['name'] ) . '" /> <input type="hidden" name="' . esc_attr( envato_market()->get_option_name() ) . '[items][' . esc_attr( $key ) . '][token]" value="' . esc_html( $item['token'] ) . '" /> <input type="hidden" name="' . esc_attr( envato_market()->get_option_name() ) . '[items][' . esc_attr( $key ) . '][id]" value="' . esc_html( $item['id'] ) . '" /> <input type="hidden" name="' . esc_attr( envato_market()->get_option_name() ) . '[items][' . esc_attr( $key ) . '][type]" value="' . esc_html( $item['type'] ) . '" /> <input type="hidden" name="' . esc_attr( envato_market()->get_option_name() ) . '[items][' . esc_attr( $key ) . '][authorized]" value="' . esc_html( $item['authorized'] ) . '" /> </li>'; } } ?> </ul> <button class="button add-envato-market-item"><?php esc_html_e( 'Add Item', 'envato-market' ); ?></button> admin/view/callback/admin.php 0000644 00000002011 15132720601 0012132 0 ustar 00 <?php /** * Admin UI * * @package Envato_Market * @since 1.0.0 */ if ( isset( $_GET['action'] ) ) { $id = ! empty( $_GET['id'] ) ? absint( trim( $_GET['id'] ) ) : ''; if ( 'install-plugin' === $_GET['action'] ) { Envato_Market_Admin::install_plugin( $id ); } elseif ( 'install-theme' === $_GET['action'] ) { Envato_Market_Admin::install_theme( $id ); } } else { add_thickbox(); ?> <div class="wrap about-wrap full-width-layout"> <?php Envato_Market_Admin::render_intro_partial(); ?> <?php Envato_Market_Admin::render_tabs_partial(); ?> <form method="POST" action="<?php echo esc_url( ENVATO_MARKET_NETWORK_ACTIVATED ? network_admin_url( 'edit.php?action=envato_market_network_settings' ) : admin_url( 'options.php' ) ); ?>"> <?php Envato_Market_Admin::render_themes_panel_partial(); ?> <?php Envato_Market_Admin::render_plugins_panel_partial(); ?> <?php Envato_Market_Admin::render_settings_panel_partial(); ?> <?php Envato_Market_Admin::render_help_panel_partial(); ?> </form> </div> <?php } admin/view/partials/themes.php 0000644 00000000715 15132720601 0012423 0 ustar 00 <?php /** * Themes panel partial * * @package Envato_Market * @since 1.0.0 */ $themes = envato_market()->items()->themes( 'purchased' ); ?> <div id="themes" class="panel <?php echo empty( $themes ) ? 'hidden' : ''; ?>"> <div class="envato-market-blocks"> <?php if ( ! empty( $themes ) ) { envato_market_themes_column( 'active' ); envato_market_themes_column( 'installed' ); envato_market_themes_column( 'install' ); } ?> </div> </div> admin/view/partials/plugins.php 0000644 00000000726 15132720601 0012621 0 ustar 00 <?php /** * Plugins panel partial * * @package Envato_Market * @since 1.0.0 */ $plugins = envato_market()->items()->plugins( 'purchased' ); ?> <div id="plugins" class="panel <?php echo empty( $plugins ) ? 'hidden' : ''; ?>"> <div class="envato-market-blocks"> <?php if ( ! empty( $plugins ) ) { envato_market_plugins_column( 'active' ); envato_market_plugins_column( 'installed' ); envato_market_plugins_column( 'install' ); } ?> </div> </div> admin/view/partials/help.php 0000644 00000005201 15132720601 0012061 0 ustar 00 <?php /** * Help panel partial * * @package Envato_Market * @since 2.0.1 */ ?> <div id="help" class="panel"> <div class="envato-market-blocks"> <div class="envato-market-block"> <h3>Troubleshooting:</h3> <p>If you’re having trouble with the plugin, please</p> <ol> <li>Confirm the old <code>Envato Toolkit</code> plugin is not installed.</li> <li>Confirm the latest version of WordPress is installed.</li> <li>Confirm the latest version of the <a href="https://envato.com/market-plugin/" target="_blank">Envato Market</a> plugin is installed.</li> <li>Try creating a new API token has from the <a href="<?php echo envato_market()->admin()->get_generate_token_url(); ?>" target="_blank">build.envato.com</a> website - ensure only the following permissions have been granted <ul> <li>View and search Envato sites</li> <li>Download your purchased items</li> <li>List purchases you've made</li> </ul> </li> <li>Check with the hosting provider to ensure the API connection to <code>api.envato.com</code> is not blocked.</li> <li>Check with the hosting provider that the minimum TLS version is 1.2 or above on the server.</li> <li>If you can’t see your items - check with the item author to confirm the Theme or Plugin is compatible with the Envato Market plugin.</li> <li>Confirm your Envato account is still active and the items are still visible from <a href="https://themeforest.net/downloads" target="_blank">your downloads page</a>.</li> <li>Note - if an item has been recently updated, it may take up to 24 hours for the latest version to appear in the Envato Market plugin.</li> </ol> </div> <div class="envato-market-block"> <h3>Health Check:</h3> <div class="envato-market-healthcheck"> Problem starting healthcheck. Please check javascript console for errors. </div> <h3>Support:</h3> <p>The Envato Market plugin is maintained - we ensure it works best on the latest version of WordPress and on a modern hosting platform, however we can’t guarantee it’ll work on all WordPress sites or hosting environments.</p> <p>If you’ve tried all the troubleshooting steps and you’re still unable to get the Envato Market plugin to work on your site/hosting, at this time, our advice is to remove the Envato Market plugin and instead visit the Downloads section of ThemeForest/CodeCanyon to download the latest version of your items.</p> <p>If you’re having trouble with a specific item from ThemeForest or CodeCanyon, it’s best you browse to the Theme or Plugin item page, visit the ‘support’ tab and follow the next steps. </p> </div> </div> </div> admin/view/partials/intro.php 0000644 00000001671 15132720601 0012273 0 ustar 00 <?php /** * Intro partial * * @package Envato_Market * @since 1.0.0 */ ?> <div class="col"> <h1 class="about-title"><img class="about-logo" src="<?php echo envato_market()->get_plugin_url(); ?>images/envato-market-logo.svg" alt="Envato Market"><sup><?php echo esc_html( envato_market()->get_version() ); ?></sup></h1> <p><?php esc_html_e( 'Welcome!', 'envato-market' ); ?></p> <p><?php esc_html_e( 'This plugin can install WordPress themes and plugins purchased from ThemeForest & CodeCanyon by connecting with the Envato Market API using a secure OAuth personal token. Once your themes & plugins are installed WordPress will periodically check for updates, so keeping your items up to date is as simple as a few clicks.', 'envato-market' ); ?></p> <p><strong><?php printf( esc_html__( 'Find out more at %1$senvato.com%2$s.', 'envato-market' ), '<a href="https://envato.com/market-plugin/" target="_blank">', '</a>' ); ?></strong></p> </div> admin/view/partials/settings.php 0000644 00000001760 15132720601 0012777 0 ustar 00 <?php /** * Settings panel partial * * @package Envato_Market * @since 1.0.0 */ $token = envato_market()->get_option( 'token' ); $items = envato_market()->get_option( 'items', array() ); ?> <div id="settings" class="panel"> <div class="envato-market-blocks"> <?php settings_fields( envato_market()->get_slug() ); ?> <?php Envato_Market_Admin::do_settings_sections( envato_market()->get_slug(), 2 ); ?> </div> <p class="submit"> <input type="submit" name="submit" id="submit" class="button button-primary" value="<?php esc_html_e( 'Save Changes', 'envato-market' ); ?>" /> <?php if ( ( '' !== $token || ! empty( $items ) ) && 10 !== has_action( 'admin_notices', array( $this, 'error_notice' ) ) ) { ?> <a href="<?php echo esc_url( add_query_arg( array( 'authorization' => 'check' ), envato_market()->get_page_url() ) ); ?>" class="button button-secondary auth-check-button" style="margin:0 5px"><?php esc_html_e( 'Test API Connection', 'envato-market' ); ?></a> <?php } ?> </p> </div> admin/view/partials/tabs.php 0000644 00000002724 15132720601 0012071 0 ustar 00 <?php /** * Tabs partial * * @package Envato_Market * @since 1.0.0 */ $tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : ''; $themes = envato_market()->items()->themes( 'purchased' ); $plugins = envato_market()->items()->plugins( 'purchased' ); ?> <h2 class="nav-tab-wrapper"> <?php // Themes tab. $theme_class = array(); if ( ! empty( $themes ) ) { if ( empty( $tab ) ) { $tab = 'themes'; } if ( 'themes' === $tab ) { $theme_class[] = 'nav-tab-active'; } } else { $theme_class[] = 'hidden'; } echo '<a href="#themes" data-id="theme" class="nav-tab ' . esc_attr( implode( ' ', $theme_class ) ) . '">' . esc_html__( 'Themes', 'envato-market' ) . '</a>'; // Plugins tab. $plugin_class = array(); if ( ! empty( $plugins ) ) { if ( empty( $tab ) ) { $tab = 'plugins'; } if ( 'plugins' === $tab ) { $plugin_class[] = 'nav-tab-active'; } } else { $plugin_class[] = 'hidden'; } echo '<a href="#plugins" data-id="plugin" class="nav-tab ' . esc_attr( implode( ' ', $plugin_class ) ) . '">' . esc_html__( 'Plugins', 'envato-market' ) . '</a>'; // Settings tab. echo '<a href="#settings" class="nav-tab ' . esc_attr( 'settings' === $tab || empty( $tab ) ? 'nav-tab-active' : '' ) . '">' . esc_html__( 'Settings', 'envato-market' ) . '</a>'; // Help tab. echo '<a href="#help" class="nav-tab ' . esc_attr( 'help' === $tab ? 'nav-tab-active' : '' ) . '">' . esc_html__( 'Help', 'envato-market' ) . '</a>'; ?> </h2> admin/class-envato-market-admin.php 0000644 00000161130 15132720601 0013312 0 ustar 00 <?php /** * Admin UI class. * * @package Envato_Market */ if ( ! class_exists( 'Envato_Market_Admin' ) && class_exists( 'Envato_Market' ) ) : /** * Creates an admin page to save the Envato API OAuth token. * * @class Envato_Market_Admin * @version 1.0.0 * @since 1.0.0 */ class Envato_Market_Admin { /** * Action nonce. * * @type string */ const AJAX_ACTION = 'envato_market'; /** * The single class instance. * * @since 1.0.0 * @access private * * @var object */ private static $_instance = null; /** * Main Envato_Market_Admin Instance * * Ensures only one instance of this class exists in memory at any one time. * * @return object The one true Envato_Market_Admin. * @codeCoverageIgnore * @uses Envato_Market_Admin::init_actions() Setup hooks and actions. * * @since 1.0.0 * @static * @see Envato_Market_Admin() */ public static function instance() { if ( is_null( self::$_instance ) ) { self::$_instance = new self(); self::$_instance->init_actions(); } return self::$_instance; } /** * A dummy constructor to prevent this class from being loaded more than once. * * @see Envato_Market_Admin::instance() * * @since 1.0.0 * @access private * @codeCoverageIgnore */ private function __construct() { /* We do nothing here! */ } /** * You cannot clone this class. * * @since 1.0.0 * @codeCoverageIgnore */ public function __clone() { _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'envato-market' ), '1.0.0' ); } /** * You cannot unserialize instances of this class. * * @since 1.0.0 * @codeCoverageIgnore */ public function __wakeup() { _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'envato-market' ), '1.0.0' ); } /** * Setup the hooks, actions and filters. * * @uses add_action() To add actions. * @uses add_filter() To add filters. * * @since 1.0.0 */ public function init_actions() { // @codeCoverageIgnoreStart if ( false === envato_market()->get_data( 'admin' ) && false === envato_market()->get_option( 'is_plugin_active' ) ) { // Turns the UI off if allowed. return; } // @codeCoverageIgnoreEnd // Deferred Download. add_action( 'upgrader_package_options', array( $this, 'maybe_deferred_download' ), 9 ); // Add pre download filter to help with 3rd party plugin integration. add_filter( 'upgrader_pre_download', array( $this, 'upgrader_pre_download' ), 2, 4 ); // Add item AJAX handler. add_action( 'wp_ajax_' . self::AJAX_ACTION . '_add_item', array( $this, 'ajax_add_item' ) ); // Remove item AJAX handler. add_action( 'wp_ajax_' . self::AJAX_ACTION . '_remove_item', array( $this, 'ajax_remove_item' ) ); // Health check AJAX handler add_action( 'wp_ajax_' . self::AJAX_ACTION . '_healthcheck', array( $this, 'ajax_healthcheck' ) ); // Maybe delete the site transients. add_action( 'init', array( $this, 'maybe_delete_transients' ), 11 ); // Add the menu icon. add_action( 'admin_head', array( $this, 'add_menu_icon' ) ); // Add the menu. add_action( 'admin_menu', array( $this, 'add_menu_page' ) ); // Register the settings. add_action( 'admin_init', array( $this, 'register_settings' ) ); // We may need to redirect after an item is enabled. add_action( 'current_screen', array( $this, 'maybe_redirect' ) ); // Add authorization notices. add_action( 'current_screen', array( $this, 'add_notices' ) ); // Set the API values. add_action( 'current_screen', array( $this, 'set_items' ) ); // Hook to verify the API token before saving it. add_filter( 'pre_update_option_' . envato_market()->get_option_name(), array( $this, 'check_api_token_before_saving', ), 9, 3 ); add_filter( 'pre_update_site_option_' . envato_market()->get_option_name(), array( $this, 'check_api_token_before_saving', ), 9, 3 ); // When network enabled, add the network options menu. add_action( 'network_admin_menu', array( $this, 'add_menu_page' ) ); // Ability to make use of the Settings API when in multisite mode. add_action( 'network_admin_edit_envato_market_network_settings', array( $this, 'save_network_settings' ) ); } /** * This runs before we save the Envato Market options array. * If the token has changed then we set a transient so we can do the update check. * * @param array $value The option to save. * @param array $old_value The old option value. * @param array $option Serialized option value. * * @return array $value The updated option value. * @since 2.0.1 */ public function check_api_token_before_saving( $value, $old_value, $option ) { if ( ! empty( $value['token'] ) && ( empty( $old_value['token'] ) || $old_value['token'] != $value['token'] || isset( $_POST['envato_market'] ) ) ) { set_site_transient( envato_market()->get_option_name() . '_check_token', $value['token'], HOUR_IN_SECONDS ); } return $value; } /** * Defers building the API download url until the last responsible moment to limit file requests. * * Filter the package options before running an update. * * @param array $options { * Options used by the upgrader. * * @type string $package Package for update. * @type string $destination Update location. * @type bool $clear_destination Clear the destination resource. * @type bool $clear_working Clear the working resource. * @type bool $abort_if_destination_exists Abort if the Destination directory exists. * @type bool $is_multi Whether the upgrader is running multiple times. * @type array $hook_extra Extra hook arguments. * } * @since 1.0.0 */ public function maybe_deferred_download( $options ) { $package = $options['package']; if ( false !== strrpos( $package, 'deferred_download' ) && false !== strrpos( $package, 'item_id' ) ) { parse_str( parse_url( $package, PHP_URL_QUERY ), $vars ); if ( $vars['item_id'] ) { $args = $this->set_bearer_args( $vars['item_id'] ); $options['package'] = envato_market()->api()->download( $vars['item_id'], $args ); } } return $options; } /** * We want to stop certain popular 3rd party scripts from blocking the update process by * adjusting the plugin name slightly so the 3rd party plugin checks stop. * * Currently works for: Visual Composer. * * @param string $reply Package URL. * @param string $package Package URL. * @param object $updater Updater Object. * * @return string $reply New Package URL. * @since 2.0.0 */ public function upgrader_pre_download( $reply, $package, $updater ) { if ( strpos( $package, 'marketplace.envato.com/short-dl' ) !== false ) { if ( isset( $updater->skin->plugin_info ) && ! empty( $updater->skin->plugin_info['Name'] ) ) { $updater->skin->plugin_info['Name'] = $updater->skin->plugin_info['Name'] . '.'; } else { $updater->skin->plugin_info = array( 'Name' => 'Name', ); } } return $reply; } /** * Returns the bearer arguments for a request with a single use API Token. * * @param int $id The item ID. * * @return array * @since 1.0.0 */ public function set_bearer_args( $id ) { $token = ''; $args = array(); foreach ( envato_market()->get_option( 'items', array() ) as $item ) { if ( absint( $item['id'] ) === absint( $id ) ) { $token = $item['token']; break; } } if ( ! empty( $token ) ) { $args = array( 'headers' => array( 'Authorization' => 'Bearer ' . $token, ), ); } return $args; } /** * Maybe delete the site transients. * * @since 1.0.0 * @codeCoverageIgnore */ public function maybe_delete_transients() { if ( isset( $_POST[ envato_market()->get_option_name() ] ) ) { // Nonce check. if ( isset( $_POST['_wpnonce'] ) && ! wp_verify_nonce( $_POST['_wpnonce'], envato_market()->get_slug() . '-options' ) ) { wp_die( __( 'You do not have sufficient permissions to delete transients.', 'envato-market' ) ); } self::delete_transients(); } elseif ( ! envato_market()->get_option( 'installed_version', 0 ) || version_compare( envato_market()->get_version(), envato_market()->get_option( 'installed_version', 0 ), '<' ) ) { // When the plugin updates we want to delete transients. envato_market()->set_option( 'installed_version', envato_market()->get_version() ); self::delete_transients(); } } /** * Delete the site transients. * * @since 1.0.0 * @access private */ private function delete_transients() { delete_site_transient( envato_market()->get_option_name() . '_themes' ); delete_site_transient( envato_market()->get_option_name() . '_plugins' ); } /** * Prints out all settings sections added to a particular settings page in columns. * * @param string $page The slug name of the page whos settings sections you want to output. * @param int $columns The number of columns in each row. * * @since 1.0.0 * * @global array $wp_settings_sections Storage array of all settings sections added to admin pages * @global array $wp_settings_fields Storage array of settings fields and info about their pages/sections */ public static function do_settings_sections( $page, $columns = 2 ) { global $wp_settings_sections, $wp_settings_fields; // @codeCoverageIgnoreStart if ( ! isset( $wp_settings_sections[ $page ] ) ) { return; } // @codeCoverageIgnoreEnd foreach ( (array) $wp_settings_sections[ $page ] as $section ) { // @codeCoverageIgnoreStart if ( ! isset( $wp_settings_fields ) || ! isset( $wp_settings_fields[ $page ] ) || ! isset( $wp_settings_fields[ $page ][ $section['id'] ] ) ) { continue; } // @codeCoverageIgnoreEnd // Set the column class. $class = 'envato-market-block'; ?> <div class="<?php echo esc_attr( $class ); ?>"> <?php if ( ! empty( $section['title'] ) ) { echo '<h3>' . esc_html( $section['title'] ) . '</h3>' . "\n"; } if ( ! empty( $section['callback'] ) ) { call_user_func( $section['callback'], $section ); } ?> <table class="form-table"> <?php do_settings_fields( $page, $section['id'] ); ?> </table> </div> <?php } } /** * Add a font based menu icon * * @since 1.0.0 */ public function add_menu_icon() { // Fonts directory URL. $fonts_dir_url = envato_market()->get_plugin_url() . 'fonts/'; // Create font styles. $style = '<style type="text/css"> /*<![CDATA[*/ @font-face { font-family: "envato-market"; src:url("' . $fonts_dir_url . 'envato-market.eot?20150626"); src:url("' . $fonts_dir_url . 'envato-market.eot?#iefix20150626") format("embedded-opentype"), url("' . $fonts_dir_url . 'envato-market.woff?20150626") format("woff"), url("' . $fonts_dir_url . 'envato-market.ttf?20150626") format("truetype"), url("' . $fonts_dir_url . 'envato-market.svg?20150626#envato") format("svg"); font-weight: normal; font-style: normal; } #adminmenu .toplevel_page_' . envato_market()->get_slug() . ' .menu-icon-generic div.wp-menu-image:before { font: normal 20px/1 "envato-market" !important; content: "\e600"; speak: none; padding: 6px 0; height: 34px; width: 20px; display: inline-block; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-transition: all .1s ease-in-out; -moz-transition: all .1s ease-in-out; transition: all .1s ease-in-out; } /*]]>*/ </style>'; // Remove space after colons. $style = str_replace( ': ', ':', $style ); // Remove whitespace. echo str_replace( array( "\r\n", "\r", "\n", "\t", ' ', ' ', ' ', ' ', ' ' ), '', $style ); } /** * Adds the menu. * * @since 1.0.0 */ public function add_menu_page() { if ( ENVATO_MARKET_NETWORK_ACTIVATED && ! is_super_admin() ) { // we do not want to show a menu item for people who do not have permission. return; } $page = add_menu_page( __( 'Envato Market', 'envato-market' ), __( 'Envato Market', 'envato-market' ), 'manage_options', envato_market()->get_slug(), array( $this, 'render_admin_callback', ) ); // Enqueue admin CSS. add_action( 'admin_print_styles-' . $page, array( $this, 'admin_enqueue_style' ) ); // Enqueue admin JavaScript. add_action( 'admin_print_scripts-' . $page, array( $this, 'admin_enqueue_script' ) ); // Add Underscore.js templates. add_action( 'admin_footer-' . $page, array( $this, 'render_templates' ) ); } /** * Enqueue admin css. * * @since 1.0.0 */ public function admin_enqueue_style() { $file_url = envato_market()->get_plugin_url() . 'css/envato-market' . ( is_rtl() ? '-rtl' : '' ) . '.css'; wp_enqueue_style( envato_market()->get_slug(), $file_url, array( 'wp-jquery-ui-dialog' ), envato_market()->get_version() ); } /** * Enqueue admin script. * * @since 1.0.0 */ public function admin_enqueue_script() { $min = ( WP_DEBUG ? '' : '.min' ); $slug = envato_market()->get_slug(); $version = envato_market()->get_version(); $plugin_url = envato_market()->get_plugin_url(); wp_enqueue_script( $slug, $plugin_url . 'js/envato-market' . $min . '.js', array( 'jquery', 'jquery-ui-dialog', 'wp-util', ), $version, true ); wp_enqueue_script( $slug . '-updates', $plugin_url . 'js/updates' . $min . '.js', array( 'jquery', 'updates', 'wp-a11y', 'wp-util', ), $version, true ); // Script data array. $exports = array( 'nonce' => wp_create_nonce( self::AJAX_ACTION ), 'action' => self::AJAX_ACTION, 'i18n' => array( 'save' => __( 'Save', 'envato-market' ), 'remove' => __( 'Remove', 'envato-market' ), 'cancel' => __( 'Cancel', 'envato-market' ), 'error' => __( 'An unknown error occurred. Try again.', 'envato-market' ), ), ); // Export data to JS. wp_scripts()->add_data( $slug, 'data', sprintf( 'var _envatoMarket = %s;', wp_json_encode( $exports ) ) ); } /** * Underscore (JS) templates for dialog windows. * * @codeCoverageIgnore */ public function render_templates() { ?> <script type="text/html" id="tmpl-envato-market-auth-check-button"> <a href="<?php echo esc_url( add_query_arg( array( 'authorization' => 'check' ), envato_market()->get_page_url() ) ); ?>" class="button button-secondary auth-check-button" style="margin:0 5px"><?php esc_html_e( 'Test API Connection', 'envato-market' ); ?></a> </script> <script type="text/html" id="tmpl-envato-market-item"> <li data-id="{{ data.id }}"> <span class="item-name"><?php esc_html_e( 'ID', 'envato-market' ); ?> : {{ data.id }} - {{ data.name }}</span> <button class="item-delete dashicons dashicons-dismiss"> <span class="screen-reader-text"><?php esc_html_e( 'Delete', 'envato-market' ); ?></span> </button> <input type="hidden" name="<?php echo esc_attr( envato_market()->get_option_name() ); ?>[items][{{ data.key }}][name]" value="{{ data.name }}"/> <input type="hidden" name="<?php echo esc_attr( envato_market()->get_option_name() ); ?>[items][{{ data.key }}][token]" value="{{ data.token }}"/> <input type="hidden" name="<?php echo esc_attr( envato_market()->get_option_name() ); ?>[items][{{ data.key }}][id]" value="{{ data.id }}"/> <input type="hidden" name="<?php echo esc_attr( envato_market()->get_option_name() ); ?>[items][{{ data.key }}][type]" value="{{ data.type }}"/> <input type="hidden" name="<?php echo esc_attr( envato_market()->get_option_name() ); ?>[items][{{ data.key }}][authorized]" value="{{ data.authorized }}"/> </li> </script> <script type="text/html" id="tmpl-envato-market-dialog-remove"> <div id="envato-market-dialog-remove" title="<?php esc_html_e( 'Remove Item', 'envato-market' ); ?>"> <p><?php esc_html_e( 'You are about to remove the connection between the Envato Market API and this item. You cannot undo this action.', 'envato-market' ); ?></p> </div> </script> <script type="text/html" id="tmpl-envato-market-dialog-form"> <div id="envato-market-dialog-form" title="<?php esc_html_e( 'Add Item', 'envato-market' ); ?>"> <form> <fieldset> <label for="token"><?php esc_html_e( 'Token', 'envato-market' ); ?></label> <input type="text" name="token" class="widefat" value=""/> <p class="description"><?php esc_html_e( 'Enter the Envato API Personal Token.', 'envato-market' ); ?></p> <label for="id"><?php esc_html_e( 'Item ID', 'envato-market' ); ?></label> <input type="text" name="id" class="widefat" value=""/> <p class="description"><?php esc_html_e( 'Enter the Envato Item ID.', 'envato-market' ); ?></p> <input type="submit" tabindex="-1" style="position:absolute; top:-5000px"/> </fieldset> </form> </div> </script> <script type="text/html" id="tmpl-envato-market-dialog-error"> <div class="notice notice-error"> <p>{{ data.message }}</p> </div> </script> <script type="text/html" id="tmpl-envato-market-card"> <div class="envato-market-block" data-id="{{ data.id }}"> <div class="envato-card {{ data.type }}"> <div class="envato-card-top"> <a href="{{ data.url }}" class="column-icon"> <img src="{{ data.thumbnail_url }}"/> </a> <div class="column-name"> <h4> <a href="{{ data.url }}">{{ data.name }}</a> <span class="version" aria-label="<?php esc_attr_e( 'Version %s', 'envato-market' ); ?>"><?php esc_html_e( 'Version', 'envato-market' ); ?> {{ data.version }}</span> </h4> </div> <div class="column-description"> <div class="description"> <p>{{ data.description }}</p> </div> <p class="author"> <cite><?php esc_html_e( 'By', 'envato-market' ); ?> {{ data.author }}</cite> </p> </div> </div> <div class="envato-card-bottom"> <div class="column-actions"> <a href="{{{ data.install }}}" class="button button-primary"> <span aria-hidden="true"><?php esc_html_e( 'Install', 'envato-market' ); ?></span> <span class="screen-reader-text"><?php esc_html_e( 'Install', 'envato-market' ); ?> {{ data.name }}</span> </a> </div> </div> </div> </div> </script> <?php } /** * Registers the settings. * * @since 1.0.0 */ public function register_settings() { // Setting. register_setting( envato_market()->get_slug(), envato_market()->get_option_name() ); // OAuth section. add_settings_section( envato_market()->get_option_name() . '_oauth_section', __( 'Getting Started (Simple)', 'envato-market' ), array( $this, 'render_oauth_section_callback' ), envato_market()->get_slug() ); // Token setting. add_settings_field( 'token', __( 'Token', 'envato-market' ), array( $this, 'render_token_setting_callback' ), envato_market()->get_slug(), envato_market()->get_option_name() . '_oauth_section' ); // Items section. add_settings_section( envato_market()->get_option_name() . '_items_section', __( 'Single Item Tokens (Advanced)', 'envato-market' ), array( $this, 'render_items_section_callback' ), envato_market()->get_slug() ); // Items setting. add_settings_field( 'items', __( 'Envato Market Items', 'envato-market' ), array( $this, 'render_items_setting_callback' ), envato_market()->get_slug(), envato_market()->get_option_name() . '_items_section' ); } /** * Redirect after the enable action runs. * * @since 1.0.0 * @codeCoverageIgnore */ public function maybe_redirect() { if ( $this->are_we_on_settings_page() ) { if ( ! empty( $_GET['action'] ) && 'install-theme' === $_GET['action'] && ! empty( $_GET['enabled'] ) ) { wp_safe_redirect( esc_url( envato_market()->get_page_url() ) ); exit; } } } /** * Add authorization notices. * * @since 1.0.0 */ public function add_notices() { if ( $this->are_we_on_settings_page() ) { // @codeCoverageIgnoreStart if ( get_site_transient( envato_market()->get_option_name() . '_check_token' ) || ( isset( $_GET['authorization'] ) && 'check' === $_GET['authorization'] ) ) { delete_site_transient( envato_market()->get_option_name() . '_check_token' ); self::authorization_redirect(); } // @codeCoverageIgnoreEnd // Get the option array. $option = envato_market()->get_options(); // Display success/error notices. if ( ! empty( $option['notices'] ) ) { self::delete_transients(); // Show succes notice. if ( isset( $option['notices']['success'] ) ) { add_action( ( ENVATO_MARKET_NETWORK_ACTIVATED ? 'network_' : '' ) . 'admin_notices', array( $this, 'render_success_notice', ) ); } // Show succes no-items notice. if ( isset( $option['notices']['success-no-items'] ) ) { add_action( ( ENVATO_MARKET_NETWORK_ACTIVATED ? 'network_' : '' ) . 'admin_notices', array( $this, 'render_success_no_items_notice', ) ); } // Show single-use succes notice. if ( isset( $option['notices']['success-single-use'] ) ) { add_action( ( ENVATO_MARKET_NETWORK_ACTIVATED ? 'network_' : '' ) . 'admin_notices', array( $this, 'render_success_single_use_notice', ) ); } // Show error notice. if ( isset( $option['notices']['error'] ) ) { add_action( ( ENVATO_MARKET_NETWORK_ACTIVATED ? 'network_' : '' ) . 'admin_notices', array( $this, 'render_error_notice', ) ); } // Show invalid permissions error notice. if ( isset( $option['notices']['error-permissions'] ) ) { add_action( ( ENVATO_MARKET_NETWORK_ACTIVATED ? 'network_' : '' ) . 'admin_notices', array( $this, 'render_error_permissions', ) ); } // Show single-use error notice. if ( isset( $option['notices']['error-single-use'] ) ) { add_action( ( ENVATO_MARKET_NETWORK_ACTIVATED ? 'network_' : '' ) . 'admin_notices', array( $this, 'render_error_single_use_notice', ) ); } // Show missing zip notice. if ( isset( $option['notices']['missing-package-zip'] ) ) { add_action( ( ENVATO_MARKET_NETWORK_ACTIVATED ? 'network_' : '' ) . 'admin_notices', array( $this, 'render_error_missing_zip', ) ); } // Show missing http connection error. if ( isset( $option['notices']['http_error'] ) ) { add_action( ( ENVATO_MARKET_NETWORK_ACTIVATED ? 'network_' : '' ) . 'admin_notices', array( $this, 'render_error_http', ) ); } // Update the saved data so the notice disappears on the next page load. unset( $option['notices'] ); envato_market()->set_options( $option ); } } } /** * Set the API values. * * @since 1.0.0 */ public function set_items() { if ( $this->are_we_on_settings_page() ) { envato_market()->items()->set_themes(); envato_market()->items()->set_plugins(); } } /** * Check if we're on the settings page. * * @since 2.0.0 * @access private */ private function are_we_on_settings_page() { return 'toplevel_page_' . envato_market()->get_slug() === get_current_screen()->id || 'toplevel_page_' . envato_market()->get_slug() . '-network' === get_current_screen()->id; } /** * Check for authorization and redirect. * * @since 1.0.0 * @access private * @codeCoverageIgnore */ private function authorization_redirect() { self::authorization(); wp_safe_redirect( esc_url( envato_market()->get_page_url() . '#settings' ) ); exit; } /** * Set the Envato API authorization value. * * @since 1.0.0 */ public function authorization() { // Get the option array. $option = envato_market()->get_options(); $option['notices'] = array(); // Check for global token. if ( envato_market()->get_option( 'token' ) || envato_market()->api()->token ) { $notice = 'success'; $scope_check = $this->authorize_token_permissions(); if ( 'http_error' === $scope_check ) { $notice = 'http_error'; } elseif ( 'error' === $this->authorize_total_items() || 'error' === $scope_check ) { $notice = 'error'; } else { if ( 'missing-permissions' == $scope_check ) { $notice = 'error-permissions'; } elseif ( 'too-many-permissions' === $scope_check ) { $notice = 'error-permissions'; } else { $themes_notice = $this->authorize_themes(); $plugins_notice = $this->authorize_plugins(); if ( 'error' === $themes_notice || 'error' === $plugins_notice ) { $notice = 'error'; } elseif ( 'success-no-themes' === $themes_notice && 'success-no-plugins' === $plugins_notice ) { $notice = 'success-no-items'; } } } $option['notices'][ $notice ] = true; } // Check for single-use token. if ( ! empty( $option['items'] ) ) { $failed = false; foreach ( $option['items'] as $key => $item ) { if ( empty( $item['name'] ) || empty( $item['token'] ) || empty( $item['id'] ) || empty( $item['type'] ) || empty( $item['authorized'] ) ) { continue; } $request_args = array( 'headers' => array( 'Authorization' => 'Bearer ' . $item['token'], ), ); // Uncached API response with single-use token. $response = envato_market()->api()->item( $item['id'], $request_args ); if ( ! is_wp_error( $response ) && isset( $response['id'] ) ) { $option['items'][ $key ]['authorized'] = 'success'; } else { if ( is_wp_error( $response ) ) { $this->store_additional_error_debug_information( 'Unable to query single item ID ' . $item['id'], $response->get_error_message(), $response->get_error_data() ); } $failed = true; $option['items'][ $key ]['authorized'] = 'failed'; } } if ( true === $failed ) { $option['notices']['error-single-use'] = true; } else { $option['notices']['success-single-use'] = true; } } // Set the option array. if ( ! empty( $option['notices'] ) ) { envato_market()->set_options( $option ); } } /** * Check that themes are authorized. * * @return bool * @since 1.0.0 */ public function authorize_total_items() { $response = envato_market()->api()->request( 'https://api.envato.com/v1/market/total-items.json' ); $notice = 'success'; if ( is_wp_error( $response ) ) { $notice = 'error'; $this->store_additional_error_debug_information( 'Failed to query total number of items in API response', $response->get_error_message(), $response->get_error_data() ); } elseif ( ! isset( $response['total-items'] ) ) { $notice = 'error'; $this->store_additional_error_debug_information( 'Incorrect response from API when querying total items' ); } return $notice; } /** * Get the required API permissions for this plugin to work. * * @single 2.0.1 * * @return array */ public function get_required_permissions() { return apply_filters( 'envato_market_required_permissions', array( 'default' => 'View and search Envato sites', 'purchase:download' => 'Download your purchased items', 'purchase:list' => 'List purchases you\'ve made', ) ); } /** * Return the URL a user needs to click to generate a personal token. * * @single 2.0.1 * * @return string The full URL to request a token. */ public function get_generate_token_url() { return 'https://build.envato.com/create-token/?' . implode( '&', array_map( function ( $val ) { return $val . '=t'; }, array_keys( $this->get_required_permissions() ) ) ); } /** * Check that themes are authorized. * * @return bool * @since 1.0.0 */ public function authorize_token_permissions() { $response = envato_market()->api()->request( 'https://api.envato.com/whoami' ); $notice = 'success'; if ( is_wp_error( $response ) && ( $response->get_error_code() === 'http_error' || $response->get_error_code() == 500 ) ) { $this->store_additional_error_debug_information( 'An error occured checking token permissions', $response->get_error_message(), $response->get_error_data() ); $notice = 'http_error'; } elseif ( is_wp_error( $response ) || ! isset( $response['scopes'] ) || ! is_array( $response['scopes'] ) ) { $this->store_additional_error_debug_information( 'No scopes found in API response message', $response->get_error_message(), $response->get_error_data() ); $notice = 'error'; } else { $minimum_scopes = $this->get_required_permissions(); $maximum_scopes = array( 'default' => 'Default' ) + $minimum_scopes; foreach ( $minimum_scopes as $required_scope => $required_scope_name ) { if ( ! in_array( $required_scope, $response['scopes'] ) ) { // The scope minimum required scope doesn't exist. $this->store_additional_error_debug_information( 'Could not find required API permission scope in output.', $required_scope ); $notice = 'missing-permissions'; } } foreach ( $response['scopes'] as $scope ) { if ( ! isset( $maximum_scopes[ $scope ] ) ) { // The available scope is outside our maximum bounds. $this->store_additional_error_debug_information( 'Found too many permissions on token.', $scope ); $notice = 'too-many-permissions'; } } } return $notice; } /** * Check that themes or plugins are authorized and downloadable. * * @param string $type The filter type, either 'themes' or 'plugins'. Default 'themes'. * * @return bool|null * @since 1.0.0 */ public function authorize_items( $type = 'themes' ) { $api_url = 'https://api.envato.com/v2/market/buyer/list-purchases?filter_by=wordpress-' . $type; $response = envato_market()->api()->request( $api_url ); $notice = 'success'; if ( is_wp_error( $response ) ) { $notice = 'error'; $this->store_additional_error_debug_information( 'Error listing buyer purchases.', $response->get_error_message(), $response->get_error_data() ); } elseif ( empty( $response ) ) { $notice = 'error'; $this->store_additional_error_debug_information( 'Empty API result listing buyer purchases' ); } elseif ( empty( $response['results'] ) ) { $notice = 'success-no-' . $type; } else { shuffle( $response['results'] ); $item = array_shift( $response['results'] ); if ( ! isset( $item['item']['id'] ) || ! envato_market()->api()->download( $item['item']['id'] ) ) { $this->store_additional_error_debug_information( 'Failed to find the correct item format in API response' ); $notice = 'error'; } } return $notice; } /** * Check that themes are authorized. * * @return bool * @since 1.0.0 */ public function authorize_themes() { return $this->authorize_items( 'themes' ); } /** * Check that plugins are authorized. * * @return bool * @since 1.0.0 */ public function authorize_plugins() { return $this->authorize_items( 'plugins' ); } /** * Install plugin. * * @param string $plugin The plugin item ID. * * @since 1.0.0 * @codeCoverageIgnore */ public function install_plugin( $plugin ) { if ( ! current_user_can( 'install_plugins' ) ) { $msg = ' <div class="wrap"> <h1>' . __( 'Installing Plugin...', 'envato-market' ) . '</h1> <p>' . __( 'You do not have sufficient permissions to install plugins on this site.', 'envato-market' ) . '</p> <a href="' . esc_url( 'admin.php?page=' . envato_market()->get_slug() . '&tab=plugins' ) . '">' . __( 'Return to Plugin Installer', 'envato-market' ) . '</a> </div>'; wp_die( $msg ); } check_admin_referer( 'install-plugin_' . $plugin ); envato_market()->items()->set_plugins( true ); $install = envato_market()->items()->plugins( 'install' ); $api = new stdClass(); foreach ( $install as $value ) { if ( absint( $value['id'] ) === absint( $plugin ) ) { $api->name = $value['name']; $api->version = $value['version']; } } $array_api = (array) $api; if ( empty( $array_api ) ) { $msg = ' <div class="wrap"> <h1>' . __( 'Installing Plugin...', 'envato-market' ) . '</h1> <p>' . __( 'An error occurred, please check that the item ID is correct.', 'envato-market' ) . '</p> <a href="' . esc_url( 'admin.php?page=' . envato_market()->get_slug() . '&tab=plugins' ) . '">' . __( 'Return to Plugin Installer', 'envato-market' ) . '</a> </div>'; wp_die( $msg ); } $title = sprintf( __( 'Installing Plugin: %s', 'envato-market' ), esc_html( $api->name . ' ' . $api->version ) ); $nonce = 'install-plugin_' . $plugin; $url = 'admin.php?page=' . envato_market()->get_slug() . '&action=install-plugin&plugin=' . urlencode( $plugin ); $type = 'web'; // Install plugin type, From Web or an Upload. $api->download_link = envato_market()->api()->download( $plugin, $this->set_bearer_args( $plugin ) ); // Must have the upgrader & skin. require envato_market()->get_plugin_path() . '/inc/admin/class-envato-market-theme-upgrader.php'; require envato_market()->get_plugin_path() . '/inc/admin/class-envato-market-theme-installer-skin.php'; $upgrader = new Envato_Market_Plugin_Upgrader( new Envato_Market_Plugin_Installer_Skin( compact( 'title', 'url', 'nonce', 'plugin', 'api' ) ) ); $upgrader->install( $api->download_link ); } /** * Install theme. * * @param string $theme The theme item ID. * * @since 1.0.0 * @codeCoverageIgnore */ public function install_theme( $theme ) { if ( ! current_user_can( 'install_themes' ) ) { $msg = ' <div class="wrap"> <h1>' . __( 'Installing Theme...', 'envato-market' ) . '</h1> <p>' . __( 'You do not have sufficient permissions to install themes on this site.', 'envato-market' ) . '</p> <a href="' . esc_url( 'admin.php?page=' . envato_market()->get_slug() . '&tab=themes' ) . '">' . __( 'Return to Theme Installer', 'envato-market' ) . '</a> </div>'; wp_die( $msg ); } check_admin_referer( 'install-theme_' . $theme ); envato_market()->items()->set_themes( true ); $install = envato_market()->items()->themes( 'install' ); $api = new stdClass(); foreach ( $install as $value ) { if ( absint( $value['id'] ) === absint( $theme ) ) { $api->name = $value['name']; $api->version = $value['version']; } } $array_api = (array) $api; if ( empty( $array_api ) ) { $msg = ' <div class="wrap"> <h1>' . __( 'Installing Theme...', 'envato-market' ) . '</h1> <p>' . __( 'An error occurred, please check that the item ID is correct.', 'envato-market' ) . '</p> <a href="' . esc_url( 'admin.php?page=' . envato_market()->get_slug() . '&tab=themes' ) . '">' . __( 'Return to Plugin Installer', 'envato-market' ) . '</a> </div>'; wp_die( $msg ); } wp_enqueue_script( 'customize-loader' ); $title = sprintf( __( 'Installing Theme: %s', 'envato-market' ), esc_html( $api->name . ' ' . $api->version ) ); $nonce = 'install-theme_' . $theme; $url = 'admin.php?page=' . envato_market()->get_slug() . '&action=install-theme&theme=' . urlencode( $theme ); $type = 'web'; // Install theme type, From Web or an Upload. $api->download_link = envato_market()->api()->download( $theme, $this->set_bearer_args( $theme ) ); // Must have the upgrader & skin. require_once envato_market()->get_plugin_path() . '/inc/admin/class-envato-market-theme-upgrader.php'; require_once envato_market()->get_plugin_path() . '/inc/admin/class-envato-market-theme-installer-skin.php'; $upgrader = new Envato_Market_Theme_Upgrader( new Envato_Market_Theme_Installer_Skin( compact( 'title', 'url', 'nonce', 'api' ) ) ); $upgrader->install( $api->download_link ); } /** * AJAX handler for adding items that use a non global token. * * @since 1.0.0 * @codeCoverageIgnore */ public function ajax_add_item() { if ( ! check_ajax_referer( self::AJAX_ACTION, 'nonce', false ) ) { status_header( 400 ); wp_send_json_error( 'bad_nonce' ); } elseif ( 'POST' !== $_SERVER['REQUEST_METHOD'] ) { status_header( 405 ); wp_send_json_error( 'bad_method' ); } elseif ( empty( $_POST['token'] ) ) { wp_send_json_error( array( 'message' => __( 'The Token is missing.', 'envato-market' ) ) ); } elseif ( empty( $_POST['id'] ) ) { wp_send_json_error( array( 'message' => __( 'The Item ID is missing.', 'envato-market' ) ) ); } $args = array( 'headers' => array( 'Authorization' => 'Bearer ' . $_POST['token'], ), ); $request = envato_market()->api()->item( $_POST['id'], $args ); if ( false === $request ) { wp_send_json_error( array( 'message' => __( 'The Token or Item ID is incorrect.', 'envato-market' ) ) ); } if ( false === envato_market()->api()->download( $_POST['id'], $args ) ) { wp_send_json_error( array( 'message' => __( 'The item cannot be downloaded.', 'envato-market' ) ) ); } if ( isset( $request['number_of_sales'] ) ) { $type = 'plugin'; } else { $type = 'theme'; } if ( isset( $type ) ) { $response = array( 'name' => $request['name'], 'token' => $_POST['token'], 'id' => $_POST['id'], 'type' => $type, 'authorized' => 'success', ); $options = get_option( envato_market()->get_option_name(), array() ); if ( ! empty( $options['items'] ) ) { $options['items'] = array_values( $options['items'] ); $key = count( $options['items'] ); } else { $options['items'] = array(); $key = 0; } $options['items'][] = $response; envato_market()->set_options( $options ); // Rebuild the theme cache. if ( 'theme' === $type ) { envato_market()->items()->set_themes( true, false ); $install_link = add_query_arg( array( 'page' => envato_market()->get_slug(), 'action' => 'install-theme', 'id' => $_POST['id'], ), self_admin_url( 'admin.php' ) ); $request['install'] = wp_nonce_url( $install_link, 'install-theme_' . $_POST['id'] ); } // Rebuild the plugin cache. if ( 'plugin' === $type ) { envato_market()->items()->set_plugins( true, false ); $install_link = add_query_arg( array( 'page' => envato_market()->get_slug(), 'action' => 'install-plugin', 'id' => $_POST['id'], ), self_admin_url( 'admin.php' ) ); $request['install'] = wp_nonce_url( $install_link, 'install-plugin_' . $_POST['id'] ); } $response['key'] = $key; $response['item'] = $request; wp_send_json_success( $response ); } wp_send_json_error( array( 'message' => __( 'An unknown error occurred.', 'envato-market' ) ) ); } /** * AJAX handler for removing items that use a non global token. * * @since 1.0.0 * @codeCoverageIgnore */ public function ajax_remove_item() { if ( ! check_ajax_referer( self::AJAX_ACTION, 'nonce', false ) ) { status_header( 400 ); wp_send_json_error( 'bad_nonce' ); } elseif ( 'POST' !== $_SERVER['REQUEST_METHOD'] ) { status_header( 405 ); wp_send_json_error( 'bad_method' ); } elseif ( empty( $_POST['id'] ) ) { wp_send_json_error( array( 'message' => __( 'The Item ID is missing.', 'envato-market' ) ) ); } $options = get_option( envato_market()->get_option_name(), array() ); $type = ''; foreach ( $options['items'] as $key => $item ) { if ( $item['id'] === $_POST['id'] ) { $type = $item['type']; unset( $options['items'][ $key ] ); break; } } $options['items'] = array_values( $options['items'] ); envato_market()->set_options( $options ); // Rebuild the theme cache. if ( 'theme' === $type ) { envato_market()->items()->set_themes( true, false ); } // Rebuild the plugin cache. if ( 'plugin' === $type ) { envato_market()->items()->set_plugins( true, false ); } wp_send_json_success(); } /** * AJAX handler for performing a healthcheck of the current website. * * @since 2.0.6 * @codeCoverageIgnore */ public function ajax_healthcheck() { if ( ! check_ajax_referer( self::AJAX_ACTION, 'nonce', false ) ) { status_header( 400 ); wp_send_json_error( 'bad_nonce' ); } elseif ( 'POST' !== $_SERVER['REQUEST_METHOD'] ) { status_header( 405 ); wp_send_json_error( 'bad_method' ); } $limits = $this->get_server_limits(); wp_send_json_success( array( 'limits' => $limits ) ); } /** * AJAX handler for performing a healthcheck of the current website. * * @since 2.0.6 * @codeCoverageIgnore */ public function get_server_limits() { $limits = []; // Check memory limit is > 256 M try { $memory_limit = wp_convert_hr_to_bytes( ini_get( 'memory_limit' ) ); $memory_limit_desired = 256; $memory_limit_ok = $memory_limit < 0 || $memory_limit >= $memory_limit_desired * 1024 * 1024; $memory_limit_in_mb = $memory_limit < 0 ? 'Unlimited' : floor( $memory_limit / ( 1024 * 1024 ) ) . 'M'; $limits['memory_limit'] = [ 'title' => 'PHP Memory Limit', 'ok' => $memory_limit_ok, 'message' => $memory_limit_ok ? "is ok at ${memory_limit_in_mb}." : "${memory_limit_in_mb} may be too small. If you are having issues please set your PHP memory limit to at least 256M - or ask your hosting provider to do this if you're unsure." ]; } catch ( \Exception $e ) { $limits['memory_limit'] = [ 'title' => 'PHP Memory Limit', 'ok' => false, 'message' => 'Failed to check memory limit. If you are having issues please ask hosting provider to raise the memory limit for you.' ]; } // Check upload size. try { $upload_size_desired = 80; $upload_max_filesize = wp_max_upload_size(); $upload_max_filesize_ok = $upload_max_filesize < 0 || $upload_max_filesize >= $upload_size_desired * 1024 * 1024; $upload_max_filesize_in_mb = $upload_max_filesize < 0 ? 'Unlimited' : floor( $upload_max_filesize / ( 1024 * 1024 ) ) . 'M'; $limits['upload'] = [ 'ok' => $upload_max_filesize_ok, 'title' => 'PHP Upload Limits', 'message' => $upload_max_filesize_ok ? "is ok at $upload_max_filesize_in_mb." : "$upload_max_filesize_in_mb may be too small. If you are having issues please set your PHP upload limits to at least ${upload_size_desired}M - or ask your hosting provider to do this if you're unsure.", ]; } catch ( \Exception $e ) { $limits['upload'] = [ 'title' => 'PHP Upload Limits', 'ok' => false, 'message' => 'Failed to check upload limit. If you are having issues please ask hosting provider to raise the upload limit for you.' ]; } // Check max_input_vars. try { $max_input_vars = ini_get( 'max_input_vars' ); $max_input_vars_desired = 1000; $max_input_vars_ok = $max_input_vars < 0 || $max_input_vars >= $max_input_vars_desired; $limits['max_input_vars'] = [ 'ok' => $max_input_vars_ok, 'title' => 'PHP Max Input Vars', 'message' => $max_input_vars_ok ? "is ok at $max_input_vars." : "$max_input_vars may be too small. If you are having issues please set your PHP max input vars to at least $max_input_vars_desired - or ask your hosting provider to do this if you're unsure.", ]; } catch ( \Exception $e ) { $limits['max_input_vars'] = [ 'title' => 'PHP Max Input Vars', 'ok' => false, 'message' => 'Failed to check input vars limit. If you are having issues please ask hosting provider to raise the input vars limit for you.' ]; } // Check max_execution_time. try { $max_execution_time = ini_get( 'max_execution_time' ); $max_execution_time_desired = 60; $max_execution_time_ok = $max_execution_time <= 0 || $max_execution_time >= $max_execution_time_desired; $limits['max_execution_time'] = [ 'ok' => $max_execution_time_ok, 'title' => 'PHP Execution Time', 'message' => $max_execution_time_ok ? "PHP execution time limit is ok at ${max_execution_time}." : "$max_execution_time is too small. Please set your PHP max execution time to at least $max_execution_time_desired - or ask your hosting provider to do this if you're unsure.", ]; } catch ( \Exception $e ) { $limits['max_execution_time'] = [ 'title' => 'PHP Execution Time', 'ok' => false, 'message' => 'Failed to check PHP execution time limit. Please ask hosting provider to raise this limit for you.' ]; } // Check various hostname connectivity. $hosts_to_check = array( array( 'hostname' => 'envato.github.io', 'url' => 'https://envato.github.io/wp-envato-market/dist/update-check.json', 'title' => 'Plugin Update API', ), array( 'hostname' => 'api.envato.com', 'url' => 'https://api.envato.com/ping', 'title' => 'Envato Market API', ), array( 'hostname' => 'marketplace.envato.com', 'url' => 'https://marketplace.envato.com/robots.txt', 'title' => 'Download API', ), ); foreach ( $hosts_to_check as $host ) { try { $response = wp_remote_get( $host['url'], [ 'user-agent' => 'WordPress - Envato Market ' . envato_market()->get_version(), 'timeout' => 5, ] ); $response_code = wp_remote_retrieve_response_code( $response ); if ( $response && ! is_wp_error( $response ) && $response_code === 200 ) { $limits[ $host['hostname'] ] = [ 'ok' => true, 'title' => $host['title'], 'message' => 'Connected ok.', ]; } else { $limits[ $host['hostname'] ] = [ 'ok' => false, 'title' => $host['title'], 'message' => "Connection failed. Status '$response_code'. Please ensure PHP is allowed to connect to the host '" . $host['hostname'] . "' - or ask your hosting provider to do this if you’re unsure. " . ( is_wp_error( $response ) ? $response->get_error_message() : '' ), ]; } } catch ( \Exception $e ) { $limits[ $host['hostname'] ] = [ 'ok' => true, 'title' => $host['title'], 'message' => "Connection failed. Please contact the hosting provider and ensure PHP is allowed to connect to the host '" . $host['hostname'] . "'. " . $e->getMessage(), ]; } } // Check authenticated API request $response = envato_market()->api()->request( 'https://api.envato.com/whoami' ); if ( is_wp_error( $response ) ) { $limits['authentication'] = [ 'ok' => false, 'title' => 'Envato API Authentication', 'message' => "Not currently authenticated with the Envato API. Please add your API token. " . $response->get_error_message(), ]; } elseif ( ! isset( $response['scopes'] ) ) { $limits['authentication'] = [ 'ok' => false, 'title' => 'Envato API Authentication', 'message' => "Missing API permissions. Please re-create your Envato API token with the correct permissions. ", ]; } else { $minimum_scopes = $this->get_required_permissions(); $maximum_scopes = array( 'default' => 'Default' ) + $minimum_scopes; $missing_scopes = array(); $additional_scopes = array(); foreach ( $minimum_scopes as $required_scope => $required_scope_name ) { if ( ! in_array( $required_scope, $response['scopes'] ) ) { // The scope minimum required scope doesn't exist. $missing_scopes [] = $required_scope; } } foreach ( $response['scopes'] as $scope ) { if ( ! isset( $maximum_scopes[ $scope ] ) ) { // The available scope is outside our maximum bounds. $additional_scopes [] = $scope; } } $limits['authentication'] = [ 'ok' => true, 'title' => 'Envato API Authentication', 'message' => "Authenticated successfully with correct scopes: " . implode( ', ', $response['scopes'] ), ]; } $debug_enabled = defined( 'WP_DEBUG' ) && WP_DEBUG; $limits['wp_debug'] = [ 'ok' => ! $debug_enabled, 'title' => 'WP Debug', 'message' => $debug_enabled ? 'If you’re on a production website, it’s best to set WP_DEBUG to false, please ask your hosting provider to do this if you’re unsure.' : 'WP Debug is disabled, all ok.', ]; $zip_archive_installed = class_exists( '\ZipArchive' ); $limits['zip_archive'] = [ 'ok' => $zip_archive_installed, 'title' => 'ZipArchive Support', 'message' => $zip_archive_installed ? 'ZipArchive is available.' : 'ZipArchive is not available. If you have issues installing or updating items please ask your hosting provider to enable ZipArchive.', ]; $php_version_ok = version_compare( PHP_VERSION, '7.0', '>=' ); $limits['php_version'] = [ 'ok' => $php_version_ok, 'title' => 'PHP Version', 'message' => $php_version_ok ? 'PHP version is ok at ' . PHP_VERSION . '.' : 'Please ask the hosting provider to upgrade your PHP version to at least 7.0 or above.', ]; require_once( ABSPATH . 'wp-admin/includes/file.php' ); $current_filesystem_method = get_filesystem_method(); if ( $current_filesystem_method !== 'direct' ) { $limits['filesystem_method'] = [ 'ok' => false, 'title' => 'WordPress Filesystem', 'message' => 'Please enable WordPress FS_METHOD direct - or ask your hosting provider to do this if you’re unsure.', ]; } $wp_upload_dir = wp_upload_dir(); $upload_base_dir = $wp_upload_dir['basedir']; $upload_base_dir_writable = is_writable( $upload_base_dir ); $limits['wp_content_writable'] = [ 'ok' => $upload_base_dir_writable, 'title' => 'WordPress File Permissions', 'message' => $upload_base_dir_writable ? 'is ok.' : 'Please set correct WordPress PHP write permissions for the wp-content directory - or ask your hosting provider to do this if you’re unsure.', ]; $active_plugins = get_option( 'active_plugins' ); $active_plugins_ok = count( $active_plugins ) < 15; if ( ! $active_plugins_ok ) { $limits['active_plugins'] = [ 'ok' => false, 'title' => 'Active Plugins', 'message' => 'Please try to reduce the number of active plugins on your WordPress site, as this will slow things down.', ]; } return $limits; } /** * Admin page callback. * * @since 1.0.0 */ public function render_admin_callback() { require( envato_market()->get_plugin_path() . 'inc/admin/view/callback/admin.php' ); } /** * OAuth section callback. * * @since 1.0.0 */ public function render_oauth_section_callback() { require( envato_market()->get_plugin_path() . 'inc/admin/view/callback/section/oauth.php' ); } /** * Items section callback. * * @since 1.0.0 */ public function render_items_section_callback() { require( envato_market()->get_plugin_path() . 'inc/admin/view/callback/section/items.php' ); } /** * Token setting callback. * * @since 1.0.0 */ public function render_token_setting_callback() { require( envato_market()->get_plugin_path() . 'inc/admin/view/callback/setting/token.php' ); } /** * Items setting callback. * * @since 1.0.0 */ public function render_items_setting_callback() { require( envato_market()->get_plugin_path() . 'inc/admin/view/callback/setting/items.php' ); } /** * Intro * * @since 1.0.0 */ public function render_intro_partial() { require( envato_market()->get_plugin_path() . 'inc/admin/view/partials/intro.php' ); } /** * Tabs * * @since 1.0.0 */ public function render_tabs_partial() { require( envato_market()->get_plugin_path() . 'inc/admin/view/partials/tabs.php' ); } /** * Settings panel * * @since 1.0.0 */ public function render_settings_panel_partial() { require( envato_market()->get_plugin_path() . 'inc/admin/view/partials/settings.php' ); } /** * Help panel * * @since 2.0.1 */ public function render_help_panel_partial() { require( envato_market()->get_plugin_path() . 'inc/admin/view/partials/help.php' ); } /** * Themes panel * * @since 1.0.0 */ public function render_themes_panel_partial() { require( envato_market()->get_plugin_path() . 'inc/admin/view/partials/themes.php' ); } /** * Plugins panel * * @since 1.0.0 */ public function render_plugins_panel_partial() { require( envato_market()->get_plugin_path() . 'inc/admin/view/partials/plugins.php' ); } /** * Success notice. * * @since 1.0.0 */ public function render_success_notice() { require( envato_market()->get_plugin_path() . 'inc/admin/view/notice/success.php' ); } /** * Success no-items notice. * * @since 1.0.0 */ public function render_success_no_items_notice() { require( envato_market()->get_plugin_path() . 'inc/admin/view/notice/success-no-items.php' ); } /** * Success single-use notice. * * @since 1.0.0 */ public function render_success_single_use_notice() { require( envato_market()->get_plugin_path() . 'inc/admin/view/notice/success-single-use.php' ); } /** * Error details. * * @since 2.0.2 */ public function render_additional_error_details() { $error_details = get_site_transient( envato_market()->get_option_name() . '_error_information' ); if ( $error_details && ! empty( $error_details['title'] ) ) { extract( $error_details ); require( envato_market()->get_plugin_path() . 'inc/admin/view/notice/error-details.php' ); } } /** * Error notice. * * @since 1.0.0 */ public function render_error_notice() { require( envato_market()->get_plugin_path() . 'inc/admin/view/notice/error.php' ); $this->render_additional_error_details(); } /** * Permission error notice. * * @since 2.0.1 */ public function render_error_permissions() { require( envato_market()->get_plugin_path() . 'inc/admin/view/notice/error-permissions.php' ); $this->render_additional_error_details(); } /** * Error single-use notice. * * @since 1.0.0 */ public function render_error_single_use_notice() { require( envato_market()->get_plugin_path() . 'inc/admin/view/notice/error-single-use.php' ); $this->render_additional_error_details(); } /** * Error missing zip. * * @since 2.0.1 */ public function render_error_missing_zip() { require( envato_market()->get_plugin_path() . 'inc/admin/view/notice/error-missing-zip.php' ); $this->render_additional_error_details(); } /** * Error http * * @since 2.0.1 */ public function render_error_http() { require( envato_market()->get_plugin_path() . 'inc/admin/view/notice/error-http.php' ); $this->render_additional_error_details(); } /** * Use the Settings API when in network mode. * * This allows us to make use of the same WordPress Settings API when displaying the menu item in network mode. * * @since 2.0.0 */ public function save_network_settings() { check_admin_referer( envato_market()->get_slug() . '-options' ); global $new_whitelist_options; $options = $new_whitelist_options[ envato_market()->get_slug() ]; foreach ( $options as $option ) { if ( isset( $_POST[ $option ] ) ) { update_site_option( $option, $_POST[ $option ] ); } else { delete_site_option( $option ); } } wp_redirect( envato_market()->get_page_url() ); exit; } /** * Store additional error information in transient so users can self debug. * * @since 2.0.2 */ public function store_additional_error_debug_information( $title, $message = '', $data = [] ) { set_site_transient( envato_market()->get_option_name() . '_error_information', [ 'title' => $title, 'message' => $message, 'data' => $data, ], 120 ); } } endif; admin/class-envato-market-theme-upgrader.php 0000644 00000003723 15132720601 0015136 0 ustar 00 <?php /** * Theme Upgrader class. * * @package Envato_Market */ // Include the WP_Upgrader class. if ( ! class_exists( 'WP_Upgrader', false ) ) : include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; endif; if ( ! class_exists( 'Envato_Market_Theme_Upgrader' ) ) : /** * Extends the WordPress Theme_Upgrader class. * * This class makes modifications to the strings during install & upgrade. * * @class Envato_Market_Plugin_Upgrader * @version 1.0.0 * @since 1.0.0 */ class Envato_Market_Theme_Upgrader extends Theme_Upgrader { /** * Initialize the upgrade strings. * * @since 1.0.0 */ public function upgrade_strings() { parent::upgrade_strings(); $this->strings['downloading_package'] = __( 'Downloading the Envato Market upgrade package…', 'envato-market' ); } /** * Initialize the install strings. * * @since 1.0.0 */ public function install_strings() { parent::install_strings(); $this->strings['downloading_package'] = __( 'Downloading the Envato Market install package…', 'envato-market' ); } } endif; if ( ! class_exists( 'Envato_Market_Plugin_Upgrader' ) ) : /** * Extends the WordPress Plugin_Upgrader class. * * This class makes modifications to the strings during install & upgrade. * * @class Envato_Market_Plugin_Upgrader * @version 1.0.0 * @since 1.0.0 */ class Envato_Market_Plugin_Upgrader extends Plugin_Upgrader { /** * Initialize the upgrade strings. * * @since 1.0.0 */ public function upgrade_strings() { parent::upgrade_strings(); $this->strings['downloading_package'] = __( 'Downloading the Envato Market upgrade package…', 'envato-market' ); } /** * Initialize the install strings. * * @since 1.0.0 */ public function install_strings() { parent::install_strings(); $this->strings['downloading_package'] = __( 'Downloading the Envato Market install package…', 'envato-market' ); } } endif; admin/functions.php 0000644 00000037607 15132720601 0010367 0 ustar 00 <?php /** * Functions * * @package Envato_Market */ /** * Interate over the themes array and displays each theme. * * @since 1.0.0 * * @param string $group The theme group. Options are 'purchased', 'active', 'installed', or 'install'. */ function envato_market_themes_column( $group = 'install' ) { $premium = envato_market()->items()->themes( $group ); if ( empty( $premium ) ) { return; } foreach ( $premium as $slug => $theme ) : $name = $theme['name']; $author = $theme['author']; $version = $theme['version']; $description = $theme['description']; $url = $theme['url']; $author_url = $theme['author_url']; $theme['hasUpdate'] = false; if ( 'active' === $group || 'installed' === $group ) { $get_theme = wp_get_theme( $slug ); if ( $get_theme->exists() ) { $name = $get_theme->get( 'Name' ); $author = $get_theme->get( 'Author' ); $version = $get_theme->get( 'Version' ); $description = $get_theme->get( 'Description' ); $author_url = $get_theme->get( 'AuthorURI' ); if ( version_compare( $version, $theme['version'], '<' ) ) { $theme['hasUpdate'] = true; } } } // Setup the column CSS classes. $classes = array( 'envato-card', 'theme' ); if ( 'active' === $group ) { $classes[] = 'active'; } // Setup the update action links. $update_actions = array(); if ( true === $theme['hasUpdate'] ) { $classes[] = 'update'; $classes[] = 'envato-card-' . esc_attr( $slug ); if ( current_user_can( 'update_themes' ) ) { // Upgrade link. $upgrade_link = add_query_arg( array( 'action' => 'upgrade-theme', 'theme' => esc_attr( $slug ), ), self_admin_url( 'update.php' ) ); $update_actions['update'] = sprintf( '<a class="update-now" href="%1$s" aria-label="%2$s" data-name="%3$s %5$s" data-slug="%4$s" data-version="%5$s">%6$s</a>', wp_nonce_url( $upgrade_link, 'upgrade-theme_' . $slug ), esc_attr__( 'Update %s now', 'envato-market' ), esc_attr( $name ), esc_attr( $slug ), esc_attr( $theme['version'] ), esc_html__( 'Update Available', 'envato-market' ) ); $update_actions['details'] = sprintf( '<a href="%1$s" class="details" title="%2$s" target="_blank">%3$s</a>', esc_url( $url ), esc_attr( $name ), sprintf( __( 'View version %1$s details.', 'envato-market' ), $theme['version'] ) ); } } // Setup the action links. $actions = array(); if ( 'active' === $group && current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) { // Customize theme. $customize_url = admin_url( 'customize.php' ); $customize_url .= '?theme=' . urlencode( $slug ); $customize_url .= '&return=' . urlencode( envato_market()->get_page_url() . '#themes' ); $actions['customize'] = '<a href="' . esc_url( $customize_url ) . '" class="button button-primary load-customize hide-if-no-customize"><span aria-hidden="true">' . __( 'Customize', 'envato-market' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Customize “%s”', 'envato-market' ), $name ) . '</span></a>'; } elseif ( 'installed' === $group ) { $can_activate = true; // @codeCoverageIgnoreStart // Multisite needs special attention. if ( is_multisite() && ! $get_theme->is_allowed( 'both' ) && current_user_can( 'manage_sites' ) ) { $can_activate = false; if ( current_user_can( 'manage_network_themes' ) ) { $actions['network_enable'] = '<a href="' . esc_url( network_admin_url( wp_nonce_url( 'themes.php?action=enable&theme=' . urlencode( $slug ) . '&paged=1&s', 'enable-theme_' . $slug ) ) ) . '" class="button"><span aria-hidden="true">' . __( 'Network Enable', 'envato-market' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Network Enable “%s”', 'envato-market' ), $name ) . '</span></a>'; } } // @codeCoverageIgnoreEnd // Can activate theme. if ( $can_activate && current_user_can( 'switch_themes' ) ) { $activate_link = add_query_arg( array( 'action' => 'activate', 'stylesheet' => urlencode( $slug ), ), admin_url( 'themes.php' ) ); $activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $slug ); // Activate link. $actions['activate'] = '<a href="' . esc_url( $activate_link ) . '" class="button"><span aria-hidden="true">' . __( 'Activate', 'envato-market' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Activate “%s”', 'envato-market' ), $name ) . '</span></a>'; // Preview theme. if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) { $preview_url = admin_url( 'customize.php' ); $preview_url .= '?theme=' . urlencode( $slug ); $preview_url .= '&return=' . urlencode( envato_market()->get_page_url() . '#themes' ); $actions['customize_preview'] = '<a href="' . esc_url( $preview_url ) . '" class="button button-primary load-customize hide-if-no-customize"><span aria-hidden="true">' . __( 'Live Preview', 'envato-market' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview “%s”', 'envato-market' ), $name ) . '</span></a>'; } } } elseif ( 'install' === $group && current_user_can( 'install_themes' ) ) { // Install link. $install_link = add_query_arg( array( 'page' => envato_market()->get_slug(), 'action' => 'install-theme', 'id' => $theme['id'], ), self_admin_url( 'admin.php' ) ); $actions['install'] = ' <a href="' . wp_nonce_url( $install_link, 'install-theme_' . $theme['id'] ) . '" class="button button-primary"> <span aria-hidden="true">' . __( 'Install', 'envato-market' ) . '</span> <span class="screen-reader-text">' . sprintf( __( 'Install %s', 'envato-market' ), $name ) . '</span> </a>'; } if ( 0 === strrpos( html_entity_decode( $author ), '<a ' ) ) { $author_link = $author; } else { $author_link = '<a href="' . esc_url( $author_url ) . '">' . esc_html( $author ) . '</a>'; } ?> <div class="envato-market-block" data-id="<?php echo esc_attr( $theme['id'] ); ?>"> <div class="<?php echo esc_attr( implode( ' ', $classes ) ); ?>"> <div class="envato-card-top"> <a href="<?php echo esc_url( $url ); ?>" class="column-icon"> <img src="<?php echo esc_url( $theme['thumbnail_url'] ); ?>"/> </a> <div class="column-name"> <h4> <a href="<?php echo esc_url( $url ); ?>"><?php echo esc_html( $name ); ?></a> <span class="version" aria-label="<?php esc_attr_e( 'Version %s', 'envato-market' ); ?>"> <?php echo esc_html( sprintf( __( 'Version %s', 'envato-market' ), $version ) ); ?> </span> </h4> </div> <div class="column-description"> <div class="description"> <?php echo wp_kses_post( wpautop( strip_tags( $description ) ) ); ?> </div> <p class="author"> <cite> <?php esc_html_e( 'By', 'envato-market' ); ?> <?php echo wp_kses_post( $author_link ); ?> </cite> </p> </div> <?php if ( ! empty( $update_actions ) ) { ?> <div class="column-update"> <?php echo implode( "\n", $update_actions ); ?> </div> <?php } ?> </div> <div class="envato-card-bottom"> <div class="column-rating"> <?php if ( ! empty( $theme['rating'] ) ) { if ( is_array( $theme['rating'] ) && ! empty( $theme['rating']['count'] ) ) { wp_star_rating( array( 'rating' => $theme['rating']['count'] > 0 ? ( $theme['rating']['rating'] / 5 * 100 ) : 0, 'type' => 'percent', 'number' => $theme['rating']['count'], ) ); } else { wp_star_rating( array( 'rating' => $theme['rating'] > 0 ? ( $theme['rating'] / 5 * 100 ) : 0, 'type' => 'percent', ) ); } } ?> </div> <div class="column-actions"> <?php echo implode( "\n", $actions ); ?> </div> </div> </div> </div> <?php endforeach; } /** * Interate over the plugins array and displays each plugin. * * @since 1.0.0 * * @param string $group The plugin group. Options are 'purchased', 'active', 'installed', or 'install'. */ function envato_market_plugins_column( $group = 'install' ) { $premium = envato_market()->items()->plugins( $group ); if ( empty( $premium ) ) { return; } $plugins = envato_market()->items()->wp_plugins(); foreach ( $premium as $slug => $plugin ) : $name = $plugin['name']; $author = $plugin['author']; $version = $plugin['version']; $description = $plugin['description']; $url = $plugin['url']; $author_url = $plugin['author_url']; $plugin['hasUpdate'] = false; // Setup the column CSS classes. $classes = array( 'envato-card', 'plugin' ); if ( 'active' === $group ) { $classes[] = 'active'; } // Setup the update action links. $update_actions = array(); // Check for an update. if ( isset( $plugins[ $slug ] ) && version_compare( $plugins[ $slug ]['Version'], $plugin['version'], '<' ) ) { $plugin['hasUpdate'] = true; $classes[] = 'update'; $classes[] = 'envato-card-' . sanitize_key( dirname( $slug ) ); if ( current_user_can( 'update_plugins' ) ) { // Upgrade link. $upgrade_link = add_query_arg( array( 'action' => 'upgrade-plugin', 'plugin' => $slug, ), self_admin_url( 'update.php' ) ); // Details link. $details_link = add_query_arg( array( 'action' => 'upgrade-plugin', 'tab' => 'plugin-information', 'plugin' => dirname( $slug ), 'section' => 'changelog', 'TB_iframe' => 'true', 'width' => 640, 'height' => 662, ), self_admin_url( 'plugin-install.php' ) ); $update_actions['update'] = sprintf( '<a class="update-now" href="%1$s" aria-label="%2$s" data-name="%3$s %6$s" data-plugin="%4$s" data-slug="%5$s" data-version="%6$s">%7$s</a>', wp_nonce_url( $upgrade_link, 'upgrade-plugin_' . $slug ), esc_attr__( 'Update %s now', 'envato-market' ), esc_attr( $name ), esc_attr( $slug ), sanitize_key( dirname( $slug ) ), esc_attr( $version ), esc_html__( 'Update Available', 'envato-market' ) ); $update_actions['details'] = sprintf( '<a href="%1$s" class="thickbox details" title="%2$s">%3$s</a>', esc_url( $details_link ), esc_attr( $name ), sprintf( __( 'View version %1$s details.', 'envato-market' ), $version ) ); } } // Setup the action links. $actions = array(); if ( 'active' === $group ) { // Deactivate link. $deactivate_link = add_query_arg( array( 'action' => 'deactivate', 'plugin' => $slug, ), self_admin_url( 'plugins.php' ) ); $actions['deactivate'] = ' <a href="' . wp_nonce_url( $deactivate_link, 'deactivate-plugin_' . $slug ) . '" class="button"> <span aria-hidden="true">' . __( 'Deactivate', 'envato-market' ) . '</span> <span class="screen-reader-text">' . sprintf( __( 'Deactivate %s', 'envato-market' ), $name ) . '</span> </a>'; } elseif ( 'installed' === $group ) { if ( ! is_multisite() && current_user_can( 'delete_plugins' ) ) { // Delete link. $delete_link = add_query_arg( array( 'action' => 'delete-selected', 'checked[]' => $slug, ), self_admin_url( 'plugins.php' ) ); $actions['delete'] = ' <a href="' . wp_nonce_url( $delete_link, 'bulk-plugins' ) . '" class="button-delete"> <span aria-hidden="true">' . __( 'Delete', 'envato-market' ) . '</span> <span class="screen-reader-text">' . sprintf( __( 'Delete %s', 'envato-market' ), $name ) . '</span> </a>'; } if ( ! is_multisite() && current_user_can( 'activate_plugins' ) ) { // Activate link. $activate_link = add_query_arg( array( 'action' => 'activate', 'plugin' => $slug, ), self_admin_url( 'plugins.php' ) ); $actions['activate'] = ' <a href="' . wp_nonce_url( $activate_link, 'activate-plugin_' . $slug ) . '" class="button"> <span aria-hidden="true">' . __( 'Activate', 'envato-market' ) . '</span> <span class="screen-reader-text">' . sprintf( __( 'Activate %s', 'envato-market' ), $name ) . '</span> </a>'; } // @codeCoverageIgnoreStart // Multisite needs special attention. if ( is_multisite() ) { if ( current_user_can( 'manage_network_plugins' ) ) { $actions['network_activate'] = ' <a href="' . esc_url( network_admin_url( wp_nonce_url( 'plugins.php?action=activate&plugin=' . urlencode( $slug ), 'activate-plugin_' . $slug ) ) ) . '" class="button"> <span aria-hidden="true">' . __( 'Network Activate', 'envato-market' ) . '</span> <span class="screen-reader-text">' . sprintf( __( 'Network Activate %s', 'envato-market' ), $name ) . '</span> </a>'; } } // @codeCoverageIgnoreEnd } elseif ( 'install' === $group && current_user_can( 'install_plugins' ) ) { // Install link. $install_link = add_query_arg( array( 'page' => envato_market()->get_slug(), 'action' => 'install-plugin', 'id' => $plugin['id'], ), self_admin_url( 'admin.php' ) ); $actions['install'] = ' <a href="' . wp_nonce_url( $install_link, 'install-plugin_' . $plugin['id'] ) . '" class="button button-primary"> <span aria-hidden="true">' . __( 'Install', 'envato-market' ) . '</span> <span class="screen-reader-text">' . sprintf( __( 'Install %s', 'envato-market' ), $name ) . '</span> </a>'; } if ( 0 === strrpos( html_entity_decode( $author ), '<a ' ) ) { $author_link = $author; } else { $author_link = '<a href="' . esc_url( $author_url ) . '">' . esc_html( $author ) . '</a>'; } ?> <div class="envato-market-block" data-id="<?php echo esc_attr( $plugin['id'] ); ?>"> <div class="<?php echo esc_attr( implode( ' ', $classes ) ); ?>"> <div class="envato-card-top"> <a href="<?php echo esc_url( $url ); ?>" class="column-icon"> <img src="<?php echo esc_url( $plugin['thumbnail_url'] ); ?>"/> </a> <div class="column-name"> <h4> <a href="<?php echo esc_url( $url ); ?>"><?php echo esc_html( $name ); ?></a> <span class="version" aria-label="<?php esc_attr_e( 'Version %s', 'envato-market' ); ?>"> <?php echo esc_html( sprintf( __( 'Version %s', 'envato-market' ), ( isset( $plugins[ $slug ] ) ? $plugins[ $slug ]['Version'] : $version ) ) ); ?> </span> </h4> </div> <div class="column-description"> <div class="description"> <?php echo wp_kses_post( wpautop( strip_tags( $description ) ) ); ?> </div> <p class="author"> <cite> <?php esc_html_e( 'By', 'envato-market' ); ?> <?php echo wp_kses_post( $author_link ); ?> </cite> </p> </div> <?php if ( ! empty( $update_actions ) ) { ?> <div class="column-update"> <?php echo implode( "\n", $update_actions ); ?> </div> <?php } ?> </div> <div class="envato-card-bottom"> <div class="column-rating"> <?php if ( ! empty( $plugin['rating'] ) ) { if ( is_array( $plugin['rating'] ) && ! empty( $plugin['rating']['count'] ) ) { wp_star_rating( array( 'rating' => $plugin['rating']['rating'] > 0 ? ( $plugin['rating']['rating'] / 5 * 100 ) : 0, 'type' => 'percent', 'number' => $plugin['rating']['count'], ) ); } else { wp_star_rating( array( 'rating' => $plugin['rating'] > 0 ? ( $plugin['rating'] / 5 * 100 ) : 0, 'type' => 'percent', ) ); } } ?> </div> <div class="column-actions"> <?php echo implode( "\n", $actions ); ?> </div> </div> </div> </div> <?php endforeach; } admin/class-envato-market-theme-installer-skin.php 0000644 00000011106 15132720601 0016256 0 ustar 00 <?php /** * Upgrader skin classes. * * @package Envato_Market */ // Include the WP_Upgrader_Skin class. if ( ! class_exists( 'WP_Upgrader_Skin', false ) ) : include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader-skins.php'; endif; if ( ! class_exists( 'Envato_Market_Theme_Installer_Skin' ) ) : /** * Theme Installer Skin. * * @class Envato_Market_Theme_Installer_Skin * @version 1.0.0 * @since 1.0.0 */ class Envato_Market_Theme_Installer_Skin extends Theme_Installer_Skin { /** * Modify the install actions. * * @since 1.0.0 */ public function after() { if ( empty( $this->upgrader->result['destination_name'] ) ) { return; } $theme_info = $this->upgrader->theme_info(); if ( empty( $theme_info ) ) { return; } $name = $theme_info->display( 'Name' ); $stylesheet = $this->upgrader->result['destination_name']; $template = $theme_info->get_template(); $activate_link = add_query_arg( array( 'action' => 'activate', 'template' => urlencode( $template ), 'stylesheet' => urlencode( $stylesheet ), ), admin_url( 'themes.php' ) ); $activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet ); $install_actions = array(); if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) { $install_actions['preview'] = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Live Preview', 'envato-market' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview “%s”', 'envato-market' ), $name ) . '</span></a>'; } if ( is_multisite() ) { if ( current_user_can( 'manage_network_themes' ) ) { $install_actions['network_enable'] = '<a href="' . esc_url( network_admin_url( wp_nonce_url( 'themes.php?action=enable&theme=' . urlencode( $stylesheet ) . '&paged=1&s', 'enable-theme_' . $stylesheet ) ) ) . '" target="_parent">' . __( 'Network Enable', 'envato-market' ) . '</a>'; } } $install_actions['activate'] = '<a href="' . esc_url( $activate_link ) . '" class="activatelink"><span aria-hidden="true">' . __( 'Activate', 'envato-market' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Activate “%s”', 'envato-market' ), $name ) . '</span></a>'; $install_actions['themes_page'] = '<a href="' . esc_url( admin_url( 'admin.php?page=' . envato_market()->get_slug() . '&tab=themes' ) ) . '" target="_parent">' . __( 'Return to Theme Installer', 'envato-market' ) . '</a>'; if ( ! $this->result || is_wp_error( $this->result ) || is_multisite() || ! current_user_can( 'switch_themes' ) ) { unset( $install_actions['activate'], $install_actions['preview'] ); } if ( ! empty( $install_actions ) ) { $this->feedback( implode( ' | ', $install_actions ) ); } } } endif; if ( ! class_exists( 'Envato_Market_Plugin_Installer_Skin' ) ) : /** * Plugin Installer Skin. * * @class Envato_Market_Plugin_Installer_Skin * @version 1.0.0 * @since 1.0.0 */ class Envato_Market_Plugin_Installer_Skin extends Plugin_Installer_Skin { /** * Modify the install actions. * * @since 1.0.0 */ public function after() { $plugin_file = $this->upgrader->plugin_info(); $install_actions = array(); if ( current_user_can( 'activate_plugins' ) ) { $install_actions['activate_plugin'] = '<a href="' . esc_url( wp_nonce_url( 'plugins.php?action=activate&plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) ) . '" target="_parent">' . __( 'Activate Plugin', 'envato-market' ) . '</a>'; } if ( is_multisite() ) { unset( $install_actions['activate_plugin'] ); if ( current_user_can( 'manage_network_plugins' ) ) { $install_actions['network_activate'] = '<a href="' . esc_url( network_admin_url( wp_nonce_url( 'plugins.php?action=activate&plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) ) ) . '" target="_parent">' . __( 'Network Activate', 'envato-market' ) . '</a>'; } } $install_actions['plugins_page'] = '<a href="' . esc_url( admin_url( 'admin.php?page=' . envato_market()->get_slug() . '&tab=plugins' ) ) . '" target="_parent">' . __( 'Return to Plugin Installer', 'envato-market' ) . '</a>'; if ( ! $this->result || is_wp_error( $this->result ) ) { unset( $install_actions['activate_plugin'], $install_actions['site_activate'], $install_actions['network_activate'] ); } if ( ! empty( $install_actions ) ) { $this->feedback( implode( ' | ', $install_actions ) ); } } } endif; class-envato-market-api.php 0000644 00000032563 15132720601 0011712 0 ustar 00 <?php /** * Envato API class. * * @package Envato_Market */ if ( ! class_exists( 'Envato_Market_API' ) && class_exists( 'Envato_Market' ) ) : /** * Creates the Envato API connection. * * @class Envato_Market_API * @version 1.0.0 * @since 1.0.0 */ class Envato_Market_API { /** * The single class instance. * * @since 1.0.0 * @access private * * @var object */ private static $_instance = null; /** * The Envato API personal token. * * @since 1.0.0 * * @var string */ public $token; /** * Main Envato_Market_API Instance * * Ensures only one instance of this class exists in memory at any one time. * * @see Envato_Market_API() * @uses Envato_Market_API::init_globals() Setup class globals. * @uses Envato_Market_API::init_actions() Setup hooks and actions. * * @since 1.0.0 * @static * @return object The one true Envato_Market_API. * @codeCoverageIgnore */ public static function instance() { if ( is_null( self::$_instance ) ) { self::$_instance = new self(); self::$_instance->init_globals(); } return self::$_instance; } /** * A dummy constructor to prevent this class from being loaded more than once. * * @see Envato_Market_API::instance() * * @since 1.0.0 * @access private * @codeCoverageIgnore */ private function __construct() { /* We do nothing here! */ } /** * You cannot clone this class. * * @since 1.0.0 * @codeCoverageIgnore */ public function __clone() { _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'envato-market' ), '1.0.0' ); } /** * You cannot unserialize instances of this class. * * @since 1.0.0 * @codeCoverageIgnore */ public function __wakeup() { _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'envato-market' ), '1.0.0' ); } /** * Setup the class globals. * * @since 1.0.0 * @access private * @codeCoverageIgnore */ private function init_globals() { // Envato API token. $this->token = envato_market()->get_option( 'token' ); } /** * Query the Envato API. * * @uses wp_remote_get() To perform an HTTP request. * * @since 1.0.0 * * @param string $url API request URL, including the request method, parameters, & file type. * @param array $args The arguments passed to `wp_remote_get`. * @return array|WP_Error The HTTP response. */ public function request( $url, $args = array() ) { $defaults = array( 'headers' => array( 'Authorization' => 'Bearer ' . $this->token, 'User-Agent' => 'WordPress - Envato Market ' . envato_market()->get_version(), ), 'timeout' => 14, ); $args = wp_parse_args( $args, $defaults ); $token = trim( str_replace( 'Bearer', '', $args['headers']['Authorization'] ) ); if ( empty( $token ) ) { return new WP_Error( 'api_token_error', __( 'An API token is required.', 'envato-market' ) ); } $debugging_information = [ 'request_url' => $url, ]; // Make an API request. $response = wp_remote_get( esc_url_raw( $url ), $args ); // Check the response code. $response_code = wp_remote_retrieve_response_code( $response ); $response_message = wp_remote_retrieve_response_message( $response ); $debugging_information['response_code'] = $response_code; $debugging_information['response_cf_ray'] = wp_remote_retrieve_header( $response, 'cf-ray' ); $debugging_information['response_server'] = wp_remote_retrieve_header( $response, 'server' ); if ( ! empty( $response->errors ) && isset( $response->errors['http_request_failed'] ) ) { // API connectivity issue, inject notice into transient with more details. $option = envato_market()->get_options(); if ( empty( $option['notices'] ) ) { $option['notices'] = []; } $option['notices']['http_error'] = current( $response->errors['http_request_failed'] ); envato_market()->set_options( $option ); return new WP_Error( 'http_error', esc_html( current( $response->errors['http_request_failed'] ) ), $debugging_information ); } if ( 200 !== $response_code && ! empty( $response_message ) ) { return new WP_Error( $response_code, $response_message, $debugging_information ); } elseif ( 200 !== $response_code ) { return new WP_Error( $response_code, __( 'An unknown API error occurred.', 'envato-market' ), $debugging_information ); } else { $return = json_decode( wp_remote_retrieve_body( $response ), true ); if ( null === $return ) { return new WP_Error( 'api_error', __( 'An unknown API error occurred.', 'envato-market' ), $debugging_information ); } return $return; } } /** * Deferred item download URL. * * @since 1.0.0 * * @param int $id The item ID. * @return string. */ public function deferred_download( $id ) { if ( empty( $id ) ) { return ''; } $args = array( 'deferred_download' => true, 'item_id' => $id, ); return add_query_arg( $args, esc_url( envato_market()->get_page_url() ) ); } /** * Get the item download. * * @since 1.0.0 * * @param int $id The item ID. * @param array $args The arguments passed to `wp_remote_get`. * @return bool|array The HTTP response. */ public function download( $id, $args = array() ) { if ( empty( $id ) ) { return false; } $url = 'https://api.envato.com/v2/market/buyer/download?item_id=' . $id . '&shorten_url=true'; $response = $this->request( $url, $args ); // @todo Find out which errors could be returned & handle them in the UI. if ( is_wp_error( $response ) || empty( $response ) || ! empty( $response['error'] ) ) { return false; } if ( ! empty( $response['wordpress_theme'] ) ) { return $response['wordpress_theme']; } if ( ! empty( $response['wordpress_plugin'] ) ) { return $response['wordpress_plugin']; } // Missing a WordPress theme and plugin, report an error. $option = envato_market()->get_options(); if ( ! isset( $option['notices'] ) ) { $option['notices'] = []; } $option['notices']['missing-package-zip'] = true; envato_market()->set_options( $option ); return false; } /** * Get an item by ID and type. * * @since 1.0.0 * * @param int $id The item ID. * @param array $args The arguments passed to `wp_remote_get`. * @return array The HTTP response. */ public function item( $id, $args = array() ) { $url = 'https://api.envato.com/v2/market/catalog/item?id=' . $id; $response = $this->request( $url, $args ); if ( is_wp_error( $response ) || empty( $response ) ) { return false; } if ( ! empty( $response['wordpress_theme_metadata'] ) ) { return $this->normalize_theme( $response ); } if ( ! empty( $response['wordpress_plugin_metadata'] ) ) { return $this->normalize_plugin( $response ); } return false; } /** * Get the list of available themes. * * @since 1.0.0 * * @param array $args The arguments passed to `wp_remote_get`. * @return array The HTTP response. */ public function themes( $args = array() ) { $themes = array(); $url = 'https://api.envato.com/v2/market/buyer/list-purchases?filter_by=wordpress-themes'; $response = $this->request( $url, $args ); if ( is_wp_error( $response ) || empty( $response ) || empty( $response['results'] ) ) { return $themes; } foreach ( $response['results'] as $theme ) { $themes[] = $this->normalize_theme( $theme['item'] ); } return $themes; } /** * Normalize a theme. * * @since 1.0.0 * * @param array $theme An array of API request values. * @return array A normalized array of values. */ public function normalize_theme( $theme ) { $normalized_theme = array( 'id' => $theme['id'], 'name' => ( ! empty( $theme['wordpress_theme_metadata']['theme_name'] ) ? $theme['wordpress_theme_metadata']['theme_name'] : '' ), 'author' => ( ! empty( $theme['wordpress_theme_metadata']['author_name'] ) ? $theme['wordpress_theme_metadata']['author_name'] : '' ), 'version' => ( ! empty( $theme['wordpress_theme_metadata']['version'] ) ? $theme['wordpress_theme_metadata']['version'] : '' ), 'description' => self::remove_non_unicode( strip_tags( $theme['wordpress_theme_metadata']['description'] ) ), 'url' => ( ! empty( $theme['url'] ) ? $theme['url'] : '' ), 'author_url' => ( ! empty( $theme['author_url'] ) ? $theme['author_url'] : '' ), 'thumbnail_url' => ( ! empty( $theme['thumbnail_url'] ) ? $theme['thumbnail_url'] : '' ), 'rating' => ( ! empty( $theme['rating'] ) ? $theme['rating'] : '' ), 'landscape_url' => '', ); // No main thumbnail in API response, so we grab it from the preview array. if ( empty( $normalized_theme['thumbnail_url'] ) && ! empty( $theme['previews'] ) && is_array( $theme['previews'] ) ) { foreach ( $theme['previews'] as $possible_preview ) { if ( ! empty( $possible_preview['landscape_url'] ) ) { $normalized_theme['landscape_url'] = $possible_preview['landscape_url']; break; } } } if ( empty( $normalized_theme['thumbnail_url'] ) && ! empty( $theme['previews'] ) && is_array( $theme['previews'] ) ) { foreach ( $theme['previews'] as $possible_preview ) { if ( ! empty( $possible_preview['icon_url'] ) ) { $normalized_theme['thumbnail_url'] = $possible_preview['icon_url']; break; } } } return $normalized_theme; } /** * Get the list of available plugins. * * @since 1.0.0 * * @param array $args The arguments passed to `wp_remote_get`. * @return array The HTTP response. */ public function plugins( $args = array() ) { $plugins = array(); $url = 'https://api.envato.com/v2/market/buyer/list-purchases?filter_by=wordpress-plugins'; $response = $this->request( $url, $args ); if ( is_wp_error( $response ) || empty( $response ) || empty( $response['results'] ) ) { return $plugins; } foreach ( $response['results'] as $plugin ) { $plugins[] = $this->normalize_plugin( $plugin['item'] ); } return $plugins; } /** * Normalize a plugin. * * @since 1.0.0 * * @param array $plugin An array of API request values. * @return array A normalized array of values. */ public function normalize_plugin( $plugin ) { $requires = null; $tested = null; $versions = array(); // Set the required and tested WordPress version numbers. foreach ( $plugin['attributes'] as $k => $v ) { if ( ! empty( $v['name'] ) && 'compatible-software' === $v['name'] && ! empty( $v['value'] ) && is_array( $v['value'] ) ) { foreach ( $v['value'] as $version ) { $versions[] = str_replace( 'WordPress ', '', trim( $version ) ); } if ( ! empty( $versions ) ) { $requires = $versions[ count( $versions ) - 1 ]; $tested = $versions[0]; } break; } } $plugin_normalized = array( 'id' => $plugin['id'], 'name' => ( ! empty( $plugin['wordpress_plugin_metadata']['plugin_name'] ) ? $plugin['wordpress_plugin_metadata']['plugin_name'] : '' ), 'author' => ( ! empty( $plugin['wordpress_plugin_metadata']['author'] ) ? $plugin['wordpress_plugin_metadata']['author'] : '' ), 'version' => ( ! empty( $plugin['wordpress_plugin_metadata']['version'] ) ? $plugin['wordpress_plugin_metadata']['version'] : '' ), 'description' => self::remove_non_unicode( strip_tags( $plugin['wordpress_plugin_metadata']['description'] ) ), 'url' => ( ! empty( $plugin['url'] ) ? $plugin['url'] : '' ), 'author_url' => ( ! empty( $plugin['author_url'] ) ? $plugin['author_url'] : '' ), 'thumbnail_url' => ( ! empty( $plugin['thumbnail_url'] ) ? $plugin['thumbnail_url'] : '' ), 'landscape_url' => ( ! empty( $plugin['previews']['landscape_preview']['landscape_url'] ) ? $plugin['previews']['landscape_preview']['landscape_url'] : '' ), 'requires' => $requires, 'tested' => $tested, 'number_of_sales' => ( ! empty( $plugin['number_of_sales'] ) ? $plugin['number_of_sales'] : '' ), 'updated_at' => ( ! empty( $plugin['updated_at'] ) ? $plugin['updated_at'] : '' ), 'rating' => ( ! empty( $plugin['rating'] ) ? $plugin['rating'] : '' ), ); // No main thumbnail in API response, so we grab it from the preview array. if ( empty( $plugin_normalized['landscape_url'] ) && ! empty( $plugin['previews'] ) && is_array( $plugin['previews'] ) ) { foreach ( $plugin['previews'] as $possible_preview ) { if ( ! empty( $possible_preview['landscape_url'] ) ) { $plugin_normalized['landscape_url'] = $possible_preview['landscape_url']; break; } } } if ( empty( $plugin_normalized['thumbnail_url'] ) && ! empty( $plugin['previews'] ) && is_array( $plugin['previews'] ) ) { foreach ( $plugin['previews'] as $possible_preview ) { if ( ! empty( $possible_preview['icon_url'] ) ) { $plugin_normalized['thumbnail_url'] = $possible_preview['icon_url']; break; } } } return $plugin_normalized; } /** * Remove all non unicode characters in a string * * @since 1.0.0 * * @param string $retval The string to fix. * @return string */ static private function remove_non_unicode( $retval ) { return preg_replace( '/[\x00-\x1F\x80-\xFF]/', '', $retval ); } } endif; class-envato-market-items.php 0000644 00000041417 15132720601 0012260 0 ustar 00 <?php /** * Items class. * * @package Envato_Market */ if ( ! class_exists( 'Envato_Market_Items' ) ) : /** * Creates the theme & plugin arrays & injects API results. * * @class Envato_Market_Items * @version 1.0.0 * @since 1.0.0 */ class Envato_Market_Items { /** * The single class instance. * * @since 1.0.0 * @access private * * @var object */ private static $_instance = null; /** * Premium themes. * * @since 1.0.0 * @access private * * @var array */ private static $themes = array(); /** * Premium plugins. * * @since 1.0.0 * @access private * * @var array */ private static $plugins = array(); /** * WordPress plugins. * * @since 1.0.0 * @access private * * @var array */ private static $wp_plugins = array(); /** * The Envato_Market_Items Instance * * Ensures only one instance of this class exists in memory at any one time. * * @see Envato_Market_Items() * @uses Envato_Market_Items::init_actions() Setup hooks and actions. * * @since 1.0.0 * @static * @return object The one true Envato_Market_Items. * @codeCoverageIgnore */ public static function instance() { if ( is_null( self::$_instance ) ) { self::$_instance = new self(); self::$_instance->init_actions(); } return self::$_instance; } /** * A dummy constructor to prevent this class from being loaded more than once. * * @see Envato_Market_Items::instance() * * @since 1.0.0 * @access private * @codeCoverageIgnore */ private function __construct() { /* We do nothing here! */ } /** * You cannot clone this class. * * @since 1.0.0 * @codeCoverageIgnore */ public function __clone() { _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'envato-market' ), '1.0.0' ); } /** * You cannot unserialize instances of this class. * * @since 1.0.0 * @codeCoverageIgnore */ public function __wakeup() { _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'envato-market' ), '1.0.0' ); } /** * Setup the hooks, actions and filters. * * @uses add_action() To add actions. * @uses add_filter() To add filters. * * @since 1.0.0 */ public function init_actions() { // Check for theme & plugin updates. add_filter( 'http_request_args', array( $this, 'update_check' ), 5, 2 ); // Inject plugin updates into the response array. add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'update_plugins' ), 5, 1 ); add_filter( 'pre_set_transient_update_plugins', array( $this, 'update_plugins' ), 5, 1 ); // Inject theme updates into the response array. add_filter( 'pre_set_site_transient_update_themes', array( $this, 'update_themes' ), 1, 99999 ); add_filter( 'pre_set_transient_update_themes', array( $this, 'update_themes' ), 1, 99999 ); // Inject plugin information into the API calls. add_filter( 'plugins_api', array( $this, 'plugins_api' ), 10, 3 ); // Rebuild the saved theme data. add_action( 'after_switch_theme', array( $this, 'rebuild_themes' ) ); // Rebuild the saved plugin data. add_action( 'activated_plugin', array( $this, 'rebuild_plugins' ) ); add_action( 'deactivated_plugin', array( $this, 'rebuild_plugins' ) ); } /** * Get the premium plugins list. * * @since 1.0.0 * * @param string $group The plugin group. Options are 'purchased', 'active', 'installed', or 'install'. * @return array */ public function plugins( $group = '' ) { if ( ! empty( $group ) ) { if ( isset( self::$plugins[ $group ] ) ) { return self::$plugins[ $group ]; } else { return array(); } } return self::$plugins; } /** * Get the premium themes list. * * @since 1.0.0 * * @param string $group The theme group. Options are 'purchased', 'active', 'installed', or 'install'. * @return array */ public function themes( $group = '' ) { if ( ! empty( $group ) ) { if ( isset( self::$themes[ $group ] ) ) { return self::$themes[ $group ]; } else { return array(); } } return self::$themes; } /** * Get the list of WordPress plugins * * @since 1.0.0 * * @param bool $flush Forces a cache flush. Default is 'false'. * @return array */ public function wp_plugins( $flush = false ) { if ( empty( self::$wp_plugins ) || true === $flush ) { wp_cache_set( 'plugins', false, 'plugins' ); self::$wp_plugins = get_plugins(); } return self::$wp_plugins; } /** * Disables requests to the wp.org repository for premium themes. * * @since 1.0.0 * * @param array $request An array of HTTP request arguments. * @param string $url The request URL. * @return array */ public function update_check( $request, $url ) { // Theme update request. if ( false !== strpos( $url, '//api.wordpress.org/themes/update-check/1.1/' ) ) { /** * Excluded theme slugs that should never ping the WordPress API. * We don't need the extra http requests for themes we know are premium. */ self::set_themes(); $installed = self::$themes['installed']; // Decode JSON so we can manipulate the array. $data = json_decode( $request['body']['themes'] ); // Remove the excluded themes. foreach ( $installed as $slug => $id ) { unset( $data->themes->$slug ); } // Encode back into JSON and update the response. $request['body']['themes'] = wp_json_encode( $data ); } // Plugin update request. if ( false !== strpos( $url, '//api.wordpress.org/plugins/update-check/1.1/' ) ) { /** * Excluded theme slugs that should never ping the WordPress API. * We don't need the extra http requests for themes we know are premium. */ self::set_plugins(); $installed = self::$plugins['installed']; // Decode JSON so we can manipulate the array. $data = json_decode( $request['body']['plugins'] ); // Remove the excluded themes. foreach ( $installed as $slug => $id ) { unset( $data->plugins->$slug ); } // Encode back into JSON and update the response. $request['body']['plugins'] = wp_json_encode( $data ); } return $request; } /** * Inject update data for premium themes. * * @since 1.0.0 * * @param object $transient The pre-saved value of the `update_themes` site transient. * @return object */ public function update_themes( $transient ) { // Process premium theme updates. if ( isset( $transient->checked ) ) { self::set_themes( true ); $installed = array_merge( self::$themes['active'], self::$themes['installed'] ); foreach ( $installed as $slug => $premium ) { $theme = wp_get_theme( $slug ); if ( $theme->exists() && version_compare( $theme->get( 'Version' ), $premium['version'], '<' ) ) { $transient->response[ $slug ] = array( 'theme' => $slug, 'new_version' => $premium['version'], 'url' => $premium['url'], 'package' => envato_market()->api()->deferred_download( $premium['id'] ), ); } } } return $transient; } /** * Inject update data for premium plugins. * * @since 1.0.0 * * @param object $transient The pre-saved value of the `update_plugins` site transient. * @return object */ public function update_plugins( $transient ) { self::set_plugins( true ); // Process premium plugin updates. $installed = array_merge( self::$plugins['active'], self::$plugins['installed'] ); $plugins = self::wp_plugins(); foreach ( $installed as $plugin => $premium ) { if ( isset( $plugins[ $plugin ] ) && version_compare( $plugins[ $plugin ]['Version'], $premium['version'], '<' ) ) { $_plugin = array( 'slug' => dirname( $plugin ), 'plugin' => $plugin, 'new_version' => $premium['version'], 'url' => $premium['url'], 'package' => envato_market()->api()->deferred_download( $premium['id'] ), ); $transient->response[ $plugin ] = (object) $_plugin; } } return $transient; } /** * Inject API data for premium plugins. * * @since 1.0.0 * * @param bool $response Always false. * @param string $action The API action being performed. * @param object $args Plugin arguments. * @return bool|object $response The plugin info or false. */ public function plugins_api( $response, $action, $args ) { self::set_plugins( true ); // Process premium theme updates. if ( 'plugin_information' === $action && isset( $args->slug ) ) { $installed = array_merge( self::$plugins['active'], self::$plugins['installed'] ); foreach ( $installed as $slug => $plugin ) { if ( dirname( $slug ) === $args->slug ) { $response = new stdClass(); $response->slug = $args->slug; $response->plugin = $slug; $response->plugin_name = $plugin['name']; $response->name = $plugin['name']; $response->version = $plugin['version']; $response->author = $plugin['author']; $response->homepage = $plugin['url']; $response->requires = $plugin['requires']; $response->tested = $plugin['tested']; $response->downloaded = $plugin['number_of_sales']; $response->last_updated = $plugin['updated_at']; $response->sections = array( 'description' => $plugin['description'] ); $response->banners['low'] = $plugin['landscape_url']; $response->rating = ! empty( $plugin['rating'] ) && ! empty( $plugin['rating']['rating'] ) && $plugin['rating']['rating'] > 0 ? $plugin['rating']['rating'] / 5 * 100 : 0; $response->num_ratings = ! empty( $plugin['rating'] ) && ! empty( $plugin['rating']['count'] ) ? $plugin['rating']['count'] : 0; $response->download_link = envato_market()->api()->deferred_download( $plugin['id'] ); break; } } } return $response; } /** * Set the list of themes * * @since 1.0.0 * * @param bool $forced Forces an API request. Default is 'false'. * @param bool $use_cache Attempts to rebuild from the cache before making an API request. */ public function set_themes( $forced = false, $use_cache = false ) { self::$themes = get_site_transient( envato_market()->get_option_name() . '_themes' ); if ( false === self::$themes || true === $forced ) { $themes = envato_market()->api()->themes(); foreach ( envato_market()->get_option( 'items', array() ) as $item ) { if ( empty( $item ) ) { continue; } if ( 'theme' === $item['type'] ) { $request_args = array( 'headers' => array( 'Authorization' => 'Bearer ' . $item['token'], ), ); $request = envato_market()->api()->item( $item['id'], $request_args ); if ( false !== $request ) { $themes[] = $request; } } } self::process_themes( $themes ); } elseif ( true === $use_cache ) { self::process_themes( self::$themes['purchased'] ); } } /** * Set the list of plugins * * @since 1.0.0 * * @param bool $forced Forces an API request. Default is 'false'. * @param bool $use_cache Attempts to rebuild from the cache before making an API request. * @param array $args Used to remove or add a plugin during activate and deactivate routines. */ public function set_plugins( $forced = false, $use_cache = false, $args = array() ) { self::$plugins = get_site_transient( envato_market()->get_option_name() . '_plugins' ); if ( false === self::$plugins || true === $forced ) { $plugins = envato_market()->api()->plugins(); foreach ( envato_market()->get_option( 'items', array() ) as $item ) { if ( empty( $item ) ) { continue; } if ( 'plugin' === $item['type'] ) { $request_args = array( 'headers' => array( 'Authorization' => 'Bearer ' . $item['token'], ), ); $request = envato_market()->api()->item( $item['id'], $request_args ); if ( false !== $request ) { $plugins[] = $request; } } } self::process_plugins( $plugins, $args ); } elseif ( true === $use_cache ) { self::process_plugins( self::$plugins['purchased'], $args ); } } /** * Rebuild the themes array using the cache value if possible. * * @since 1.0.0 * * @param mixed $filter Any data being filtered. * @return mixed */ public function rebuild_themes( $filter ) { self::set_themes( false, true ); return $filter; } /** * Rebuild the plugins array using the cache value if possible. * * @since 1.0.0 * * @param string $plugin The plugin to add or remove. */ public function rebuild_plugins( $plugin ) { $remove = ( 'deactivated_plugin' === current_filter() ) ? true : false; self::set_plugins( false, true, array( 'plugin' => $plugin, 'remove' => $remove, ) ); } /** * Normalizes a string to do a value check against. * * Strip all HTML tags including script and style & then decode the * HTML entities so `&` will equal `&` in the value check and * finally lower case the entire string. This is required becuase some * themes & plugins add a link to the Author field or ambersands to the * names, or change the case of their files or names, which will not match * the saved value in the database causing a false negative. * * @since 1.0.0 * * @param string $string The string to normalize. * @return string */ public function normalize( $string ) { return strtolower( html_entity_decode( wp_strip_all_tags( $string ) ) ); } /** * Process the themes and save the transient. * * @since 1.0.0 * * @param array $purchased The purchased themes array. */ private function process_themes( $purchased ) { if ( is_wp_error( $purchased ) ) { $purchased = array(); } $current = wp_get_theme()->get_template(); $active = array(); $installed = array(); $install = $purchased; if ( ! empty( $purchased ) ) { foreach ( wp_get_themes() as $theme ) { /** * WP_Theme object. * * @var WP_Theme $theme */ $template = $theme->get_template(); $title = $theme->get( 'Name' ); $author = $theme->get( 'Author' ); foreach ( $install as $key => $value ) { if ( $this->normalize( $value['name'] ) === $this->normalize( $title ) && $this->normalize( $value['author'] ) === $this->normalize( $author ) ) { $installed[ $template ] = $value; unset( $install[ $key ] ); } } } } if ( isset( $installed[ $current ] ) ) { $active[ $current ] = $installed[ $current ]; unset( $installed[ $current ] ); } self::$themes['purchased'] = array_unique( $purchased, SORT_REGULAR ); self::$themes['active'] = array_unique( $active, SORT_REGULAR ); self::$themes['installed'] = array_unique( $installed, SORT_REGULAR ); self::$themes['install'] = array_unique( array_values( $install ), SORT_REGULAR ); set_site_transient( envato_market()->get_option_name() . '_themes', self::$themes, HOUR_IN_SECONDS ); } /** * Process the plugins and save the transient. * * @since 1.0.0 * * @param array $purchased The purchased plugins array. * @param array $args Used to remove or add a plugin during activate and deactivate routines. */ private function process_plugins( $purchased, $args = array() ) { if ( is_wp_error( $purchased ) ) { $purchased = array(); } $active = array(); $installed = array(); $install = $purchased; if ( ! empty( $purchased ) ) { foreach ( self::wp_plugins( true ) as $slug => $plugin ) { foreach ( $install as $key => $value ) { if ( $this->normalize( $value['name'] ) === $this->normalize( $plugin['Name'] ) && $this->normalize( $value['author'] ) === $this->normalize( $plugin['Author'] ) && file_exists( WP_PLUGIN_DIR . '/' . $slug ) ) { $installed[ $slug ] = $value; unset( $install[ $key ] ); } } } } foreach ( $installed as $slug => $plugin ) { $condition = false; if ( ! empty( $args ) && $slug === $args['plugin'] ) { if ( true === $args['remove'] ) { continue; } $condition = true; } if ( $condition || is_plugin_active( $slug ) ) { $active[ $slug ] = $plugin; unset( $installed[ $slug ] ); } } self::$plugins['purchased'] = array_unique( $purchased, SORT_REGULAR ); self::$plugins['active'] = array_unique( $active, SORT_REGULAR ); self::$plugins['installed'] = array_unique( $installed, SORT_REGULAR ); self::$plugins['install'] = array_unique( array_values( $install ), SORT_REGULAR ); set_site_transient( envato_market()->get_option_name() . '_plugins', self::$plugins, HOUR_IN_SECONDS ); } } endif;
| ver. 1.4 |
Github
|
.
| PHP 8.2.29 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка