$h ) { $plugins[ $basename ] = self::entry( $h, 'plugin', in_array( $basename, $active, true ) || in_array( $basename, $network, true ), in_array( $basename, $network, true ), in_array( $basename, $heads, true ) ); } if ( function_exists( 'get_mu_plugins' ) ) { foreach ( (array) get_mu_plugins() as $file => $h ) { $plugins[ 'mu-plugins/' . $file ] = self::entry( $h, 'mu', true, false, in_array( 'mu-plugins/' . $file, $heads, true ) ); } } if ( function_exists( 'get_dropins' ) ) { foreach ( (array) get_dropins() as $file => $h ) { $plugins[ $file ] = self::entry( $h, 'dropin', true, false, false ); } } ksort( $plugins ); $total = count( $plugins ); $truncated = false; if ( $total > self::MAX_ENTRIES ) { $plugins = array_slice( $plugins, 0, self::MAX_ENTRIES, true ); $truncated = true; } $counts = array( 'total' => $total, 'active' => 0, 'mu' => 0, 'dropins' => 0, 'head_writers' => 0 ); foreach ( $plugins as $p ) { if ( $p['active'] ) { $counts['active']++; } if ( 'mu' === $p['kind'] ) { $counts['mu']++; } if ( 'dropin' === $p['kind'] ) { $counts['dropins']++; } if ( $p['head_writer'] ) { $counts['head_writers']++; } } $theme = wp_get_theme(); $parent = $theme->parent(); $out = array( 'schema' => self::SCHEMA, 'scanned_at' => gmdate( 'c' ), 'plugin_version' => defined( 'AIEO_VERSION' ) ? AIEO_VERSION : '', 'site' => array( 'url' => home_url(), 'label' => wp_specialchars_decode( (string) get_bloginfo( 'name' ), ENT_QUOTES ), 'fp' => class_exists( 'AIEO_Portal_Client' ) ? AIEO_Portal_Client::fp() : '', 'wp' => get_bloginfo( 'version' ), 'php' => PHP_VERSION, 'wc' => defined( 'WC_VERSION' ) ? WC_VERSION : '', 'locale' => get_locale(), 'multisite' => is_multisite(), 'runtime' => defined( 'AIEO_RUNTIME_VERSION' ) || class_exists( 'AIEO_Runtime' ), ), 'theme' => array( 'slug' => $theme->get_stylesheet(), 'name' => $theme->get( 'Name' ), 'version' => $theme->get( 'Version' ), 'parent' => $parent ? $parent->get_stylesheet() : '', ), 'environment' => self::environment(), 'plugins' => $plugins, 'counts' => $counts, ); if ( $truncated ) { $out['truncated'] = true; } return $out; } public static function environment() { global $wpdb; $db_server = 'Unknown'; if ( method_exists( $wpdb, 'db_server_info' ) ) { $server_info = (string) $wpdb->db_server_info(); if ( false !== stripos( $server_info, 'mariadb' ) ) { preg_match( '/(\d+\.\d+\.\d+)-MariaDB/i', $server_info, $m ); $db_server = 'MariaDB ' . ( $m[1] ?? '' ); } else { $db_server = 'MySQL ' . $wpdb->db_version(); } } $object_cache = 'None'; if ( wp_using_ext_object_cache() ) { if ( class_exists( 'Redis' ) || class_exists( 'WPRedis' ) || defined( 'WP_REDIS_VERSION' ) ) { $object_cache = 'Redis' . ( defined( 'WP_REDIS_VERSION' ) ? ' ' . WP_REDIS_VERSION : '' ); } elseif ( class_exists( 'Memcached' ) ) { $object_cache = 'Memcached'; } elseif ( class_exists( 'Memcache' ) ) { $object_cache = 'Memcache'; } else { $object_cache = 'External (unknown)'; } } $opcache = 'Off'; if ( function_exists( 'opcache_get_status' ) ) { $status = @opcache_get_status( false ); if ( $status && ! empty( $status['opcache_enabled'] ) ) { $opcache = 'On'; if ( ! empty( $status['opcache_statistics']['num_cached_scripts'] ) ) { $opcache .= ' (' . (int) $status['opcache_statistics']['num_cached_scripts'] . ' scripts)'; } } } $server_name = (string) ( gethostname() ?: ( $_SERVER['SERVER_NAME'] ?? '' ) ); $addr = (string) ( $_SERVER['SERVER_ADDR'] ?? '' ); $server_ip = ( '' !== $addr && filter_var( $addr, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) ? $addr : ''; $os_info = PHP_OS_FAMILY; if ( function_exists( 'php_uname' ) ) { $os_info = php_uname( 's' ) . ' ' . php_uname( 'r' ); } return array( 'server_name' => sanitize_text_field( $server_name ), 'server_ip' => $server_ip, 'os_info' => sanitize_text_field( trim( $os_info ) ), 'db_server' => sanitize_text_field( trim( $db_server ) ), 'object_cache' => sanitize_text_field( $object_cache ), 'opcache' => sanitize_text_field( $opcache ), ); } public static function fingerprint() { $snap = self::snapshot( false ); $lines = array(); foreach ( $snap['plugins'] as $b => $p ) { $lines[] = $b . ':' . $p['version'] . ':' . ( $p['active'] ? '1' : '0' ); } sort( $lines ); $lines[] = 'theme:' . $snap['theme']['slug'] . ':' . $snap['theme']['version']; return md5( implode( "\n", $lines ) ); } public static function head_writers() { global $wp_filter; $out = array(); $base = wp_normalize_path( WP_PLUGIN_DIR ) . '/'; $mu = wp_normalize_path( WPMU_PLUGIN_DIR ) . '/'; $hooks = array( 'wp_head', 'wp_footer', 'wp_enqueue_scripts' ); foreach ( $hooks as $hook ) { if ( empty( $wp_filter[ $hook ] ) || ! ( $wp_filter[ $hook ] instanceof WP_Hook ) ) { continue; } foreach ( $wp_filter[ $hook ]->callbacks as $prio => $cbs ) { foreach ( (array) $cbs as $cb ) { $file = self::callback_file( isset( $cb['function'] ) ? $cb['function'] : null ); if ( '' === $file ) { continue; } $file = wp_normalize_path( $file ); if ( 0 === strpos( $file, $base ) ) { $rel = substr( $file, strlen( $base ) ); $parts = explode( '/', $rel ); $out[] = $parts[0]; } elseif ( 0 === strpos( $file, $mu ) ) { $out[] = 'mu-plugins/' . substr( $file, strlen( $mu ) ); } } } } $out = array_values( array_unique( $out ) ); if ( ! function_exists( 'get_plugins' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $names = array(); foreach ( array_keys( (array) get_plugins() ) as $basename ) { $dir = strtok( $basename, '/' ); if ( in_array( $dir, $out, true ) || in_array( $basename, $out, true ) ) { $names[] = $basename; } } foreach ( $out as $o ) { if ( 0 === strpos( $o, 'mu-plugins/' ) ) { $names[] = $o; } } return array_values( array_unique( $names ) ); } private static function callback_file( $fn ) { try { if ( is_string( $fn ) && function_exists( $fn ) ) { $r = new ReflectionFunction( $fn ); return (string) $r->getFileName(); } if ( $fn instanceof Closure ) { $r = new ReflectionFunction( $fn ); return (string) $r->getFileName(); } if ( is_array( $fn ) && 2 === count( $fn ) ) { $r = new ReflectionMethod( $fn[0], $fn[1] ); return (string) $r->getFileName(); } if ( is_object( $fn ) && method_exists( $fn, '__invoke' ) ) { $r = new ReflectionMethod( $fn, '__invoke' ); return (string) $r->getFileName(); } } catch ( \Throwable $e ) { return ''; } return ''; } private static function entry( array $h, $kind, $active, $network, $head ) { return array( 'name' => isset( $h['Name'] ) ? wp_strip_all_tags( (string) $h['Name'] ) : '', 'version' => isset( $h['Version'] ) ? (string) $h['Version'] : '', 'author' => isset( $h['Author'] ) ? wp_strip_all_tags( (string) $h['Author'] ) : '', 'active' => (bool) $active, 'kind' => $kind, 'network' => (bool) $network, 'head_writer' => (bool) $head, ); } private static function raw_active() { global $wpdb; $raw = $wpdb->get_var( "SELECT option_value FROM {$wpdb->options} WHERE option_name = 'active_plugins' LIMIT 1" ); $val = maybe_unserialize( (string) $raw ); $out = array(); foreach ( (array) $val as $b ) { if ( is_string( $b ) && '' !== $b ) { $out[] = $b; } } return $out; } }