8 ) ); if ( is_wp_error( $response ) ) { return null; } $code = (int) wp_remote_retrieve_response_code( $response ); $body = ( $code === 200 ) ? json_decode( wp_remote_retrieve_body( $response ), true ) : null; // Fallback to /tags if no Release object exists yet. if ( $code !== 200 || ! is_array( $body ) || empty( $body['tag_name'] ) ) { $tags_response = wp_remote_get( $base_api . '/tags?limit=1', array( 'timeout' => 8 ) ); if ( ! is_wp_error( $tags_response ) && (int) wp_remote_retrieve_response_code( $tags_response ) === 200 ) { $tags = json_decode( wp_remote_retrieve_body( $tags_response ), true ); if ( is_array( $tags ) && ! empty( $tags[0]['name'] ) ) { $body = array( 'tag_name' => $tags[0]['name'], 'html_url' => radio_gitea_repo_url() . '/src/tag/' . rawurlencode( $tags[0]['name'] ), 'body' => isset( $tags[0]['message'] ) ? $tags[0]['message'] : '', 'published_at' => isset( $tags[0]['commit']['created'] ) ? $tags[0]['commit']['created'] : null, 'assets' => array(), ); $code = 200; } } } if ( $code !== 200 || ! is_array( $body ) || empty( $body['tag_name'] ) ) { $info = array( 'version' => null, 'html_url' => radio_gitea_releases_url(), 'download_url' => null, 'body' => '', 'published_at' => null, 'error_code' => $code, ); set_site_transient( $cache_key, $info, HOUR_IN_SECONDS ); return $info; } $version = ltrim( (string) $body['tag_name'], 'vV' ); // Prefer a .zip asset; fall back to Gitea source-archive URL. $download_url = null; if ( ! empty( $body['assets'] ) && is_array( $body['assets'] ) ) { foreach ( $body['assets'] as $asset ) { if ( isset( $asset['name'], $asset['browser_download_url'] ) && substr( strtolower( $asset['name'] ), -4 ) === '.zip' ) { $download_url = $asset['browser_download_url']; break; } } } if ( ! $download_url ) { $download_url = radio_gitea_repo_url() . '/archive/' . rawurlencode( $body['tag_name'] ) . '.zip'; } $info = array( 'version' => $version, 'html_url' => isset( $body['html_url'] ) ? esc_url_raw( $body['html_url'] ) : '', 'download_url' => esc_url_raw( $download_url ), 'body' => isset( $body['body'] ) ? wp_strip_all_tags( $body['body'] ) : '', 'published_at' => isset( $body['published_at'] ) ? $body['published_at'] : null, ); set_site_transient( $cache_key, $info, 12 * HOUR_IN_SECONDS ); return $info; } function radio_update_status( $force_refresh = false ) { $current = defined( 'RADIO_VERSION' ) ? RADIO_VERSION : '0.0.0'; $latest = radio_fetch_latest_release( $force_refresh ); if ( ! $latest || empty( $latest['version'] ) ) { $msg = __( 'No releases tagged on the Gitea repo yet.', 'radio' ); if ( $latest && ! empty( $latest['error_code'] ) && (int) $latest['error_code'] !== 404 ) { $msg = sprintf( __( 'Could not reach Gitea (HTTP %d). Try again in a few minutes.', 'radio' ), (int) $latest['error_code'] ); } return array( 'status' => 'unknown', 'current' => $current, 'message' => $msg, 'repo_url' => radio_gitea_repo_url(), ); } if ( version_compare( $latest['version'], $current, '>' ) ) { return array( 'status' => 'available', 'current' => $current, 'latest' => $latest['version'], 'html_url' => $latest['html_url'], 'download_url' => $latest['download_url'], 'published_at' => $latest['published_at'], 'body' => $latest['body'], 'message' => sprintf( __( 'A new version (v%1$s) is available — you are on v%2$s.', 'radio' ), $latest['version'], $current ), ); } return array( 'status' => 'up-to-date', 'current' => $current, 'latest' => $latest['version'], 'message' => sprintf( __( 'You are up to date (v%s).', 'radio' ), $current ), 'repo_url' => radio_gitea_repo_url(), ); } add_action( 'wp_ajax_radio_check_updates', 'radio_ajax_check_updates' ); function radio_ajax_check_updates() { if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( 'Insufficient permissions.', 403 ); } check_ajax_referer( 'radio_check_updates', 'nonce' ); delete_site_transient( 'radio_gitea_latest' ); wp_send_json_success( radio_update_status( true ) ); } function radio_render_updates_panel() { $status = radio_update_status( false ); $nonce = wp_create_nonce( 'radio_check_updates' ); $repo_url = radio_gitea_repo_url(); $rel_url = radio_gitea_releases_url(); ?>