@@ -45,6 +45,25 @@ public static function update_key( $key ) {
4545 return update_option ( 'dt_mapbox_api_key ' , $ key , true );
4646 }
4747
48+ /**
49+ * Get request arguments with Referer header for Mapbox API calls
50+ * This ensures URL restrictions work correctly with server-side requests
51+ *
52+ * @return array Request arguments array with Referer header
53+ */
54+ private static function get_mapbox_request_args () {
55+ // Get and normalize the server URL for Referer header
56+ $ server_url = home_url ( '' , 'https ' );
57+ // Remove trailing slash for consistency
58+ $ server_url = rtrim ( $ server_url , '/ ' );
59+
60+ return [
61+ 'headers ' => [
62+ 'Referer ' => $ server_url
63+ ]
64+ ];
65+ }
66+
4867 /**
4968 * Geocoder Scripts for Echo
5069 */
@@ -77,7 +96,8 @@ public static function forward_lookup( $address, $country_code = null ) {
7796 }
7897
7998 /** @link https://codex.wordpress.org/Function_Reference/wp_remote_get */
80- $ response = wp_remote_get ( esc_url_raw ( $ url ) );
99+ $ args = self ::get_mapbox_request_args ();
100+ $ response = wp_remote_get ( esc_url_raw ( $ url ), $ args );
81101 $ data_result = wp_remote_retrieve_body ( $ response );
82102
83103 if ( ! $ data_result ) {
@@ -138,9 +158,9 @@ public static function lookup( $search_string, $type = 'full', $country_code = n
138158 break ;
139159 }
140160
141-
142161 /** @link https://codex.wordpress.org/Function_Reference/wp_remote_get */
143- $ response = wp_remote_get ( esc_url_raw ( $ url ) );
162+ $ args = self ::get_mapbox_request_args ();
163+ $ response = wp_remote_get ( esc_url_raw ( $ url ), $ args );
144164 $ data_result = wp_remote_retrieve_body ( $ response );
145165
146166 if ( ! $ data_result ) {
@@ -150,8 +170,9 @@ public static function lookup( $search_string, $type = 'full', $country_code = n
150170 }
151171
152172 public static function reverse_lookup ( $ longitude , $ latitude ) {
153- $ url = self ::$ mapbox_endpoint . $ longitude . ', ' . $ latitude . '.json?access_token= ' . self ::get_key ();
154- $ response = wp_remote_get ( esc_url_raw ( $ url ) );
173+ $ url = self ::$ mapbox_endpoint . $ longitude . ', ' . $ latitude . '.json?access_token= ' . self ::get_key ();
174+ $ args = self ::get_mapbox_request_args ();
175+ $ response = wp_remote_get ( esc_url_raw ( $ url ), $ args );
155176 $ data_result = wp_remote_retrieve_body ( $ response );
156177
157178 if ( ! $ data_result ) {
@@ -171,11 +192,19 @@ public static function reverse_lookup( $longitude, $latitude ) {
171192 public static function get_country_by_coordinates ( $ longitude , $ latitude ) {
172193 $ country_code = false ;
173194 if ( self ::get_key () ) {
174- $ url = self ::$ mapbox_endpoint . $ longitude . ', ' . $ latitude . '.json?types=country&access_token= ' . self ::get_key ();
175- $ data_result = @file_get_contents ( $ url );
195+ $ url = self ::$ mapbox_endpoint . $ longitude . ', ' . $ latitude . '.json?types=country&access_token= ' . self ::get_key ();
196+ $ args = self ::get_mapbox_request_args ();
197+ $ response = wp_remote_get ( esc_url_raw ( $ url ), $ args );
198+
199+ if ( is_wp_error ( $ response ) ) {
200+ return false ;
201+ }
202+
203+ $ data_result = wp_remote_retrieve_body ( $ response );
176204 if ( ! $ data_result ) {
177205 return false ;
178206 }
207+
179208 $ data = json_decode ( $ data_result , true );
180209
181210 if ( isset ( $ data ['features ' ][0 ]['properties ' ]['short_code ' ] ) ) {
@@ -396,21 +425,91 @@ public static function load_admin_header() {
396425
397426 public static function is_active_mapbox_key () : array {
398427 $ key = self ::get_key ();
399- $ url = self ::$ mapbox_endpoint . 'Denver.json?access_token= ' . $ key ;
400- $ response = wp_remote_get ( esc_url_raw ( $ url ) );
401- $ data_result = json_decode ( wp_remote_retrieve_body ( $ response ), true );
402428
403- if ( isset ( $ data_result [ ' features ' ] ) && ! empty ( $ data_result [ ' features ' ] ) ) {
429+ if ( empty ( $ key ) ) {
404430 return [
405- 'success ' => true ,
406- 'message ' => ''
431+ 'success ' => false ,
432+ 'message ' => 'No Mapbox API token provided ' ,
433+ 'error_type ' => 'missing_token '
407434 ];
408- } else {
435+ }
436+
437+ // Get normalized server URL for error reporting
438+ $ server_url = home_url ( '' , 'https ' );
439+ $ server_url = rtrim ( $ server_url , '/ ' );
440+ $ referer_url = $ server_url ;
441+
442+ $ url = self ::$ mapbox_endpoint . 'Denver.json?access_token= ' . $ key ;
443+
444+ // Set Referer header to match the site URL so Mapbox can validate URL restrictions
445+ $ args = self ::get_mapbox_request_args ();
446+ $ response = wp_remote_get ( esc_url_raw ( $ url ), $ args );
447+
448+ // Check for WordPress HTTP errors
449+ if ( is_wp_error ( $ response ) ) {
409450 return [
410451 'success ' => false ,
411- 'message ' => ( isset ( $ data_result ['message ' ] ) && ! empty ( $ data_result ['message ' ] ) ) ? $ data_result ['message ' ] : ''
452+ 'message ' => 'Network error: ' . $ response ->get_error_message (),
453+ 'error_type ' => 'network_error '
412454 ];
413455 }
456+
457+ // Get HTTP response code
458+ $ http_code = wp_remote_retrieve_response_code ( $ response );
459+ $ body = wp_remote_retrieve_body ( $ response );
460+ $ data_result = json_decode ( $ body , true );
461+
462+ // Success case
463+ if ( $ http_code === 200 && isset ( $ data_result ['features ' ] ) && ! empty ( $ data_result ['features ' ] ) ) {
464+ return [
465+ 'success ' => true ,
466+ 'message ' => ''
467+ ];
468+ }
469+
470+ // Error cases based on HTTP status code
471+ $ error_message = isset ( $ data_result ['message ' ] ) ? $ data_result ['message ' ] : 'Unknown error ' ;
472+
473+ switch ( $ http_code ) {
474+ case 401 :
475+ return [
476+ 'success ' => false ,
477+ 'message ' => 'Invalid or expired Mapbox access token. Please check your token. ' ,
478+ 'error_type ' => 'unauthorized ' ,
479+ 'api_message ' => $ error_message
480+ ];
481+
482+ case 403 :
483+ // Build detailed error message for URL restriction issues
484+ $ message = 'Mapbox token is valid but access is restricted. ' ;
485+ $ message .= 'This may be due to URL restrictions on your token. ' ;
486+ $ message .= 'The request was sent with Referer header: ' . $ referer_url ;
487+
488+ return [
489+ 'success ' => false ,
490+ 'message ' => $ message ,
491+ 'error_type ' => 'forbidden ' ,
492+ 'api_message ' => $ error_message ,
493+ 'server_url ' => $ server_url ,
494+ 'referer_sent ' => $ referer_url
495+ ];
496+
497+ case 429 :
498+ return [
499+ 'success ' => false ,
500+ 'message ' => 'Rate limit exceeded. Please try again later. ' ,
501+ 'error_type ' => 'rate_limit ' ,
502+ 'api_message ' => $ error_message
503+ ];
504+
505+ default :
506+ return [
507+ 'success ' => false ,
508+ 'message ' => 'Could not verify Mapbox token. HTTP ' . $ http_code . ': ' . $ error_message ,
509+ 'error_type ' => 'api_error ' ,
510+ 'api_message ' => $ error_message
511+ ];
512+ }
414513 }
415514
416515 /**
@@ -441,8 +540,44 @@ public static function metabox_for_admin() {
441540 if ( empty ( $ key ) ) {
442541 $ message = 'Please add a Mapbox API Token ' ;
443542 } else {
444- $ message = 'Could not connect to the Mapbox API or could not verify the token ' ;
445- $ message .= ! empty ( $ mapbox_key_active_state ['message ' ] ) ? ' - ' . $ mapbox_key_active_state ['message ' ] : '' ;
543+ $ message = $ mapbox_key_active_state ['message ' ];
544+
545+ // Add detailed information for 403 errors (URL restrictions)
546+ if ( isset ( $ mapbox_key_active_state ['error_type ' ] ) && $ mapbox_key_active_state ['error_type ' ] === 'forbidden ' ) {
547+ $ message .= '<br><br><strong>Debugging Information:</strong> ' ;
548+ $ message .= '<br><strong>Site URL detected:</strong> <code> ' . esc_html ( $ mapbox_key_active_state ['server_url ' ] ?? 'N/A ' ) . '</code> ' ;
549+
550+ if ( isset ( $ mapbox_key_active_state ['referer_sent ' ] ) ) {
551+ $ message .= '<br><strong>Referer header sent:</strong> <code> ' . esc_html ( $ mapbox_key_active_state ['referer_sent ' ] ) . '</code> ' ;
552+ }
553+
554+ $ message .= '<br><br><strong>To fix this:</strong> ' ;
555+ $ message .= '<ol style="margin-left: 20px;"> ' ;
556+ $ message .= '<li>Go to your <a href="https://account.mapbox.com/access-tokens/" target="_blank">Mapbox account settings</a></li> ' ;
557+ $ message .= '<li>Find your access token and click to edit it</li> ' ;
558+ $ message .= '<li>In the "URL restrictions" section, add the URL shown above</li> ' ;
559+
560+ // Special note for local development URLs
561+ if ( isset ( $ mapbox_key_active_state ['referer_sent ' ] ) ) {
562+ $ referer = $ mapbox_key_active_state ['referer_sent ' ];
563+ if ( strpos ( $ referer , 'localhost ' ) !== false || strpos ( $ referer , '.local ' ) !== false || strpos ( $ referer , '127.0.0.1 ' ) !== false ) {
564+ $ message .= '<li><strong>Note:</strong> You \'re using a local development URL. Mapbox URL restrictions may not work with localhost or .local domains. Consider using a token without URL restrictions for local development, or use a tool like ngrok to create a public URL for testing.</li> ' ;
565+ }
566+ }
567+
568+ $ message .= '<li>Save your changes and test again</li> ' ;
569+ $ message .= '</ol> ' ;
570+
571+ // Add API message if available
572+ if ( isset ( $ mapbox_key_active_state ['api_message ' ] ) && ! empty ( $ mapbox_key_active_state ['api_message ' ] ) ) {
573+ $ message .= '<br><br><em>Mapbox API Response: ' . esc_html ( $ mapbox_key_active_state ['api_message ' ] ) . '</em> ' ;
574+ }
575+ } else {
576+ // Add API message details for other error types if available
577+ if ( isset ( $ mapbox_key_active_state ['api_message ' ] ) && ! empty ( $ mapbox_key_active_state ['api_message ' ] ) && $ mapbox_key_active_state ['api_message ' ] !== $ mapbox_key_active_state ['message ' ] ) {
578+ $ message .= '<br><br><em>API Response: ' . esc_html ( $ mapbox_key_active_state ['api_message ' ] ) . '</em> ' ;
579+ }
580+ }
446581 }
447582 }
448583 ?>
@@ -470,7 +605,7 @@ public static function metabox_for_admin() {
470605 <tr>
471606 <td>
472607 <p id="reachable_source" class="<?php echo esc_attr ( $ status_class ) ?> ">
473- <?php echo esc_html ( $ message ); ?>
608+ <?php echo wp_kses_post ( $ message ); ?>
474609 </p>
475610 </td>
476611 </tr>
0 commit comments