sanitizer = new ComponentEvidenceSanitizer( $hash_key ?? ( new LocalHashKey() )->derive() ); } /** * @return array{components:list,total_count:int,truncated:bool} */ public function snapshot(): array { if ( ! function_exists( 'get_plugins' ) ) { $plugin_api = ( new WordPressPathProvider() )->core_file( 'wp-admin/includes/plugin.php' ); require_once $plugin_api; } $components = array( array( 'type' => 'core', 'slug' => 'wordpress', 'name' => 'WordPress', 'version' => $this->sanitizer->version( get_bloginfo( 'version' ) ), ), ); $plugins = get_plugins(); $total_count = 1 + count( $plugins ); foreach ( array_slice( $plugins, 0, self::MAX_COMPONENTS - 1, true ) as $file => $headers ) { $directory = dirname( (string) $file ); $slug = '.' === $directory ? basename( (string) $file, '.php' ) : basename( $directory ); $version = isset( $headers['Version'] ) && is_string( $headers['Version'] ) ? $this->sanitizer->version( $headers['Version'] ) : 'unknown'; if ( 1 !== preg_match( '/^[a-z0-9][a-z0-9-]{0,99}$/D', $slug ) || 'unknown' === $version ) { continue; } $components[] = array( 'type' => 'plugin', 'slug' => $slug, 'name' => $this->sanitizer->text( isset( $headers['Name'] ) && is_string( $headers['Name'] ) ? $headers['Name'] : $slug ), 'version' => $version, ); } $themes = ( new LocalThemeAdapter() )->themes(); $total_count += count( $themes ); $remaining = max( 0, self::MAX_COMPONENTS - count( $components ) ); foreach ( array_slice( $themes, 0, $remaining ) as $theme ) { if ( 1 !== preg_match( '/^[a-z0-9][a-z0-9-]{0,99}$/D', $theme['slug'] ) ) { continue; } $version = $this->sanitizer->version( $theme['version'] ); if ( 'unknown' === $version ) { continue; } $components[] = array( 'type' => 'theme', 'slug' => $theme['slug'], 'name' => $this->sanitizer->text( $theme['name'] ), 'version' => $version, ); } $components = array_slice( $components, 0, self::MAX_COMPONENTS ); usort( $components, static function ( array $left, array $right ): int { return array( $left['type'], $left['slug'], $left['version'] ) <=> array( $right['type'], $right['slug'], $right['version'] ); } ); return array( 'components' => $components, 'total_count' => $total_count, 'truncated' => count( $components ) < $total_count, ); } }