1
+ <?php
2
+ class Search{
3
+ public $ hotelsByDistance = [];
4
+ public $ hotelsByPrice = [];
5
+
6
+ const FETCH_HOTELS_URL = "https://s3.amazonaws.com/koisys-interviews/hotels.json " ;
7
+
8
+ public function fetchHotels (){
9
+ //Fetch array of hotels from API
10
+ $ hotelsInJson = file_get_contents (Search::FETCH_HOTELS_URL );
11
+ $ hotels = json_decode ($ hotelsInJson );
12
+ return $ hotels ->message ;
13
+ }
14
+
15
+ public function getHotelsByDistance ($ latitude , $ longitude ){
16
+ //Fetch the array of hotels from API
17
+ $ hotelList = $ this ->fetchHotels ();
18
+
19
+ //Calculate the distance of the user from each hotel fetched
20
+ foreach ($ hotelList as $ key => $ hotelData ) {
21
+
22
+ $ hotelLatitude = null ;
23
+ $ hotelLongitude = null ;
24
+
25
+ /*
26
+ Here we assume, that the fisrt coordinate is the latitude and the second longitude
27
+ some hotel data have varying length of arrays hence index of latitude and longitude changes with length*/
28
+ $ latKey = count ($ hotelData )-3 ;
29
+ $ longKey = count ($ hotelData )-2 ;
30
+
31
+ $ hotelLatitude = (is_numeric ($ hotelData [$ latKey ])) ? $ hotelData [$ latKey ] : null ;
32
+ $ hotelLongitude = (is_numeric ($ hotelData [$ longKey ])) ? $ hotelData [$ longKey ] : null ;
33
+
34
+
35
+
36
+ if ($ hotelLatitude != null || $ hotelLongitude != null ){
37
+
38
+ //convert to radians from degrees
39
+ $ firstLong = deg2rad ($ longitude );
40
+ $ secondLong = deg2rad ($ hotelLongitude );
41
+ $ firstLat = deg2rad ($ latitude );
42
+ $ secondLat = deg2rad ($ hotelLatitude );
43
+
44
+ //Haversine Formula for calculating distance between coordinates
45
+ $ changeInLong = $ secondLong - $ firstLong ;
46
+ $ changeInLat = $ secondLat - $ firstLat ;
47
+
48
+ $ val = pow (sin ($ changeInLat /2 ),2 )+cos ($ firstLat )*cos ($ secondLat )*pow (sin ($ changeInLong /2 ),2 );
49
+
50
+ $ res = 2 * asin (sqrt ($ val ));
51
+
52
+ $ radius = 6372.795477598 ;
53
+ $ distInKm = $ res *$ radius ;
54
+
55
+
56
+ $ hotelsByDistance [$ key ] = $ distInKm ;
57
+ }
58
+
59
+
60
+ }
61
+ //returns unsorted one-dimensional array with each distance from the user
62
+ return $ hotelsByDistance ;
63
+
64
+ }
65
+
66
+ public static function getHotelsByPrice (){
67
+ //fetch hotels from API
68
+ $ search = new Search ();
69
+ $ hotelList = $ search ->fetchHotels ();
70
+
71
+ //create an array to hold all the prices of the hotels only with their corresponding keys
72
+ foreach ($ hotelList as $ key => $ hotelData ) {
73
+
74
+ $ hotelsByPrice [$ key ] = $ hotelData [count ($ hotelData )-1 ];
75
+ }
76
+ //returns unsorted one-dimensional array that contains the price for each hotel per night
77
+ return $ hotelsByPrice ;
78
+
79
+ }
80
+
81
+ public static function getNearbyHotels ($ latitude , $ longitude , $ orderBy , $ limit ){
82
+ //fetch hotels from API
83
+ $ search = new Search ();
84
+ $ hotelList = $ search ->fetchHotels ();
85
+ //get unsorted array of price
86
+ $ listHotelsByPrice = $ search ->getHotelsByPrice ();
87
+ //get unsorted array of distances
88
+ $ listHotelsByDistance = $ search ->getHotelsByDistance ($ latitude , $ longitude );
89
+
90
+ //$nearByHotels array holds final result
91
+ $ nearByHotels = [];
92
+
93
+ if (isset ($ orderBy ) && $ orderBy == "pricepernight " ){
94
+ //sort in ascending order
95
+ asort ($ listHotelsByPrice );
96
+
97
+ if (is_int ($ limit ) && $ limit > 0 ){
98
+
99
+ //$i is our counter for the limit passed to this function
100
+ $ i = 0 ;
101
+ foreach ($ listHotelsByPrice as $ key => $ value ) {
102
+ //create new array to hold name, distance and price for each hotel sorted by price
103
+ $ nearByHotels [$ i ]["name " ] = $ hotelList [$ key ][0 ]."' " ;
104
+ $ nearByHotels [$ i ]["distance " ] = $ listHotelsByDistance [$ key ]." KM, " ;
105
+ $ nearByHotels [$ i ]["price " ] = $ value ." EUR " ;
106
+ $ i ++;
107
+
108
+ if ($ i ==$ limit ) {
109
+ break ;
110
+ }
111
+
112
+ }
113
+ return $ nearByHotels ;
114
+ }
115
+ return "Invalid limit " ;
116
+
117
+ }
118
+ else {
119
+ //sort distance in ascending order
120
+ asort ($ listHotelsByDistance );
121
+ if (is_int ($ limit ) && $ limit > 0 ){
122
+ $ i = 0 ;
123
+ foreach ($ listHotelsByDistance as $ key => $ value ) {
124
+ //nearByHotels holds name, distance and price for each hotel sorted by price
125
+ $ nearByHotels [$ i ]["name " ] = $ hotelList [$ key ][0 ].", " ;
126
+ $ nearByHotels [$ i ]["distance " ] = $ value ." KM, " ;
127
+ $ nearByHotels [$ i ]["price " ] = $ listHotelsByPrice [$ key ]." EUR " ;
128
+
129
+ $ i ++;
130
+
131
+ if ($ i ==$ limit ) {
132
+ break ;
133
+ }
134
+
135
+ }
136
+ return $ nearByHotels ;
137
+ }
138
+ return "Invalid limit " ;
139
+
140
+
141
+ return ($ nearByHotels );
142
+ }
143
+
144
+
145
+ }
146
+
147
+
148
+
149
+
150
+ }
151
+
152
+
153
+
154
+
155
+
156
+
157
+ ?>
0 commit comments