commit | author | age
|
ced309
|
1 |
<?php |
JK |
2 |
include(__DIR__.'/stops/common.php'); |
|
3 |
include(__DIR__.'/stops/stops.php'); |
|
4 |
|
|
5 |
try { |
|
6 |
// Reject invalid input |
|
7 |
if(!isset($_GET['query'])) throw new UnexpectedValueException(); |
|
8 |
if(empty($_GET['query'])) throw new UnexpectedValueException(); |
|
9 |
if(strlen($_GET['query']) > 50) throw new UnexpectedValueException(); |
|
10 |
|
bcae33
|
11 |
// Initialize a DB connection an a query |
ced309
|
12 |
$pdo = new PDO('sqlite:stops/stops.db', NULL, NULL, array( |
JK |
13 |
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION |
|
14 |
)); |
|
15 |
$st = $pdo->prepare('SELECT DISTINCT id FROM stop_search WHERE word LIKE ?'); |
|
16 |
|
|
17 |
// Split stop name into words |
|
18 |
$words = split_stop_name($_GET['query']); |
|
19 |
|
bcae33
|
20 |
// Find matching stops (their IDs) |
ced309
|
21 |
$ids = NULL; |
JK |
22 |
foreach($words as $word) { |
|
23 |
if(empty($word)) continue; |
|
24 |
|
|
25 |
// Find stop IDs with names matching the word |
|
26 |
$st->execute(array($word.'%')); |
|
27 |
$results = $st->fetchAll(PDO::FETCH_COLUMN); |
|
28 |
$st->closeCursor(); |
|
29 |
|
|
30 |
if(is_array($ids)) { |
bcae33
|
31 |
// Merge results with list for previous words |
ced309
|
32 |
$ids = array_intersect($ids, $results); |
JK |
33 |
} else { |
bcae33
|
34 |
// First search - initialize results list |
ced309
|
35 |
$ids = $results; |
JK |
36 |
} |
|
37 |
|
|
38 |
// No results will be found |
|
39 |
if(count($ids) == 0) break; |
|
40 |
} |
|
41 |
|
bcae33
|
42 |
// Close a DB connection |
ced309
|
43 |
unset($st, $pdo); |
JK |
44 |
|
bcae33
|
45 |
// No query was executed - return empty list |
ced309
|
46 |
if(!is_array($ids)) throw new UnexpectedValueException(); |
JK |
47 |
|
bcae33
|
48 |
// Build a structure for the UI |
ced309
|
49 |
$stop_list = []; |
505a3b
|
50 |
$query_lower = mb_strtolower($_GET['query'], 'UTF-8'); |
ced309
|
51 |
foreach($ids as $id) { |
JK |
52 |
$stop_list[] = [ |
|
53 |
'id' => $id, |
|
54 |
'name' => $stops[$id], |
|
55 |
'type' => 'stop', |
505a3b
|
56 |
'relevance' => similar_text( |
JK |
57 |
$query_lower, |
|
58 |
mb_strtolower($stops[$id], 'UTF-8') |
|
59 |
) |
ced309
|
60 |
]; |
JK |
61 |
} |
|
62 |
|
bcae33
|
63 |
// Sort stops by relevance |
ced309
|
64 |
usort($stop_list, function($a, $b) { |
505a3b
|
65 |
$rel = $b['relevance'] - $a['relevance']; |
JK |
66 |
if($rel == 0) return strcasecmp($a['name'], $b['name']); |
|
67 |
return $rel; |
ced309
|
68 |
}); |
JK |
69 |
|
|
70 |
// Return JSON |
|
71 |
echo json_encode($stop_list); |
|
72 |
} catch(UnexpectedValueException $e) { |
|
73 |
echo '[]'; |
|
74 |
} catch(Exception $e) { |
|
75 |
header('HTTP/1.1 503 Service Unavailable'); |
|
76 |
echo $e->getMessage(); |
|
77 |
} |