[ 'code' => 200, 'message' => 'OK', ], 'body' => json_encode( [ 'platform' => _x( 'your platform', 'browser version check', 'fair' ), 'name' => _x( 'your browser', 'browser version check', 'fair' ), 'version' => '', 'current_version' => '', 'upgrade' => ! $supported, 'insecure' => ! $supported, 'update_url' => 'https://browsehappy.com/', 'img_src' => '', 'img_src_ssl' => '', ] ), 'headers' => [], 'cookies' => [], 'http_response_code' => 200, ]; } /** * Get PHP branch data from php.net * * @return array|null Branch-indexed data from PHP.net, or null on failure. */ function get_php_branches() { $releases = get_transient( 'php_releases' ); if ( $releases ) { return $releases; } $response = wp_remote_get( 'https://www.php.net/releases/branches' ); if ( is_wp_error( $response ) ) { // Failed - we'll fall back to hardcoded data. return null; } $data = json_decode( wp_remote_retrieve_body( $response ), true ); if ( ! is_array( $data ) ) { // Likely a server-level error - fall back to hardcoded data. return null; } // Index data by branch. $indexed = []; foreach ( $data as $ver ) { if ( empty( $ver['branch'] ) ) { continue; } $indexed[ $ver['branch'] ] = $ver; } set_transient( 'php_releases', $indexed, CACHE_LIFETIME ); return $indexed; } /** * Check the PHP version against current versions. * * (WP sets is_lower_than_future_minimum manually based on >=7.4) * * The logic for the dashboard widget is: * - If is_acceptable, show nothing. * - Else if is_lower_than_future_minimum, show "PHP Update Required" * - Else, show "PHP Update Recommended" * * The logic for the Site Health check is: * - If the version is greater than recommended_version, show "running a recommended version" * - Else if is_supported, show "running on an older version" * - Else if is_secure and is_lower_than_future_minimum, show "outdated version which will soon not be supported" * - Else if is_secure, show "running on an older version which should be updated" * - Else if is_lower_than_future_minimum, show "outdated version which does not receive security updates and will soon not be supported" * - Else, show "outdated version which does not receive security updates" * * @param string $version Version to check. * @return array HTTP API response-like data. */ function check_php_version( string $version ) { $branches = get_php_branches(); if ( empty( $branches ) ) { // Hardcoded fallback if we can't contact PHP.net. return [ 'recommended_version' => RECOMMENDED_PHP, 'minimum_version' => MINIMUM_PHP, 'is_supported' => version_compare( $version, SUPPORTED_PHP, '>=' ), 'is_secure' => version_compare( $version, SECURE_PHP, '>=' ), 'is_acceptable' => version_compare( $version, ACCEPTABLE_PHP, '>=' ), ]; } $min_stable = null; $min_secure = null; foreach ( $branches as $ver ) { // 'branch' is the major version. // 'latest' is the latest minor version on the branch. switch ( $ver['state'] ) { case 'stable': if ( $min_stable === null || version_compare( $ver['branch'], $min_stable, '<' ) ) { $min_stable = $ver['branch']; $min_secure = $ver['branch']; } break; case 'security': if ( $min_secure === null || version_compare( $ver['branch'], $min_secure, '<' ) ) { $min_secure = $ver['branch']; } break; case 'eol': // Ignore EOL versions. break; } } $ver_parts = explode( '.', $version ); $cur_branch = sprintf( '%d.%d', $ver_parts[0], $ver_parts[1] ); if ( empty( $branches[ $cur_branch ] ) ) { // Unknown version, likely future. return [ 'recommended_version' => $min_stable, 'minimum_version' => MINIMUM_PHP, 'is_supported' => version_compare( $version, $min_stable, '>=' ), 'is_secure' => version_compare( $version, $min_secure, '>=' ), 'is_acceptable' => version_compare( $version, $min_secure, '>=' ), ]; } $cur_branch_data = $branches[ $cur_branch ]; if ( $cur_branch_data['state'] === 'security' ) { return [ // If we're on the security branches, the recommended version // should be the latest version of this branch. 'recommended_version' => $cur_branch_data['latest'], 'minimum_version' => MINIMUM_PHP, 'is_supported' => $cur_branch_data['state'] === 'stable', 'is_secure' => version_compare( $version, $cur_branch_data['latest'], '>=' ), 'is_acceptable' => version_compare( $version, $cur_branch_data['latest'], '>=' ), ]; } // Must be eol or future version. return [ // Show the latest version of this branch or the minimum stable, whichever is greater. 'recommended_version' => version_compare( $version, $min_stable, '>' ) ? $cur_branch_data['latest'] : $min_stable, 'minimum_version' => MINIMUM_PHP, 'is_supported' => version_compare( $version, $min_stable, '>=' ), 'is_secure' => version_compare( $version, $min_secure, '>=' ), 'is_acceptable' => version_compare( $version, $min_secure, '>=' ), ]; } /** * Get the server check shim response. * * @param string $version Version to check. * @return array HTTP API response-like data. */ function get_server_check_response( string $version ) { return [ 'response' => [ 'code' => 200, 'message' => 'OK', ], 'body' => json_encode( check_php_version( $version ) ), 'headers' => [], 'cookies' => [], 'http_response_code' => 200, ]; }