Failed Conditions
Pull Request — master (#1851)
by Struan
04:38
created

Standard::checkForCommonMistakes()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 10
c 0
b 0
f 0
nc 4
nop 0
dl 0
loc 16
rs 9.6111
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
    public function display() {
20
        global $this_page;
21
        $this_page = "alert";
22
23
        $this->processAction();
24
        $this->getBasicData();
25
        $this->checkInput();
26
        $this->searchForConstituenciesAndMembers();
27
28
        if ($this->data['step'] || $this->data['addword']) {
29
            $this->processStep();
30
        } elseif (!$this->data['results'] == 'changes-abandoned' && !sizeof($this->data['errors']) && $this->data['submitted'] && ($this->data['keyword'] || $this->data['pid'])) {
31
            $this->addAlert();
32
        }
33
34
        $this->formatSearchTerms();
35
        $this->checkForCommonMistakes();
36
        $this->formatSearchMemberData();
37
        $this->setUserData();
38
39
        return $this->data;
40
    }
41
42
    # This only happens if we have an alert and want to do something to it.
43
    private function processAction() {
44
        $token = get_http_var('t');
45
        $alert = $this->alert->check_token($token);
46
47
        $this->data['results'] = false;
48
        if ($action = get_http_var('action')) {
49
            $success = true;
50
            if ($action == 'Confirm') {
51
                $success = $this->confirmAlert($token);
52
                if ($success) {
53
                    $this->data['results'] = 'alert-confirmed';
54
                    $this->data['criteria'] = $this->alert->criteria;
55
                    $this->data['display_criteria'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($this->alert->criteria, $this->alert->ignore_speaker_votes);
56
                }
57
            } elseif ($action == 'Suspend') {
58
                $success = $this->suspendAlert($token);
59
                if ($success) {
60
                    $this->data['results'] = 'alert-suspended';
61
                }
62
            } elseif ($action == 'Resume') {
63
                $success = $this->resumeAlert($token);
64
                if ($success) {
65
                    $this->data['results'] = 'alert-resumed';
66
                }
67
            } elseif ($action == 'Delete') {
68
                $success = $this->deleteAlert($token);
69
                if ($success) {
70
                    $this->data['results'] = 'alert-deleted';
71
                }
72
            } elseif ($action == 'Delete All') {
73
                $success = $this->deleteAllAlerts($token);
74
                if ($success) {
75
                    $this->data['results'] = 'all-alerts-deleted';
76
                }
77
            } elseif ($action == 'Abandon') {
78
                $this->data['results'] = 'changes-abandoned';
79
            }
80
            if (!$success) {
81
                $this->data['results'] = 'alert-fail';
82
            }
83
        }
84
85
        $this->data['alert'] = $alert;
86
    }
87
88
    # Process a screen in the alert creation wizard
89
    private function processStep() {
90
        # fetch a list of suggested terms. Need this for the define screen so we can filter out the suggested terms
91
        # and not show them if the user goes back
92
        if (($this->data['step'] == 'review' || $this->data['step'] == 'define') && !$this->data['shown_related']) {
93
            $suggestions = [];
94
            foreach ($this->data['keywords'] as $word) {
95
                $terms = $this->alert->get_related_terms($word);
96
                $terms = array_diff($terms, $this->data['keywords']);
97
                if ($terms && count($terms)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $terms of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
98
                    $suggestions = array_merge($suggestions, $terms);
99
                }
100
            }
101
102
            if (count($suggestions) > 0) {
103
                $this->data['step'] = 'add_vector_related';
104
                $this->data['suggestions'] = $suggestions;
105
            }
106
            # confirm the alert. Handles both creating and editing alerts
107
        } elseif ($this->data['step'] == 'confirm') {
108
            $success = true;
109
            # if there's already an alert assume we are editing it and user must be logged in
110
            if ($this->data['alert']) {
111
                $success = $this->updateAlert($this->data['alert']['id'], $this->data);
0 ignored issues
show
Unused Code introduced by
The call to MySociety\TheyWorkForYou...Standard::updateAlert() has too many arguments starting with $this->data. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

111
                /** @scrutinizer ignore-call */ 
112
                $success = $this->updateAlert($this->data['alert']['id'], $this->data);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
112
                if ($success) {
113
                    # reset all the data to stop anything getting confused
114
                    $this->data['results'] = 'alert-confirmed';
115
                    $this->data['step'] = '';
116
                    $this->data['pid'] = '';
117
                    $this->data['alertsearch'] = '';
118
                    $this->data['pc'] = '';
119
                    $this->data['members'] = false;
120
                    $this->data['constituencies'] = [];
121
                } else {
122
                    $this->data['results'] = 'alert-fail';
123
                    $this->data['step'] = 'review';
124
                }
125
            } else {
126
                $success = $this->addAlert();
0 ignored issues
show
Unused Code introduced by
The assignment to $success is dead and can be removed.
Loading history...
Bug introduced by
Are you sure the assignment to $success is correct as $this->addAlert() targeting MySociety\TheyWorkForYou...ew\Standard::addAlert() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
127
                $this->data['step'] = '';
128
            }
129
        }
130
    }
131
132
133
    private function getBasicData() {
134
        global $this_page;
135
136
        if ($this->user->loggedin()) {
137
            $this->data['email'] = $this->user->email();
138
            $this->data['email_verified'] = true;
139
        } elseif ($this->data['alert']) {
140
            $this->data['email'] = $this->data['alert']['email'];
141
            $this->data['email_verified'] = true;
142
        } else {
143
            $this->data["email"] = trim(get_http_var("email"));
144
            $this->data['email_verified'] = false;
145
        }
146
147
        $this->data['token'] = get_http_var('t');
148
        $this->data['step'] = trim(get_http_var("step"));
149
        $this->data['mp_step'] = trim(get_http_var("mp_step"));
150
        $this->data['addword'] = trim(get_http_var("addword"));
151
        $this->data['this_step'] = trim(get_http_var("this_step"));
152
        $this->data['shown_related'] = get_http_var('shown_related');
153
        $this->data['match_all'] = get_http_var('match_all') == 'on';
154
        $this->data['keyword'] = trim(get_http_var("keyword"));
155
        $this->data['search_section'] = '';
156
        $this->data['alertsearch'] = trim(get_http_var("alertsearch"));
157
        $this->data['mp_search'] = trim(get_http_var("mp_search"));
158
        $this->data['pid'] = trim(get_http_var("pid"));
159
        $this->data['pc'] = get_http_var('pc');
160
        $this->data['submitted'] = get_http_var('submitted') || $this->data['pid'] || $this->data['keyword'] || $this->data['step'];
161
        $this->data['ignore_speaker_votes'] = get_http_var('ignore_speaker_votes');
162
163
        if ($this->data['addword'] || $this->data['step']) {
164
            $alert = $this->alert->check_token($this->data['token']);
165
166
            $criteria = '';
167
            $alert_ignore_speaker_votes = 0;
168
            if ($alert) {
169
                $criteria = $alert['criteria'];
170
                $alert_ignore_speaker_votes = $alert['ignore_speaker_votes'];
171
            }
172
173
            $ignore_speaker_votes = get_http_var('ignore_speaker_votes', $alert_ignore_speaker_votes);
174
            $this->data['ignore_speaker_votes'] = ($ignore_speaker_votes == 'on' || $ignore_speaker_votes == 1);
175
176
            $this->data['alert'] = $alert;
177
178
            $this->data['alert_parts'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($criteria, $alert_ignore_speaker_votes, true);
179
180
            $existing_rep = '';
181
            if (isset($this->data['alert_parts']['spokenby'])) {
182
                $existing_rep = $this->data['alert_parts']['spokenby'][0];
183
            }
184
185
            $existing_section = '';
186
            if (count($this->data['alert_parts']['sections'])) {
187
                $existing_section = $this->data['alert_parts']['sections'][0];
188
            }
189
190
            if ($this->data['alert_parts']['match_all']) {
191
                $this->data['match_all'] = true;
192
            }
193
194
            $words = get_http_var('words', $this->data['alert_parts']['words'], true);
195
196
            $this->data['words'] = [];
197
            $this->data['keywords'] = [];
198
            foreach ($words as $word) {
199
                if (trim($word) != '') {
200
                    $this->data['keywords'][] = $word;
201
                    $this->data['words'][] = $this->wrap_phrase_in_quotes($word);
202
                }
203
            }
204
205
            $add_all_related = get_http_var('add_all_related');
206
            $this->data['add_all_related'] = $add_all_related;
207
            $this->data['skip_keyword_terms'] = [];
208
209
            $selected_related_terms = get_http_var('selected_related_terms', [], true);
210
            $this->data['selected_related_terms'] = $selected_related_terms;
211
212
            if ($this->data['step'] !== 'define') {
213
                if ($add_all_related) {
214
                    $this->data['selected_related_terms'] = [];
215
                    $related_terms = get_http_var('related_terms', [], true);
216
                    foreach ($related_terms as $term) {
217
                        $this->data['skip_keyword_terms'][] = $term;
218
                        $this->data['keywords'][] = $term;
219
                        $this->data['words'][] = $this->wrap_phrase_in_quotes($term);
220
                    }
221
                } else {
222
                    $this->data['skip_keyword_terms'] = $selected_related_terms;
223
                    foreach ($selected_related_terms as $term) {
224
                        $this->data['keywords'][] = $term;
225
                        $this->data['words'][] = $this->wrap_phrase_in_quotes($term);
226
                    }
227
                }
228
            }
229
            $this->data['exclusions'] = trim(get_http_var("exclusions", implode(' ', $this->data['alert_parts']['exclusions'])));
230
            $this->data['representative'] = trim(get_http_var("representative", $existing_rep));
231
232
            $this->data['search_section'] = trim(get_http_var("search_section", $existing_section));
233
234
            $separator = ' OR ';
235
            if ($this->data['match_all']) {
236
                $separator = ' ';
237
            }
238
            $this->data['keyword'] = implode($separator, $this->data['words']);
239
            if ($this->data['exclusions']) {
240
                $this->data['keyword'] = '(' . $this->data['keyword'] . ') -' . implode(' -', explode(' ', $this->data["exclusions"]));
241
            }
242
243
            $this->data['results'] = '';
244
245
            $this->getSearchSections();
246
        } elseif ($this->data['mp_step'] == 'mp_alert') {
247
            $alert = $this->alert->check_token($this->data['token']);
248
            if ($alert) {
249
                $ignore_speaker_votes = get_http_var('ignore_speaker_votes', $alert['ignore_speaker_votes']);
250
                $this->data['ignore_speaker_votes'] = ($ignore_speaker_votes == 'on' || $ignore_speaker_votes == 1);
251
252
                $existing_rep = '';
253
                if (isset($alert['criteria'])) {
254
                    $alert_parts = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($alert['criteria'], $alert['ignore_speaker_votes'], true);
255
                    $existing_rep = $alert_parts['spokenby'][0];
256
                    $this->data['pid'] = $alert_parts['pid'];
257
                }
258
                $this->data['keyword'] = get_http_var('mp_search', $existing_rep);
259
            } else {
260
                $this->data['ignore_speaker_votes'] = get_http_var('ignore_speaker_votes');
261
            }
262
        }
263
264
        $this->data['sign'] = get_http_var('sign');
265
        $this->data['site'] = get_http_var('site');
266
        $this->data['message'] = '';
267
268
        $ACTIONURL = new \MySociety\TheyWorkForYou\Url($this_page);
269
        $ACTIONURL->reset();
270
        $this->data['actionurl'] = $ACTIONURL->generate();
271
272
    }
273
274
    private function wrap_phrase_in_quotes($phrase) {
275
        if (strpos($phrase, ' ') > 0) {
276
            $phrase = '"' . trim($phrase, '"') . '"';
277
        }
278
279
        return $phrase;
280
    }
281
282
    private function getRecentResults($text) {
283
        global $SEARCHENGINE;
284
        $today = date_create();
285
        $one_week_ago = date_create('7 days ago');
286
        $restriction = date_format($one_week_ago, 'd/m/Y') . '..' . date_format($today, 'd/m/Y');
287
288
        $se = new \SEARCHENGINE($text . ' ' . $restriction);
289
        $this->data['search_result_count'] = $se->run_count(0, 10);
290
        $se = new \SEARCHENGINE($text);
291
        $count = $se->run_count(0, 10, 'date');
292
        if ($count > 0) {
293
            $se->run_search(0, 1, 'date');
294
            $gid = $se->get_gids()[0];
295
296
            $q = ['gid_to' => $gid];
297
            do {
298
                $gid = $q['gid_to'];
299
                $q = $this->db->query("SELECT gid_to FROM gidredirect WHERE gid_from = :gid", [':gid' => $gid])->first();
300
            } while ($q);
301
302
            $q = $this->db->query("SELECT hansard.gid, hansard.hdate
303
            FROM hansard
304
            WHERE hansard.gid = :gid", [':gid' => $gid])->first();
305
306
            $last_mention = date_create($q['hdate']);
307
            $this->data['lastmention'] = date_format($last_mention, 'd M Y'); //$se->get_gids()[0];
308
        }
309
    }
310
311
    private function getSearchSections() {
312
        $this->data['sections'] = [];
313
        if ($this->data['search_section']) {
314
            foreach (explode(' ', $this->data['search_section']) as $section) {
315
                $this->data['sections'][] = \MySociety\TheyWorkForYou\Utility\Alert::sectionToTitle($section);
316
            }
317
        }
318
    }
319
320
    private function updateAlert($token) {
321
        $success = $this->alert->update($token, $this->data);
322
        return $success;
323
    }
324
325
    private function checkInput() {
326
        global $SEARCHENGINE;
327
328
        $errors = [];
329
330
        # these are the initial screens and so cannot have any errors as we've not submitted
331
        if (!$this->data['submitted'] || $this->data['step'] == 'define' || $this->data['mp_step'] == 'mp_alert') {
332
            $this->data['errors'] = $errors;
333
            return;
334
        }
335
336
        // Check each of the things the user has input.
337
        // If there is a problem with any of them, set an entry in the $errors array.
338
        // This will then be used to (a) indicate there were errors and (b) display
339
        // error messages when we show the form again.
340
341
        // Check email address is valid and unique.
342
        if (!$this->data['email']) {
343
            $errors["email"] = gettext("Please enter your email address");
344
        } elseif (!validate_email($this->data["email"])) {
345
            // validate_email() is in includes/utilities.php
346
            $errors["email"] = gettext("Please enter a valid email address");
347
        }
348
349
        if ($this->data['pid'] && !ctype_digit($this->data['pid'])) {
350
            $errors['pid'] = 'Invalid person ID passed';
351
        }
352
353
        $text = $this->data['alertsearch'];
354
        if ($this->data['mp_search']) {
355
            $text = $this->data['mp_search'];
356
        }
357
        if (!$text) {
358
            $text = $this->data['keyword'];
359
        }
360
361
        if ($this->data['submitted'] && !$this->data['pid'] && !$text) {
362
            $errors['alertsearch'] = gettext('Please enter what you want to be alerted about');
363
        }
364
365
        if (strpos($text, '..')) {
366
            $errors['alertsearch'] = gettext('You probably don&rsquo;t want a date range as part of your criteria, as you won&rsquo;t be alerted to anything new!');
367
        }
368
369
        $se = new \SEARCHENGINE($text);
370
        if (!$se->valid) {
371
            $errors['alertsearch'] = sprintf(gettext('That search appears to be invalid - %s - please check and try again.'), $se->error);
372
        }
373
374
        if (strlen($text) > 255) {
375
            $errors['alertsearch'] = gettext('That search is too long for our database; please split it up into multiple smaller alerts.');
376
        }
377
378
        $this->data['errors'] = $errors;
379
    }
380
381
    private function searchForConstituenciesAndMembers() {
382
        if ($this->data['results'] == 'changes-abandoned') {
383
            $this->data['members'] = false;
384
            return;
385
        }
386
387
        $text = $this->data['alertsearch'];
388
        if ($this->data['mp_search']) {
389
            $text = $this->data['mp_search'];
390
        }
391
        $errors = [];
392
        if ($text != '') {
393
            //$members_from_pids = array_values(\MySociety\TheyWorkForYou\Utility\Search::membersForIDs($this->data['alertsearch']));
394
            $members_from_names = [];
395
            $names_from_pids = array_values(\MySociety\TheyWorkForYou\Utility\Search::speakerNamesForIDs($text));
396
            foreach ($names_from_pids as $name) {
397
                $members_from_names = array_merge($members_from_names, \MySociety\TheyWorkForYou\Utility\Search::searchMemberDbLookupWithNames($name));
398
            }
399
            $members_from_words = \MySociety\TheyWorkForYou\Utility\Search::searchMemberDbLookupWithNames($text, true);
400
            $this->data['members'] = array_merge($members_from_words, $members_from_names);
401
            [$this->data['constituencies'], $this->data['valid_postcode']] = \MySociety\TheyWorkForYou\Utility\Search::searchConstituenciesByQuery($text, false);
402
        } elseif ($this->data['pid']) {
403
            $MEMBER = new \MEMBER(['person_id' => $this->data['pid']]);
404
            $this->data['members'] = [[
405
                "person_id" => $MEMBER->person_id,
406
                "given_name" => $MEMBER->given_name,
407
                "family_name" => $MEMBER->family_name,
408
                "house" => $MEMBER->house_disp,
409
                "title" => $MEMBER->title,
410
                "lordofname" => $MEMBER->lordofname,
411
                "constituency" => $MEMBER->constituency,
412
            ]];
413
        } elseif (isset($this->data['representative']) && $this->data['representative'] != '') {
414
            $this->data['members'] = \MySociety\TheyWorkForYou\Utility\Search::searchMemberDbLookupWithNames($this->data['representative'], true);
415
416
            $member_count = count($this->data['members']);
417
            if ($member_count == 0) {
418
                $errors["representative"] = gettext("No matching representative found");
419
            } elseif ($member_count > 1) {
420
                $errors["representative"] = gettext("Multiple matching representatives found, please select one.");
421
            } else {
422
                $this->data['pid'] = $this->data['members'][0]['person_id'];
423
            }
424
        } else {
425
            $this->data['members'] = [];
426
        }
427
428
        # If the above search returned one result for constituency
429
        # search by postcode, use it immediately
430
        if (isset($this->data['constituencies']) && count($this->data['constituencies']) == 1 && $this->data['valid_postcode']) {
431
            $MEMBER = new \MEMBER(['constituency' => array_values($this->data['constituencies'])[0], 'house' => 1]);
432
            $this->data['pid'] = $MEMBER->person_id();
433
            $this->data['pc'] = $text;
434
            unset($this->data['constituencies']);
435
        }
436
437
        if (isset($this->data['constituencies'])) {
438
            $cons = [];
439
            foreach ($this->data['constituencies'] as $constituency) {
440
                try {
441
                    $MEMBER = new \MEMBER(['constituency' => $constituency]);
442
                    $cons[$constituency] = $MEMBER;
443
                } catch (\MySociety\TheyWorkForYou\MemberException $e) {
444
                    // do nothing
445
                }
446
            }
447
            $this->data['constituencies'] = $cons;
448
            if (count($cons) == 1) {
449
                $cons = array_values($cons);
450
                $this->data['pid'] = $cons[0]->person_id();
451
            }
452
        }
453
454
        if ($this->data['alertsearch'] && !$this->data['mp_step'] && ($this->data['pid'] || $this->data['members'] || $this->data['constituencies'])) {
455
            if (count($this->data['members']) == 1) {
456
                $this->data['pid'] = $this->data['members'][0]['person_id'];
457
            }
458
            $this->data['mp_step'] = 'mp_alert';
459
            $this->data['mp_search'] = $this->data['alertsearch'];
460
            $this->data['alertsearch'] = '';
461
        }
462
463
        if (count($this->data["errors"]) > 0) {
464
            $this->data["errors"] = array_merge($this->data["errors"], $errors);
465
        } else {
466
            $this->data["errors"] = $errors;
467
        }
468
    }
469
470
    private function addAlert() {
471
        $external_auth = auth_verify_with_shared_secret($this->data['email'], OPTION_AUTH_SHARED_SECRET, get_http_var('sign'));
472
        if ($external_auth) {
473
            $confirm = false;
474
        } elseif ($this->data['email_verified']) {
475
            $confirm = false;
476
        } else {
477
            $confirm = true;
478
        }
479
480
        // If this goes well, the alert will be added to the database and a confirmation email
481
        // will be sent to them.
482
        $success = $this->alert->add($this->data, $confirm);
483
484
        if ($success > 0 && !$confirm) {
485
            $this->data['step'] = '';
486
            $this->data['mp_step'] = '';
487
            $result = 'alert-added';
488
        } elseif ($success > 0) {
489
            $this->data['step'] = '';
490
            $this->data['mp_step'] = '';
491
            $result = 'alert-confirmation';
492
        } elseif ($success == -2) {
493
            // we need to make sure we know that the person attempting to sign up
494
            // for the alert has that email address to stop people trying to work
495
            // out what alerts they are signed up to
496
            if ($this->data['email_verified'] || ($this->user->loggedin && $this->user->email() == $this->data['email'])) {
497
                $result = 'alert-exists';
498
            } else {
499
                // don't throw an error message as that implies that they have already signed
500
                // up for the alert but instead pretend all is normal but send an email saying
501
                // that someone tried to sign them up for an existing alert
502
                $result = 'alert-already-signed';
503
                $this->alert->send_already_signedup_email($this->data);
504
            }
505
        } else {
506
            $result = 'alert-fail';
507
        }
508
509
        // don't need these anymore so get rid of them
510
        $this->data['keyword'] = '';
511
        $this->data['pid'] = '';
512
        $this->data['alertsearch'] = '';
513
        $this->data['pc'] = '';
514
515
        $this->data['results'] = $result;
516
        $this->data['criteria'] = $this->alert->criteria;
517
        $this->data['display_criteria'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($this->alert->criteria, $this->alert->ignore_speaker_votes);
518
    }
519
520
521
    private function formatSearchTerms() {
522
        if ($this->data['alertsearch']) {
523
            $this->data['alertsearch_pretty'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($this->data['alertsearch']);
524
            $this->data['search_text'] = $this->data['alertsearch'];
525
        } else {
526
            $this->data['search_text'] = $this->data['keyword'];
527
        }
528
    }
529
530
    private function checkForCommonMistakes() {
531
        $mistakes = [];
532
        if (strstr($this->data['alertsearch'], ',') > -1) {
533
            $mistakes['multiple'] = 1;
534
        }
535
536
        if (
537
            preg_match('#([A-Z]{1,2}\d+[A-Z]? ?\d[A-Z]{2})#i', $this->data['alertsearch'], $m) &&
538
            strlen($this->data['alertsearch']) > strlen($m[1]) &&
539
            validate_postcode($m[1])
540
        ) {
541
            $this->data['postcode'] = $m[1];
542
            $mistakes['postcode_and'] = 1;
543
        }
544
545
        $this->data['mistakes'] = $mistakes;
546
    }
547
548
    private function formatSearchMemberData() {
549
        if (isset($this->data['postcode'])) {
550
            try {
551
                $postcode = $this->data['postcode'];
552
553
                $MEMBER = new \MEMBER(['postcode' => $postcode]);
554
                // move the postcode to the front just to be tidy
555
                $tidy_alertsearch = $postcode . " " . trim(str_replace("$postcode", "", $this->data['alertsearch']));
556
                $alertsearch_display = str_replace("$postcode ", "", $tidy_alertsearch);
557
558
                $this->data['member_alertsearch'] = str_replace("$postcode", "speaker:" . $MEMBER->person_id, $tidy_alertsearch);
559
                $this->data['member_displaysearch'] = $alertsearch_display;
560
                $this->data['member'] = $MEMBER;
561
562
                if (isset($this->data['mistakes']['postcode_and'])) {
563
                    $constituencies = \MySociety\TheyWorkForYou\Utility\Postcode::postcodeToConstituencies($postcode);
564
                    if (isset($constituencies['SPC'])) {
565
                        $MEMBER = new \MEMBER(['constituency' => $constituencies['SPC'], 'house' => HOUSE_TYPE_SCOTLAND]);
566
                        $this->data['scottish_alertsearch'] = str_replace("$postcode", "speaker:" . $MEMBER->person_id, $tidy_alertsearch);
567
                        $this->data['scottish_member'] = $MEMBER;
568
                    } elseif (isset($constituencies['WAC'])) {
569
                        $MEMBER = new \MEMBER(['constituency' => $constituencies['WAC'], 'house' => HOUSE_TYPE_WALES]);
570
                        $this->data['welsh_alertsearch'] = str_replace("$postcode", "speaker:" . $MEMBER->person_id, $tidy_alertsearch);
571
                        $this->data['welsh_member'] = $MEMBER;
572
                    }
573
                }
574
            } catch (\MySociety\TheyWorkForYou\MemberException $e) {
575
                $this->data['member_error'] = 1;
576
            }
577
        }
578
579
        if ($this->data['pid']) {
580
            $MEMBER = new \MEMBER(['person_id' => $this->data['pid']]);
581
            $this->data['pid_member'] = $MEMBER;
582
        }
583
584
        if ($this->data['keyword']) {
585
            $this->data['display_keyword'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($this->data['keyword']);
586
        }
587
    }
588
589
    private function setUserData() {
590
        if (!isset($this->data['criteria'])) {
591
            $criteria = $this->data['keyword'];
592
            if ($criteria) {
593
                if (!$this->data['match_all']) {
594
                    $has_or = strpos($criteria, ' OR ') !== false;
595
                    $missing_braces = strpos($criteria, '(') === false;
596
597
                    if ($has_or && $missing_braces) {
598
                        $criteria = "($criteria)";
599
                    }
600
                }
601
                if ($this->data['search_section']) {
602
                    $criteria .= " section:" . $this->data['search_section'];
603
                }
604
                if ($this->data['pid']) {
605
                    $criteria .= " speaker:" . $this->data['pid'];
606
                }
607
                $this->getRecentResults($criteria);
608
            }
609
610
            $this->data['criteria'] = $criteria;
611
            $this->data['display_criteria'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($criteria);
612
        }
613
        if ($this->data['results'] == 'changes-abandoned') {
614
            $this->data['members'] = false;
615
            $this->data['alertsearch'] = '';
616
        }
617
618
        if ($this->data['alertsearch'] && !(isset($this->data['mistakes']['postcode_and']) || $this->data['members'] || $this->data['pid'])) {
619
            $this->data['step'] = 'define';
620
            $this->data['words'] = [$this->data['alertsearch']];
621
            $this->data['keywords'] = [$this->data['alertsearch']];
622
            $this->data['exclusions'] = '';
623
            $this->data['representative'] = '';
624
        } elseif ($this->data['alertsearch'] && ($this->data['members'] || $this->data['pid'])) {
625
            $this->data['mp_step'] = 'mp_alert';
626
            $this->data['mp_search'] = [$this->data['alertsearch']];
627
        } elseif ($this->data['members'] && $this->data['mp_step'] == 'mp_search') {
628
            $this->data['mp_step'] = '';
629
        }
630
631
        $this->data['current_mp'] = false;
632
        $this->data['alerts'] = [];
633
        $this->data['keyword_alerts'] = [];
634
        $this->data['speaker_alerts'] = [];
635
        $this->data['spoken_alerts'] = [];
636
        $this->data['own_member_alerts'] = [];
637
        $this->data['all_keywords'] = [];
638
        $this->data['own_mp_criteria'] = '';
639
        $own_mp_criteria = '';
640
641
        if ($this->data['email_verified']) {
642
            if ($this->user->postcode()) {
643
                $current_mp = new \MEMBER(['postcode' => $this->user->postcode()]);
644
                if ($current_mp_alert = !$this->alert->fetch_by_mp($this->data['email'], $current_mp->person_id())) {
0 ignored issues
show
Unused Code introduced by
The assignment to $current_mp_alert is dead and can be removed.
Loading history...
645
                    $this->data['current_mp'] = $current_mp;
646
                    $own_mp_criteria = sprintf('speaker:%s', $current_mp->person_id());
0 ignored issues
show
Unused Code introduced by
The assignment to $own_mp_criteria is dead and can be removed.
Loading history...
647
                }
648
                $own_mp_criteria = $current_mp->full_name();
649
                $this->data['own_mp_criteria'] = $own_mp_criteria;
650
            }
651
            $this->data['alerts'] = \MySociety\TheyWorkForYou\Utility\Alert::forUser($this->data['email']);
652
            foreach ($this->data['alerts'] as $alert) {
653
                if (array_key_exists('spokenby', $alert) and sizeof($alert['spokenby']) == 1 and $alert['spokenby'][0] == $own_mp_criteria) {
654
                    $this->data['own_member_alerts'][] = $alert;
655
                } elseif (array_key_exists('spokenby', $alert)) {
656
                    if (!array_key_exists($alert['spokenby'][0], $this->data['spoken_alerts'])) {
657
                        $this->data['spoken_alerts'][$alert['spokenby'][0]] = [];
658
                    }
659
                    $this->data['spoken_alerts'][$alert['spokenby'][0]][] = $alert;
660
                }
661
            }
662
            foreach ($this->data['alerts'] as $alert) {
663
                $term = implode(' ', $alert['words']);
664
                $add = true;
665
                if (array_key_exists('spokenby', $alert)) {
666
                    $add = false;
667
                } elseif (array_key_exists($term, $this->data['spoken_alerts'])) {
668
                    $add = false;
669
                    $this->data['all_keywords'][] = $term;
670
                    $this->data['spoken_alerts'][$term][] = $alert;
671
                } elseif ($term == $own_mp_criteria) {
672
                    $add = false;
673
                    $this->data['all_keywords'][] = $term;
674
                    $this->data['own_member_alerts'][] = $alert;
675
                } elseif (\MySociety\TheyWorkForYou\Utility\Search::searchMemberDbLookupWithNames($term, true)) {
676
                    if (!array_key_exists($term, $this->data['spoken_alerts'])) {
677
                        $this->data['spoken_alerts'][$term] = [];
678
                    }
679
                    $add = false;
680
                    # need to add this to make it consistent so the front end know where to get the name
681
                    $alert['spokenby'] = [$term];
682
                    $this->data['all_keywords'][] = $term;
683
                    $this->data['spoken_alerts'][$term][] = $alert;
684
                }
685
                if ($add) {
686
                    $this->data['all_keywords'][] = $term;
687
                    $this->data['keyword_alerts'][] = $alert;
688
                }
689
            }
690
        } else {
691
            if ($this->data['alertsearch'] && $this->data['pc']) {
692
                $this->data['mp_step'] = 'mp_alert';
693
            }
694
        }
695
        if (count($this->data['alerts'])) {
696
            $this->data['delete_token'] = $this->data['alerts'][0]['token'];
697
        }
698
        if ($this->data['addword'] != '' || ($this->data['step'] && count($this->data['errors']) > 0)) {
699
            $this->data["step"] = get_http_var('this_step');
700
        } else {
701
            $this->data['this_step'] = '';
702
        }
703
704
        $this->data["search_term"] = $this->data['alertsearch'];
705
        if ($this->data['mp_search']) {
706
            $this->data["search_term"] = $this->data['mp_search'];
707
        }
708
    }
709
}
710