array( 'amp' => 'AMP', 'accelerated-mobile-pages' => 'AMP for WP', ), 'cache' => array( // Page caching plugins and services. 'enabler' => 'Cache Enabler', 'comet' => 'Comet Cache', 'hummingbird' => 'Hummingbird Cache', 'litespeed' => 'LiteSpeed Cache', 'pagely' => 'Pagely Cache', 'siteground' => 'SiteGround Cache', 'w3tc' => 'W3 Total Cache', 'wp-engine' => 'WP Engine cache', 'wp-fastest' => 'WP Fastest Cache', 'wp-rocket' => 'WP Rocket Cache', 'wp-super' => 'WP Super Cache', ), 'media' => array( 'wp-retina-2x' => 'Perfect Images + Retina', ), 'p' => array( 'schema' => 'Schema Markup', ), 'seo' => array( 'jetpack-seo' => 'Jetpack SEO Tools', 'seoultimate' => 'SEO Ultimate', 'slim-seo' => 'Slim SEO', 'squirrlyseo' => 'Squirrly SEO', 'wpseo-wc' => 'Yoast WooCommerce SEO', ), 'util' => array( 'autoptimize' => 'Autoptimize', ), ); /* * This class is instantiated before the SucomDebug class, so do not use $this->p->debug to log status messages. */ public function __construct( &$plugin ) { $this->p =& $plugin; } /* * This method is run once by Wpsso->set_objects() and typically runs in 0.0002 secs. * * Do not save or retrieve the array from the transient cache as this is slower than running the method. * * Please note that get_avail() is executed before the debug class object is defined, so do not log debugging * messages using $this->p->debug. * * Non-admin PHP library files have been loaded, even if the class object variables have not been defined yet, so * you can safely call static methods, like SucomUtil::get_const(), for example. */ public function get_avail() { $mtime_start = microtime( $get_float = true ); $get_avail = array(); // Initialize the array to return. $is_admin = is_admin(); $lib_checks = $this->extend_lib_checks; $lib_checks = SucomUtil::array_merge_recursive_distinct( $lib_checks, $this->p->cf[ '*' ][ 'lib' ][ 'integ' ] ); $lib_checks = SucomUtil::array_merge_recursive_distinct( $lib_checks, $this->p->cf[ '*' ][ 'lib' ][ 'pro' ] ); foreach ( $lib_checks as $sub => $lib ) { $get_avail[ $sub ] = array(); $get_avail[ $sub ][ 'any' ] = false; foreach ( $lib as $id => $name ) { $chk = array(); $get_avail[ $sub ][ $id ] = false; // Default value. switch ( $sub ) { case 'admin': /* * Load admin modules in back-end. */ if ( $is_admin ) { $get_avail[ $sub ][ 'any' ] = $get_avail[ $sub ][ $id ] = true; } break; case 'amp': switch ( $id ) { /* * AMP. * * See https://wordpress.org/plugins/amp/. */ case 'amp': $chk[ 'function' ] = 'is_amp_endpoint'; break; /* * Accelerated Mobile Pages. * * See https://wordpress.org/plugins/accelerated-mobile-pages/. */ case 'accelerated-mobile-pages': $chk[ 'function' ] = 'ampforwp_is_amp_endpoint'; break; } break; case 'cache': switch ( $id ) { /* * Cache Enabler. * * See https://wordpress.org/plugins/cache-enabler/. */ case 'enabler': $chk[ 'class' ] = 'Cache_Enabler'; break; /* * Comet Cache. * * See https://wordpress.org/plugins/comet-cache/. */ case 'comet': if ( isset( $GLOBALS[ 'comet_cache' ] ) ) { $get_avail[ $sub ][ 'any' ] = $get_avail[ $sub ][ $id ] = true; } break; /* * Hummingbird Cache. * * See https://wordpress.org/plugins/hummingbird-performance/. */ case 'hummingbird': $chk[ 'class' ] = '\Hummingbird\WP_Hummingbird'; break; /* * LiteSpeed Cache. * * See https://wordpress.org/plugins/litespeed-cache/. */ case 'litespeed': $chk[ 'function' ] = 'run_litespeed_cache'; break; /* * Pagely Cache. */ case 'pagely': $chk[ 'class' ] = 'PagelyCachePurge'; break; /* * SiteGround Cache. */ case 'siteground': $chk[ 'function' ] = 'sg_cachepress_purge_cache'; break; /* * W3 Total Cache. * * See https://wordpress.org/plugins/w3-total-cache/. */ case 'w3tc': $chk[ 'function' ] = 'w3tc_pgcache_flush'; break; /* * WP Engine Cache. */ case 'wp-engine': $chk[ 'class' ] = 'WpeCommon'; break; /* * WP Fastest Cache. * * See https://wordpress.org/plugins/wp-fastest-cache/. */ case 'wp-fastest': $chk[ 'function' ] = 'wpfc_clear_all_cache'; break; /* * WP Rocket Cache. */ case 'wp-rocket': $chk[ 'function' ] = 'rocket_clean_domain'; break; /* * WP Super Cache. * * See https://wordpress.org/plugins/wp-super-cache/. */ case 'wp-super': $chk[ 'function' ] = 'wp_cache_clear_cache'; break; } break; case 'ecom': switch ( $id ) { /* * Perfect Brands for WooCommerce. */ case 'perfect-woocommerce-brands': $chk[ 'constant' ] = 'PWB_PLUGIN_VERSION'; break; /* * WooCommerce. * * See https://wordpress.org/plugins/woocommerce/. */ case 'woocommerce': $chk[ 'class' ] = 'WooCommerce'; $chk[ 'version_const' ] = 'WC_VERSION'; $chk[ 'min_version' ] = '6.0.0'; break; /* * WooCommerce Brands. * * See woocommerce/includes/class-wc-brands.php. */ case 'woocommerce-brands': $chk[ 'class' ] = 'WC_Brands'; break; /* * WooCommerce Currency Switcher. */ case 'woocommerce-currency-switcher': $chk[ 'class' ] = 'WOOCS'; break; /* * WooCommerce UPC, EAN, and ISBN. */ case 'woo-add-gtin': $chk[ 'class' ] = 'Woo_GTIN'; break; /* * Product GTIN for WooCommerce. */ case 'wpm-product-gtin-wc': $chk[ 'class' ] = 'WPM_Product_GTIN_WC'; break; /* * YITH WooCommerce Brands Add-on. */ case 'yith-woocommerce-brands': $chk[ 'class' ] = 'YITH_WCBR'; break; } break; case 'data': switch ( $id ) { /* * Import All in One SEO Pack metadata. */ case 'aioseop-meta': $chk[ 'opt_key' ] = 'plugin_import_aioseop_meta'; break; /* * Import Rank Math SEO metadata. */ case 'rankmath-meta': $chk[ 'opt_key' ] = 'plugin_import_rankmath_meta'; break; /* * Import The SEO Framework metadata. */ case 'seoframework-meta': $chk[ 'opt_key' ] = 'plugin_import_seoframework_meta'; break; /* * Import WP Meta SEO metadata. */ case 'wpmetaseo-meta': $chk[ 'opt_key' ] = 'plugin_import_wpmetaseo_meta'; break; /* * Import Yoast SEO block attrs. */ case 'wpseo-blocks': $chk[ 'opt_key' ] = 'plugin_import_wpseo_blocks'; break; /* * Import Yoast SEO metadata. */ case 'wpseo-meta': $chk[ 'opt_key' ] = 'plugin_import_wpseo_meta'; break; } break; case 'event': switch ( $id ) { /* * The Events Calendar. * * See https://wordpress.org/plugins/the-events-calendar/. */ case 'the-events-calendar': $chk[ 'class' ] = 'Tribe__Events__Main'; break; } break; case 'form': switch ( $id ) { case 'gravityforms': $chk[ 'class' ] = 'GFForms'; break; case 'gravityview': $chk[ 'class' ] = 'GravityView_Plugin'; break; } break; case 'job': switch ( $id ) { /* * Simple Job Board. * * See https://wordpress.org/plugins/simple-job-board/. */ case 'simplejobboard': $chk[ 'class' ] = 'Simple_Job_Board'; break; /* * WP Job Manager. * * See https://wordpress.org/plugins/wp-job-manager/. */ case 'wpjobmanager': $chk[ 'class' ] = 'WP_Job_Manager'; break; } break; case 'lang': switch ( $id ) { /* * GTranslate. * * See https://wordpress.org/plugins/gtranslate/. */ case 'gtranslate': $chk[ 'class' ] = 'GTranslate'; break; /* * Polylang. * * See https://wordpress.org/plugins/polylang/. */ case 'polylang': $chk[ 'class' ] = 'Polylang'; break; /* * qTranslate-XT. * * https://github.com/qtranslate/qtranslate-xt. */ case 'qtranslate-xt': $chk[ 'constant' ] = 'QTX_VERSION'; break; /* * WPML. * * See https://wpml.org/. */ case 'wpml': $chk[ 'class' ] = 'SitePress'; break; } break; case 'media': switch ( $id ) { /* * Perfect Images (aka WP Retina 2x). * * See https://wordpress.org/plugins/wp-retina-2x/. */ case 'wp-retina-2x': $chk[ 'class' ] = 'Meow_WR2X_Core'; break; /* * Premium edition feature / option. */ case 'facebook': // Detect Embedded Media: Facebook Video. case 'slideshare': // Detect Embedded Media: Slideshare Presentation. case 'soundcloud': // Detect Embedded Media: Soundcloud Track. case 'vimeo': // Detect Embedded Media: Vimeo Video. case 'wistia': // Detect Embedded Media: Wistia Video. case 'wpvideoblock': // Detect Embedded Media: WP Media Library Video Block. case 'wpvideoshortcode': // Detect Embedded Media: WP Media Library Video Shortcode. case 'youtube': // Detect Embedded Media: Youtube Videos and Playlist. $chk[ 'opt_key' ] = 'plugin_media_' . $id; break; /* * Premium edition feature / option. */ case 'gravatar': // Gravatar is Default Author Image. $chk[ 'opt_key' ] = 'plugin_gravatar_image'; break; /* * Premium edition feature / option. */ case 'upscale': // Upscale Media Library Images. $chk[ 'opt_key' ] = 'plugin_upscale_images'; break; } break; case 'p': switch ( $id ) { case 'schema': $schema_disable = SucomUtil::get_const( 'WPSSO_SCHEMA_MARKUP_DISABLE' ); $get_avail[ $sub ][ $id ] = $schema_disable ? false : true; break; } break; case 'rating': switch ( $id ) { /* * Rate my Post. * * https://wordpress.org/plugins/rate-my-post/ */ case 'rate-my-post': $chk[ 'class' ] = 'Rate_My_Post'; break; /* * WP-PostRatings. * * https://wordpress.org/plugins/wp-postratings/ */ case 'wppostratings': $chk[ 'constant' ] = 'WP_POSTRATINGS_VERSION'; break; } break; case 'recipe': switch ( $id ) { /* * WP Recipe Maker. * * See https://wordpress.org/plugins/wp-recipe-maker/. */ case 'wprecipemaker': $chk[ 'class' ] = 'WP_Recipe_Maker'; break; } break; case 'review': switch ( $id ) { case 'judgeme': // Judge.me. $chk[ 'opt_key' ] = array( 'plugin_ratings_reviews_svc' => 'judgeme', 'plugin_judgeme_shop_domain' => null, // Any non-empty value. 'plugin_judgeme_shop_token' => null, // Any non-empty value. ); break; case 'judgeme-for-wc': // Judge.me Product Reviews for WooCommerce. $chk[ 'class' ] = 'JudgeMe'; break; case 'shopperapproved': // Shopper Approved. $chk[ 'opt_key' ] = array( 'plugin_ratings_reviews_svc' => 'shopperapproved', 'plugin_shopperapproved_site_id' => null, // Any non-empty value. 'plugin_shopperapproved_token' => null, // Any non-empty value. ); break; case 'stamped': // Stamped.io. $chk[ 'opt_key' ] = array( 'plugin_ratings_reviews_svc' => 'stamped', 'plugin_stamped_store_hash' => null, // Any non-empty value. 'plugin_stamped_key_public' => null, // Any non-empty value. ); break; /* * WP Product Review Lite. * * See https://wordpress.org/plugins/wp-product-review/. */ case 'wpproductreview': $chk[ 'class' ] = 'WPPR'; break; /* * Yotpo: Product & Photo Reviews for WooCommerce. * * See https://wordpress.org/plugins/yotpo-social-reviews-for-woocommerce/. */ case 'yotpowc': $chk[ 'function' ] = 'wc_yotpo_init'; break; } break; case 'seo': switch ( $id ) { /* * All in One SEO Pack. * * See https://wordpress.org/plugins/all-in-one-seo-pack/. */ case 'aioseop': $chk[ 'function' ] = 'aioseo'; break; /* * Jetpack SEO module. * * See https://wordpress.org/plugins/jetpack/. */ case 'jetpack-seo': if ( method_exists( 'Jetpack', 'get_active_modules' ) ) { $jetpack_modules = Jetpack::get_active_modules(); if ( in_array( 'seo-tools', $jetpack_modules ) ) { $get_avail[ $sub ][ 'any' ] = $get_avail[ $sub ][ $id ] = true; } } break; /* * Rank Math. * * See https://wordpress.org/plugins/seo-by-rank-math/. */ case 'rankmath': $chk[ 'class' ] = 'RankMath'; break; /* * The SEO Framework. * * See https://wordpress.org/plugins/autodescription/. */ case 'seoframework': $chk[ 'function' ] = 'the_seo_framework'; break; /* * SEOPress. * * See https://wordpress.org/plugins/wp-seopress/. */ case 'seopress': $chk[ 'function' ] = 'seopress_init'; break; /* * SEO Ultimate. * * See https://wordpress.org/plugins/seo-ultimate/. */ case 'seoultimate': $chk[ 'plugin' ] = 'seo-ultimate/seo-ultimate.php'; break; /* * Slim SEO. * * See https://wordpress.org/plugins/slim-seo/. */ case 'slim-seo': $chk[ 'plugin' ] = 'slim-seo/slim-seo.php'; break; /* * SEO 2020 by Squirrly. * * https://wordpress.org/plugins/squirrly-seo/. */ case 'squirrlyseo': $chk[ 'plugin' ] = 'squirrly-seo/squirrly.php'; break; /* * WP Meta SEO. * * See https://wordpress.org/plugins/wp-meta-seo/. */ case 'wpmetaseo': $chk[ 'class' ] = 'WpMetaSeo'; break; /* * Yoast SEO. * * See https://wordpress.org/plugins/wordpress-seo/. */ case 'wpseo': $chk[ 'function' ] = 'wpseo_init'; break; /* * Yoast WooCommerce SEO. * * https://yoast.com/wordpress/plugins/yoast-woocommerce-seo/. */ case 'wpseo-wc': $chk[ 'class' ] = 'Yoast_WooCommerce_SEO'; break; } break; case 'user': switch ( $id ) { /* * Co-Authors Plus. * * See https://wordpress.org/plugins/co-authors-plus/. */ case 'co-authors-plus': $chk[ 'plugin' ] = 'co-authors-plus/co-authors-plus.php'; break; /* * PublishPress Authors. * * See https://wordpress.org/plugins/publishpress-authors/. */ case 'publishpress-authors': $chk[ 'constant' ] = 'PP_AUTHORS_VERSION'; break; /* * Ultimate Member. * * See https://wordpress.org/plugins/ultimate-member/. */ case 'ultimate-member': $chk[ 'class' ] = 'UM'; break; } break; case 'util': switch ( $id ) { /* * Autoptimize. * * See https://wordpress.org/plugins/autoptimize/. */ case 'autoptimize': $chk[ 'class' ] = 'autoptimizeCache'; break; /* * Yoast Duplicate Post. */ case 'duplicate-post': $chk[ 'constant' ] = 'DUPLICATE_POST_CURRENT_VERSION'; break; /* * Elementor. */ case 'elementor': $chk[ 'constant' ] = 'ELEMENTOR_VERSION'; break; /* * Jetpack. * * See https://wordpress.org/plugins/jetpack/. */ case 'jetpack': $chk[ 'class' ] = 'Jetpack'; break; /* * Jetpack Boost. * * See https://wordpress.org/plugins/jetpack-boost/. */ case 'jetpack-boost': $chk[ 'constant' ] = 'JETPACK_BOOST_VERSION'; break; /* * URL Shortening Service. */ case 'shorten': $chk[ 'opt_key' ] = 'plugin_shortener'; break; } break; } /* * Check for plugin classes and functions first, to include both free and pro / premium * plugins that have different plugin slugs, but use the same class or function names. */ if ( ! empty( $chk ) ) { if ( isset( $chk[ 'class' ] ) || isset( $chk[ 'function' ] ) || isset( $chk[ 'plugin' ] ) ) { if ( ( ! empty( $chk[ 'class' ] ) && class_exists( $chk[ 'class' ] ) ) || ( ! empty( $chk[ 'function' ] ) && function_exists( $chk[ 'function' ] ) ) || ( ! empty( $chk[ 'plugin' ] ) && SucomPlugin::is_plugin_active( $chk[ 'plugin' ] ) ) ) { $version = false; if ( ! empty( $chk[ 'min_version' ] ) ) { if ( ! empty( $chk[ 'version_global' ] ) ) { $version = $GLOBALS[ $chk[ 'version_global' ] ]; } elseif ( ! empty( $chk[ 'version_const' ] ) ) { $version = constant( $chk[ 'version_const' ] ); } } if ( ! $version || version_compare( $version, $chk[ 'min_version' ], '>=' ) ) { $get_avail[ $sub ][ 'any' ] = $get_avail[ $sub ][ $id ] = true; } } } elseif ( isset( $chk[ 'opt_key' ] ) ) { if ( is_array( $chk[ 'opt_key' ] ) ) { $all_enabled = true; foreach ( $chk[ 'opt_key' ] as $key => $val ) { if ( ! $this->is_opt_enabled( $key, $val ) ) { $all_enabled = false; break; } } if ( $all_enabled ) { $get_avail[ $sub ][ 'any' ] = $get_avail[ $sub ][ $id ] = true; } } elseif ( $this->is_opt_enabled( $chk[ 'opt_key' ] ) ) { $get_avail[ $sub ][ 'any' ] = $get_avail[ $sub ][ $id ] = true; } } elseif ( isset( $chk[ 'constant' ] ) ) { if ( defined( $chk[ 'constant' ] ) ) { $get_avail[ $sub ][ 'any' ] = $get_avail[ $sub ][ $id ] = true; } } } } } /* * Define WPSSO_UNKNOWN_SEO_PLUGIN_ACTIVE as true to disable WPSSO's SEO related meta tags and features. */ if ( defined( 'WPSSO_UNKNOWN_SEO_PLUGIN_ACTIVE' ) && WPSSO_UNKNOWN_SEO_PLUGIN_ACTIVE ) { $get_avail[ 'seo' ][ 'any' ] = true; } /* * This method is run once by Wpsso->set_objects() and typically runs in 0.0002 secs. */ $get_avail[ 'p' ][ 'avail_mtime' ] = microtime( $get_float = true ) - $mtime_start; $get_avail = apply_filters( 'wpsso_get_avail', $get_avail ); return $get_avail; } public function is_pp( $ext = null, $read_cache = true ) { return $this->pp( $ext, $li = true, $rv = true, $read_cache ); } public function pp( $ext = null, $li = true, $rv = true, $read_cache = true, $mx = null ) { static $local_cache = array(); $ext = null === $ext ? $this->p->id : $ext; $id = $ext . '-' . $li . '-' . $rv . '-' . $mx; $rv = null === $mx ? $rv : $rv * $mx; if ( $read_cache && isset( $local_cache[ $id ] ) ) { return $local_cache[ $id ]; } elseif ( defined( 'WPSSO_PRO_DISABLE' ) && WPSSO_PRO_DISABLE ) { return $local_cache[ $id ] = false; } elseif ( ! $ext_dir = WpssoConfig::get_ext_dir( $ext ) ) { return $local_cache[ $id ] = false; } $key = 'plugin_' . $ext . '_tid'; $pdir = is_dir( $ext_dir . 'lib/pro/' ) ? $rv : false; $umv = class_exists( 'WpssoUmConfig' ) && WpssoUmConfig::get_version() ? true : false; return $local_cache[ $id ] = $li ? ( ( ! empty( $this->p->options[ $key ] ) && $pdir && $umv && ( $ume = SucomUpdate::get_umsg( $ext ) ? false : $pdir ) ) ? $ume : false ) : $pdir; } public function get_ext_gen_list() { static $local_cache = null; if ( null !== $local_cache ) { return $local_cache; } $local_cache = array(); $ext_sorted = WpssoConfig::get_ext_sorted(); foreach ( $ext_sorted as $ext => $info ) { if ( empty( $info[ 'version' ] ) ) continue; // Include only active add-ons. $local_cache[] = $info[ 'short' ] . ' ' . $info[ 'version' ] . '/' . $this->get_ext_status( $ext ); } return $local_cache; } public function get_ext_status( $ext ) { $ext_pdir = $this->pp( $ext, $li = false ); $ext_tid = $this->get_ext_auth_id( $ext ); $ext_pp = $ext_tid && WPSSO_UNDEF === $this->pp( $ext, $li = true, WPSSO_UNDEF ) ? true : false; return ( $ext_pp ? 'L' : ( $ext_pdir ? 'U' : 'S' ) ) . ( $ext_tid ? '*' : '' ); } public function get_ext_auth_type( $ext ) { return empty( $this->p->cf[ 'plugin' ][ $ext ][ 'update_auth' ] ) ? 'none' : $this->p->cf[ 'plugin' ][ $ext ][ 'update_auth' ]; } public function get_ext_auth_id( $ext ) { $ext_auth_type = $this->get_ext_auth_type( $ext ); $ext_auth_key = 'plugin_' . $ext . '_' . $ext_auth_type; return empty( $this->p->options[ $ext_auth_key ] ) ? '' : $this->p->options[ $ext_auth_key ]; } public function is_umver_gt_min() { static $local_cache = null; if ( null !== $local_cache ) { return $local_cache; } if ( isset( $this->p->cf[ 'plugin' ][ 'wpssoum' ][ 'base' ] ) ) { if ( SucomPlugin::is_plugin_active( $this->p->cf[ 'plugin' ][ 'wpssoum' ][ 'base' ] ) ) { if ( class_exists( 'WpssoUmConfig' ) ) { $um_version = WpssoUmConfig::get_version(); $um_min_ver = WpssoConfig::$cf[ 'um' ][ 'min_version' ]; if ( version_compare( $um_version, $um_min_ver, '>=' ) ) { return $local_cache = true; } elseif ( $this->p->debug->enabled ) { $this->p->debug->log( 'update manager version less than minimum' ); } } elseif ( $this->p->debug->enabled ) { $this->p->debug->log( 'update manager config class not found' ); } } elseif ( $this->p->debug->enabled ) { $this->p->debug->log( 'update manager add-on is not active' ); } } elseif ( $this->p->debug->enabled ) { $this->p->debug->log( 'update manager config not found' ); } return $local_cache = false; } private function is_opt_enabled( $key, $val = null ) { if ( ! empty( $key ) ) { // Just in case. if ( null === $val ) { if ( ! empty( $this->p->options[ $key ] ) ) { // Not 0 or empty string. if ( $this->p->options[ $key ] !== 'none' ) { return true; } } } elseif ( isset( $this->p->options[ $key ] ) ) { // Just in case. if ( $val === $this->p->options[ $key ] ) { return true; } } } return false; } } }