|
1
|
|
|
<?php |
|
|
|
|
|
|
2
|
|
|
|
|
3
|
|
|
namespace MySociety\TheyWorkForYou\AlertView; |
|
4
|
|
|
|
|
5
|
|
|
include_once '../../../www/includes/easyparliament/init.php'; |
|
6
|
|
|
include_once INCLUDESPATH . "easyparliament/people.php"; |
|
|
|
|
|
|
7
|
|
|
include_once INCLUDESPATH . "easyparliament/member.php"; |
|
8
|
|
|
include_once INCLUDESPATH . "easyparliament/searchengine.php"; |
|
9
|
|
|
include_once INCLUDESPATH . '../../commonlib/phplib/auth.php'; |
|
10
|
|
|
include_once INCLUDESPATH . '../../commonlib/phplib/crosssell.php'; |
|
11
|
|
|
|
|
12
|
|
|
class Standard extends \MySociety\TheyWorkForYou\AlertView { |
|
13
|
|
|
public $data; |
|
14
|
|
|
|
|
15
|
|
|
public function __construct($THEUSER = NULL) { |
|
16
|
|
|
parent::__construct($THEUSER); |
|
17
|
|
|
$this->data = array(); |
|
18
|
|
|
} |
|
19
|
|
|
|
|
20
|
|
|
public function display() { |
|
21
|
|
|
global $this_page; |
|
|
|
|
|
|
22
|
|
|
$this_page = "alert"; |
|
23
|
|
|
|
|
24
|
|
|
$this->processAction(); |
|
25
|
|
|
$this->getBasicData(); |
|
26
|
|
|
$this->checkInput(); |
|
27
|
|
|
$this->searchForConstituenciesAndMembers(); |
|
28
|
|
|
|
|
29
|
|
|
if (!sizeof($this->data['errors']) && ($this->data['keyword'] || $this->data['pid'])) { |
|
30
|
|
|
$this->addAlert(); |
|
31
|
|
|
} |
|
32
|
|
|
|
|
33
|
|
|
$this->formatSearchTerms(); |
|
34
|
|
|
$this->checkForCommonMistakes(); |
|
35
|
|
|
$this->formatSearchMemberData(); |
|
36
|
|
|
$this->setUserData(); |
|
37
|
|
|
|
|
38
|
|
|
return $this->data; |
|
39
|
|
|
} |
|
40
|
|
|
|
|
41
|
|
|
private function processAction() { |
|
42
|
|
|
$token = get_http_var('t'); |
|
43
|
|
|
$alert = $this->alert->check_token($token); |
|
44
|
|
|
|
|
45
|
|
|
$this->data['results'] = false; |
|
46
|
|
|
if ($action = get_http_var('action')) { |
|
47
|
|
|
$success = true; |
|
48
|
|
|
if ($action == 'Confirm') { |
|
49
|
|
|
$success = $this->confirmAlert($token); |
|
50
|
|
|
if ($success) { |
|
51
|
|
|
$this->data['results'] = 'alert-confirmed'; |
|
52
|
|
|
$this->data['criteria'] = $this->prettifyCriteria($this->alert->criteria); |
|
53
|
|
|
} |
|
54
|
|
|
} elseif ($action == 'Suspend') { |
|
55
|
|
|
$success = $this->suspendAlert($token); |
|
56
|
|
|
if ($success) { |
|
57
|
|
|
$this->data['results'] = 'alert-suspended'; |
|
58
|
|
|
} |
|
59
|
|
|
} elseif ($action == 'Resume') { |
|
60
|
|
|
$success = $this->resumeAlert($token); |
|
61
|
|
|
if ($success) { |
|
62
|
|
|
$this->data['results'] = 'alert-resumed'; |
|
63
|
|
|
} |
|
64
|
|
|
} elseif ($action == 'Delete') { |
|
65
|
|
|
$success = $this->deleteAlert($token); |
|
66
|
|
|
if ($success) { |
|
67
|
|
|
$this->data['results'] = 'alert-deleted'; |
|
68
|
|
|
} |
|
69
|
|
|
} |
|
70
|
|
|
if (!$success) { |
|
71
|
|
|
$this->data['results'] = 'alert-fail'; |
|
72
|
|
|
} |
|
73
|
|
|
} |
|
74
|
|
|
|
|
75
|
|
|
$this->data['alert'] = $alert; |
|
76
|
|
|
} |
|
77
|
|
|
|
|
78
|
|
|
|
|
79
|
|
|
private function getBasicData() { |
|
80
|
|
|
global $this_page; |
|
|
|
|
|
|
81
|
|
|
|
|
82
|
|
|
if ($this->user->loggedin()) { |
|
83
|
|
|
$this->data['email'] = $this->user->email(); |
|
84
|
|
|
$this->data['email_verified'] = true; |
|
85
|
|
|
} elseif ($this->data['alert']) { |
|
86
|
|
|
$this->data['email'] = $this->data['alert']['email']; |
|
87
|
|
|
$this->data['email_verified'] = true; |
|
88
|
|
|
} else { |
|
89
|
|
|
$this->data["email"] = trim(get_http_var("email")); |
|
90
|
|
|
$this->data['email_verified'] = false; |
|
91
|
|
|
} |
|
92
|
|
|
$this->data['keyword'] = trim(get_http_var("keyword")); |
|
93
|
|
|
$this->data['pid'] = trim(get_http_var("pid")); |
|
94
|
|
|
$this->data['alertsearch'] = trim(get_http_var("alertsearch")); |
|
95
|
|
|
$this->data['pc'] = get_http_var('pc'); |
|
96
|
|
|
$this->data['submitted'] = get_http_var('submitted') || $this->data['pid'] || $this->data['keyword']; |
|
97
|
|
|
$this->data['token'] = get_http_var('t'); |
|
98
|
|
|
$this->data['sign'] = get_http_var('sign'); |
|
99
|
|
|
$this->data['site'] = get_http_var('site'); |
|
100
|
|
|
$this->data['message'] = ''; |
|
101
|
|
|
|
|
102
|
|
|
$ACTIONURL = new \MySociety\TheyWorkForYou\Url($this_page); |
|
103
|
|
|
$ACTIONURL->reset(); |
|
104
|
|
|
$this->data['actionurl'] = $ACTIONURL->generate(); |
|
105
|
|
|
} |
|
106
|
|
|
|
|
107
|
|
|
private function checkInput() { |
|
108
|
|
|
global $SEARCHENGINE; |
|
|
|
|
|
|
109
|
|
|
|
|
110
|
|
|
$errors = array(); |
|
111
|
|
|
|
|
112
|
|
|
// Check each of the things the user has input. |
|
113
|
|
|
// If there is a problem with any of them, set an entry in the $errors array. |
|
114
|
|
|
// This will then be used to (a) indicate there were errors and (b) display |
|
115
|
|
|
// error messages when we show the form again. |
|
116
|
|
|
|
|
117
|
|
|
// Check email address is valid and unique. |
|
118
|
|
|
if (!$this->data['email']) { |
|
119
|
|
|
$errors["email"] = "Please enter your email address"; |
|
120
|
|
|
} elseif (!validate_email($this->data["email"])) { |
|
121
|
|
|
// validate_email() is in includes/utilities.php |
|
122
|
|
|
$errors["email"] = "Please enter a valid email address"; |
|
123
|
|
|
} |
|
124
|
|
|
|
|
125
|
|
|
if ($this->data['pid'] && !ctype_digit($this->data['pid'])) { |
|
126
|
|
|
$errors['pid'] = 'Invalid person ID passed'; |
|
127
|
|
|
} |
|
128
|
|
|
|
|
129
|
|
|
$text = $this->data['alertsearch']; |
|
130
|
|
|
if (!$text) $text = $this->data['keyword']; |
|
131
|
|
|
|
|
132
|
|
|
if ($this->data['submitted'] && !$this->data['pid'] && !$text) { |
|
133
|
|
|
$errors['alertsearch'] = 'Please enter what you want to be alerted about'; |
|
134
|
|
|
} |
|
135
|
|
|
|
|
136
|
|
|
if (strpos($text, '..')) { |
|
137
|
|
|
$errors['alertsearch'] = 'You probably don’t want a date range as part of your criteria, as you won’t be alerted to anything new!'; |
|
138
|
|
|
} |
|
139
|
|
|
|
|
140
|
|
|
$se = new \SEARCHENGINE($text); |
|
141
|
|
|
if (!$se->valid) { |
|
142
|
|
|
$errors['alertsearch'] = 'That search appears to be invalid - ' . $se->error . ' - please check and try again.'; |
|
143
|
|
|
} |
|
144
|
|
|
|
|
145
|
|
|
if (strlen($text) > 255) { |
|
146
|
|
|
$errors['alertsearch'] = 'That search is too long for our database; please split it up into multiple smaller alerts.'; |
|
147
|
|
|
} |
|
148
|
|
|
|
|
149
|
|
|
$this->data['errors'] = $errors; |
|
150
|
|
|
} |
|
151
|
|
|
|
|
152
|
|
|
private function searchForConstituenciesAndMembers() { |
|
153
|
|
|
// Do the search |
|
154
|
|
|
if ($this->data['alertsearch']) { |
|
155
|
|
|
$this->data['members'] = \MySociety\TheyWorkForYou\Utility\Search::searchMemberDbLookupWithNames($this->data['alertsearch'], true); |
|
156
|
|
|
list ($this->data['constituencies'], $this->data['valid_postcode']) = \MySociety\TheyWorkForYou\Utility\Search::searchConstituenciesByQuery($this->data['alertsearch']); |
|
157
|
|
|
} |
|
158
|
|
|
|
|
159
|
|
|
# If the above search returned one result for member or constituency search, |
|
160
|
|
|
# use it immediately |
|
161
|
|
|
|
|
162
|
|
|
if (isset($this->data['members']) && $this->data['members']->rows() == 1) { |
|
163
|
|
|
$this->data['pid'] = $this->data['members']->field(0, 'person_id'); |
|
164
|
|
|
unset($this->data['members']); |
|
165
|
|
|
$this->data['alertsearch'] = ''; |
|
166
|
|
|
} |
|
167
|
|
|
|
|
168
|
|
|
if (isset($this->data['constituencies']) && count($this->data['constituencies']) == 1 && $this->data['valid_postcode']) { |
|
169
|
|
|
$MEMBER = new \MEMBER(array('constituency' => $this->data['constituencies'][0], 'house' => 1)); |
|
170
|
|
|
$this->data['pid'] = $MEMBER->person_id(); |
|
171
|
|
|
$this->data['pc'] = $this->data['alertsearch']; |
|
172
|
|
|
unset($this->data['constituencies']); |
|
173
|
|
|
$this->data['alertsearch'] = ''; |
|
174
|
|
|
} |
|
175
|
|
|
|
|
176
|
|
|
if (isset($this->data['constituencies'])) { |
|
177
|
|
|
$cons = array(); |
|
178
|
|
|
foreach ($this->data['constituencies'] as $constituency) { |
|
179
|
|
|
try { |
|
180
|
|
|
$MEMBER = new \MEMBER(array('constituency'=>$constituency, 'house' => 1)); |
|
181
|
|
|
$cons[$constituency] = $MEMBER; |
|
182
|
|
|
} catch ( \MySociety\TheyWorkForYou\MemberException $e ) { |
|
183
|
|
|
// do nothing |
|
184
|
|
|
} |
|
185
|
|
|
} |
|
186
|
|
|
$this->data['constituencies'] = $cons; |
|
187
|
|
|
} |
|
188
|
|
|
} |
|
189
|
|
|
|
|
190
|
|
|
private function addAlert() { |
|
191
|
|
|
$external_auth = auth_verify_with_shared_secret($this->data['email'], OPTION_AUTH_SHARED_SECRET, get_http_var('sign')); |
|
|
|
|
|
|
192
|
|
|
if ($external_auth) { |
|
193
|
|
|
$confirm = false; |
|
194
|
|
|
} elseif ($this->data['email_verified']) { |
|
195
|
|
|
$confirm = false; |
|
196
|
|
|
} else { |
|
197
|
|
|
$confirm = true; |
|
198
|
|
|
} |
|
199
|
|
|
|
|
200
|
|
|
// If this goes well, the alert will be added to the database and a confirmation email |
|
201
|
|
|
// will be sent to them. |
|
202
|
|
|
$success = $this->alert->add( $this->data, $confirm ); |
|
203
|
|
|
|
|
204
|
|
|
if ($success>0 && !$confirm) { |
|
205
|
|
|
$result = 'alert-added'; |
|
206
|
|
|
} elseif ($success>0) { |
|
207
|
|
|
$result = 'alert-confirmation'; |
|
208
|
|
|
} elseif ($success == -2) { |
|
209
|
|
|
// we need to make sure we know that the person attempting to sign up |
|
210
|
|
|
// for the alert has that email address to stop people trying to work |
|
211
|
|
|
// out what alerts they are signed up to |
|
212
|
|
|
if ( $this->data['email_verified'] || ( $this->user->loggedin && $this->user->email() == $this->data['email'] ) ) { |
|
213
|
|
|
$result = 'alert-exists'; |
|
214
|
|
|
} else { |
|
215
|
|
|
// don't throw an error message as that implies that they have already signed |
|
216
|
|
|
// up for the alert but instead pretend all is normal but send an email saying |
|
217
|
|
|
// that someone tried to sign them up for an existing alert |
|
218
|
|
|
$result = 'alert-already-signed'; |
|
219
|
|
|
$this->alert->send_already_signedup_email($this->data); |
|
220
|
|
|
} |
|
221
|
|
|
} else { |
|
222
|
|
|
$result = 'alert-fail'; |
|
223
|
|
|
} |
|
224
|
|
|
|
|
225
|
|
|
// don't need these anymore so get rid of them |
|
226
|
|
|
$this->data['keyword'] = ''; |
|
227
|
|
|
$this->data['pid'] = ''; |
|
228
|
|
|
$this->data['alertsearch'] = ''; |
|
229
|
|
|
$this->data['pc'] = ''; |
|
230
|
|
|
|
|
231
|
|
|
$this->data['results'] = $result; |
|
232
|
|
|
$this->data['criteria'] = $this->prettifyCriteria($this->alert->criteria); |
|
233
|
|
|
} |
|
234
|
|
|
|
|
235
|
|
|
|
|
236
|
|
|
private function formatSearchTerms() { |
|
237
|
|
|
if ( $this->data['alertsearch'] ) { |
|
238
|
|
|
$this->data['alertsearch_pretty'] = $this->prettifyCriteria($this->data['alertsearch']); |
|
239
|
|
|
$this->data['search_text'] = $this->data['alertsearch']; |
|
240
|
|
|
} else { |
|
241
|
|
|
$this->data['search_text'] = $this->data['keyword']; |
|
242
|
|
|
} |
|
243
|
|
|
} |
|
244
|
|
|
|
|
245
|
|
|
private function prettifyCriteria($alert_criteria) { |
|
246
|
|
|
$text = ''; |
|
247
|
|
|
if ( $alert_criteria ) { |
|
248
|
|
|
$criteria = explode(' ', $alert_criteria); |
|
249
|
|
|
$words = array(); |
|
250
|
|
|
$spokenby = array_values(\MySociety\TheyWorkForYou\Utility\Search::speakerNamesForIDs($alert_criteria)); |
|
251
|
|
|
|
|
252
|
|
|
foreach ($criteria as $c) { |
|
253
|
|
|
if (!preg_match('#^speaker:(\d+)#',$c,$m)) { |
|
254
|
|
|
$words[] = $c; |
|
255
|
|
|
} |
|
256
|
|
|
} |
|
257
|
|
|
if ( $spokenby && count($words) ) { |
|
|
|
|
|
|
258
|
|
|
$text = implode(' or ', $spokenby) . ' mentions [' . implode(' ', $words) . ']'; |
|
259
|
|
|
} else if ( count( $words ) ) { |
|
260
|
|
|
$text = '[' . implode(' ', $words) . ']' . ' is mentioned'; |
|
261
|
|
|
} else if ( $spokenby ) { |
|
|
|
|
|
|
262
|
|
|
$text = implode(' or ', $spokenby) . " speaks"; |
|
263
|
|
|
} |
|
264
|
|
|
|
|
265
|
|
|
return $text; |
|
266
|
|
|
} |
|
267
|
|
|
|
|
268
|
|
|
return $text; |
|
269
|
|
|
} |
|
270
|
|
|
|
|
271
|
|
|
private function checkForCommonMistakes() { |
|
272
|
|
|
$mistakes = array(); |
|
273
|
|
|
if (strstr($this->data['alertsearch'], ',') > -1) { |
|
274
|
|
|
$mistakes['multiple'] = 1; |
|
275
|
|
|
} |
|
276
|
|
|
|
|
277
|
|
|
if ( |
|
278
|
|
|
preg_match('#([A-Z]{1,2}\d+[A-Z]? ?\d[A-Z]{2})#i', $this->data['alertsearch'], $m) && |
|
279
|
|
|
strlen($this->data['alertsearch']) > strlen($m[1]) && |
|
280
|
|
|
validate_postcode($m[1]) |
|
281
|
|
|
) { |
|
282
|
|
|
$this->data['postcode'] = $m[1]; |
|
283
|
|
|
$this->data['scottish_text'] = ''; |
|
284
|
|
|
$this->data['mp_display_text'] = ''; |
|
285
|
|
|
if (\MySociety\TheyWorkForYou\Utility\Postcode::postcodeIsScottish($m[1])) { |
|
286
|
|
|
$this->data['mp_display_text'] = 'your MP, '; |
|
287
|
|
|
$this->data['scottish_text'] = ' or MSP'; |
|
288
|
|
|
} |
|
289
|
|
|
$mistakes['postcode_and'] = 1; |
|
290
|
|
|
} |
|
291
|
|
|
|
|
292
|
|
|
$this->data['mistakes'] = $mistakes; |
|
293
|
|
|
} |
|
294
|
|
|
|
|
295
|
|
|
private function formatSearchMemberData() { |
|
296
|
|
|
if ( isset($this->data['postcode']) ) { |
|
297
|
|
|
try { |
|
298
|
|
|
$postcode = $this->data['postcode']; |
|
299
|
|
|
|
|
300
|
|
|
$MEMBER = new \MEMBER( array('postcode' => $postcode) ); |
|
301
|
|
|
// move the postcode to the front just to be tidy |
|
302
|
|
|
$tidy_alertsearch = $postcode . " " . trim(str_replace("$postcode", "", $this->data['alertsearch'])); |
|
303
|
|
|
$alertsearch_display = str_replace("$postcode ", "", $tidy_alertsearch); |
|
304
|
|
|
|
|
305
|
|
|
$this->data['member_alertsearch'] = str_replace("$postcode", "speaker:" . $MEMBER->person_id, $tidy_alertsearch); |
|
306
|
|
|
$this->data['member_displaysearch'] = $alertsearch_display; |
|
307
|
|
|
$this->data['member'] = $MEMBER; |
|
308
|
|
|
|
|
309
|
|
|
if ( $this->data['scottish_text'] ) { |
|
310
|
|
|
$constituencies = \MySociety\TheyWorkForYou\Utility\Postcode::postcodeToConstituencies($postcode); |
|
311
|
|
|
if ( isset($constituencies['SPC']) ) { |
|
312
|
|
|
$MEMBER = new \MEMBER(array('constituency' => $constituencies['SPC'], 'house' => 4)); |
|
313
|
|
|
$this->data['scottish_alertsearch'] = str_replace("$postcode", "speaker:" . $MEMBER->person_id, $tidy_alertsearch); |
|
314
|
|
|
$this->data['scottish_member'] = $MEMBER; |
|
315
|
|
|
} |
|
316
|
|
|
} |
|
317
|
|
|
} catch ( \MySociety\TheyWorkForYou\MemberException $e ) { |
|
318
|
|
|
$this->data['member_error'] = 1; |
|
319
|
|
|
} |
|
320
|
|
|
} |
|
321
|
|
|
|
|
322
|
|
|
if ( $this->data['pid'] ) { |
|
323
|
|
|
$MEMBER = new \MEMBER( array('person_id' => $this->data['pid']) ); |
|
324
|
|
|
$this->data['pid_member'] = $MEMBER; |
|
325
|
|
|
} |
|
326
|
|
|
|
|
327
|
|
|
if ( $this->data['keyword'] ) { |
|
328
|
|
|
$this->data['display_keyword'] = $this->prettifyCriteria($this->data['keyword']); |
|
329
|
|
|
} |
|
330
|
|
|
} |
|
331
|
|
|
|
|
332
|
|
|
private function setUserData() { |
|
333
|
|
|
$this->data['current_mp'] = false; |
|
334
|
|
|
$this->data['alerts'] = array(); |
|
335
|
|
|
if ($this->data['email_verified']) { |
|
336
|
|
|
if ($this->user->postcode()) { |
|
337
|
|
|
$current_mp = new \MEMBER(array('postcode' => $this->user->postcode())); |
|
338
|
|
|
if (!$this->alert->fetch_by_mp($this->user->email(), $current_mp->person_id())) { |
|
339
|
|
|
$this->data['current_mp'] = $current_mp; |
|
340
|
|
|
} |
|
341
|
|
|
} |
|
342
|
|
|
$this->data['alerts'] = $this->getUsersAlerts(); |
|
343
|
|
|
} |
|
344
|
|
|
} |
|
345
|
|
|
|
|
346
|
|
|
private function getUsersAlerts() { |
|
347
|
|
|
$q = $this->db->query('SELECT * FROM alerts WHERE email = :email |
|
348
|
|
|
AND deleted != 1 ORDER BY created', array( |
|
349
|
|
|
':email' => $this->data['email'] |
|
350
|
|
|
)); |
|
351
|
|
|
|
|
352
|
|
|
$alerts = array(); |
|
353
|
|
|
$num_alerts = $q->rows(); |
|
354
|
|
|
for ($i = 0; $i < $num_alerts; $i++) { |
|
355
|
|
|
$row = $q->row($i); |
|
356
|
|
|
$criteria = $this->prettifyCriteria($row['criteria']); |
|
357
|
|
|
$token = $row['alert_id'] . '-' . $row['registrationtoken']; |
|
358
|
|
|
|
|
359
|
|
|
$status = 'confirmed'; |
|
360
|
|
|
if ( !$row['confirmed'] ) { |
|
361
|
|
|
$status = 'unconfirmed'; |
|
362
|
|
|
} elseif ( $row['deleted'] == 2 ) { |
|
363
|
|
|
$status = 'suspended'; |
|
364
|
|
|
} |
|
365
|
|
|
|
|
366
|
|
|
$alerts[] = array( |
|
367
|
|
|
'token' => $token, |
|
368
|
|
|
'status' => $status, |
|
369
|
|
|
'criteria' => $criteria, |
|
370
|
|
|
'raw' => $row['criteria'] |
|
371
|
|
|
); |
|
372
|
|
|
} |
|
373
|
|
|
|
|
374
|
|
|
return $alerts; |
|
375
|
|
|
} |
|
376
|
|
|
|
|
377
|
|
|
} |
|
378
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.