1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace MySociety\TheyWorkForYou\Utility; |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* Alert Utilities |
7
|
|
|
* |
8
|
|
|
* Utility functions related to alerts |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
class Alert { |
12
|
|
|
public static function sectionToTitle($section) { |
13
|
|
|
$section_map = [ |
14
|
3 |
|
"uk" => gettext('All UK'), |
15
|
3 |
|
"debates" => gettext('House of Commons debates'), |
16
|
|
|
"whalls" => gettext('Westminster Hall debates'), |
17
|
3 |
|
"lords" => gettext('House of Lords debates'), |
18
|
3 |
|
"wrans" => gettext('Written answers'), |
19
|
|
|
"wms" => gettext('Written ministerial statements'), |
20
|
|
|
"standing" => gettext('Bill Committees'), |
21
|
3 |
|
"future" => gettext('Future Business'), |
22
|
|
|
"ni" => gettext('Northern Ireland Assembly Debates'), |
23
|
|
|
"scotland" => gettext('All Scotland'), |
24
|
|
|
"sp" => gettext('Scottish Parliament Debates'), |
25
|
3 |
|
"spwrans" => gettext('Scottish Parliament Written answers'), |
26
|
3 |
|
"wales" => gettext('Welsh parliament record'), |
27
|
|
|
"lmqs" => gettext('Questions to the Mayor of London'), |
28
|
|
|
]; |
29
|
|
|
|
30
|
|
|
return $section_map[$section]; |
31
|
|
|
} |
32
|
|
|
public static function detailsToCriteria($details) { |
33
|
|
|
$criteria = []; |
34
|
|
|
|
35
|
|
|
if (!empty($details['keyword'])) { |
36
|
|
|
$criteria[] = $details['keyword']; |
37
|
|
|
} |
38
|
|
|
|
39
|
|
|
if (!empty($details['pid'])) { |
40
|
|
|
$criteria[] = 'speaker:' . $details['pid']; |
41
|
|
|
} |
42
|
|
|
|
43
|
|
|
if (!empty($details['search_section'])) { |
44
|
|
|
$criteria[] = 'section:' . $details['search_section']; |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
$criteria = join(' ', $criteria); |
48
|
|
|
return $criteria; |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
public static function forUser($email) { |
52
|
|
|
$db = new \ParlDB(); |
53
|
|
|
$q = $db->query('SELECT * FROM alerts WHERE email = :email |
54
|
|
|
AND deleted != 1 ORDER BY created', [ |
55
|
|
|
':email' => $email, |
56
|
|
|
]); |
57
|
|
|
|
58
|
|
|
$alerts = []; |
59
|
|
|
foreach ($q as $row) { |
60
|
|
|
$criteria = self::prettifyCriteria($row['criteria'], $row['ignore_speaker_votes']); |
61
|
|
|
$parts = self::prettifyCriteria($row['criteria'], $row['ignore_speaker_votes'], true); |
62
|
|
|
$token = $row['alert_id'] . '-' . $row['registrationtoken']; |
63
|
|
|
|
64
|
|
|
$status = 'confirmed'; |
65
|
|
|
if (!$row['confirmed']) { |
66
|
|
|
$status = 'unconfirmed'; |
67
|
|
|
} elseif ($row['deleted'] == 2) { |
68
|
|
|
$status = 'suspended'; |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
$alert = [ |
72
|
|
|
'token' => $token, |
73
|
|
|
'status' => $status, |
74
|
|
|
'criteria' => $criteria, |
75
|
|
|
'raw' => $row['criteria'], |
76
|
|
|
'ignore_speaker_votes' => $row['ignore_speaker_votes'], |
77
|
|
|
'keywords' => [], |
78
|
|
|
'exclusions' => [], |
79
|
|
|
'sections' => [], |
80
|
|
|
]; |
81
|
|
|
|
82
|
|
|
$alert = array_merge($alert, $parts); |
83
|
|
|
|
84
|
|
|
$alerts[] = $alert; |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
return $alerts; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
public static function prettifyCriteria($alert_criteria, $ignore_speaker_votes = false, $as_parts = false) { |
91
|
|
|
$text = ''; |
92
|
|
|
$parts = ['words' => [], 'sections' => [], 'exclusions' => [], 'match_all' => true, 'pid' => false]; |
93
|
|
|
if ($alert_criteria) { |
94
|
|
|
# check for phrases |
95
|
|
|
if (strpos($alert_criteria, ' OR ') !== false) { |
96
|
|
|
$parts['match_all'] = false; |
97
|
|
|
} |
98
|
|
|
$alert_criteria = str_replace(' OR ', ' ', $alert_criteria); |
99
|
|
|
$alert_criteria = str_replace(['(', ')'], '', $alert_criteria); |
100
|
|
|
if (strpos($alert_criteria, '"') !== false) { |
101
|
|
|
# match phrases |
102
|
|
|
preg_match_all('/"([^"]*)"/', $alert_criteria, $phrases); |
103
|
|
|
# and then remove them from the criteria |
104
|
|
|
$alert_criteria = trim(preg_replace('/ +/', ' ', str_replace($phrases[0], "", $alert_criteria))); |
105
|
|
|
|
106
|
|
|
# and then create an array with the words and phrases |
107
|
|
|
$criteria = []; |
108
|
|
|
if ($alert_criteria != "") { |
109
|
|
|
$criteria = explode(' ', $alert_criteria); |
110
|
|
|
} |
111
|
|
|
$criteria = array_merge($criteria, $phrases[1]); |
112
|
|
|
} else { |
113
|
|
|
$criteria = explode(' ', $alert_criteria); |
114
|
|
|
} |
115
|
|
|
$words = []; |
116
|
|
|
$exclusions = []; |
117
|
|
|
$sections = []; |
118
|
|
|
$sections_verbose = []; |
119
|
|
|
$speaker_parts = \MySociety\TheyWorkForYou\Utility\Search::speakerNamesForIDs($alert_criteria); |
120
|
|
|
$pids = array_keys($speaker_parts); |
121
|
|
|
$spokenby = array_values($speaker_parts); |
122
|
|
|
|
123
|
|
|
if (count($pids) == 1) { |
124
|
|
|
$parts['pid'] = $pids[0]; |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
foreach ($criteria as $c) { |
128
|
|
|
if (preg_match('#^section:(\w+)#', $c, $m)) { |
129
|
|
|
$sections[] = $m[1]; |
130
|
|
|
$sections_verbose[] = self::sectionToTitle($m[1]); |
131
|
|
|
} elseif (strpos($c, '-') === 0) { |
132
|
|
|
$exclusions[] = str_replace('-', '', $c); |
133
|
|
|
} elseif (!preg_match('#^speaker:(\d+)#', $c, $m)) { |
134
|
|
|
$words[] = $c; |
135
|
|
|
} |
136
|
|
|
} |
137
|
|
|
if ($spokenby && count($words)) { |
|
|
|
|
138
|
|
|
$text = implode(' or ', $spokenby) . ' mentions [' . implode(' ', $words) . ']'; |
139
|
|
|
$parts['spokenby'] = $spokenby; |
140
|
|
|
$parts['words'] = $words; |
141
|
|
|
} elseif (count($words)) { |
142
|
|
|
$text = '[' . implode(' ', $words) . ']' . ' is mentioned'; |
143
|
|
|
$parts['words'] = $words; |
144
|
|
|
} elseif ($spokenby) { |
|
|
|
|
145
|
|
|
$text = implode(' or ', $spokenby) . " speaks"; |
146
|
|
|
if ($ignore_speaker_votes) { |
147
|
|
|
$text .= " excluding votes"; |
148
|
|
|
} |
149
|
|
|
$parts['spokenby'] = $spokenby; |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
if ($sections) { |
153
|
|
|
$text = $text . " in " . implode(' or ', $sections_verbose); |
154
|
|
|
$parts['sections'] = $sections; |
155
|
|
|
$parts['sections_verbose'] = $sections_verbose; |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
$parts['exclusions'] = $exclusions; |
159
|
|
|
} |
160
|
|
|
if ($as_parts) { |
161
|
|
|
return $parts; |
162
|
|
|
} |
163
|
|
|
return $text; |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
} |
167
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.