PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.2.9
Yatra – Travel Booking & Tour Operator Software v3.0.2.9
3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 All 84 releases
yatra / app / Ajax / GeocodingAjax.php

GeocodingAjax.php in Yatra – Travel Booking & Tour Operator Software 3.0.2.9, at app/Ajax/GeocodingAjax.php

165 lines 5.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace Yatra\Ajax;
6
7 use Yatra\Repositories\GeocodingRepository;
8
9 /**
10 * AJAX handlers for Geocoding functionality
11 *
12 * Rate limiting uses WordPress transients (always on). Response caching goes through
13 * {@see GeocodingRepository} → {@see \Yatra\Utils\Cache} (not options).
14 */
15 class GeocodingAjax
16 {
17 private GeocodingRepository $geocodingRepository;
18
19 public function __construct()
20 {
21 $this->geocodingRepository = new GeocodingRepository();
22 add_action('wp_ajax_yatra_search_locations', [$this, 'searchLocations']);
23 add_action('wp_ajax_nopriv_yatra_search_locations', [$this, 'searchLocations']);
24 add_action('wp_ajax_yatra_reverse_geocode', [$this, 'reverseGeocode']);
25 add_action('wp_ajax_nopriv_yatra_reverse_geocode', [$this, 'reverseGeocode']);
26 }
27
28 /**
29 * Search for locations using Nominatim API
30 */
31 public function searchLocations(): void
32 {
33 // Verify nonce
34 if (!wp_verify_nonce($_POST['nonce'] ?? '', 'yatra_geocoding_nonce')) {
35 wp_send_json_error(['message' => 'Security check failed']);
36 return;
37 }
38
39 $query = sanitize_text_field($_POST['query'] ?? '');
40 $limit = intval($_POST['limit'] ?? 5);
41
42 if (empty($query) || strlen($query) < 2) {
43 wp_send_json_error(['message' => 'Query too short']);
44 return;
45 }
46
47 // Rate limiting - check if user has made too many requests
48 $user_ip = $_SERVER['REMOTE_ADDR'];
49 $cache_key = 'yatra_geocoding_' . md5($user_ip);
50 $request_count = get_transient($cache_key);
51
52 if ($request_count === false) {
53 // First request, set counter
54 set_transient($cache_key, 1, 60); // 1 minute window
55 } elseif ($request_count >= 10) {
56 // Too many requests
57 wp_send_json_error(['message' => 'Too many requests. Please wait a moment.']);
58 return;
59 } else {
60 // Increment counter
61 set_transient($cache_key, $request_count + 1, 60);
62 }
63
64 $resultCacheKey = $this->geocodingRepository->cacheKeySearch($query, $limit);
65 $cached = $this->geocodingRepository->getPayload($resultCacheKey);
66 if (is_array($cached)) {
67 wp_send_json_success(['results' => $cached]);
68 return;
69 }
70
71 $url = add_query_arg([
72 'format' => 'json',
73 'q' => $query,
74 'limit' => $limit,
75 'addressdetails' => 1,
76 'accept-language' => 'en-US,en;q=0.9',
77 'countrycodes' => 'id,np,us,gb,fr,de,it,es,au,nz',
78 ], 'https://nominatim.openstreetmap.org/search');
79
80 $response = wp_remote_get($url, [
81 'timeout' => 10,
82 'user-agent' => 'Yatra Travel Plugin (https://wpyatra.com/)',
83 'headers' => [
84 'Accept' => 'application/json',
85 ],
86 ]);
87
88 if (is_wp_error($response)) {
89 wp_send_json_error(['message' => 'Search failed. Please try again.']);
90 return;
91 }
92
93 $body = wp_remote_retrieve_body($response);
94 $data = json_decode($body, true);
95 if (!is_array($data) || empty($data)) {
96 wp_send_json_success(['results' => []]);
97 return;
98 }
99
100 $this->geocodingRepository->setPayload($resultCacheKey, $data, 300);
101
102 wp_send_json_success(['results' => $data]);
103 }
104
105 /**
106 * Reverse geocode coordinates to get location name
107 */
108 public function reverseGeocode(): void
109 {
110 // Verify nonce
111 if (!wp_verify_nonce($_POST['nonce'] ?? '', 'yatra_geocoding_nonce')) {
112 wp_send_json_error(['message' => 'Security check failed']);
113 return;
114 }
115
116 $lat = floatval($_POST['lat'] ?? 0);
117 $lng = floatval($_POST['lng'] ?? 0);
118
119 if ($lat === 0 || $lng === 0) {
120 wp_send_json_error(['message' => 'Invalid coordinates']);
121 return;
122 }
123
124 $resultCacheKey = $this->geocodingRepository->cacheKeyReverse($lat, $lng);
125 $cached = $this->geocodingRepository->getPayload($resultCacheKey);
126 if (is_array($cached)) {
127 wp_send_json_success(['result' => $cached]);
128 return;
129 }
130
131 $url = add_query_arg([
132 'format' => 'json',
133 'lat' => $lat,
134 'lon' => $lng,
135 'zoom' => 18,
136 'addressdetails' => 1,
137 'accept-language' => 'en-US,en;q=0.9',
138 ], 'https://nominatim.openstreetmap.org/reverse');
139
140 $response = wp_remote_get($url, [
141 'timeout' => 10,
142 'user-agent' => 'Yatra Travel Plugin (https://wpyatra.com/)',
143 'headers' => [
144 'Accept' => 'application/json',
145 ],
146 ]);
147
148 if (is_wp_error($response)) {
149 wp_send_json_error(['message' => 'Reverse geocoding failed']);
150 return;
151 }
152
153 $body = wp_remote_retrieve_body($response);
154 $data = json_decode($body, true);
155 if (!is_array($data)) {
156 wp_send_json_error(['message' => 'Reverse geocoding failed']);
157 return;
158 }
159
160 $this->geocodingRepository->setPayload($resultCacheKey, $data, 600);
161
162 wp_send_json_success(['result' => $data]);
163 }
164 }
165