PK ! f block-styles.phpnu [ 'twentytwentyone-columns-overlap', 'label' => esc_html__( 'Overlap', 'twentytwentyone' ), ) ); // Cover: Borders. register_block_style( 'core/cover', array( 'name' => 'twentytwentyone-border', 'label' => esc_html__( 'Borders', 'twentytwentyone' ), ) ); // Group: Borders. register_block_style( 'core/group', array( 'name' => 'twentytwentyone-border', 'label' => esc_html__( 'Borders', 'twentytwentyone' ), ) ); // Image: Borders. register_block_style( 'core/image', array( 'name' => 'twentytwentyone-border', 'label' => esc_html__( 'Borders', 'twentytwentyone' ), ) ); // Image: Frame. register_block_style( 'core/image', array( 'name' => 'twentytwentyone-image-frame', 'label' => esc_html__( 'Frame', 'twentytwentyone' ), ) ); // Latest Posts: Dividers. register_block_style( 'core/latest-posts', array( 'name' => 'twentytwentyone-latest-posts-dividers', 'label' => esc_html__( 'Dividers', 'twentytwentyone' ), ) ); // Latest Posts: Borders. register_block_style( 'core/latest-posts', array( 'name' => 'twentytwentyone-latest-posts-borders', 'label' => esc_html__( 'Borders', 'twentytwentyone' ), ) ); // Media & Text: Borders. register_block_style( 'core/media-text', array( 'name' => 'twentytwentyone-border', 'label' => esc_html__( 'Borders', 'twentytwentyone' ), ) ); // Separator: Thick. register_block_style( 'core/separator', array( 'name' => 'twentytwentyone-separator-thick', 'label' => esc_html__( 'Thick', 'twentytwentyone' ), ) ); // Social icons: Dark gray color. register_block_style( 'core/social-links', array( 'name' => 'twentytwentyone-social-icons-color', 'label' => esc_html__( 'Dark gray', 'twentytwentyone' ), ) ); } add_action( 'init', 'twenty_twenty_one_register_block_styles' ); } PK ! zsd d template-tags.phpnu [ %2$s'; $time_string = sprintf( $time_string, esc_attr( get_the_date( DATE_W3C ) ), esc_html( get_the_date() ) ); echo ''; printf( /* translators: %s: Publish date. */ esc_html__( 'Published %s', 'twentytwentyone' ), $time_string // phpcs:ignore WordPress.Security.EscapeOutput ); echo ''; } } if ( ! function_exists( 'twenty_twenty_one_posted_by' ) ) { /** * Prints HTML with meta information about theme author. * * @since Twenty Twenty-One 1.0 * * @return void */ function twenty_twenty_one_posted_by() { if ( ! get_the_author_meta( 'description' ) && post_type_supports( get_post_type(), 'author' ) ) { echo ' '; } } } if ( ! function_exists( 'twenty_twenty_one_entry_meta_footer' ) ) { /** * Prints HTML with meta information for the categories, tags and comments. * Footer entry meta is displayed differently in archives and single posts. * * @since Twenty Twenty-One 1.0 * * @return void */ function twenty_twenty_one_entry_meta_footer() { // Early exit if not a post. if ( 'post' !== get_post_type() ) { return; } // Hide meta information on pages. if ( ! is_single() ) { if ( is_sticky() ) { echo '
' . esc_html_x( 'Featured post', 'Label for sticky posts', 'twentytwentyone' ) . '
'; } $post_format = get_post_format(); if ( 'aside' === $post_format || 'status' === $post_format ) { echo '' . twenty_twenty_one_continue_reading_text() . '
'; // phpcs:ignore WordPress.Security.EscapeOutput } // Posted on. twenty_twenty_one_posted_on(); // Edit post link. edit_post_link( sprintf( /* translators: %s: Post title. Only visible to screen readers. */ esc_html__( 'Edit %s', 'twentytwentyone' ), '' . get_the_title() . '' ), '', ''; printf( /* translators: %s: WordPress Version. */ esc_html__( 'This theme requires WordPress 5.3 or newer. You are running version %s. Please upgrade.', 'twentytwentyone' ), esc_html( $GLOBALS['wp_version'] ) ); echo '
'; } /** * Prevents the Customizer from being loaded on WordPress versions prior to 5.3. * * @since Twenty Twenty-One 1.0 * * @global string $wp_version WordPress version. * * @return void */ function twenty_twenty_one_customize() { wp_die( sprintf( /* translators: %s: WordPress Version. */ esc_html__( 'This theme requires WordPress 5.3 or newer. You are running version %s. Please upgrade.', 'twentytwentyone' ), esc_html( $GLOBALS['wp_version'] ) ), '', array( 'back_link' => true, ) ); } add_action( 'load-customize.php', 'twenty_twenty_one_customize' ); /** * Prevents the Theme Preview from being loaded on WordPress versions prior to 5.3. * * @since Twenty Twenty-One 1.0 * * @global string $wp_version WordPress version. * * @return void */ function twenty_twenty_one_preview() { if ( isset( $_GET['preview'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification wp_die( sprintf( /* translators: %s: WordPress Version. */ esc_html__( 'This theme requires WordPress 5.3 or newer. You are running version %s. Please upgrade.', 'twentytwentyone' ), esc_html( $GLOBALS['wp_version'] ) ) ); } } add_action( 'template_redirect', 'twenty_twenty_one_preview' ); PK ! kŴ block-patterns.phpnu [ array( 'label' => __( 'Featured', 'twentytwentytwo' ) ), 'footer' => array( 'label' => __( 'Footers', 'twentytwentytwo' ) ), 'header' => array( 'label' => __( 'Headers', 'twentytwentytwo' ) ), 'query' => array( 'label' => __( 'Query', 'twentytwentytwo' ) ), 'twentytwentytwo_pages' => array( 'label' => __( 'Pages', 'twentytwentytwo' ) ), ); /** * Filters the theme block pattern categories. * * @since Twenty Twenty-Two 1.0 * * @param array[] $block_pattern_categories { * An associative array of block pattern categories, keyed by category name. * * @type array[] $properties { * An array of block category properties. * * @type string $label A human-readable label for the pattern category. * } * } */ $block_pattern_categories = apply_filters( 'twentytwentytwo_block_pattern_categories', $block_pattern_categories ); foreach ( $block_pattern_categories as $name => $properties ) { if ( ! WP_Block_Pattern_Categories_Registry::get_instance()->is_registered( $name ) ) { register_block_pattern_category( $name, $properties ); } } $block_patterns = array( 'footer-default', 'footer-dark', 'footer-logo', 'footer-navigation', 'footer-title-tagline-social', 'footer-social-copyright', 'footer-navigation-copyright', 'footer-about-title-logo', 'footer-query-title-citation', 'footer-query-images-title-citation', 'footer-blog', 'general-subscribe', 'general-featured-posts', 'general-layered-images-with-duotone', 'general-wide-image-intro-buttons', 'general-large-list-names', 'general-video-header-details', 'general-list-events', 'general-two-images-text', 'general-image-with-caption', 'general-video-trailer', 'general-pricing-table', 'general-divider-light', 'general-divider-dark', 'header-default', 'header-large-dark', 'header-small-dark', 'header-image-background', 'header-image-background-overlay', 'header-with-tagline', 'header-text-only-green-background', 'header-text-only-salmon-background', 'header-title-and-button', 'header-text-only-with-tagline-black-background', 'header-logo-navigation-gray-background', 'header-logo-navigation-social-black-background', 'header-title-navigation-social', 'header-logo-navigation-offset-tagline', 'header-stacked', 'header-centered-logo', 'header-centered-logo-black-background', 'header-centered-title-navigation-social', 'header-title-and-button', 'hidden-404', 'hidden-bird', 'hidden-heading-and-bird', 'page-about-media-left', 'page-about-simple-dark', 'page-about-media-right', 'page-about-solid-color', 'page-about-links', 'page-about-links-dark', 'page-about-large-image-and-buttons', 'page-layout-image-and-text', 'page-layout-image-text-and-video', 'page-layout-two-columns', 'page-sidebar-poster', 'page-sidebar-grid-posts', 'page-sidebar-blog-posts', 'page-sidebar-blog-posts-right', 'query-default', 'query-simple-blog', 'query-grid', 'query-text-grid', 'query-image-grid', 'query-large-titles', 'query-irregular-grid', ); /** * Filters the theme block patterns. * * @since Twenty Twenty-Two 1.0 * * @param array $block_patterns List of block patterns by name. */ $block_patterns = apply_filters( 'twentytwentytwo_block_patterns', $block_patterns ); foreach ( $block_patterns as $block_pattern ) { $pattern_file = get_theme_file_path( '/inc/patterns/' . $block_pattern . '.php' ); register_block_pattern( 'twentytwentytwo/' . $block_pattern, require $pattern_file ); } } add_action( 'init', 'twentytwentytwo_register_block_patterns', 9 ); PK ! ʺ custom-css.phpnu [ tags and can only be interpreted as CSS on the browser. * Using wp_strip_all_tags() here is sufficient escaping to avoid * malicious attempts to close and open a __( 'User not allowed to update items.', 'envato-market' ) ) ); } 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; PK ! ks( ( class-envato-market.phpnu [ 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; if ( defined('ENVATO_LOCAL_DEVELOPMENT') ) { $this->envato_api_domain = ENVATO_API_DOMAIN; $this->envato_api_headers = ENVATO_API_HEADERS; } else { $this->envato_api_headers = [ 'Authorization' => 'Bearer ' . $this->get_option( 'token' ) ]; $this->envato_api_domain = 'https://api.envato.com'; } } /** * 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(); } public function get_envato_api_domain() { return $this->envato_api_domain; } public function get_envato_api_headers() { return $this->envato_api_headers; } } endif; PK ! G=-HC C class-envato-market-items.phpnu [ 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 ) { $themes_transient = get_site_transient( envato_market()->get_option_name() . '_themes' ); self::$themes = is_array($themes_transient) ? $themes_transient : array(); if ( empty(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() ) { $plugins_transient = get_site_transient( envato_market()->get_option_name() . '_plugins' ); self::$plugins = is_array($plugins_transient) ? $plugins_transient : array(); if ( empty(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; PK ! C( % admin/view/callback/section/oauth.phpnu [' . esc_html__( 'envato.com', 'envato-market' ) . '' ); ?>
downloads page' ); ?>