commit | author | age
|
cbce8b
|
1 |
<?php |
JK |
2 |
include('common.php'); |
|
3 |
include('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 |
|
|
11 |
// Split stop name into words |
|
12 |
$words = split_stop_name($_GET['query']); |
|
13 |
$find_ondemand = in_array('nz', $words); |
|
14 |
|
|
15 |
// Initialize a DB connection and a query |
|
16 |
$pdo = new PDO('sqlite:stops.db', NULL, NULL, array( |
|
17 |
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION |
|
18 |
)); |
|
19 |
$st = $pdo->prepare('SELECT DISTINCT id FROM stop_search WHERE word LIKE ?'.($find_ondemand ? '' : ' AND word != \'nz\'').' ORDER BY id DESC'); |
|
20 |
|
|
21 |
// Find matching stops (their IDs) |
|
22 |
$ids = NULL; |
|
23 |
foreach($words as $word) { |
|
24 |
if(empty($word)) continue; |
|
25 |
|
|
26 |
// Find stop IDs with names matching the word |
|
27 |
$st->execute(array($word.'%')); |
|
28 |
$results = $st->fetchAll(PDO::FETCH_COLUMN); |
|
29 |
$st->closeCursor(); |
|
30 |
|
|
31 |
if(is_array($ids)) { |
|
32 |
// Merge results with list for previous words |
|
33 |
$ids = array_intersect($ids, $results); |
|
34 |
} else { |
|
35 |
// First search - initialize results list |
|
36 |
$ids = $results; |
|
37 |
} |
|
38 |
|
|
39 |
// No results will be found |
|
40 |
if(count($ids) == 0) break; |
|
41 |
} |
|
42 |
|
|
43 |
// Close a DB connection |
|
44 |
unset($st, $pdo); |
|
45 |
|
|
46 |
// No query was executed - return empty list |
|
47 |
if(!is_array($ids)) throw new UnexpectedValueException(); |
|
48 |
|
|
49 |
// Build a structure for the UI |
|
50 |
$stop_list = []; |
ca42d3
|
51 |
$query_lower = normalize_name_cmp($_GET['query']); |
cbce8b
|
52 |
foreach($ids as $id) { |
d87cf0
|
53 |
$letters = similar_text( |
cbce8b
|
54 |
$query_lower, |
ca42d3
|
55 |
normalize_name_cmp($stops[$id]), |
cbce8b
|
56 |
$percent |
JK |
57 |
); |
d87cf0
|
58 |
$percent += $letters * 100; |
cbce8b
|
59 |
// -5 due to UTF-8 |
JK |
60 |
if(substr($stops[$id], -5) == '(nż)' && !$find_ondemand) { |
|
61 |
$percent /= 2; |
|
62 |
} |
|
63 |
$stop_list[] = [ |
|
64 |
'id' => $id, |
ca42d3
|
65 |
'name' => normalize_name($stops[$id]), |
cbce8b
|
66 |
'type' => 'stop', |
JK |
67 |
'relevance' => $percent, |
|
68 |
]; |
|
69 |
} |
|
70 |
|
|
71 |
// Sort stops by relevance |
|
72 |
usort($stop_list, function($a, $b) { |
|
73 |
$rel = $b['relevance'] - $a['relevance']; |
|
74 |
if($rel == 0) return strcasecmp($a['name'], $b['name']); |
|
75 |
return $rel; |
|
76 |
}); |
|
77 |
|
|
78 |
// Return JSON |
|
79 |
header('Content-Type: application/json'); |
|
80 |
echo json_encode($stop_list); |
|
81 |
} catch(UnexpectedValueException $e) { |
|
82 |
header('Content-Type: application/json'); |
|
83 |
echo '[]'; |
|
84 |
} catch(Exception $e) { |
|
85 |
header('HTTP/1.1 503 Service Unavailable'); |
|
86 |
echo $e->getMessage(); |
|
87 |
} |