Standard::checkForCommonMistakes()   A
last analyzed

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 (!sizeof($this->data['errors']) && ($this->data['keyword'] || $this->data['pid'])) {
29
            $this->addAlert();
30
        }
31
32
        $this->formatSearchTerms();
33
        $this->checkForCommonMistakes();
34
        $this->formatSearchMemberData();
35
        $this->setUserData();
36
37
        return $this->data;
38
    }
39
40
    private function processAction() {
41
        $token = get_http_var('t');
42
        $alert = $this->alert->check_token($token);
43
44
        $this->data['results'] = false;
45
        if ($action = get_http_var('action')) {
46
            $success = true;
47
            if ($action == 'Confirm') {
48
                $success = $this->confirmAlert($token);
49
                if ($success) {
50
                    $this->data['results'] = 'alert-confirmed';
51
                    $this->data['criteria'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($this->alert->criteria);
52
                }
53
            } elseif ($action == 'Suspend') {
54
                $success = $this->suspendAlert($token);
55
                if ($success) {
56
                    $this->data['results'] = 'alert-suspended';
57
                }
58
            } elseif ($action == 'Resume') {
59
                $success = $this->resumeAlert($token);
60
                if ($success) {
61
                    $this->data['results'] = 'alert-resumed';
62
                }
63
            } elseif ($action == 'Delete') {
64
                $success = $this->deleteAlert($token);
65
                if ($success) {
66
                    $this->data['results'] = 'alert-deleted';
67
                }
68
            } elseif ($action == 'Delete All') {
69
                $success = $this->deleteAllAlerts($token);
70
                if ($success) {
71
                    $this->data['results'] = 'all-alerts-deleted';
72
                }
73
            }
74
            if (!$success) {
75
                $this->data['results'] = 'alert-fail';
76
            }
77
        }
78
79
        $this->data['alert'] = $alert;
80
    }
81
82
83
    private function getBasicData() {
84
        global $this_page;
85
86
        if ($this->user->loggedin()) {
87
            $this->data['email'] = $this->user->email();
88
            $this->data['email_verified'] = true;
89
        } elseif ($this->data['alert']) {
90
            $this->data['email'] = $this->data['alert']['email'];
91
            $this->data['email_verified'] = true;
92
        } else {
93
            $this->data["email"] = trim(get_http_var("email"));
94
            $this->data['email_verified'] = false;
95
        }
96
        $this->data['keyword'] = trim(get_http_var("keyword"));
97
        $this->data['pid'] = trim(get_http_var("pid"));
98
        $this->data['alertsearch'] = trim(get_http_var("alertsearch"));
99
        $this->data['pc'] = get_http_var('pc');
100
        $this->data['submitted'] = get_http_var('submitted') || $this->data['pid'] || $this->data['keyword'];
101
        $this->data['token'] = get_http_var('t');
102
        $this->data['sign'] = get_http_var('sign');
103
        $this->data['site'] = get_http_var('site');
104
        $this->data['message'] = '';
105
106
        $ACTIONURL = new \MySociety\TheyWorkForYou\Url($this_page);
107
        $ACTIONURL->reset();
108
        $this->data['actionurl'] = $ACTIONURL->generate();
109
    }
110
111
    private function checkInput() {
112
        global $SEARCHENGINE;
113
114
        $errors = [];
115
116
        // Check each of the things the user has input.
117
        // If there is a problem with any of them, set an entry in the $errors array.
118
        // This will then be used to (a) indicate there were errors and (b) display
119
        // error messages when we show the form again.
120
121
        // Check email address is valid and unique.
122
        if (!$this->data['email']) {
123
            $errors["email"] = gettext("Please enter your email address");
124
        } elseif (!validate_email($this->data["email"])) {
125
            // validate_email() is in includes/utilities.php
126
            $errors["email"] = gettext("Please enter a valid email address");
127
        }
128
129
        if ($this->data['pid'] && !ctype_digit($this->data['pid'])) {
130
            $errors['pid'] = 'Invalid person ID passed';
131
        }
132
133
        $text = $this->data['alertsearch'];
134
        if (!$text) {
135
            $text = $this->data['keyword'];
136
        }
137
138
        if ($this->data['submitted'] && !$this->data['pid'] && !$text) {
139
            $errors['alertsearch'] = gettext('Please enter what you want to be alerted about');
140
        }
141
142
        if (strpos($text, '..')) {
143
            $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!');
144
        }
145
146
        $se = new \SEARCHENGINE($text);
147
        if (!$se->valid) {
148
            $errors['alertsearch'] = sprintf(gettext('That search appears to be invalid - %s - please check and try again.'), $se->error);
149
        }
150
151
        if (strlen($text) > 255) {
152
            $errors['alertsearch'] = gettext('That search is too long for our database; please split it up into multiple smaller alerts.');
153
        }
154
155
        $this->data['errors'] = $errors;
156
    }
157
158
    private function searchForConstituenciesAndMembers() {
159
        // Do the search
160
        if ($this->data['alertsearch']) {
161
            $this->data['members'] = \MySociety\TheyWorkForYou\Utility\Search::searchMemberDbLookupWithNames($this->data['alertsearch'], true);
162
            [$this->data['constituencies'], $this->data['valid_postcode']] = \MySociety\TheyWorkForYou\Utility\Search::searchConstituenciesByQuery($this->data['alertsearch']);
163
        } else {
164
            $this->data['members'] = [];
165
        }
166
167
        # If the above search returned one result for constituency
168
        # search by postcode, use it immediately
169
        if (isset($this->data['constituencies']) && count($this->data['constituencies']) == 1 && $this->data['valid_postcode']) {
170
            $MEMBER = new \MEMBER(['constituency' => $this->data['constituencies'][0], 'house' => 1]);
171
            $this->data['pid'] = $MEMBER->person_id();
172
            $this->data['pc'] = $this->data['alertsearch'];
173
            unset($this->data['constituencies']);
174
            $this->data['alertsearch'] = '';
175
        }
176
177
        if (isset($this->data['constituencies'])) {
178
            $cons = [];
179
            foreach ($this->data['constituencies'] as $constituency) {
180
                try {
181
                    $MEMBER = new \MEMBER(['constituency' => $constituency, 'house' => 1]);
182
                    $cons[$constituency] = $MEMBER;
183
                } catch (\MySociety\TheyWorkForYou\MemberException $e) {
184
                    // do nothing
185
                }
186
            }
187
            $this->data['constituencies'] = $cons;
188
        }
189
    }
190
191
    private function addAlert() {
192
        $external_auth = auth_verify_with_shared_secret($this->data['email'], OPTION_AUTH_SHARED_SECRET, get_http_var('sign'));
193
        if ($external_auth) {
194
            $confirm = false;
195
        } elseif ($this->data['email_verified']) {
196
            $confirm = false;
197
        } else {
198
            $confirm = true;
199
        }
200
201
        // If this goes well, the alert will be added to the database and a confirmation email
202
        // will be sent to them.
203
        $success = $this->alert->add($this->data, $confirm);
204
205
        if ($success > 0 && !$confirm) {
206
            $result = 'alert-added';
207
        } elseif ($success > 0) {
208
            $result = 'alert-confirmation';
209
        } elseif ($success == -2) {
210
            // we need to make sure we know that the person attempting to sign up
211
            // for the alert has that email address to stop people trying to work
212
            // out what alerts they are signed up to
213
            if ($this->data['email_verified'] || ($this->user->loggedin && $this->user->email() == $this->data['email'])) {
214
                $result = 'alert-exists';
215
            } else {
216
                // don't throw an error message as that implies that they have already signed
217
                // up for the alert but instead pretend all is normal but send an email saying
218
                // that someone tried to sign them up for an existing alert
219
                $result = 'alert-already-signed';
220
                $this->alert->send_already_signedup_email($this->data);
221
            }
222
        } else {
223
            $result = 'alert-fail';
224
        }
225
226
        // don't need these anymore so get rid of them
227
        $this->data['keyword'] = '';
228
        $this->data['pid'] = '';
229
        $this->data['alertsearch'] = '';
230
        $this->data['pc'] = '';
231
232
        $this->data['results'] = $result;
233
        $this->data['criteria'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($this->alert->criteria);
234
    }
235
236
237
    private function formatSearchTerms() {
238
        if ($this->data['alertsearch']) {
239
            $this->data['alertsearch_pretty'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($this->data['alertsearch']);
240
            $this->data['search_text'] = $this->data['alertsearch'];
241
        } else {
242
            $this->data['search_text'] = $this->data['keyword'];
243
        }
244
    }
245
246
    private function checkForCommonMistakes() {
247
        $mistakes = [];
248
        if (strstr($this->data['alertsearch'], ',') > -1) {
249
            $mistakes['multiple'] = 1;
250
        }
251
252
        if (
253
            preg_match('#([A-Z]{1,2}\d+[A-Z]? ?\d[A-Z]{2})#i', $this->data['alertsearch'], $m) &&
254
            strlen($this->data['alertsearch']) > strlen($m[1]) &&
255
            validate_postcode($m[1])
256
        ) {
257
            $this->data['postcode'] = $m[1];
258
            $mistakes['postcode_and'] = 1;
259
        }
260
261
        $this->data['mistakes'] = $mistakes;
262
    }
263
264
    private function formatSearchMemberData() {
265
        if (isset($this->data['postcode'])) {
266
            try {
267
                $postcode = $this->data['postcode'];
268
269
                $MEMBER = new \MEMBER(['postcode' => $postcode]);
270
                // move the postcode to the front just to be tidy
271
                $tidy_alertsearch = $postcode . " " . trim(str_replace("$postcode", "", $this->data['alertsearch']));
272
                $alertsearch_display = str_replace("$postcode ", "", $tidy_alertsearch);
273
274
                $this->data['member_alertsearch'] = str_replace("$postcode", "speaker:" . $MEMBER->person_id, $tidy_alertsearch);
275
                $this->data['member_displaysearch'] = $alertsearch_display;
276
                $this->data['member'] = $MEMBER;
277
278
                if (isset($this->data['mistakes']['postcode_and'])) {
279
                    $constituencies = \MySociety\TheyWorkForYou\Utility\Postcode::postcodeToConstituencies($postcode);
280
                    if (isset($constituencies['SPC'])) {
281
                        $MEMBER = new \MEMBER(['constituency' => $constituencies['SPC'], 'house' => HOUSE_TYPE_SCOTLAND]);
282
                        $this->data['scottish_alertsearch'] = str_replace("$postcode", "speaker:" . $MEMBER->person_id, $tidy_alertsearch);
283
                        $this->data['scottish_member'] = $MEMBER;
284
                    } elseif (isset($constituencies['WAC'])) {
285
                        $MEMBER = new \MEMBER(['constituency' => $constituencies['WAC'], 'house' => HOUSE_TYPE_WALES]);
286
                        $this->data['welsh_alertsearch'] = str_replace("$postcode", "speaker:" . $MEMBER->person_id, $tidy_alertsearch);
287
                        $this->data['welsh_member'] = $MEMBER;
288
                    }
289
                }
290
            } catch (\MySociety\TheyWorkForYou\MemberException $e) {
291
                $this->data['member_error'] = 1;
292
            }
293
        }
294
295
        if ($this->data['pid']) {
296
            $MEMBER = new \MEMBER(['person_id' => $this->data['pid']]);
297
            $this->data['pid_member'] = $MEMBER;
298
        }
299
300
        if ($this->data['keyword']) {
301
            $this->data['display_keyword'] = \MySociety\TheyWorkForYou\Utility\Alert::prettifyCriteria($this->data['keyword']);
302
        }
303
    }
304
305
    private function setUserData() {
306
        $this->data['current_mp'] = false;
307
        $this->data['alerts'] = [];
308
        if ($this->data['email_verified']) {
309
            if ($this->user->postcode()) {
310
                $current_mp = new \MEMBER(['postcode' => $this->user->postcode()]);
311
                if (!$this->alert->fetch_by_mp($this->data['email'], $current_mp->person_id())) {
312
                    $this->data['current_mp'] = $current_mp;
313
                }
314
            }
315
            $this->data['alerts'] = \MySociety\TheyWorkForYou\Utility\Alert::forUser($this->data['email']);
316
        }
317
    }
318
}
319