prefix . 'ailm_link_monitor'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery $links = $wpdb->get_results( $wpdb->prepare( "SELECT id, url FROM %i WHERE status_code = %d ORDER BY id ASC LIMIT %d", $table_name, 0, $batch_size ) ); if ( empty( $links ) ) { return 0; // No links to check } $processed = 0; foreach ( $links as $link ) { $status_code = self::ping_url( $link->url ); // Update status and check time in the database // phpcs:ignore WordPress.DB.DirectDatabaseQuery $wpdb->update( $table_name, array( 'status_code' => $status_code, 'last_checked' => current_time( 'mysql' ) ), array( 'id' => $link->id ), array( '%d', '%s' ), array( '%d' ) ); $processed++; } return $processed; } /** * Pings a URL to get its HTTP status. * * @param string $url The URL to check. * @return int HTTP code (200, 301, 404) or 500 on timeout/cURL error. */ private static function ping_url( $url ) { $args = array( 'timeout' => 5, // 5 second timeout to avoid hanging the server 'redirection' => 5, // Follow redirects 'sslverify' => false // Disable strict SSL verification to prevent false 500 errors from misconfigured certificates ); // First, try a lightweight HEAD request (downloads only headers, saves bandwidth) $response = wp_remote_head( $url, $args ); // Architectural trick: some servers or firewalls (like Cloudflare) // block HEAD requests, returning 405 Method Not Allowed or 403 Forbidden. // In that case, perform a regular GET request as a fallback. $code = wp_remote_retrieve_response_code( $response ); if ( is_wp_error( $response ) || $code == 405 || $code == 403 ) { $response = wp_remote_get( $url, $args ); } if ( is_wp_error( $response ) ) { return 500; // Connection error or timeout } return (int) wp_remote_retrieve_response_code( $response ); } }