Improved www.ttss.krakow.pl
Jacek Kowalski
2019-05-04 ca42d38139f52d8edf6e0792b8cfb5b6404d9112
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) {
JK 53         similar_text(
54             $query_lower,
ca42d3 55             normalize_name_cmp($stops[$id]),
cbce8b 56             $percent
JK 57         );
58         // -5 due to UTF-8
59         if(substr($stops[$id], -5) == '(nż)' && !$find_ondemand) {
60             $percent /= 2;
61         }
62         $stop_list[] = [
63             'id' => $id,
ca42d3 64             'name' => normalize_name($stops[$id]),
cbce8b 65             'type' => 'stop',
JK 66             'relevance' => $percent,
67         ];
68     }
69     
70     // Sort stops by relevance
71     usort($stop_list, function($a, $b) {
72         $rel = $b['relevance'] - $a['relevance'];
73         if($rel == 0) return strcasecmp($a['name'], $b['name']);
74         return $rel;
75     });
76     
77     // Return JSON
78     header('Content-Type: application/json');
79     echo json_encode($stop_list);
80 } catch(UnexpectedValueException $e) {
81     header('Content-Type: application/json');
82     echo '[]';
83 } catch(Exception $e) {
84     header('HTTP/1.1 503 Service Unavailable');
85     echo $e->getMessage();
86 }