1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace MySociety\TheyWorkForYou\AlertView; |
4
|
|
|
|
5
|
|
|
include_once '../../../www/includes/easyparliament/init.php'; |
6
|
|
|
include_once INCLUDESPATH . "easyparliament/member.php"; |
7
|
|
|
include_once INCLUDESPATH . "easyparliament/searchengine.php"; |
8
|
|
|
include_once INCLUDESPATH . '../../commonlib/phplib/auth.php'; |
9
|
|
|
include_once INCLUDESPATH . '../../commonlib/phplib/crosssell.php'; |
10
|
|
|
|
11
|
|
|
class Standard extends \MySociety\TheyWorkForYou\AlertView { |
12
|
|
|
public $data; |
13
|
|
|
|
14
|
|
|
public function __construct($THEUSER = null) { |
15
|
|
|
parent::__construct($THEUSER); |
16
|
|
|
$this->data = []; |
17
|
|
|
} |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* This file handles all actions on user alerts. |
21
|
|
|
* |
22
|
|
|
* It splits alerts into two types and they get different screens: |
23
|
|
|
* * keyword alerts - a person wants an alert when a word or phrase is said |
24
|
|
|
* * representative alerts - a person wants an alert when a representative speaks or votes |
25
|
|
|
* |
26
|
|
|
* There are several form variables that control what is displayed or what action is taken: |
27
|
|
|
* * action - this is used for things happening to alerts - creation/editing, deletion, suspension etc |
28
|
|
|
* * step - this determines which step of creating a keyword alert to display |
29
|
|
|
* * this_step - stores which step is currently being processed, also used for prev step button |
30
|
|
|
* * mp_step - show the representative alert screen |
31
|
|
|
* * results - stores the results of an action, used to display appropriate message |
32
|
|
|
* |
33
|
|
|
* The steps in the keyword alert creation/editing process are: |
34
|
|
|
* * define - Initial options where you can add a keyword, any exclusions plus select which chambers it applies to |
35
|
|
|
* * add_vector_related - an optional related terms step which suggests extra terms if we find any in the database |
36
|
|
|
* * review - a confirmation step |
37
|
|
|
* |
38
|
|
|
* If the user is happy then they will click Confirm which will submit the form with action set to Confirm and the alert |
39
|
|
|
* will be created or updated. |
40
|
|
|
* |
41
|
|
|
* If mp_step is one of the parameters set then the form to add a representative alert is displayed. This only has a creation |
42
|
|
|
* and a confirm step. As part of this the mp_search param will be submitted which will trigger checking detecting |
43
|
|
|
* which MP the user is trying to add. This will try the following steps: |
44
|
|
|
* * try to match the search text against a name |
45
|
|
|
* * check if the text contains a postcode and if so use that to look up the constituencies |
46
|
|
|
* * if there's not a postcode then try to match against a constituency name |
47
|
|
|
* |
48
|
|
|
* If there is more than one match then these are stored in the constituencies varaible and a choice is |
49
|
|
|
* presented to the user. |
50
|
|
|
* |
51
|
|
|
* The representive alert creation flow will also be entered if an alertsearch or pid parameter is submitted. This |
52
|
|
|
* is used for handling "create an alert when $rep speaks" links from elsewhere in the site (e.g. an MP page) |
53
|
|
|
* |
54
|
|
|
* Other actions such as suspend use a form with only an action value and the alert token if required. |
55
|
|
|
*/ |
56
|
|
|
public function display() { |
57
|
|
|
global $this_page; |
58
|
|
|
$this_page = "alert"; |
59
|
|
|
|
60
|
|
|
$this->processAction(); |
61
|
|
|
$this->getBasicData(); |
62
|
|
|
$this->checkInput(); |
63
|
|
|
$this->searchForConstituenciesAndMembers(); |
64
|
|
|
|
65
|
|
|
if ($this->data['step'] || $this->data['addword']) { |
66
|
|
|
$this->processStep(); |
67
|
|
|
} elseif (!$this->data['results'] == 'changes-abandoned' && !sizeof($this->data['errors']) && $this->data['submitted'] && ($this->data['keyword'] || $this->data['pid'])) { |
68
|
|
|
$this->addAlert(); |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
$this->formatSearchTerms(); |
72
|
|
|
$this->checkForCommonMistakes(); |
73
|
|
|
$this->formatSearchMemberData(); |
74
|
|
|
|
75
|
|
|
// Determine if we should fetch alert counts |
76
|
|
|
// We skip counts when in form workflows (step, mp_step, disambiguation) |
77
|
|
|
$in_active_workflow = $this->data['step'] // Alert creation wizard steps |
78
|
|
|
|| $this->data['mp_step'] // MP alert creation |
79
|
|
|
|| $this->data['alertsearch']; // Search disambiguation (but not if showing results) |
80
|
|
|
|
81
|
|
|
$this->data['showing_main_alert_list'] = !$in_active_workflow; |
82
|
|
|
|
83
|
|
|
$this->setUserData(); |
84
|
|
|
|
85
|
|
|
return $this->data; |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
# This only happens if we have an alert and want to do something to it. |
89
|
|
|
private function processAction() { |
90
|
|
|
$token = get_http_var('t'); |
91
|
|
|
$alert = $this->alert->check_token($token); |
92
|
|
|
|
93
|
|
|
$this->data['results'] = false; |
94
|
|
|
if ($action = get_http_var('action')) { |
95
|
|
|
$success = true; |
96
|
|
|
if ($action == 'Confirm') { |
97
|
|
|
$success = $this->confirmAlert($token); |
98
|
|
|
if ($success) { |
99
|
|
|
$this->data['results'] = 'alert-confirmed'; |
100
|
|
|
$this->data['criteria'] = $this->alert->criteria; |
101
|
|
|
$this->data['display_criteria'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($this->alert->criteria, $this->alert->ignore_speaker_votes); |
102
|
|
|
} |
103
|
|
|
} elseif ($action == 'Suspend') { |
104
|
|
|
$success = $this->suspendAlert($token); |
105
|
|
|
if ($success) { |
106
|
|
|
$this->data['results'] = 'alert-suspended'; |
107
|
|
|
} |
108
|
|
|
} elseif ($action == 'Resume') { |
109
|
|
|
$success = $this->resumeAlert($token); |
110
|
|
|
if ($success) { |
111
|
|
|
$this->data['results'] = 'alert-resumed'; |
112
|
|
|
} |
113
|
|
|
} elseif ($action == 'Delete') { |
114
|
|
|
$success = $this->deleteAlert($token); |
115
|
|
|
if ($success) { |
116
|
|
|
$this->data['results'] = 'alert-deleted'; |
117
|
|
|
} |
118
|
|
|
} elseif ($action == 'Delete All') { |
119
|
|
|
$success = $this->deleteAllAlerts($token); |
120
|
|
|
if ($success) { |
121
|
|
|
$this->data['results'] = 'all-alerts-deleted'; |
122
|
|
|
} |
123
|
|
|
} elseif ($action == 'ignore-votes') { |
124
|
|
|
$success = $this->ignoreVotesAlert($token); |
125
|
|
|
if ($success) { |
126
|
|
|
$this->data['criteria'] = $this->alert->criteria; |
127
|
|
|
$display = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($this->alert->criteria, $this->alert->ignore_speaker_votes); |
128
|
|
|
$this->data['display_criteria'] = str_replace('speaks', 'votes', $display); |
129
|
|
|
$this->data['results'] = 'alert-ignore-votes'; |
130
|
|
|
} |
131
|
|
|
} elseif ($action == 'include-votes') { |
132
|
|
|
$success = $this->includeVotesAlert($token); |
133
|
|
|
if ($success) { |
134
|
|
|
$this->data['criteria'] = $this->alert->criteria; |
135
|
|
|
$display = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($this->alert->criteria, $this->alert->ignore_speaker_votes); |
136
|
|
|
$this->data['display_criteria'] = str_replace('speaks', 'votes', $display); |
137
|
|
|
$this->data['results'] = 'alert-include-votes'; |
138
|
|
|
} |
139
|
|
|
} elseif ($action == 'Abandon') { |
140
|
|
|
$this->data['results'] = 'changes-abandoned'; |
141
|
|
|
} |
142
|
|
|
if (!$success) { |
143
|
|
|
$this->data['results'] = 'alert-fail'; |
144
|
|
|
} |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
$this->data['alert'] = $alert; |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
# Process a screen in the alert creation wizard |
151
|
|
|
private function processStep() { |
152
|
|
|
# fetch a list of suggested terms. Need this for the define screen so we can filter out the suggested terms |
153
|
|
|
# and not show them if the user goes back |
154
|
|
|
if (($this->data['step'] == 'review' || $this->data['step'] == 'define') && !$this->data['shown_related']) { |
155
|
|
|
$suggestions = []; |
156
|
|
|
foreach ($this->data['keywords'] as $word) { |
157
|
|
|
$terms = $this->alert->get_related_terms($word); |
158
|
|
|
$terms = array_diff($terms, $this->data['keywords']); |
159
|
|
|
if ($terms && count($terms)) { |
|
|
|
|
160
|
|
|
$suggestions = array_merge($suggestions, $terms); |
161
|
|
|
} |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
if (count($suggestions) > 0) { |
165
|
|
|
$this->data['step'] = 'add_vector_related'; |
166
|
|
|
$this->data['suggestions'] = $suggestions; |
167
|
|
|
} |
168
|
|
|
# confirm the alert. Handles both creating and editing alerts |
169
|
|
|
} elseif ($this->data['step'] == 'confirm') { |
170
|
|
|
$success = true; |
171
|
|
|
# if there's already an alert assume we are editing it and user must be logged in |
172
|
|
|
if ($this->data['alert']) { |
173
|
|
|
$success = $this->updateAlert($this->data['alert']['id'], $this->data); |
|
|
|
|
174
|
|
|
if ($success) { |
175
|
|
|
# reset all the data to stop anything getting confused |
176
|
|
|
$this->data['results'] = 'alert-confirmed'; |
177
|
|
|
$this->data['step'] = ''; |
178
|
|
|
$this->data['pid'] = ''; |
179
|
|
|
$this->data['alertsearch'] = ''; |
180
|
|
|
$this->data['pc'] = ''; |
181
|
|
|
$this->data['members'] = false; |
182
|
|
|
$this->data['constituencies'] = []; |
183
|
|
|
$this->data['member_constituencies'] = []; |
184
|
|
|
} else { |
185
|
|
|
$this->data['results'] = 'alert-fail'; |
186
|
|
|
$this->data['step'] = 'review'; |
187
|
|
|
} |
188
|
|
|
} else { |
189
|
|
|
$success = $this->addAlert(); |
|
|
|
|
190
|
|
|
$this->data['step'] = ''; |
191
|
|
|
} |
192
|
|
|
} |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
|
196
|
|
|
/* |
197
|
|
|
* set up the data we will be using in processing later steps |
198
|
|
|
*/ |
199
|
|
|
private function getBasicData() { |
200
|
|
|
global $this_page; |
201
|
|
|
|
202
|
|
|
if ($this->user->loggedin()) { |
203
|
|
|
$this->data['email'] = $this->user->email(); |
204
|
|
|
$this->data['email_verified'] = true; |
205
|
|
|
} elseif ($this->data['alert']) { |
206
|
|
|
$this->data['email'] = $this->data['alert']['email']; |
207
|
|
|
$this->data['email_verified'] = true; |
208
|
|
|
} else { |
209
|
|
|
$this->data["email"] = trim(get_http_var("email")); |
210
|
|
|
$this->data['email_verified'] = false; |
211
|
|
|
} |
212
|
|
|
|
213
|
|
|
$this->data['token'] = get_http_var('t'); |
214
|
|
|
$this->data['step'] = trim(get_http_var("step")); |
215
|
|
|
$this->data['mp_step'] = trim(get_http_var("mp_step")); |
216
|
|
|
$this->data['addword'] = trim(get_http_var("addword")); |
217
|
|
|
$this->data['this_step'] = trim(get_http_var("this_step")); |
218
|
|
|
$this->data['shown_related'] = get_http_var('shown_related'); |
219
|
|
|
$this->data['match_all'] = get_http_var('match_all') == 'on'; |
220
|
|
|
$this->data['keyword'] = trim(get_http_var("keyword")); |
221
|
|
|
$this->data['search_section'] = ''; |
222
|
|
|
$this->data['alertsearch'] = trim(get_http_var("alertsearch")); |
223
|
|
|
$this->data['mp_search'] = trim(get_http_var("mp_search")); |
224
|
|
|
$this->data['pid'] = trim(get_http_var("pid")); |
225
|
|
|
$this->data['pc'] = get_http_var('pc'); |
226
|
|
|
$this->data['submitted'] = get_http_var('submitted') || $this->data['pid'] || $this->data['keyword'] || $this->data['step']; |
227
|
|
|
$this->data['ignore_speaker_votes'] = get_http_var('ignore_speaker_votes'); |
228
|
|
|
|
229
|
|
|
if ($this->data['addword'] || $this->data['step']) { |
230
|
|
|
$alert = $this->alert->check_token($this->data['token']); |
231
|
|
|
|
232
|
|
|
$criteria = ''; |
233
|
|
|
$alert_ignore_speaker_votes = 0; |
234
|
|
|
if ($alert) { |
235
|
|
|
$criteria = $alert['criteria']; |
236
|
|
|
$alert_ignore_speaker_votes = $alert['ignore_speaker_votes']; |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
$ignore_speaker_votes = get_http_var('ignore_speaker_votes', $alert_ignore_speaker_votes); |
240
|
|
|
$this->data['ignore_speaker_votes'] = ($ignore_speaker_votes == 'on' || $ignore_speaker_votes == 1); |
241
|
|
|
|
242
|
|
|
$this->data['alert'] = $alert; |
243
|
|
|
|
244
|
|
|
$this->data['alert_parts'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($criteria, $alert_ignore_speaker_votes, true); |
245
|
|
|
|
246
|
|
|
$existing_rep = ''; |
247
|
|
|
if (isset($this->data['alert_parts']['spokenby'])) { |
248
|
|
|
$existing_rep = $this->data['alert_parts']['spokenby'][0]; |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
$existing_section = ''; |
252
|
|
|
if (count($this->data['alert_parts']['sections'])) { |
253
|
|
|
$existing_section = $this->data['alert_parts']['sections'][0]; |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
# only want to load this the first time, otherwise we want to default to the form |
257
|
|
|
# value |
258
|
|
|
if (!$this->data['this_step'] && $this->data['alert_parts']['match_all']) { |
259
|
|
|
$this->data['match_all'] = false; |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
$words = get_http_var('words', $this->data['alert_parts']['words'], true); |
263
|
|
|
|
264
|
|
|
$this->data['words'] = []; |
265
|
|
|
$this->data['keywords'] = []; |
266
|
|
|
foreach ($words as $word) { |
267
|
|
|
if (trim($word) != '') { |
268
|
|
|
$this->data['keywords'][] = $word; |
269
|
|
|
$this->data['words'][] = $this->wrap_phrase_in_quotes($word); |
270
|
|
|
} |
271
|
|
|
} |
272
|
|
|
|
273
|
|
|
$add_all_related = get_http_var('add_all_related'); |
274
|
|
|
$this->data['add_all_related'] = $add_all_related; |
275
|
|
|
$this->data['skip_keyword_terms'] = []; |
276
|
|
|
|
277
|
|
|
$selected_related_terms = get_http_var('selected_related_terms', [], true); |
278
|
|
|
$this->data['selected_related_terms'] = $selected_related_terms; |
279
|
|
|
|
280
|
|
|
if ($this->data['step'] !== 'define') { |
281
|
|
|
if ($add_all_related) { |
282
|
|
|
$this->data['selected_related_terms'] = []; |
283
|
|
|
$related_terms = get_http_var('related_terms', [], true); |
284
|
|
|
foreach ($related_terms as $term) { |
285
|
|
|
$this->data['skip_keyword_terms'][] = $term; |
286
|
|
|
$this->data['keywords'][] = $term; |
287
|
|
|
$this->data['words'][] = $this->wrap_phrase_in_quotes($term); |
288
|
|
|
} |
289
|
|
|
} else { |
290
|
|
|
$this->data['skip_keyword_terms'] = $selected_related_terms; |
291
|
|
|
foreach ($selected_related_terms as $term) { |
292
|
|
|
$this->data['keywords'][] = $term; |
293
|
|
|
$this->data['words'][] = $this->wrap_phrase_in_quotes($term); |
294
|
|
|
} |
295
|
|
|
} |
296
|
|
|
} |
297
|
|
|
$this->data['exclusions'] = trim(get_http_var("exclusions", implode(' ', $this->data['alert_parts']['exclusions']))); |
298
|
|
|
$this->data['representative'] = trim(get_http_var("representative", $existing_rep)); |
299
|
|
|
|
300
|
|
|
$this->data['search_section'] = trim(get_http_var("search_section", $existing_section)); |
301
|
|
|
|
302
|
|
|
$separator = ' OR '; |
303
|
|
|
if ($this->data['match_all']) { |
304
|
|
|
$separator = ' '; |
305
|
|
|
} |
306
|
|
|
$this->data['keyword'] = implode($separator, $this->data['words']); |
307
|
|
|
if ($this->data['exclusions']) { |
308
|
|
|
$this->data['keyword'] = '(' . $this->data['keyword'] . ') -' . implode(' -', explode(' ', $this->data["exclusions"])); |
309
|
|
|
} |
310
|
|
|
|
311
|
|
|
$this->data['results'] = ''; |
312
|
|
|
|
313
|
|
|
$this->getSearchSections(); |
314
|
|
|
} elseif ($this->data['mp_step'] == 'mp_alert') { |
315
|
|
|
$alert = $this->alert->check_token($this->data['token']); |
316
|
|
|
if ($alert) { |
317
|
|
|
$ignore_speaker_votes = get_http_var('ignore_speaker_votes', $alert['ignore_speaker_votes']); |
318
|
|
|
$this->data['ignore_speaker_votes'] = ($ignore_speaker_votes == 'on' || $ignore_speaker_votes == 1); |
319
|
|
|
|
320
|
|
|
$existing_rep = ''; |
321
|
|
|
if (isset($alert['criteria'])) { |
322
|
|
|
$alert_parts = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($alert['criteria'], $alert['ignore_speaker_votes'], true); |
323
|
|
|
$existing_rep = $alert_parts['spokenby'][0]; |
324
|
|
|
$this->data['pid'] = $alert_parts['pid']; |
325
|
|
|
} |
326
|
|
|
$this->data['keyword'] = get_http_var('mp_search', $existing_rep); |
327
|
|
|
} else { |
328
|
|
|
$this->data['ignore_speaker_votes'] = get_http_var('ignore_speaker_votes'); |
329
|
|
|
} |
330
|
|
|
} |
331
|
|
|
|
332
|
|
|
$this->data['sign'] = get_http_var('sign'); |
333
|
|
|
$this->data['site'] = get_http_var('site'); |
334
|
|
|
$this->data['message'] = ''; |
335
|
|
|
|
336
|
|
|
$ACTIONURL = new \MySociety\TheyWorkForYou\Url($this_page); |
337
|
|
|
$ACTIONURL->reset(); |
338
|
|
|
$this->data['actionurl'] = $ACTIONURL->generate(); |
339
|
|
|
|
340
|
|
|
} |
341
|
|
|
|
342
|
|
|
private function wrap_phrase_in_quotes($phrase) { |
343
|
|
|
if (strpos($phrase, ' ') > 0) { |
344
|
|
|
$phrase = '"' . trim($phrase, '"') . '"'; |
345
|
|
|
} |
346
|
|
|
|
347
|
|
|
return $phrase; |
348
|
|
|
} |
349
|
|
|
|
350
|
|
|
/* |
351
|
|
|
* Check if the current alert has returned any results recently |
352
|
|
|
*/ |
353
|
|
|
private function getRecentResults($text) { |
354
|
|
|
global $SEARCHENGINE; |
355
|
|
|
$today = date_create(); |
356
|
|
|
$one_week_ago = date_create('7 days ago'); |
357
|
|
|
$restriction = date_format($one_week_ago, 'd/m/Y') . '..' . date_format($today, 'd/m/Y'); |
358
|
|
|
// Wrap the original query in parentheses and add the date restriction with AND |
359
|
|
|
$wrapped_query = '(' . $text . ') AND ' . $restriction; |
360
|
|
|
$last_week_count = 0; |
|
|
|
|
361
|
|
|
$se = new \SEARCHENGINE($wrapped_query); |
362
|
|
|
$last_week_count = $se->run_count(0, 10); |
363
|
|
|
$se = new \SEARCHENGINE($text); |
364
|
|
|
$count = $se->run_count(0, 10, 'date'); |
365
|
|
|
$last_mention = null; |
366
|
|
|
if ($count > 0) { |
367
|
|
|
$se->run_search(0, 1, 'date'); |
368
|
|
|
$gid = $se->get_gids()[0]; |
369
|
|
|
|
370
|
|
|
$q = ['gid_to' => $gid]; |
371
|
|
|
do { |
372
|
|
|
$gid = $q['gid_to']; |
373
|
|
|
$q = $this->db->query("SELECT gid_to FROM gidredirect WHERE gid_from = :gid", [':gid' => $gid])->first(); |
374
|
|
|
} while ($q); |
375
|
|
|
|
376
|
|
|
$q = $this->db->query("SELECT hansard.gid, hansard.hdate |
377
|
|
|
FROM hansard |
378
|
|
|
WHERE hansard.gid = :gid", [':gid' => $gid])->first(); |
379
|
|
|
|
380
|
|
|
if ($q) { |
381
|
|
|
$last_mention_date = date_create($q['hdate']); |
382
|
|
|
$last_mention = date_format($last_mention_date, 'd M Y'); //$se->get_gids()[0]; |
383
|
|
|
} |
384
|
|
|
} |
385
|
|
|
return [ |
386
|
|
|
"last_mention" => $last_mention, |
387
|
|
|
"last_week_count" => $last_week_count, |
388
|
|
|
"all_time_count" => $count, |
389
|
|
|
]; |
390
|
|
|
} |
391
|
|
|
|
392
|
|
|
private function getSearchSections() { |
393
|
|
|
$this->data['sections'] = []; |
394
|
|
|
if ($this->data['search_section']) { |
395
|
|
|
foreach (explode(' ', $this->data['search_section']) as $section) { |
396
|
|
|
$this->data['sections'][] = \MySociety\TheyWorkForYou\Utility\Alert::sectionToTitle($section); |
397
|
|
|
} |
398
|
|
|
} |
399
|
|
|
} |
400
|
|
|
|
401
|
|
|
private function updateAlert($token) { |
402
|
|
|
$success = $this->alert->update($token, $this->data); |
403
|
|
|
return $success; |
404
|
|
|
} |
405
|
|
|
|
406
|
|
|
private function checkInput() { |
407
|
|
|
global $SEARCHENGINE; |
408
|
|
|
|
409
|
|
|
$errors = []; |
410
|
|
|
|
411
|
|
|
# these are the initial screens and so cannot have any errors as we've not submitted |
412
|
|
|
if (!$this->data['submitted'] || $this->data['step'] == 'define' || $this->data['mp_step'] == 'mp_alert') { |
413
|
|
|
$this->data['errors'] = $errors; |
414
|
|
|
return; |
415
|
|
|
} |
416
|
|
|
|
417
|
|
|
// Check each of the things the user has input. |
418
|
|
|
// If there is a problem with any of them, set an entry in the $errors array. |
419
|
|
|
// This will then be used to (a) indicate there were errors and (b) display |
420
|
|
|
// error messages when we show the form again. |
421
|
|
|
|
422
|
|
|
// Check email address is valid and unique. |
423
|
|
|
if (!$this->data['email']) { |
424
|
|
|
$errors["email"] = gettext("Please enter your email address"); |
425
|
|
|
} elseif (!validate_email($this->data["email"])) { |
426
|
|
|
// validate_email() is in includes/utilities.php |
427
|
|
|
$errors["email"] = gettext("Please enter a valid email address"); |
428
|
|
|
} |
429
|
|
|
|
430
|
|
|
if ($this->data['pid'] && !ctype_digit($this->data['pid'])) { |
431
|
|
|
$errors['pid'] = 'Invalid person ID passed'; |
432
|
|
|
} |
433
|
|
|
|
434
|
|
|
$text = $this->data['alertsearch']; |
435
|
|
|
if ($this->data['mp_search']) { |
436
|
|
|
$text = $this->data['mp_search']; |
437
|
|
|
} |
438
|
|
|
if (!$text) { |
439
|
|
|
$text = $this->data['keyword']; |
440
|
|
|
} |
441
|
|
|
|
442
|
|
|
if ($this->data['submitted'] && !$this->data['pid'] && !$text) { |
443
|
|
|
$errors['alertsearch'] = gettext('Please enter what you want to be alerted about'); |
444
|
|
|
} |
445
|
|
|
|
446
|
|
|
if (strpos($text, '..')) { |
447
|
|
|
$errors['alertsearch'] = gettext('You probably don’t want a date range as part of your criteria, as you won’t be alerted to anything new!'); |
448
|
|
|
} |
449
|
|
|
|
450
|
|
|
$se = new \SEARCHENGINE($text); |
451
|
|
|
if (!$se->valid) { |
452
|
|
|
$errors['alertsearch'] = sprintf(gettext('That search appears to be invalid - %s - please check and try again.'), $se->error); |
453
|
|
|
} |
454
|
|
|
|
455
|
|
|
if (strlen($text) > 255) { |
456
|
|
|
$errors['alertsearch'] = gettext('That search is too long for our database; please split it up into multiple smaller alerts.'); |
457
|
|
|
} |
458
|
|
|
|
459
|
|
|
$this->data['errors'] = $errors; |
460
|
|
|
} |
461
|
|
|
|
462
|
|
|
|
463
|
|
|
private function searchForConstituenciesAndMembers() { |
464
|
|
|
if ($this->data['results'] == 'changes-abandoned') { |
465
|
|
|
$this->data['members'] = false; |
466
|
|
|
return; |
467
|
|
|
} |
468
|
|
|
|
469
|
|
|
$cons_sort = function ($a, $b) { |
470
|
|
|
if ($a['rep_name'] == $b['rep_name']) { |
471
|
|
|
if ($a['constituency'] == $b['constituency']) { |
472
|
|
|
if ($a['member']->family_name == $b['member']->family_name) { |
473
|
|
|
return 0; |
474
|
|
|
} |
475
|
|
|
return ($a['member']->family_name < $b['member']->family_name) ? -1 : 1; |
476
|
|
|
} |
477
|
|
|
return ($a['constituency'] < $b['constituency']) ? -1 : 1; |
478
|
|
|
} |
479
|
|
|
|
480
|
|
|
return ($a['rep_name'] < $b['rep_name']) ? -1 : 1; |
481
|
|
|
}; |
482
|
|
|
|
483
|
|
|
$text = $this->data['alertsearch']; |
484
|
|
|
if ($this->data['mp_search']) { |
485
|
|
|
$text = $this->data['mp_search']; |
486
|
|
|
} |
487
|
|
|
$errors = []; |
488
|
|
|
if ($text != '') { |
489
|
|
|
//$members_from_pids = array_values(\MySociety\TheyWorkForYou\Utility\Search::membersForIDs($this->data['alertsearch'])); |
490
|
|
|
$members_from_names = []; |
491
|
|
|
$names_from_pids = array_values(\MySociety\TheyWorkForYou\Utility\Search::speakerNamesForIDs($text)); |
492
|
|
|
foreach ($names_from_pids as $name) { |
493
|
|
|
$members_from_names = array_merge($members_from_names, \MySociety\TheyWorkForYou\Utility\Search::searchMemberDbLookupWithNames($name)); |
494
|
|
|
} |
495
|
|
|
$members_from_words = \MySociety\TheyWorkForYou\Utility\Search::searchMemberDbLookupWithNames($text, true); |
496
|
|
|
$this->data['members'] = array_merge($members_from_words, $members_from_names); |
497
|
|
|
[$this->data['constituencies'], $this->data['valid_postcode']] = \MySociety\TheyWorkForYou\Utility\Search::searchConstituenciesByQuery($text, false); |
498
|
|
|
# if there's no postcode match then constituencies will only have a list of names of westminster constituencies |
499
|
|
|
# so do a lookup using the member table to get members in all constituency types |
500
|
|
|
if (!$this->data['valid_postcode']) { |
501
|
|
|
$this->data['member_constituencies'] = \MySociety\TheyWorkForYou\Utility\Search::searchMembersByConstituency($text); |
502
|
|
|
} |
503
|
|
|
$member_count = count($this->data['members']); |
504
|
|
|
$cons_count = count($this->data['constituencies']); |
505
|
|
|
$mem_cons_count = isset($this->data['member_constituencies']) ? count($this->data['member_constituencies']) : 0; |
506
|
|
|
if (!$this->data['alertsearch'] && $member_count == 0 && $cons_count == 0 && $mem_cons_count == 0) { |
507
|
|
|
$errors["representative"] = gettext("No matching representative found"); |
508
|
|
|
} |
509
|
|
|
} elseif ($this->data['pid']) { |
510
|
|
|
$MEMBER = new \MySociety\TheyWorkForYou\Member(['person_id' => $this->data['pid']]); |
511
|
|
|
$this->data['members'] = [[ |
512
|
|
|
"person_id" => $MEMBER->person_id, |
513
|
|
|
"given_name" => $MEMBER->given_name, |
514
|
|
|
"family_name" => $MEMBER->family_name, |
515
|
|
|
"house" => $MEMBER->house_disp, |
516
|
|
|
"title" => $MEMBER->title, |
517
|
|
|
"lordofname" => $MEMBER->lordofname, |
518
|
|
|
"constituency" => $MEMBER->constituency, |
519
|
|
|
]]; |
520
|
|
|
} elseif (isset($this->data['representative']) && $this->data['representative'] != '') { |
521
|
|
|
$this->data['members'] = \MySociety\TheyWorkForYou\Utility\Search::searchMemberDbLookupWithNames($this->data['representative'], true); |
522
|
|
|
|
523
|
|
|
$member_count = count($this->data['members']); |
524
|
|
|
if ($member_count == 0) { |
525
|
|
|
$errors["representative"] = gettext("No matching representative found"); |
526
|
|
|
} elseif ($member_count > 1) { |
527
|
|
|
$errors["representative"] = gettext("Multiple matching representatives found, please select one."); |
528
|
|
|
} else { |
529
|
|
|
$this->data['pid'] = $this->data['members'][0]['person_id']; |
530
|
|
|
} |
531
|
|
|
} else { |
532
|
|
|
$this->data['members'] = []; |
533
|
|
|
} |
534
|
|
|
|
535
|
|
|
|
536
|
|
|
/* |
537
|
|
|
* If member_constituncies is set then it implies there wasn't a postcode match and hence we will have |
538
|
|
|
* a list of members which we can turn into constituencies, otherwise we have a hash of constituency names |
539
|
|
|
* keyed by mapit type |
540
|
|
|
*/ |
541
|
|
|
if (isset($this->data['member_constituencies'])) { |
542
|
|
|
$cons = []; |
543
|
|
|
foreach ($this->data['member_constituencies'] as $pid) { |
544
|
|
|
try { |
545
|
|
|
$MEMBER = new \MySociety\TheyWorkForYou\Member(['person_id' => $pid]); |
546
|
|
|
$cons[] = [ 'member' => $MEMBER, 'constituency' => $MEMBER->constituency, 'rep_name' => $MEMBER->getMostRecentMembership()['rep_name'] ]; |
547
|
|
|
} catch (\MySociety\TheyWorkForYou\MemberException $e) { |
548
|
|
|
// do nothing |
549
|
|
|
} |
550
|
|
|
} |
551
|
|
|
uasort($cons, $cons_sort); |
552
|
|
|
$this->data['constituencies'] = $cons; |
553
|
|
|
} elseif (isset($this->data['constituencies'])) { |
554
|
|
|
$cons = []; |
555
|
|
|
foreach ($this->data['constituencies'] as $type => $constituency) { |
556
|
|
|
try { |
557
|
|
|
$house = \MySociety\TheyWorkForYou\Utility\Postcode::mapitTypeToHouse($type); |
558
|
|
|
// regional list reps for wales and scotland |
559
|
|
|
if ($type == 'SPE' || $type == 'WAE') { |
560
|
|
|
$db = new \ParlDB(); |
561
|
|
|
$q = $db->query("SELECT person_id FROM member WHERE constituency = :constituency AND house = :house and left_reason = 'still_in_office'", [':constituency' => $constituency, ':house' => $house]); |
562
|
|
|
foreach ($q as $row) { |
563
|
|
|
$MEMBER = new \MySociety\TheyWorkForYou\Member(['person_id' => $row['person_id'], 'house' => $house]); |
564
|
|
|
$cons[] = [ 'member' => $MEMBER, 'constituency' => $constituency, 'rep_name' => $MEMBER->getMostRecentMembership()['rep_name'] ]; |
565
|
|
|
} |
566
|
|
|
|
567
|
|
|
} else { |
568
|
|
|
$MEMBER = new \MySociety\TheyWorkForYou\Member(['constituency' => $constituency, 'house' => $house]); |
569
|
|
|
$cons[] = [ 'member' => $MEMBER, 'constituency' => $constituency ]; |
570
|
|
|
} |
571
|
|
|
} catch (\MySociety\TheyWorkForYou\MemberException $e) { |
572
|
|
|
// do nothing |
573
|
|
|
} |
574
|
|
|
} |
575
|
|
|
uasort($cons, $cons_sort); |
576
|
|
|
$this->data['constituencies'] = $cons; |
577
|
|
|
} |
578
|
|
|
|
579
|
|
|
|
580
|
|
|
if ($this->data['alertsearch'] && !$this->data['mp_step'] && ($this->data['pid'] || $this->data['members'] || $this->data['constituencies'])) { |
581
|
|
|
$this->data['mp_step'] = 'mp_alert'; |
582
|
|
|
$this->data['mp_search'] = $this->data['alertsearch']; |
583
|
|
|
$this->data['alertsearch'] = ''; |
584
|
|
|
} |
585
|
|
|
|
586
|
|
|
if (count($this->data["errors"]) > 0) { |
587
|
|
|
$this->data["errors"] = array_merge($this->data["errors"], $errors); |
588
|
|
|
} else { |
589
|
|
|
$this->data["errors"] = $errors; |
590
|
|
|
} |
591
|
|
|
} |
592
|
|
|
|
593
|
|
|
private function addAlert() { |
594
|
|
|
$external_auth = auth_verify_with_shared_secret($this->data['email'], OPTION_AUTH_SHARED_SECRET, get_http_var('sign')); |
595
|
|
|
if ($external_auth) { |
596
|
|
|
$confirm = false; |
597
|
|
|
} elseif ($this->data['email_verified']) { |
598
|
|
|
$confirm = false; |
599
|
|
|
} else { |
600
|
|
|
$confirm = true; |
601
|
|
|
} |
602
|
|
|
|
603
|
|
|
// If this goes well, the alert will be added to the database and a confirmation email |
604
|
|
|
// will be sent to them. |
605
|
|
|
$success = $this->alert->add($this->data, $confirm); |
606
|
|
|
|
607
|
|
|
if ($success > 0 && !$confirm) { |
608
|
|
|
$this->data['step'] = ''; |
609
|
|
|
$this->data['mp_step'] = ''; |
610
|
|
|
$result = 'alert-added'; |
611
|
|
|
} elseif ($success > 0) { |
612
|
|
|
$this->data['step'] = ''; |
613
|
|
|
$this->data['mp_step'] = ''; |
614
|
|
|
$result = 'alert-confirmation'; |
615
|
|
|
} elseif ($success == -2) { |
616
|
|
|
// we need to make sure we know that the person attempting to sign up |
617
|
|
|
// for the alert has that email address to stop people trying to work |
618
|
|
|
// out what alerts they are signed up to |
619
|
|
|
if ($this->data['email_verified'] || ($this->user->loggedin && $this->user->email() == $this->data['email'])) { |
620
|
|
|
$result = 'alert-exists'; |
621
|
|
|
} else { |
622
|
|
|
// don't throw an error message as that implies that they have already signed |
623
|
|
|
// up for the alert but instead pretend all is normal but send an email saying |
624
|
|
|
// that someone tried to sign them up for an existing alert |
625
|
|
|
$result = 'alert-already-signed'; |
626
|
|
|
$this->alert->send_already_signedup_email($this->data); |
627
|
|
|
} |
628
|
|
|
} else { |
629
|
|
|
$result = 'alert-fail'; |
630
|
|
|
} |
631
|
|
|
|
632
|
|
|
// don't need these anymore so get rid of them |
633
|
|
|
$this->data['keyword'] = ''; |
634
|
|
|
$this->data['pid'] = ''; |
635
|
|
|
$this->data['alertsearch'] = ''; |
636
|
|
|
$this->data['pc'] = ''; |
637
|
|
|
|
638
|
|
|
$this->data['results'] = $result; |
639
|
|
|
$this->data['criteria'] = $this->alert->criteria; |
640
|
|
|
$this->data['display_criteria'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($this->alert->criteria, $this->alert->ignore_speaker_votes); |
641
|
|
|
} |
642
|
|
|
|
643
|
|
|
|
644
|
|
|
private function formatSearchTerms() { |
645
|
|
|
if ($this->data['alertsearch']) { |
646
|
|
|
$this->data['alertsearch_pretty'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($this->data['alertsearch']); |
647
|
|
|
$this->data['search_text'] = $this->data['alertsearch']; |
648
|
|
|
} elseif ($this->data['mp_search']) { |
649
|
|
|
$this->data['search_text'] = $this->data['mp_search']; |
650
|
|
|
} else { |
651
|
|
|
$this->data['search_text'] = $this->data['keyword']; |
652
|
|
|
} |
653
|
|
|
} |
654
|
|
|
|
655
|
|
|
private function checkForCommonMistakes() { |
656
|
|
|
$mistakes = []; |
657
|
|
|
if (strstr($this->data['alertsearch'], ',') > -1) { |
658
|
|
|
$mistakes['multiple'] = 1; |
659
|
|
|
} |
660
|
|
|
|
661
|
|
|
if ( |
662
|
|
|
preg_match('#([A-Z]{1,2}\d+[A-Z]? ?\d[A-Z]{2})#i', $this->data['alertsearch'], $m) && |
663
|
|
|
strlen($this->data['alertsearch']) > strlen($m[1]) && |
664
|
|
|
validate_postcode($m[1]) |
665
|
|
|
) { |
666
|
|
|
$this->data['postcode'] = $m[1]; |
667
|
|
|
$mistakes['postcode_and'] = 1; |
668
|
|
|
} |
669
|
|
|
|
670
|
|
|
$this->data['mistakes'] = $mistakes; |
671
|
|
|
} |
672
|
|
|
|
673
|
|
|
private function formatSearchMemberData() { |
674
|
|
|
if (isset($this->data['postcode'])) { |
675
|
|
|
try { |
676
|
|
|
$postcode = $this->data['postcode']; |
677
|
|
|
|
678
|
|
|
$MEMBER = new \MySociety\TheyWorkForYou\Member(['postcode' => $postcode]); |
679
|
|
|
// move the postcode to the front just to be tidy |
680
|
|
|
$tidy_alertsearch = $postcode . " " . trim(str_replace("$postcode", "", $this->data['alertsearch'])); |
681
|
|
|
$alertsearch_display = str_replace("$postcode ", "", $tidy_alertsearch); |
682
|
|
|
|
683
|
|
|
$this->data['member_alertsearch'] = str_replace("$postcode", "speaker:" . $MEMBER->person_id, $tidy_alertsearch); |
684
|
|
|
$this->data['member_displaysearch'] = $alertsearch_display; |
685
|
|
|
$this->data['member'] = $MEMBER; |
686
|
|
|
|
687
|
|
|
if (isset($this->data['mistakes']['postcode_and'])) { |
688
|
|
|
$constituencies = \MySociety\TheyWorkForYou\Utility\Postcode::postcodeToConstituencies($postcode); |
689
|
|
|
if (isset($constituencies['SPC'])) { |
690
|
|
|
$MEMBER = new \MySociety\TheyWorkForYou\Member(['constituency' => $constituencies['SPC'], 'house' => HOUSE_TYPE_SCOTLAND]); |
691
|
|
|
$this->data['scottish_alertsearch'] = str_replace("$postcode", "speaker:" . $MEMBER->person_id, $tidy_alertsearch); |
692
|
|
|
$this->data['scottish_member'] = $MEMBER; |
693
|
|
|
} elseif (isset($constituencies['WAC'])) { |
694
|
|
|
$MEMBER = new \MySociety\TheyWorkForYou\Member(['constituency' => $constituencies['WAC'], 'house' => HOUSE_TYPE_WALES]); |
695
|
|
|
$this->data['welsh_alertsearch'] = str_replace("$postcode", "speaker:" . $MEMBER->person_id, $tidy_alertsearch); |
696
|
|
|
$this->data['welsh_member'] = $MEMBER; |
697
|
|
|
} |
698
|
|
|
} |
699
|
|
|
} catch (\MySociety\TheyWorkForYou\MemberException $e) { |
700
|
|
|
$this->data['member_error'] = 1; |
701
|
|
|
} |
702
|
|
|
} |
703
|
|
|
|
704
|
|
|
if ($this->data['pid']) { |
705
|
|
|
$MEMBER = new \MySociety\TheyWorkForYou\Member(['person_id' => $this->data['pid']]); |
706
|
|
|
$this->data['pid_member'] = $MEMBER; |
707
|
|
|
} |
708
|
|
|
|
709
|
|
|
if ($this->data['keyword']) { |
710
|
|
|
$this->data['display_keyword'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($this->data['keyword']); |
711
|
|
|
} |
712
|
|
|
} |
713
|
|
|
|
714
|
|
|
/* |
715
|
|
|
* This makes sure that the $this->data makes sense once all the other steps have been completed |
716
|
|
|
*/ |
717
|
|
|
private function setUserData() { |
718
|
|
|
if (!isset($this->data['criteria'])) { |
719
|
|
|
$criteria = $this->data['keyword']; |
720
|
|
|
if ($criteria) { |
721
|
|
|
if (!$this->data['match_all']) { |
722
|
|
|
$has_or = strpos($criteria, ' OR ') !== false; |
723
|
|
|
$missing_braces = strpos($criteria, '(') === false; |
724
|
|
|
|
725
|
|
|
if ($has_or && $missing_braces) { |
726
|
|
|
$criteria = "($criteria)"; |
727
|
|
|
} |
728
|
|
|
} |
729
|
|
|
if ($this->data['search_section']) { |
730
|
|
|
$criteria .= " section:" . $this->data['search_section']; |
731
|
|
|
} |
732
|
|
|
if ($this->data['pid']) { |
733
|
|
|
$criteria .= " speaker:" . $this->data['pid']; |
734
|
|
|
} |
735
|
|
|
$this->data['search_results'] = $this->getRecentResults($criteria); |
736
|
|
|
} |
737
|
|
|
|
738
|
|
|
$this->data['criteria'] = $criteria; |
739
|
|
|
$this->data['display_criteria'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($criteria); |
740
|
|
|
} |
741
|
|
|
if ($this->data['results'] == 'changes-abandoned') { |
742
|
|
|
$this->data['members'] = false; |
743
|
|
|
$this->data['alertsearch'] = ''; |
744
|
|
|
} |
745
|
|
|
|
746
|
|
|
if ($this->data['alertsearch'] && !(isset($this->data['mistakes']['postcode_and']) || $this->data['members'] || $this->data['pid'] || $this->data['constituencies'])) { |
747
|
|
|
$this->data['step'] = 'define'; |
748
|
|
|
$this->data['words'] = [$this->data['alertsearch']]; |
749
|
|
|
$this->data['keywords'] = [$this->data['alertsearch']]; |
750
|
|
|
$this->data['exclusions'] = ''; |
751
|
|
|
$this->data['representative'] = ''; |
752
|
|
|
} elseif ($this->data['alertsearch'] && ($this->data['members'] || $this->data['pid'])) { |
753
|
|
|
$this->data['mp_step'] = 'mp_alert'; |
754
|
|
|
$this->data['mp_search'] = [$this->data['alertsearch']]; |
755
|
|
|
} elseif ($this->data['members'] && $this->data['mp_step'] == 'mp_search' && count($this->data['errors']) == 0) { |
756
|
|
|
$this->data['mp_step'] = ''; |
757
|
|
|
} |
758
|
|
|
|
759
|
|
|
$this->data['current_mp'] = false; |
760
|
|
|
$this->data['alerts'] = []; |
761
|
|
|
$this->data['keyword_alerts'] = []; |
762
|
|
|
$this->data['speaker_alerts'] = []; |
763
|
|
|
$this->data['spoken_alerts'] = []; |
764
|
|
|
$this->data['own_member_alerts'] = []; |
765
|
|
|
$this->data['all_keywords'] = []; |
766
|
|
|
$this->data['own_mp_criteria'] = ''; |
767
|
|
|
$own_mp_criteria = ''; |
768
|
|
|
|
769
|
|
|
if ($this->data['email_verified']) { |
770
|
|
|
if ($this->user->postcode()) { |
771
|
|
|
$current_mp = new \MySociety\TheyWorkForYou\Member(['postcode' => $this->user->postcode()]); |
772
|
|
|
if ($current_mp_alert = !$this->alert->fetch_by_mp($this->data['email'], $current_mp->person_id())) { |
|
|
|
|
773
|
|
|
$this->data['current_mp'] = $current_mp; |
774
|
|
|
$own_mp_criteria = sprintf('speaker:%s', $current_mp->person_id()); |
|
|
|
|
775
|
|
|
} |
776
|
|
|
$own_mp_criteria = $current_mp->full_name(); |
777
|
|
|
$this->data['own_mp_criteria'] = $own_mp_criteria; |
778
|
|
|
} |
779
|
|
|
$this->data['alerts'] = \MySociety\TheyWorkForYou\Utility\Alert::forUser($this->data['email']); |
780
|
|
|
foreach ($this->data['alerts'] as $alert) { |
781
|
|
|
if (array_key_exists('spokenby', $alert) and sizeof($alert['spokenby']) == 1 and $alert['spokenby'][0] == $own_mp_criteria) { |
782
|
|
|
$this->data['own_member_alerts'][] = $alert; |
783
|
|
|
} elseif (array_key_exists('spokenby', $alert)) { |
784
|
|
|
if (!array_key_exists($alert['spokenby'][0], $this->data['spoken_alerts'])) { |
785
|
|
|
$this->data['spoken_alerts'][$alert['spokenby'][0]] = []; |
786
|
|
|
} |
787
|
|
|
$this->data['spoken_alerts'][$alert['spokenby'][0]][] = $alert; |
788
|
|
|
} |
789
|
|
|
} |
790
|
|
|
foreach ($this->data['alerts'] as $alert) { |
791
|
|
|
$term = implode(' ', $alert['words']); |
792
|
|
|
$add = true; |
793
|
|
|
if (array_key_exists('spokenby', $alert)) { |
794
|
|
|
$add = false; |
795
|
|
|
} elseif (array_key_exists($term, $this->data['spoken_alerts'])) { |
796
|
|
|
$add = false; |
797
|
|
|
$this->data['all_keywords'][] = $term; |
798
|
|
|
$this->data['spoken_alerts'][$term][] = $alert; |
799
|
|
|
} elseif ($term == $own_mp_criteria) { |
800
|
|
|
$add = false; |
801
|
|
|
$this->data['all_keywords'][] = $term; |
802
|
|
|
$this->data['own_member_alerts'][] = $alert; |
803
|
|
|
} elseif (\MySociety\TheyWorkForYou\Utility\Search::searchMemberDbLookupWithNames($term, true)) { |
804
|
|
|
if (!array_key_exists($term, $this->data['spoken_alerts'])) { |
805
|
|
|
$this->data['spoken_alerts'][$term] = []; |
806
|
|
|
} |
807
|
|
|
$add = false; |
808
|
|
|
# need to add this to make it consistent so the front end know where to get the name |
809
|
|
|
$alert['spokenby'] = [$term]; |
810
|
|
|
$this->data['all_keywords'][] = $term; |
811
|
|
|
$this->data['spoken_alerts'][$term][] = $alert; |
812
|
|
|
} |
813
|
|
|
if ($add) { |
814
|
|
|
$this->data['all_keywords'][] = $term; |
815
|
|
|
// Only fetch search results when displaying the main alert list |
816
|
|
|
if ($this->data['showing_main_alert_list']) { |
817
|
|
|
$alert['search_results'] = $this->getRecentResults($alert["raw"]); |
818
|
|
|
} |
819
|
|
|
$this->data['keyword_alerts'][] = $alert; |
820
|
|
|
} |
821
|
|
|
} |
822
|
|
|
} else { |
823
|
|
|
if ($this->data['alertsearch'] && $this->data['pc']) { |
824
|
|
|
$this->data['mp_step'] = 'mp_alert'; |
825
|
|
|
} |
826
|
|
|
} |
827
|
|
|
if (count($this->data['alerts'])) { |
828
|
|
|
$this->data['delete_token'] = $this->data['alerts'][0]['token']; |
829
|
|
|
} |
830
|
|
|
if ($this->data['addword'] != '' || ($this->data['step'] && count($this->data['errors']) > 0)) { |
831
|
|
|
$this->data["step"] = get_http_var('this_step'); |
832
|
|
|
} elseif ($this->data['mp_step'] && count($this->data['errors']) > 0) { |
833
|
|
|
$this->data["mp_step"] = 'mp_alert'; |
834
|
|
|
} else { |
835
|
|
|
$this->data['this_step'] = ''; |
836
|
|
|
} |
837
|
|
|
|
838
|
|
|
$this->data["search_term"] = $this->data['alertsearch']; |
839
|
|
|
if ($this->data['mp_search']) { |
840
|
|
|
$this->data["search_term"] = $this->data['mp_search']; |
841
|
|
|
} |
842
|
|
|
} |
843
|
|
|
} |
844
|
|
|
|
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.