/home/techb158/public_html/wp-content/plugins/akismet
Edit: /home/techb158/public_html/wp-content/plugins/akismet/class-akismet-compatible-plugins.php (8020B)
$data ) {
$path = $data['path'];
// Skip if not installed.
if ( ! isset( $all_plugins[ $path ] ) ) {
continue;
}
// Check activation: per-site or network-wide (multisite).
$site_active = is_plugin_active( $path );
$network_active = is_multisite() && is_plugin_active_for_network( $path );
if ( $site_active || $network_active ) {
$active_compatible_plugins[ $slug ] = $data;
}
}
return $active_compatible_plugins;
}
/**
* Initializes action hooks for the class.
*
* @return void
*/
public static function init(): void {
add_action( 'activated_plugin', array( static::class, 'handle_plugin_change' ), true );
add_action( 'deactivated_plugin', array( static::class, 'handle_plugin_change' ), true );
}
/**
* Handles plugin activation and deactivation events.
*
* @param string $plugin The path to the main plugin file from plugins directory.
* @return void
*/
public static function handle_plugin_change( string $plugin ): void {
$cached_plugins = static::get_cached_plugins();
/**
* Terminate if nothing's cached.
*/
if ( false === $cached_plugins ) {
return;
}
$plugin_change_should_invalidate_cache = in_array( $plugin, array_column( $cached_plugins, 'path' ) );
/**
* Purge the cache if the plugin is activated or deactivated.
*/
if ( $plugin_change_should_invalidate_cache ) {
static::purge_cache();
}
}
/**
* Gets plugins that are compatible with Akismet from the Akismet API.
*
* @param bool $bypass_cache Whether to bypass the cache and fetch fresh data.
* @return array
*/
private static function get_compatible_plugins( bool $bypass_cache = false ): array {
// Return cached result if present (false => cache miss; empty array is valid).
$cached_plugins = static::get_cached_plugins();
if ( false !== $cached_plugins && ! $bypass_cache ) {
return $cached_plugins;
}
$response = wp_remote_get(
self::COMPATIBLE_PLUGIN_ENDPOINT
);
$sanitized = static::validate_compatible_plugin_response( $response );
if ( false === $sanitized ) {
return array();
}
/**
* Sets local static associative array of plugin data keyed by plugin slug.
*/
$compatible_plugins = array();
foreach ( $sanitized as $plugin ) {
$compatible_plugins[ $plugin['slug'] ] = $plugin;
}
static::set_cached_plugins( $compatible_plugins );
return $compatible_plugins;
}
/**
* Validates a response object from the Compatible Plugins API.
*
* @param array|WP_Error $response
* @return array|false
*/
private static function validate_compatible_plugin_response( $response ) {
/**
* Terminates the function if the response is a WP_Error object.
*/
if ( is_wp_error( $response ) ) {
return false;
}
/**
* The response returned is an array of header + body string data.
* This pops off the body string for processing.
*/
$response_body = wp_remote_retrieve_body( $response );
if ( empty( $response_body ) ) {
return false;
}
$plugins = json_decode( $response_body, true );
if ( false === is_array( $plugins ) ) {
return false;
}
foreach ( $plugins as $plugin ) {
if ( ! is_array( $plugin ) ) {
/**
* Skips to the next iteration if for some reason the plugin is not an array.
*/
continue;
}
// Ensure that the plugin config read in from the API has all the required fields.
$plugin_key_count = count(
array_intersect_key( $plugin, array_flip( static::COMPATIBLE_PLUGIN_FIELDS ) )
);
$does_not_have_all_required_fields = ! (
$plugin_key_count === count( static::COMPATIBLE_PLUGIN_FIELDS )
);
if ( $does_not_have_all_required_fields ) {
return false;
}
if ( false === static::has_valid_plugin_path( $plugin['path'] ) ) {
return false;
}
}
return static::sanitize_compatible_plugin_response( $plugins );
}
/**
* Validates a plugin path format.
*
* The path should be in the format of 'plugin-name/plugin-name.php'.
* Allows alphanumeric characters, dashes, underscores, and optional dots in folder names.
*
* @param string $path
* @return bool
*/
private static function has_valid_plugin_path( string $path ): bool {
return preg_match( '/^[a-zA-Z0-9._-]+\/[a-zA-Z0-9_-]+\.php$/', $path ) === 1;
}
/**
* Sanitizes a response object from the Compatible Plugins API.
*
* @param array $plugins
* @return array
*/
private static function sanitize_compatible_plugin_response( array $plugins = array() ): array {
foreach ( $plugins as $key => $plugin ) {
$plugins[ $key ] = array_map( 'sanitize_text_field', $plugin );
$plugins[ $key ]['help_url'] = esc_url_raw( $plugins[ $key ]['help_url'] );
$plugins[ $key ]['logo'] = esc_url_raw( $plugins[ $key ]['logo'] );
}
return $plugins;
}
/**
* @param array $plugins
* @return bool
*/
private static function set_cached_plugins( array $plugins ): bool {
$_blog_id = (int) get_current_blog_id();
return set_transient(
static::CACHE_KEY . "_$_blog_id",
$plugins,
DAY_IN_SECONDS
);
}
/**
* Attempts to get cached compatible plugins.
*
* @return mixed|false
*/
private static function get_cached_plugins() {
$_blog_id = (int) get_current_blog_id();
return get_transient(
static::CACHE_KEY . "_$_blog_id"
);
}
/**
* Purges the cache for the compatible plugins.
*
* @return bool
*/
private static function purge_cache(): bool {
$_blog_id = (int) get_current_blog_id();
return delete_transient(
static::CACHE_KEY . "_$_blog_id"
);
}
}