@@ -233,6 +233,11 @@ protected function get_events_items( $limit ) {
233233 }
234234 }
235235
236+ // Fallback: call the events API directly if no result yet.
237+ if ( \is_wp_error ( $ response ) || empty ( $ response ['events ' ] ) ) {
238+ $ response = $ this ->fetch_events_via_api ( $ limit , $ locations );
239+ }
240+
236241 if ( \is_wp_error ( $ response ) || empty ( $ response ['events ' ] ) ) {
237242 return array ();
238243 }
@@ -314,6 +319,73 @@ protected function build_event_locations( $user_id ) {
314319 return $ unique ;
315320 }
316321
322+ /**
323+ * Direct API fallback to fetch events from api.wordpress.org.
324+ *
325+ * @param int $limit Max events.
326+ * @param array $locations Locations to try.
327+ * @return array|\WP_Error Response array with 'events' or WP_Error.
328+ */
329+ protected function fetch_events_via_api ( $ limit , $ locations ) {
330+ $ ip = isset ( $ _SERVER ['REMOTE_ADDR ' ] ) ? $ _SERVER ['REMOTE_ADDR ' ] : '' ;
331+ $ locale = \function_exists ( 'get_user_locale ' ) ? \get_user_locale () : 'en_US ' ;
332+ $ tz = \function_exists ( 'wp_timezone_string ' ) ? \wp_timezone_string () : '' ;
333+ $ base = 'https://api.wordpress.org/events/1.0/ ' ;
334+ $ params = array (
335+ 'number ' => $ limit ,
336+ 'locale ' => $ locale ,
337+ 'timezone ' => $ tz ,
338+ );
339+
340+ // Try each location; if none, fall back to IP-only query.
341+ if ( empty ( $ locations ) ) {
342+ $ locations [] = array ();
343+ }
344+
345+ foreach ( $ locations as $ location ) {
346+ $ query_args = $ params ;
347+
348+ if ( ! empty ( $ location ['latitude ' ] ) && ! empty ( $ location ['longitude ' ] ) ) {
349+ $ query_args ['latitude ' ] = $ location ['latitude ' ];
350+ $ query_args ['longitude ' ] = $ location ['longitude ' ];
351+ } elseif ( ! empty ( $ location ['city ' ] ) ) {
352+ $ query_args ['location ' ] = $ location ['city ' ];
353+ if ( ! empty ( $ location ['country ' ] ) ) {
354+ $ query_args ['country ' ] = $ location ['country ' ];
355+ }
356+ } elseif ( ! empty ( $ location ['country ' ] ) ) {
357+ $ query_args ['country ' ] = $ location ['country ' ];
358+ } elseif ( $ ip ) {
359+ $ query_args ['ip ' ] = $ ip ;
360+ }
361+
362+ if ( $ ip && ! isset ( $ query_args ['ip ' ] ) ) {
363+ $ query_args ['ip ' ] = $ ip ;
364+ }
365+
366+ $ url = \add_query_arg ( array_filter ( $ query_args ), $ base );
367+ $ response = \wp_remote_get ( $ url , array ( 'timeout ' => 8 ) );
368+
369+ if ( \is_wp_error ( $ response ) ) {
370+ continue ;
371+ }
372+
373+ $ code = \wp_remote_retrieve_response_code ( $ response );
374+ if ( 200 !== (int ) $ code ) {
375+ continue ;
376+ }
377+
378+ $ body = \wp_remote_retrieve_body ( $ response );
379+ $ data = \json_decode ( $ body , true );
380+
381+ if ( ! empty ( $ data ['events ' ] ) && \is_array ( $ data ['events ' ] ) ) {
382+ return array ( 'events ' => $ data ['events ' ] );
383+ }
384+ }
385+
386+ return array ( 'events ' => array () );
387+ }
388+
317389 /**
318390 * Return the country code inferred from the site locale.
319391 *
0 commit comments