1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
|
5
|
|
|
NO HTML IN THIS FILE!! |
6
|
|
|
|
7
|
|
|
This file contains USER and THEUSER classes. |
8
|
|
|
|
9
|
|
|
It automatically instantiates a $THEUSER global object. This refers to the person actually viewing the site. If they have a valid cookie set, $THEUSER's data will be fetched from the DB and they will be logged in. Otherwise they will have a minimum access level and will not be logged in. |
10
|
|
|
|
11
|
|
|
|
12
|
|
|
The USER class allows us to fetch and alter data about any user (rather than $THEUSER). |
13
|
|
|
|
14
|
|
|
To create a new user do: |
15
|
|
|
$USER = new USER; |
16
|
|
|
$USER->init($user_id); |
17
|
|
|
|
18
|
|
|
You can then access all the user's variables with appropriately named functions, such as: |
19
|
|
|
$USER->user_id(); |
20
|
|
|
$USER->email(); |
21
|
|
|
etc. Don't access the variables directly because I think that's bad. |
22
|
|
|
|
23
|
|
|
USER is extended into the THEUSER class which is used only for the person currently using the site. ie, it adds functions for logging in and out, checking log in status, etc. |
24
|
|
|
|
25
|
|
|
GUESTUSER: |
26
|
|
|
In the database there should be a user with an id of 0 and a status of 'Viewer' (and probably a name of 'Guest'). |
27
|
|
|
|
28
|
|
|
The cookie set to indicate a logged in user is called "epuser_id". More on that in THEUSER(). |
29
|
|
|
|
30
|
|
|
Functions here: |
31
|
|
|
|
32
|
|
|
USER |
33
|
|
|
init() Send it a user id to fetch data from DB. |
34
|
|
|
add() Add a new user to the DB. |
35
|
|
|
send_confirmation_email() Done after add()ing the user. |
36
|
|
|
update_other_user() Update the data of another user. |
37
|
|
|
change_password() Generate a new password and put in DB. |
38
|
|
|
id_exists() Checks if a user_id is valid. |
39
|
|
|
email_exists() Checks if a user exists with a certain email address. |
40
|
|
|
is_able_to() Is the user allowed to perform this action? |
41
|
|
|
possible_statuses() Return an array of the possible security statuses for users. |
42
|
|
|
Accessor functions for each object variable (eg, user_id() ). |
43
|
|
|
_update() Private function that updates a user's data in DB. |
44
|
|
|
|
45
|
|
|
THEUSER |
46
|
|
|
THEUSER() Constructor that logs in if the cookie is correct. |
47
|
|
|
isloggedin() Check if the user is logged in or not. |
48
|
|
|
isvalid() Check to see if the user's login form details are OK. |
49
|
|
|
login() Log the user in. |
50
|
|
|
logout() Log the user out. |
51
|
|
|
confirm() With the correct token, confirms the user then logs them in. |
52
|
|
|
update_self() Update the user's own data in the DB. |
53
|
|
|
check_user_access() Check a the user is allowed to view this page. |
54
|
|
|
|
55
|
|
|
*/ |
56
|
|
|
|
57
|
|
|
class USER { |
58
|
|
|
public $user_id = "0"; // So we have an ID for non-logged in users reporting comments etc. |
59
|
|
|
public $firstname = "Guest"; // So we have something to print for non-logged in users. |
60
|
|
|
public $lastname = ""; |
61
|
|
|
public $password = ""; // This will be a hashed version of a plaintext pw. |
62
|
|
|
public $email = ""; |
63
|
|
|
public $postcode = ""; |
64
|
|
|
public $url = ""; |
65
|
|
|
public $lastvisit = ""; // Last time the logged-in user loaded a page (GMT). |
66
|
|
|
public $registrationtime = ""; // When they registered (GMT). |
67
|
|
|
public $registrationip = ""; // Where they registered from. |
68
|
|
|
public $optin = ""; // Int containing multiple binary opt-ins. (See top of User.php) |
69
|
|
|
public $deleted = ""; // User can't log in or have their info displayed. |
70
|
|
|
public $confirmed = ''; // boolean - Has the user confirmed via email? |
71
|
|
|
public $facebook_id = ''; // Facebook ID for users who login with FB |
72
|
|
|
public $facebook_token = ''; // Facebook token for users who login with FB |
73
|
|
|
// Don't use the status to check access privileges - use the is_able_to() function. |
74
|
|
|
public $status = "Viewer"; |
75
|
|
|
|
76
|
|
|
// If you add more user variables above you should also: |
77
|
|
|
// Add the approrprate code to $this->add() |
78
|
|
|
// Add the appropriate code to $this->_update() |
79
|
|
|
// Add accessor functions way down below... |
80
|
|
|
// Alter THEUSER->update_self() to update with the new vars, if appropriate. |
81
|
|
|
// Change things in the add/edit/view user page. |
82
|
|
|
|
83
|
|
|
public function __construct() { |
84
|
1 |
|
$this->db = new ParlDB(); |
|
|
|
|
85
|
1 |
|
} |
86
|
1 |
|
|
87
|
|
|
public function init($user_id) { |
88
|
4 |
|
// Pass it a user id and it will fetch the user's data from the db |
89
|
|
|
// and put it all in the appropriate variables. |
90
|
|
|
// Returns true if we've found user_id in the DB, false otherwise. |
91
|
|
|
|
92
|
|
|
// Look for this user_id's details. |
93
|
|
|
$q = $this->db->query( |
94
|
4 |
|
"SELECT firstname, |
95
|
|
|
lastname, |
96
|
|
|
password, |
97
|
|
|
email, |
98
|
|
|
postcode, |
99
|
|
|
url, |
100
|
|
|
lastvisit, |
101
|
|
|
registrationtime, |
102
|
|
|
registrationtoken, |
103
|
|
|
registrationip, |
104
|
|
|
optin, |
105
|
|
|
status, |
106
|
|
|
deleted, |
107
|
|
|
confirmed, |
108
|
|
|
facebook_id, |
109
|
|
|
facebook_token |
110
|
|
|
FROM users |
111
|
|
|
WHERE user_id = :user_id", |
112
|
4 |
|
[':user_id' => $user_id] |
113
|
|
|
)->first(); |
114
|
|
|
|
115
|
4 |
|
|
116
|
|
|
if ($q) { |
117
|
|
|
// We've got a user, so set them up. |
118
|
4 |
|
|
119
|
4 |
|
$this->user_id = $user_id; |
120
|
4 |
|
$this->firstname = $q["firstname"]; |
121
|
4 |
|
$this->lastname = $q["lastname"]; |
122
|
4 |
|
$this->password = $q["password"]; |
123
|
4 |
|
$this->email = $q["email"]; |
124
|
4 |
|
$this->postcode = $q["postcode"]; |
125
|
4 |
|
$this->facebook_id = $q["facebook_id"]; |
126
|
4 |
|
$this->facebook_token = $q["facebook_token"]; |
127
|
4 |
|
$this->url = $q["url"]; |
128
|
4 |
|
$this->lastvisit = $q["lastvisit"]; |
129
|
4 |
|
$this->registrationtoken = $q['registrationtoken']; |
|
|
|
|
130
|
4 |
|
$this->registrationtime = $q["registrationtime"]; |
131
|
4 |
|
$this->registrationip = $q["registrationip"]; |
132
|
4 |
|
$this->optin = $q["optin"]; |
133
|
4 |
|
$this->status = $q["status"]; |
134
|
4 |
|
$this->deleted = $q["deleted"] == 1 ? true : false; |
135
|
|
|
$this->confirmed = $q["confirmed"] == 1 ? true : false; |
136
|
4 |
|
|
137
|
|
|
return true; |
138
|
|
|
|
139
|
|
|
} else { |
140
|
|
|
return false; |
141
|
|
|
twfy_debug("USER", "There is no user with an id of '" . _htmlentities($user_id) . "'"); |
|
|
|
|
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
} |
145
|
1 |
|
|
146
|
|
|
public function add($details, $confirmation_required = true) { |
147
|
|
|
// Adds a new user's info into the db. |
148
|
|
|
// Then optionally (and usually) calls another function to |
149
|
|
|
// send them a confirmation email. |
150
|
|
|
|
151
|
|
|
// $details is an associative array of all the user's details, of the form: |
152
|
|
|
// array ( |
153
|
|
|
// "firstname" => "Fred", |
154
|
|
|
// "lastname" => "Bloggs", |
155
|
|
|
// etc... using the same keys as the object variable names. |
156
|
|
|
// ) |
157
|
|
|
// The BOOL variables (eg, optin) will be true or false and will need to be |
158
|
1 |
|
// converted to 1/0 for MySQL. |
159
|
|
|
global $REMOTE_ADDR; |
160
|
1 |
|
|
161
|
|
|
$registrationtime = gmdate("YmdHis"); |
162
|
1 |
|
|
163
|
|
|
$passwordforDB = password_hash($details["password"], PASSWORD_BCRYPT); |
164
|
1 |
|
|
165
|
|
|
if (!isset($details["status"])) { |
166
|
|
|
$details["status"] = "User"; |
167
|
|
|
} |
168
|
1 |
|
|
169
|
1 |
|
if (!isset($details["facebook_id"])) { |
170
|
|
|
$details["facebook_id"] = ""; |
171
|
|
|
} |
172
|
1 |
|
|
173
|
|
|
$q = $this->db->query("INSERT INTO users ( |
174
|
|
|
firstname, |
175
|
|
|
lastname, |
176
|
|
|
email, |
177
|
|
|
postcode, |
178
|
|
|
url, |
179
|
|
|
password, |
180
|
|
|
optin, |
181
|
|
|
status, |
182
|
|
|
registrationtime, |
183
|
|
|
registrationip, |
184
|
|
|
facebook_id, |
185
|
|
|
deleted |
186
|
|
|
) VALUES ( |
187
|
|
|
:firstname, |
188
|
|
|
:lastname, |
189
|
|
|
:email, |
190
|
|
|
:postcode, |
191
|
|
|
:url, |
192
|
|
|
:password, |
193
|
|
|
:optin, |
194
|
|
|
:status, |
195
|
|
|
:registrationtime, |
196
|
|
|
:registrationip, |
197
|
|
|
:facebook_id, |
198
|
|
|
'0' |
199
|
|
|
) |
200
|
1 |
|
", [ |
201
|
1 |
|
':firstname' => $details["firstname"], |
202
|
1 |
|
':lastname' => $details["lastname"], |
203
|
1 |
|
':email' => $details["email"], |
204
|
1 |
|
':postcode' => $details["postcode"], |
205
|
1 |
|
':url' => $details["url"], |
206
|
1 |
|
':password' => $passwordforDB, |
207
|
1 |
|
':optin' => $details["optin"], |
208
|
1 |
|
':status' => $details["status"], |
209
|
1 |
|
':registrationtime' => $registrationtime, |
210
|
1 |
|
':facebook_id' => $details["facebook_id"], |
211
|
|
|
':registrationip' => $REMOTE_ADDR, |
212
|
|
|
]); |
213
|
1 |
|
|
214
|
|
|
if ($q->success()) { |
215
|
|
|
// Set these so we can log in. |
216
|
|
|
// Except we no longer automatically log new users in, we |
217
|
1 |
|
// send them an email. So this may not be required. |
218
|
1 |
|
$this->user_id = $q->insert_id(); |
219
|
1 |
|
$this->password = $passwordforDB; |
220
|
|
|
$this->facebook_id = $details["facebook_id"]; |
221
|
|
|
|
222
|
|
|
// We have to set the user's registration token. |
223
|
|
|
// This will be sent to them via email, so we can confirm they exist. |
224
|
|
|
// The token will be the first 16 characters of a hash. |
225
|
1 |
|
|
226
|
|
|
$token = substr(password_hash($details["email"] . microtime(), PASSWORD_BCRYPT), 29, 16); |
227
|
|
|
|
228
|
|
|
// Full stops don't work well at the end of URLs in emails, so |
229
|
|
|
// replace them. And double slash would be treated as single and |
230
|
|
|
// not work either. We won't be doing anything clever with the hash |
231
|
1 |
|
// stuff, just need to match this token. |
232
|
1 |
|
$token = strtr($token, './', 'Xx'); |
233
|
|
|
$this->registrationtoken = $token; |
|
|
|
|
234
|
|
|
|
235
|
1 |
|
// Add that to the DB. |
236
|
|
|
$r = $this->db->query("UPDATE users |
237
|
|
|
SET registrationtoken = :registrationtoken |
238
|
|
|
WHERE user_id = :user_id |
239
|
1 |
|
", [ |
240
|
1 |
|
':registrationtoken' => $this->registrationtoken, |
241
|
|
|
':user_id' => $this->user_id, |
242
|
|
|
]); |
243
|
1 |
|
|
244
|
|
|
if ($r->success()) { |
245
|
|
|
// Updated DB OK. |
246
|
1 |
|
|
247
|
|
|
if ($details['mp_alert'] && $details['postcode']) { |
248
|
|
|
$MEMBER = new MEMBER(['postcode' => $details['postcode'], 'house' => HOUSE_TYPE_COMMONS]); |
249
|
|
|
$pid = $MEMBER->person_id(); |
250
|
|
|
# No confirmation email, but don't automatically confirm |
251
|
|
|
$ALERT = new ALERT(); |
252
|
|
|
$ALERT->add([ |
253
|
|
|
'email' => $details['email'], |
254
|
|
|
'pid' => $pid, |
255
|
|
|
'pc' => $details['postcode'], |
256
|
|
|
], false, false); |
257
|
|
|
} |
258
|
1 |
|
|
259
|
|
|
if ($confirmation_required) { |
260
|
|
|
// Right, send the email... |
261
|
|
|
$success = $this->send_confirmation_email($details); |
262
|
|
|
|
263
|
|
|
if ($success) { |
264
|
|
|
// All is good in the world! |
265
|
|
|
return true; |
266
|
|
|
} else { |
267
|
|
|
// Couldn't send the email. |
268
|
|
|
return false; |
269
|
|
|
} |
270
|
|
|
} else { |
271
|
1 |
|
// No confirmation email needed. |
272
|
|
|
return true; |
273
|
|
|
} |
274
|
|
|
} else { |
275
|
|
|
// Couldn't add the registration token to the DB. |
276
|
|
|
return false; |
277
|
|
|
} |
278
|
|
|
|
279
|
|
|
} else { |
280
|
|
|
// Couldn't add the user's data to the DB. |
281
|
|
|
return false; |
282
|
|
|
} |
283
|
|
|
} |
284
|
|
|
|
285
|
|
|
public function add_facebook_id($facebook_id) { |
286
|
|
|
$q = $this->db->query( |
287
|
|
|
"UPDATE users SET facebook_id = :facebook_id WHERE email = :email", |
288
|
|
|
[ |
289
|
|
|
':facebook_id' => $facebook_id, |
290
|
|
|
':email' => $this->email, |
291
|
|
|
] |
292
|
|
|
); |
293
|
|
|
|
294
|
|
|
if ($q->success()) { |
295
|
|
|
$this->facebook_id = $facebook_id; |
296
|
|
|
|
297
|
|
|
return $facebook_id; |
298
|
|
|
} else { |
299
|
|
|
return false; |
300
|
|
|
} |
301
|
|
|
} |
302
|
|
|
|
303
|
|
|
public function send_email_confirmation_email($details) { |
304
|
|
|
// A brief check of the facts... |
305
|
|
|
if (!is_numeric($this->user_id) || |
306
|
|
|
!isset($details['email']) || |
307
|
|
|
$details['email'] == '' || |
308
|
|
|
!isset($details['token']) || |
309
|
|
|
$details['token'] == '') { |
310
|
|
|
return false; |
311
|
|
|
} |
312
|
|
|
|
313
|
|
|
// We prefix the registration token with the user's id and '-'. |
314
|
|
|
// Not for any particularly good reason, but we do. |
315
|
|
|
|
316
|
|
|
$urltoken = $this->user_id . '-' . $details['token']; |
317
|
|
|
|
318
|
|
|
$confirmurl = 'https://' . DOMAIN . '/E/' . $urltoken; |
319
|
|
|
|
320
|
|
|
// Arrays we need to send a templated email. |
321
|
|
|
$data = [ |
322
|
|
|
'to' => $details['email'], |
323
|
|
|
'template' => 'email_confirmation', |
324
|
|
|
]; |
325
|
|
|
|
326
|
|
|
$merge = [ |
327
|
|
|
'CONFIRMURL' => $confirmurl, |
328
|
|
|
]; |
329
|
|
|
|
330
|
|
|
$success = send_template_email($data, $merge); |
331
|
|
|
|
332
|
|
|
if ($success) { |
333
|
|
|
return true; |
334
|
|
|
} else { |
335
|
|
|
return false; |
336
|
|
|
} |
337
|
|
|
} |
338
|
|
|
|
339
|
|
|
public function send_confirmation_email($details) { |
340
|
|
|
// After we've add()ed a user we'll probably be sending them |
341
|
|
|
// a confirmation email with a link to confirm their address. |
342
|
|
|
|
343
|
|
|
// $details is the array we just sent to add(), and which it's |
344
|
|
|
// passed on to us here. |
345
|
|
|
|
346
|
|
|
// A brief check of the facts... |
347
|
|
|
if (!is_numeric($this->user_id) || |
348
|
|
|
!isset($details['email']) || |
349
|
|
|
$details['email'] == '') { |
350
|
|
|
return false; |
351
|
|
|
} |
352
|
|
|
|
353
|
|
|
// We prefix the registration token with the user's id and '-'. |
354
|
|
|
// Not for any particularly good reason, but we do. |
355
|
|
|
|
356
|
|
|
$urltoken = $this->user_id . '-' . $this->registrationtoken; |
357
|
|
|
|
358
|
|
|
$confirmurl = 'https://' . DOMAIN . '/U/' . $urltoken; |
359
|
|
|
if (isset($details['ret'])) { |
360
|
|
|
$confirmurl .= '?ret=' . $details['ret']; |
361
|
|
|
} |
362
|
|
|
|
363
|
|
|
// Arrays we need to send a templated email. |
364
|
|
|
$data = [ |
365
|
|
|
'to' => $details['email'], |
366
|
|
|
'template' => 'join_confirmation', |
367
|
|
|
]; |
368
|
|
|
|
369
|
|
|
$merge = [ |
370
|
|
|
'CONFIRMURL' => $confirmurl, |
371
|
|
|
]; |
372
|
|
|
|
373
|
|
|
$success = send_template_email($data, $merge); |
374
|
|
|
|
375
|
|
|
if ($success) { |
376
|
|
|
return true; |
377
|
|
|
} else { |
378
|
|
|
return false; |
379
|
|
|
} |
380
|
|
|
} |
381
|
|
|
|
382
|
|
|
|
383
|
|
|
public function update_other_user($details) { |
384
|
|
|
// If someone (like an admin) is updating another user, call this |
385
|
|
|
// function. It checks their privileges before letting them. |
386
|
|
|
|
387
|
|
|
// $details is an array like that in $this->add(). |
388
|
|
|
// It must include a 'user_id' element! |
389
|
|
|
|
390
|
|
|
global $THEUSER; |
391
|
|
|
|
392
|
|
|
if (!isset($details["user_id"])) { |
393
|
|
|
return false; |
394
|
|
|
|
395
|
|
|
} elseif ($THEUSER->is_able_to("edituser")) { |
396
|
|
|
|
397
|
|
|
// If the user doing the updating has appropriate privileges... |
398
|
|
|
|
399
|
|
|
$newdetails = $this->_update($details); |
400
|
|
|
|
401
|
|
|
// $newdetails will be an array of details if all went well, |
402
|
|
|
// false otherwise. |
403
|
|
|
if ($newdetails) { |
404
|
|
|
return true; |
405
|
|
|
} else { |
406
|
|
|
return false; |
407
|
|
|
} |
408
|
|
|
|
409
|
|
|
} else { |
410
|
|
|
return false; |
411
|
|
|
|
412
|
|
|
} |
413
|
|
|
} |
414
|
|
|
|
415
|
|
|
|
416
|
|
|
|
417
|
|
|
public function change_password($email) { |
418
|
|
|
|
419
|
|
|
// This function is called from the Change Password page. |
420
|
|
|
// It will create a new password for the user with $email address. |
421
|
|
|
// If all goes OK it will return the plaintext version of the password. |
422
|
|
|
// Otherwise it returns false. |
423
|
|
|
|
424
|
|
|
if ($this->email_exists($email)) { |
425
|
|
|
|
426
|
|
|
$this->email = $email; |
427
|
|
|
for (;;) { |
428
|
|
|
|
429
|
|
|
$pwd = null; |
430
|
|
|
$o = null; |
431
|
|
|
|
432
|
|
|
// Generates the password .... |
433
|
|
|
for ($x = 0; $x < 6;) { |
434
|
|
|
$y = rand(1, 1000); |
435
|
|
|
if($y > 350 && $y < 601) { |
436
|
|
|
$d = chr(rand(48, 57)); |
437
|
|
|
} |
438
|
|
|
if($y < 351) { |
439
|
|
|
$d = chr(rand(65, 90)); |
440
|
|
|
} |
441
|
|
|
if($y > 600) { |
442
|
|
|
$d = chr(rand(97, 122)); |
443
|
|
|
} |
444
|
|
|
if ($d != $o && !preg_match('#[O01lI]#', $d)) { |
|
|
|
|
445
|
|
|
$o = $d; |
446
|
|
|
$pwd .= $d; |
447
|
|
|
$x++; |
448
|
|
|
} |
449
|
|
|
} |
450
|
|
|
|
451
|
|
|
// If the PW fits your purpose (e.g. this regexpression) return it, else make a new one |
452
|
|
|
// (You can change this regular-expression how you want ....) |
453
|
|
|
if (preg_match("/^[a-zA-Z]{1}([a-zA-Z]+[0-9][a-zA-Z]+)+/", $pwd)) { |
|
|
|
|
454
|
|
|
break; |
455
|
|
|
} |
456
|
|
|
|
457
|
|
|
} |
458
|
|
|
$pwd = strtoupper($pwd); |
|
|
|
|
459
|
|
|
|
460
|
|
|
// End password generating stuff. |
461
|
|
|
|
462
|
|
|
} else { |
463
|
|
|
|
464
|
|
|
// Email didn't exist. |
465
|
|
|
return false; |
466
|
|
|
|
467
|
|
|
} |
468
|
|
|
|
469
|
|
|
$passwordforDB = password_hash($pwd, PASSWORD_BCRYPT); |
470
|
|
|
|
471
|
|
|
$q = $this->db->query( |
472
|
|
|
"UPDATE users SET password = :password WHERE email = :email", |
473
|
|
|
[ |
474
|
|
|
':password' => $passwordforDB, |
475
|
|
|
':email' => $email, |
476
|
|
|
] |
477
|
|
|
); |
478
|
|
|
|
479
|
|
|
if ($q->success()) { |
480
|
|
|
$this->password = $pwd; |
481
|
|
|
|
482
|
|
|
return $pwd; |
483
|
|
|
|
484
|
|
|
} else { |
485
|
|
|
return false; |
486
|
|
|
} |
487
|
|
|
|
488
|
|
|
} |
489
|
|
|
|
490
|
|
|
public function send_password_reminder() { |
491
|
|
|
global $PAGE; |
492
|
|
|
|
493
|
|
|
// You'll probably have just called $this->change_password(). |
494
|
|
|
|
495
|
|
|
if ($this->email() == '') { |
496
|
|
|
$PAGE->error_message("No email set for this user, so can't send a password reminder."); |
497
|
|
|
|
498
|
|
|
return false; |
499
|
|
|
} |
500
|
|
|
|
501
|
|
|
$data = [ |
502
|
|
|
'to' => $this->email(), |
503
|
|
|
'template' => 'new_password', |
504
|
|
|
]; |
505
|
|
|
|
506
|
|
|
$URL = new \MySociety\TheyWorkForYou\Url("userlogin"); |
507
|
|
|
|
508
|
|
|
$merge = [ |
509
|
|
|
'EMAIL' => $this->email(), |
510
|
|
|
'LOGINURL' => "https://" . DOMAIN . $URL->generate(), |
511
|
|
|
'PASSWORD' => $this->password(), |
512
|
|
|
]; |
513
|
|
|
|
514
|
|
|
// send_template_email in utility.php. |
515
|
|
|
$success = send_template_email($data, $merge); |
516
|
|
|
|
517
|
|
|
return $success; |
518
|
|
|
|
519
|
|
|
} |
520
|
|
|
|
521
|
|
|
|
522
|
|
|
|
523
|
|
|
|
524
|
|
|
public function id_exists($user_id) { |
525
|
|
|
// Returns true if there's a user with this user_id. |
526
|
|
|
|
527
|
|
|
if (is_numeric($user_id)) { |
528
|
|
|
$q = $this->db->query( |
529
|
1 |
|
"SELECT user_id FROM users WHERE user_id = :user_id", |
530
|
|
|
[':user_id' => $user_id] |
531
|
|
|
); |
532
|
1 |
|
if ($q->rows() > 0) { |
533
|
1 |
|
return true; |
534
|
1 |
|
} else { |
535
|
|
|
return false; |
536
|
|
|
} |
537
|
|
|
} else { |
538
|
|
|
return false; |
539
|
|
|
} |
540
|
1 |
|
|
541
|
|
|
} |
542
|
|
|
|
543
|
|
|
|
544
|
|
|
public function email_exists($email, $return_id = false) { |
545
|
|
|
// Returns true if there's a user with this email address. |
546
|
|
|
|
547
|
|
|
if ($email != "") { |
548
|
|
|
$q = $this->db->query("SELECT user_id FROM users WHERE email = :email", [':email' => $email])->first(); |
549
|
|
|
if ($q) { |
550
|
|
|
if ($return_id) { |
551
|
|
|
return $q['user_id']; |
552
|
|
|
} |
553
|
|
|
return true; |
554
|
|
|
} else { |
555
|
|
|
return false; |
556
|
|
|
} |
557
|
|
|
} else { |
558
|
|
|
return false; |
559
|
|
|
} |
560
|
|
|
} |
561
|
|
|
|
562
|
|
|
public function facebook_id_exists($id, $return_id = false) { |
563
|
|
|
// Returns true if there's a user with this facebook id. |
564
|
|
|
|
565
|
|
|
if ($id != "") { |
566
|
|
|
$q = $this->db->query("SELECT user_id FROM users WHERE facebook_id = :id", [':id' => $id])->first(); |
567
|
|
|
if ($q) { |
568
|
|
|
if ($return_id) { |
569
|
|
|
return $q['user_id']; |
570
|
|
|
} |
571
|
|
|
return true; |
572
|
|
|
} else { |
573
|
|
|
return false; |
574
|
|
|
} |
575
|
|
|
} else { |
576
|
|
|
return false; |
577
|
|
|
} |
578
|
|
|
} |
579
|
|
|
|
580
|
|
|
public function is_able_to($action) { |
581
|
|
|
// Call this function to find out if a user is allowed to do something. |
582
|
|
|
// It uses the user's status to return true or false. |
583
|
|
|
// Possible actions: |
584
|
|
|
// "addcomment" |
585
|
|
|
// "reportcomment" |
586
|
|
|
// "edituser" |
587
|
|
|
global $PAGE; |
588
|
|
|
|
589
|
|
|
$status = $this->status(); |
590
|
|
|
|
591
|
|
|
switch ($action) { |
592
|
|
|
|
593
|
|
|
// You can add more below as they're needed... |
594
|
|
|
// But keep them in alphabetical order! |
595
|
|
|
|
596
|
|
|
case "deletecomment": // Delete comments. |
597
|
|
|
|
598
|
|
|
switch ($status) { |
599
|
|
|
case "User": return false; |
600
|
|
|
case "Moderator": return true; |
601
|
|
|
case "Administrator": return true; |
602
|
|
|
case "Superuser": return true; |
603
|
|
|
default: /* Viewer */ return false; |
604
|
|
|
} |
605
|
|
|
|
606
|
|
|
// no break |
607
|
|
|
case "edituser": |
608
|
|
|
|
609
|
|
|
switch ($status) { |
610
|
|
|
case "User": return false; |
611
|
|
|
case "Moderator": return false; |
612
|
|
|
case "Administrator": return false; |
613
|
|
|
case "Superuser": return true; |
614
|
|
|
default: /* Viewer */ return false; |
615
|
|
|
} |
616
|
|
|
|
617
|
|
|
// no break |
618
|
|
|
case "reportcomment": // Report a comment for moderation. |
619
|
|
|
|
620
|
|
|
switch ($status) { |
621
|
|
|
case "User": return true; |
622
|
|
|
case "Moderator": return true; |
623
|
|
|
case "Administrator": return true; |
624
|
|
|
case "Superuser": return true; |
625
|
|
|
default: /* Viewer */ return true; |
626
|
|
|
} |
627
|
|
|
|
628
|
|
|
// no break |
629
|
|
|
case "viewadminsection": // Access pages in the Admin section. |
630
|
|
|
|
631
|
|
|
switch ($status) { |
632
|
|
|
case "User": return false; |
633
|
|
|
case "Moderator": return false; |
634
|
|
|
case "Administrator": return true; |
635
|
|
|
case "Superuser": return true; |
636
|
|
|
default: /* Viewer */ return false; |
637
|
|
|
} |
638
|
|
|
|
639
|
|
|
// no break |
640
|
|
|
case "voteonhansard": // Rate hansard things interesting/not. |
641
|
|
|
/* Everyone */ return true; |
642
|
|
|
|
643
|
|
|
default: |
644
|
|
|
$PAGE->error_message("You need to set permissions for '$action'!"); |
645
|
|
|
|
646
|
|
|
return false; |
647
|
|
|
|
648
|
|
|
|
649
|
|
|
} |
650
|
|
|
|
651
|
|
|
|
652
|
|
|
|
653
|
|
|
} |
654
|
|
|
|
655
|
|
|
// Same for every user... |
656
|
|
|
// Just returns an array of the possible statuses a user could have. |
657
|
|
|
// Handy for forms where you edit/view users etc. |
658
|
|
|
public function possible_statuses() { |
659
|
|
|
// Maybe there's a way of fetching these from the DB, |
660
|
|
|
// so we don't duplicate them here...? |
661
|
|
|
|
662
|
|
|
$statuses = ["Viewer", "User", "Moderator", "Administrator", "Superuser"]; |
663
|
|
|
|
664
|
|
|
return $statuses; |
665
|
|
|
|
666
|
|
|
} |
667
|
|
|
|
668
|
|
|
|
669
|
|
|
|
670
|
|
|
// Functions for accessing the user's variables. |
671
|
|
|
|
672
|
|
|
public function user_id() { |
673
|
|
|
return $this->user_id; |
674
|
|
|
} |
675
|
|
|
public function firstname() { |
676
|
|
|
return $this->firstname; |
677
|
40 |
|
} |
678
|
|
|
public function lastname() { |
679
|
|
|
return $this->lastname; |
680
|
40 |
|
} |
681
|
|
|
public function password() { |
682
|
|
|
return $this->password; |
683
|
40 |
|
} |
684
|
|
|
public function email() { |
685
|
|
|
return $this->email; |
686
|
|
|
} |
687
|
|
|
public function postcode() { |
688
|
|
|
return $this->postcode; |
689
|
|
|
} |
690
|
2 |
|
public function url() { |
691
|
|
|
return $this->url; |
692
|
|
|
} |
693
|
|
|
public function lastvisit() { |
694
|
|
|
return $this->lastvisit; |
695
|
|
|
} |
696
|
2 |
|
public function facebook_id() { |
697
|
|
|
return $this->facebook_id; |
698
|
|
|
} |
699
|
2 |
|
public function facebook_token() { |
700
|
1 |
|
return $this->facebook_token; |
701
|
|
|
} |
702
|
1 |
|
public function facebook_user() { |
703
|
1 |
|
return $this->facebook_user; |
704
|
|
|
} |
705
|
|
|
|
706
|
|
|
public function registrationtime() { |
707
|
|
|
return $this->registrationtime; |
708
|
|
|
} |
709
|
2 |
|
public function registrationip() { |
710
|
2 |
|
return $this->registrationip; |
711
|
2 |
|
} |
712
|
2 |
|
public function optin() { |
713
|
2 |
|
return $this->optin; |
714
|
|
|
} |
715
|
2 |
|
// Don't use the status to check access privileges - use the is_able_to() function. |
716
|
|
|
// But you might use status() to return text to display, describing a user. |
717
|
2 |
|
// We can then change what status() does in the future if our permissions system |
718
|
|
|
// changes. |
719
|
|
|
public function status() { |
720
|
|
|
return $this->status; |
721
|
|
|
} |
722
|
|
|
public function deleted() { |
723
|
|
|
return $this->deleted; |
724
|
|
|
} |
725
|
|
|
public function confirmed() { |
726
|
|
|
return $this->confirmed; |
727
|
|
|
} |
728
|
2 |
|
|
729
|
|
|
|
730
|
|
|
public function postcode_is_set() { |
731
|
|
|
// So we can tell if the, er, postcode is set or not. |
732
|
|
|
// Could maybe put some validation in here at some point. |
733
|
|
|
if ($this->postcode != '') { |
734
|
|
|
return true; |
735
|
|
|
} else { |
736
|
|
|
return false; |
737
|
|
|
} |
738
|
|
|
} |
739
|
|
|
|
740
|
|
|
|
741
|
2 |
|
/////////// PRIVATE FUNCTIONS BELOW... //////////////// |
742
|
|
|
|
743
|
|
|
public function _update($details) { |
744
|
|
|
// Update a user's info. |
745
|
|
|
// DO NOT call this function direct. |
746
|
|
|
// Call either $this->update_other_user() or $this->update_self(). |
747
|
|
|
|
748
|
|
|
// $details is an array like that in $this->add(). |
749
|
|
|
global $PAGE; |
750
|
|
|
|
751
|
|
|
// Update email alerts if email address changed |
752
|
|
|
if (isset($details['email']) && $this->email != $details['email']) { |
753
|
|
|
$this->db->query( |
754
|
2 |
|
'UPDATE alerts SET email = :details_email WHERE email = :email', |
755
|
|
|
[ |
756
|
|
|
':details_email' => $details['email'], |
757
|
|
|
':email' => $this->email, |
758
|
|
|
] |
759
|
|
|
); |
760
|
|
|
} |
761
|
|
|
|
762
|
2 |
|
// These are used to put optional fragments of SQL in, depending |
763
|
1 |
|
// on whether we're changing those things or not. |
764
|
1 |
|
$passwordsql = ""; |
765
|
|
|
$deletedsql = ""; |
766
|
|
|
$confirmedsql = ""; |
767
|
2 |
|
$statussql = ""; |
768
|
|
|
$emailsql = ''; |
769
|
|
|
|
770
|
|
|
$params = []; |
771
|
|
|
|
772
|
2 |
|
if (isset($details["password"]) && $details["password"] != "") { |
773
|
2 |
|
// The password is being updated. |
774
|
2 |
|
// If not, the password fields on the form will be left blank |
775
|
2 |
|
// so we don't want to overwrite the user's pw in the DB! |
776
|
2 |
|
|
777
|
|
|
$passwordforDB = password_hash($details["password"], PASSWORD_BCRYPT); |
778
|
|
|
|
779
|
2 |
|
$passwordsql = "password = :password, "; |
780
|
2 |
|
$params[':password'] = $passwordforDB; |
781
|
2 |
|
} |
782
|
2 |
|
|
783
|
2 |
|
if (isset($details["deleted"])) { |
784
|
2 |
|
// 'deleted' won't always be an option (ie, if the user is updating |
785
|
2 |
|
// their own info). |
786
|
|
|
if ($details['deleted'] == true) { |
787
|
|
|
$del = '1'; |
788
|
|
|
} elseif ($details['deleted'] == false) { |
789
|
|
|
$del = '0'; |
790
|
|
|
} |
791
|
2 |
|
if (isset($del)) { |
792
|
2 |
|
$deletedsql = "deleted = '$del', "; |
793
|
|
|
} |
794
|
|
|
} |
795
|
|
|
|
796
|
|
|
if (isset($details["confirmed"])) { |
797
|
|
|
// 'confirmed' won't always be an option (ie, if the user is updating |
798
|
|
|
// their own info). |
799
|
|
|
if ($details['confirmed'] == true) { |
800
|
|
|
$con = '1'; |
801
|
|
|
} elseif ($details['confirmed'] == false) { |
802
|
|
|
$con = '0'; |
803
|
|
|
} |
804
|
|
|
if (isset($con)) { |
805
|
|
|
$confirmedsql = "confirmed = '$con', "; |
806
|
|
|
} |
807
|
|
|
} |
808
|
|
|
|
809
|
|
|
if (isset($details["status"]) && $details["status"] != "") { |
810
|
|
|
// 'status' won't always be an option (ie, if the user is updating |
811
|
|
|
// their own info. |
812
|
|
|
$statussql = "status = :status, "; |
813
|
|
|
$params[':status'] = $details['status']; |
814
|
|
|
|
815
|
|
|
} |
816
|
|
|
|
817
|
|
|
if (isset($details['email']) && $details['email']) { |
818
|
|
|
$emailsql = "email = :email, "; |
819
|
|
|
$params[':email'] = $details['email']; |
820
|
|
|
} |
821
|
|
|
|
822
|
|
|
$q = $this->db->query("UPDATE users |
823
|
|
|
SET firstname = :firstname, |
824
|
3 |
|
lastname = :lastname, |
825
|
|
|
postcode = :postcode, |
826
|
|
|
url = :url," |
827
|
|
|
. $passwordsql |
828
|
3 |
|
. $deletedsql |
829
|
|
|
. $confirmedsql |
830
|
|
|
. $emailsql |
831
|
|
|
. $statussql . " |
832
|
|
|
optin = :optin |
833
|
|
|
WHERE user_id = :user_id |
834
|
|
|
", array_merge($params, [ |
835
|
|
|
':firstname' => $details['firstname'], |
836
|
|
|
':lastname' => $details['lastname'], |
837
|
|
|
':postcode' => $details['postcode'], |
838
|
|
|
':url' => $details['url'], |
839
|
|
|
':optin' => $details['optin'], |
840
|
3 |
|
':user_id' => $details['user_id'], |
841
|
|
|
])); |
842
|
3 |
|
|
843
|
|
|
// If we're returning to |
844
|
|
|
// $this->update_self() then $THEUSER will have its variables |
845
|
|
|
// updated if everything went well. |
846
|
|
|
if ($q->success()) { |
847
|
|
|
return $details; |
848
|
|
|
|
849
|
|
|
} else { |
850
|
3 |
|
$PAGE->error_message("Sorry, we were unable to update user id '" . _htmlentities($details["user_id"]) . "'"); |
851
|
|
|
|
852
|
|
|
return false; |
853
|
|
|
} |
854
|
3 |
|
|
855
|
|
|
|
856
|
3 |
|
} |
857
|
|
|
|
858
|
3 |
|
|
859
|
|
|
|
860
|
3 |
|
|
861
|
|
|
|
862
|
|
|
} // End USER class |
863
|
|
|
|
864
|
|
|
|
865
|
|
|
|
866
|
3 |
|
|
867
|
|
|
|
868
|
|
|
|
869
|
|
|
class THEUSER extends USER { |
870
|
|
|
// Handles all the login/out functionality and checking for the user |
871
|
|
|
// who is using the site right NOW. Yes, him, over there. |
872
|
|
|
|
873
|
|
|
// This will become true if all goes well... |
874
|
|
|
public $loggedin = false; |
875
|
|
|
public $facebook_user = false; |
876
|
|
|
|
877
|
|
|
|
878
|
3 |
|
public function __construct() { |
879
|
|
|
// This function is run automatically when a THEUSER |
880
|
|
|
// object is instantiated. |
881
|
|
|
|
882
|
|
|
$this->db = new ParlDB(); |
|
|
|
|
883
|
|
|
|
884
|
|
|
// We look at the user's cookie and see if it's valid. |
885
|
|
|
// If so, we're going to log them in. |
886
|
|
|
|
887
|
|
|
// A user's cookie is of the form: |
888
|
|
|
// 123.blahblahblah |
889
|
|
|
// Where '123' is a user id, and 'blahblahblah' is an md5 hash of the |
890
|
3 |
|
// encrypted password we've stored in the db. |
891
|
3 |
|
// (Maybe we could just put the encrypted pw in the cookie and md5ing |
892
|
3 |
|
// it is overkill? Whatever, it works.) |
893
|
|
|
|
894
|
|
|
$cookie = get_cookie_var("epuser_id"); // In includes/utility.php. |
895
|
3 |
|
|
896
|
|
|
if ($cookie == '') { |
897
|
|
|
$cookie = get_cookie_var("facebook_id"); |
898
|
|
|
if ($cookie != '') { |
899
|
|
|
$this->facebook_user = true; |
900
|
|
|
twfy_debug("THEUSER", "is facebook login"); |
901
|
3 |
|
} |
902
|
|
|
} |
903
|
|
|
|
904
|
|
|
if ($cookie == '') { |
905
|
|
|
twfy_debug("THEUSER init FAILED", "No cookie set"); |
906
|
3 |
|
$this->loggedin = false; |
907
|
|
|
|
908
|
|
|
} elseif (preg_match("/([[:alnum:]]*)\.([[:alnum:]]*)/", $cookie, $matches)) { |
909
|
|
|
|
910
|
|
|
if (is_numeric($matches[1])) { |
911
|
|
|
|
912
|
|
|
$success = $this->init($matches[1]); |
913
|
|
|
|
914
|
|
|
if ($success) { |
915
|
|
|
// We got all the user's data from the DB. |
916
|
|
|
|
917
|
|
|
// But we need to check the password before we log them in. |
918
|
3 |
|
// And make sure the user hasn't been "deleted". |
919
|
3 |
|
|
920
|
|
|
if ($this->facebook_user) { |
921
|
|
|
if (md5($this->facebook_token()) == $matches[2] && $this->deleted() == false) { |
|
|
|
|
922
|
|
|
twfy_debug("THEUSER", "init SUCCESS: setting as logged in"); |
923
|
|
|
$this->loggedin = true; |
924
|
|
|
} elseif (md5($this->facebook_token()) != $matches[2]) { |
925
|
|
|
twfy_debug("THEUSER", "init FAILED: Facebook token doesn't match cookie"); |
926
|
3 |
|
$this->loggedin = false; |
927
|
|
|
} else { |
928
|
3 |
|
twfy_debug("THEUSER", "init FAILED: User is deleted"); |
929
|
|
|
$this->loggedin = false; |
930
|
3 |
|
} |
931
|
|
|
} else { |
932
|
3 |
|
if (md5($this->password()) == $matches[2] && $this->deleted() == false) { |
|
|
|
|
933
|
|
|
// The correct password is in the cookie, |
934
|
|
|
// and the user isn't deleted, so set the user to be logged in. |
935
|
|
|
|
936
|
|
|
// This would be an appropriate place to call other functions |
937
|
|
|
// that might set user info that only a logged-in user is going |
938
|
|
|
// to need. Their preferences and saved things or something. |
939
|
|
|
|
940
|
3 |
|
|
941
|
|
|
twfy_debug("THEUSER init SUCCEEDED", "setting as logged in"); |
942
|
|
|
$this->loggedin = true; |
943
|
|
|
|
944
|
|
|
} elseif (md5($this->password()) != $matches[2]) { |
945
|
|
|
twfy_debug("THEUSER init FAILED", "Password doesn't match cookie"); |
946
|
|
|
$this->loggedin = false; |
947
|
|
|
} else { |
948
|
7 |
|
twfy_debug("THEUSER init FAILED", "User is deleted"); |
949
|
|
|
$this->loggedin = false; |
950
|
|
|
} |
951
|
7 |
|
} |
952
|
2 |
|
|
953
|
|
|
} else { |
954
|
2 |
|
twfy_debug("THEUSER init FAILED", "didn't get 1 row from db"); |
955
|
|
|
$this->loggedin = false; |
956
|
7 |
|
} |
957
|
|
|
|
958
|
7 |
|
} else { |
959
|
|
|
twfy_debug("THEUSER init FAILED", "cookie's user_id is not numeric"); |
960
|
|
|
$this->loggedin = false; |
961
|
|
|
} |
962
|
|
|
|
963
|
|
|
} else { |
964
|
|
|
twfy_debug("THEUSER init FAILED", "cookie is not of the correct form"); |
965
|
|
|
$this->loggedin = false; |
966
|
|
|
} |
967
|
|
|
|
968
|
|
|
// If a user is logged in they *might* have set their own postcode. |
969
|
|
|
// If they aren't logged in, or they haven't set one, then we may |
970
|
|
|
// have set a postcode for them when they searched for their MP. |
971
|
|
|
// If so, we'll use that as $this->postcode. |
972
|
|
|
if ($this->postcode == '') { |
973
|
|
|
if (get_cookie_var(POSTCODE_COOKIE) != '') { |
974
|
|
|
$pc = get_cookie_var(POSTCODE_COOKIE); |
975
|
|
|
|
976
|
|
|
$this->set_postcode_cookie($pc); |
977
|
|
|
} |
978
|
|
|
} |
979
|
|
|
|
980
|
|
|
$this->update_lastvisit(); |
981
|
|
|
|
982
|
|
|
} // End THEUSER() |
983
|
|
|
|
984
|
|
|
public function update_lastvisit() { |
985
|
|
|
|
986
|
|
|
if ($this->isloggedin()) { |
987
|
|
|
// Set last_visit to now. |
988
|
|
|
$date_now = gmdate("Y-m-d H:i:s"); |
989
|
|
|
$this->db->query( |
990
|
|
|
"UPDATE users SET lastvisit = :lastvisit WHERE user_id = :user_id", |
991
|
|
|
[ ':lastvisit' => $date_now, ':user_id' => $this->user_id() ] |
992
|
|
|
); |
993
|
|
|
|
994
|
|
|
$this->lastvisit = $date_now; |
995
|
|
|
} |
996
|
|
|
} |
997
|
|
|
|
998
|
|
|
// For completeness, but it's better to call $this->isloggedin() |
999
|
|
|
// if you want to check the log in status. |
1000
|
|
|
public function loggedin() { |
1001
|
|
|
return $this->loggedin; |
1002
|
|
|
} |
1003
|
4 |
|
|
1004
|
4 |
|
|
1005
|
4 |
|
|
1006
|
|
|
public function isloggedin() { |
1007
|
|
|
// Call this function to check if the user is successfully logged in. |
1008
|
4 |
|
|
1009
|
|
|
if ($this->loggedin()) { |
1010
|
|
|
twfy_debug("THEUSER", "isloggedin: true"); |
1011
|
|
|
|
1012
|
|
|
return true; |
1013
|
|
|
} else { |
1014
|
|
|
twfy_debug("THEUSER", "isloggedin: false"); |
1015
|
|
|
|
1016
|
|
|
return false; |
1017
|
|
|
} |
1018
|
|
|
} |
1019
|
|
|
|
1020
|
|
|
|
1021
|
|
|
public function isvalid($email, $userenteredpassword) { |
1022
|
|
|
// Returns true if this email and plaintext password match a user in the db. |
1023
|
|
|
// If false returns an array of form error messages. |
1024
|
|
|
|
1025
|
|
|
// We use this on the log in page to check if the details the user entered |
1026
|
|
|
// are correct. We can then continue with logging the user in (taking into |
1027
|
|
|
// account their cookie remembering settings etc) with $this->login(). |
1028
|
|
|
|
1029
|
|
|
// This error string is shared between both email and password errors to |
1030
|
|
|
// prevent leaking of account existence. |
1031
|
|
|
|
1032
|
|
|
$error_string = 'There is no user registered with an email of ' . _htmlentities($email) . ', or the given password is incorrect. If you are subscribed to email alerts, you are not necessarily registered on the website. If you register, you will be able to manage your email alerts, as well as leave annotations.'; |
1033
|
|
|
|
1034
|
|
|
$q = $this->db->query("SELECT user_id, password, deleted, confirmed FROM users WHERE email = :email", [':email' => $email])->first(); |
1035
|
|
|
|
1036
|
|
|
if ($q) { |
1037
|
|
|
// OK. |
1038
|
|
|
$dbpassword = $q["password"]; |
1039
|
|
|
if (password_verify($userenteredpassword, $dbpassword)) { |
1040
|
|
|
$this->user_id = $q["user_id"]; |
1041
|
|
|
$this->password = $dbpassword; |
1042
|
|
|
// We'll need these when we're going to log in. |
1043
|
|
|
$this->deleted = $q["deleted"] == 1 ? true : false; |
1044
|
|
|
$this->confirmed = $q["confirmed"] == 1 ? true : false; |
1045
|
|
|
|
1046
|
|
|
return true; |
1047
|
|
|
|
1048
|
|
|
} else { |
1049
|
|
|
// Failed. |
1050
|
|
|
return ["invalidemail" => $error_string]; |
1051
|
|
|
|
1052
|
|
|
} |
1053
|
|
|
|
1054
|
|
|
} else { |
1055
|
|
|
// Failed. |
1056
|
|
|
return ["invalidemail" => $error_string]; |
1057
|
|
|
} |
1058
|
|
|
|
1059
|
|
|
} |
1060
|
|
|
|
1061
|
|
|
public function has_postcode() { |
1062
|
|
|
$has_postcode = false; |
1063
|
|
|
if ($this->isloggedin() && $this->postcode() != '' || $this->postcode_is_set()) { |
|
|
|
|
1064
|
|
|
$has_postcode = true; |
1065
|
|
|
} |
1066
|
|
|
return $has_postcode; |
1067
|
|
|
} |
1068
|
|
|
|
1069
|
|
|
|
1070
|
|
|
public function facebook_login($returl, $expire, $accessToken) { |
1071
|
|
|
global $PAGE; |
1072
|
|
|
|
1073
|
|
|
twfy_debug("THEUSER", "Faceook login, user_id " . $this->user_id); |
1074
|
|
|
twfy_debug("THEUSER", "Faceook login, facebook_id " . $this->facebook_id); |
1075
|
|
|
twfy_debug("THEUSER", "Faceook login, email" . $this->email); |
1076
|
|
|
if ($this->facebook_id() == "") { |
1077
|
|
|
$PAGE->error_message("We don't have a facebook id for this user.", true); |
1078
|
|
|
|
1079
|
|
|
return; |
1080
|
|
|
} |
1081
|
|
|
|
1082
|
|
|
twfy_debug("THEUSER", "Faceook login, facebook_token: " . $accessToken); |
1083
|
|
|
|
1084
|
|
|
$q = $this->db->query( |
1085
|
|
|
"UPDATE users SET facebook_token = :token WHERE email = :email", |
1086
|
|
|
[ |
1087
|
|
|
':token' => $accessToken, |
1088
|
|
|
':email' => $this->email, |
1089
|
|
|
] |
1090
|
|
|
); |
1091
|
|
|
|
1092
|
|
|
if (!$q->success()) { |
1093
|
|
|
$PAGE->error_message("There was a problem logging you in", true); |
1094
|
|
|
twfy_debug("THEUSER", "Faceook login, failed to set accessToken"); |
1095
|
|
|
|
1096
|
|
|
return false; |
1097
|
|
|
} |
1098
|
|
|
|
1099
|
|
|
// facebook login users probably don't have a password |
1100
|
|
|
$cookie = $this->user_id() . "." . md5($accessToken); |
1101
|
|
|
twfy_debug("THEUSER", "Faceook login, cookie: " . $cookie); |
1102
|
|
|
|
1103
|
|
|
twfy_debug("USER", "logging in user from facebook " . $this->user_id); |
1104
|
|
|
|
1105
|
|
|
$this->loggedin = true; |
1106
|
|
|
$this->_login($returl, $expire, $cookie, 'facebook_id'); |
1107
|
|
|
return true; |
1108
|
|
|
} |
1109
|
|
|
|
1110
|
|
|
public function login($returl, $expire) { |
1111
|
|
|
|
1112
|
|
|
// This is used to log the user in. Duh. |
1113
|
|
|
// You should already have checked the user's email and password using |
1114
|
|
|
// $this->isvalid() |
1115
|
|
|
// That will have set $this->user_id and $this->password, allowing the |
1116
|
|
|
// login to proceed... |
1117
|
|
|
|
1118
|
|
|
// $expire is either 'session' or 'never' - for the cookie. |
1119
|
|
|
|
1120
|
|
|
// $returl is the URL to redirect the user to after log in, generally the |
1121
|
|
|
// page they were on before. But if it doesn't exist, they'll just go to |
1122
|
|
|
// the front page. |
1123
|
|
|
global $PAGE; |
1124
|
|
|
|
1125
|
|
|
if ($returl == "") { |
1126
|
|
|
$URL = new \MySociety\TheyWorkForYou\Url("home"); |
1127
|
|
|
$returl = $URL->generate(); |
1128
|
|
|
} |
1129
|
|
|
|
1130
|
|
|
// Various checks about the user - if they fail, we exit. |
1131
|
|
|
if ($this->user_id() == "" || $this->password == "") { |
1132
|
|
|
$PAGE->error_message("We don't have the user_id or password to make the cookie.", true); |
1133
|
|
|
|
1134
|
|
|
return; |
1135
|
|
|
} elseif ($this->deleted) { |
1136
|
|
|
$PAGE->error_message("This user has been deleted.", true); |
1137
|
|
|
|
1138
|
|
|
return; |
1139
|
|
|
} elseif (!$this->confirmed) { |
1140
|
2 |
|
$PAGE->error_message("You have not yet confirmed your account by clicking the link in the confirmation email we sent to you. If you don't have the email, you can <a href='/user/login/?resend=" . $this->user_id() . "'>have it resent</a>. If it still doesn't arrive, get in touch.", true); |
1141
|
2 |
|
|
1142
|
2 |
|
return; |
1143
|
2 |
|
} |
1144
|
2 |
|
|
1145
|
|
|
// Reminder: $this->password is actually a hashed version of the plaintext pw. |
1146
|
2 |
|
$cookie = $this->user_id() . "." . md5($this->password()); |
1147
|
|
|
|
1148
|
|
|
$this->_login($returl, $expire, $cookie); |
1149
|
2 |
|
} |
1150
|
|
|
|
1151
|
|
|
private function _login($returl, $expire, $cookie, $cookie_name = 'epuser_id') { |
1152
|
|
|
// Unset any existing postcode cookie. |
1153
|
2 |
|
// This will be the postcode the user set for themselves as a non-logged-in |
1154
|
|
|
// user. We don't want it hanging around as it causes confusion. |
1155
|
2 |
|
$this->unset_postcode_cookie(); |
1156
|
2 |
|
|
1157
|
2 |
|
twfy_debug("THEUSER", "expire is " . $expire); |
1158
|
2 |
|
|
1159
|
1 |
|
$cookie_expires = 0; |
1160
|
1 |
|
if ($expire == 'never') { |
1161
|
|
|
twfy_debug("THEUSER", "cookie never expires"); |
1162
|
|
|
$cookie_expires = time() + 86400 * 365 * 20; |
1163
|
|
|
} elseif (is_int($expire) && $expire > time()) { |
1164
|
1 |
|
twfy_debug("THEUSER", "cookie expires at " . $expire); |
1165
|
|
|
$cookie_expires = $expire; |
1166
|
|
|
} else { |
1167
|
1 |
|
twfy_debug("THEUSER", "cookie expires with session"); |
1168
|
|
|
} |
1169
|
|
|
|
1170
|
1 |
|
header("Location: $returl"); |
1171
|
|
|
setcookie($cookie_name, $cookie, $cookie_expires, '/', COOKIEDOMAIN); |
1172
|
|
|
} |
1173
|
|
|
|
1174
|
|
|
|
1175
|
|
|
public function logout($returl) { |
1176
|
1 |
|
|
1177
|
|
|
// $returl is the URL to redirect the user to after log in, generally the |
1178
|
|
|
// page they were on before. But if it doesn't exist, they'll just go to |
1179
|
|
|
// the front page. |
1180
|
|
|
|
1181
|
1 |
|
if ($returl == '') { |
1182
|
1 |
|
$URL = new \MySociety\TheyWorkForYou\Url("home"); |
1183
|
1 |
|
$returl = $URL->generate(); |
1184
|
1 |
|
} |
1185
|
1 |
|
|
1186
|
1 |
|
// get_cookie_var() is in includes/utility.php |
1187
|
1 |
|
if (get_cookie_var("epuser_id") != "") { |
1188
|
|
|
// They're logged in, so set the cookie to empty. |
1189
|
1 |
|
header("Location: $returl"); |
1190
|
|
|
setcookie('epuser_id', '', time() - 86400, '/', COOKIEDOMAIN); |
1191
|
1 |
|
} |
1192
|
|
|
|
1193
|
1 |
|
if (get_cookie_var("facebook_id") != "") { |
1194
|
|
|
// They're logged in, so set the cookie to empty. |
1195
|
|
|
header("Location: $returl"); |
1196
|
|
|
setcookie('facebook_id', '', time() - 86400, '/', COOKIEDOMAIN); |
1197
|
1 |
|
} |
1198
|
|
|
} |
1199
|
1 |
|
|
1200
|
|
|
public function confirm_email($token, $redirect = true) { |
1201
|
|
|
$arg = ''; |
1202
|
1 |
|
if (strstr($token, '::')) { |
1203
|
1 |
|
$arg = '::'; |
1204
|
1 |
|
} |
1205
|
|
|
if (strstr($token, '-')) { |
1206
|
|
|
$arg = '-'; |
1207
|
1 |
|
} |
1208
|
1 |
|
[$user_id, $registrationtoken] = explode($arg, $token); |
1209
|
1 |
|
|
1210
|
1 |
|
if (!is_numeric($user_id) || $registrationtoken == '') { |
1211
|
|
|
return false; |
1212
|
|
|
} |
1213
|
1 |
|
$q = $this->db->query("SELECT expires, data |
1214
|
|
|
FROM tokens |
1215
|
|
|
WHERE token = :token |
1216
|
|
|
AND type = 'E' |
1217
|
|
|
", [':token' => $registrationtoken])->first(); |
1218
|
|
|
|
1219
|
|
|
if ($q) { |
1220
|
|
|
$expires = $q['expires']; |
1221
|
|
|
$expire_time = strtotime($expires); |
1222
|
|
|
if ($expire_time < time()) { |
1223
|
|
|
global $PAGE; |
1224
|
|
|
if ($PAGE && $redirect) { |
1225
|
|
|
$PAGE->error_message("Sorry, that token seems to have expired"); |
1226
|
|
|
} |
1227
|
|
|
|
1228
|
|
|
return false; |
1229
|
|
|
} |
1230
|
|
|
|
1231
|
|
|
[$user_id, $email] = explode('::', $q['data']); |
1232
|
|
|
|
1233
|
|
|
// if we are logged in as someone else don't change the email |
1234
|
|
|
if ($this->user_id() != 0 && $this->user_id() != $user_id) { |
1235
|
|
|
return false; |
1236
|
|
|
} |
1237
|
|
|
|
1238
|
|
|
// if the user isn't logged in then try and load the |
1239
|
|
|
// details |
1240
|
|
|
if ($this->user_id() == 0 && !$this->init($user_id)) { |
1241
|
|
|
return false; |
1242
|
|
|
} |
1243
|
|
|
|
1244
|
|
|
$details = [ |
1245
|
|
|
'email' => $email, |
1246
|
|
|
'firstname' => $this->firstname(), |
1247
|
|
|
'lastname' => $this->lastname(), |
1248
|
|
|
'postcode' => $this->postcode(), |
1249
|
|
|
'url' => $this->url(), |
1250
|
|
|
'optin' => $this->optin(), |
1251
|
|
|
'user_id' => $user_id, |
1252
|
|
|
]; |
1253
|
|
|
$ret = $this->_update($details); |
1254
|
|
|
|
1255
|
|
|
if ($ret) { |
1256
|
|
|
// and remove the token to be tidy |
1257
|
|
|
$this->db->query("DELETE |
1258
|
|
|
FROM tokens |
1259
|
|
|
WHERE token = :token |
1260
|
|
|
AND type = 'E' |
1261
|
|
|
", [':token' => $registrationtoken]); |
1262
|
|
|
|
1263
|
|
|
$this->email = $email; |
1264
|
|
|
|
1265
|
|
|
# Check Stripe email |
1266
|
|
|
$subscription = new MySociety\TheyWorkForYou\Subscription($this); |
1267
|
|
|
if ($subscription->stripe) { |
1268
|
|
|
$subscription->update_email($email); |
1269
|
|
|
} |
1270
|
|
|
|
1271
|
|
|
$URL = new \MySociety\TheyWorkForYou\Url('userconfirmed'); |
1272
|
|
|
$URL->insert(['email' => 't']); |
1273
|
|
|
$redirecturl = $URL->generate(); |
1274
|
|
|
if ($redirect) { |
1275
|
|
|
$this->login($redirecturl, 'session'); |
1276
|
|
|
} else { |
1277
|
|
|
return true; |
1278
|
|
|
} |
1279
|
|
|
} else { |
1280
|
|
|
return false; |
1281
|
|
|
} |
1282
|
|
|
} else { |
1283
|
|
|
return false; |
1284
|
|
|
} |
1285
|
|
|
|
1286
|
|
|
} |
1287
|
|
|
|
1288
|
|
|
public function confirm($token) { |
1289
|
|
|
// The user has clicked the link in their confirmation email |
1290
|
|
|
// and the confirm page has passed the token from the URL to here. |
1291
|
|
|
// If all goes well they'll be confirmed and then logged in. |
1292
|
|
|
|
1293
|
|
|
// Split the token into its parts. |
1294
|
|
|
$arg = ''; |
1295
|
|
|
if (strstr($token, '::')) { |
1296
|
|
|
$arg = '::'; |
1297
|
|
|
} |
1298
|
|
|
if (strstr($token, '-')) { |
1299
|
|
|
$arg = '-'; |
1300
|
|
|
} |
1301
|
|
|
[$user_id, $registrationtoken] = explode($arg, $token); |
1302
|
|
|
|
1303
|
|
|
if (!is_numeric($user_id) || $registrationtoken == '') { |
1304
|
|
|
return false; |
1305
|
|
|
} |
1306
|
|
|
|
1307
|
|
|
$q = $this->db->query("SELECT email, password, postcode |
1308
|
|
|
FROM users |
1309
|
|
|
WHERE user_id = :user_id |
1310
|
|
|
AND registrationtoken = :token |
1311
|
|
|
", [ |
1312
|
|
|
':user_id' => $user_id, |
1313
|
|
|
':token' => $registrationtoken, |
1314
|
|
|
])->first(); |
1315
|
|
|
|
1316
|
|
|
if ($q) { |
1317
|
|
|
|
1318
|
|
|
// We'll need these to be set before logging the user in. |
1319
|
|
|
$this->user_id = $user_id; |
1320
|
|
|
$this->email = $q['email']; |
1321
|
|
|
$this->password = $q['password']; |
1322
|
|
|
|
1323
|
|
|
// Set that they're confirmed in the DB. |
1324
|
|
|
$r = $this->db->query("UPDATE users |
1325
|
|
|
SET confirmed = '1' |
1326
|
|
|
WHERE user_id = :user_id |
1327
|
|
|
", [':user_id' => $user_id]); |
1328
|
|
|
|
1329
|
|
|
if ($q['postcode']) { |
1330
|
|
|
try { |
1331
|
|
|
$MEMBER = new MEMBER(['postcode' => $q['postcode'], 'house' => HOUSE_TYPE_COMMONS]); |
1332
|
|
|
$pid = $MEMBER->person_id(); |
1333
|
|
|
# This should probably be in the ALERT class |
1334
|
|
|
$this->db->query('update alerts set confirmed=1 where email = :email and criteria = :criteria', [ |
1335
|
|
|
':email' => $this->email, |
1336
|
|
|
':criteria' => 'speaker:' . $pid, |
1337
|
|
|
]); |
1338
|
|
|
} catch (MySociety\TheyWorkForYou\MemberException $e) { |
|
|
|
|
1339
|
|
|
} |
1340
|
|
|
} |
1341
|
|
|
|
1342
|
|
|
if ($r->success()) { |
1343
|
|
|
|
1344
|
|
|
$this->confirmed = true; |
1345
|
|
|
|
1346
|
|
|
$redirecturl = get_http_var('ret'); |
1347
|
|
|
if (!$redirecturl || substr($redirecturl, 0, 1) != '/') { |
1348
|
|
|
// Log the user in, redirecting them to the confirm page |
1349
|
|
|
// where they should get a nice welcome message. |
1350
|
|
|
$URL = new \MySociety\TheyWorkForYou\Url('userconfirmed'); |
1351
|
|
|
$URL->insert(['welcome' => 't']); |
1352
|
|
|
$redirecturl = $URL->generate(); |
1353
|
|
|
} |
1354
|
|
|
|
1355
|
|
|
$this->login($redirecturl, 'session'); |
1356
|
|
|
|
1357
|
|
|
} else { |
1358
|
|
|
// Couldn't set them as confirmed in the DB. |
1359
|
|
|
return false; |
1360
|
|
|
} |
1361
|
|
|
|
1362
|
|
|
} else { |
1363
|
|
|
// Couldn't find this user in the DB. Maybe the token was |
1364
|
|
|
// wrong or incomplete? |
1365
|
|
|
return false; |
1366
|
|
|
} |
1367
|
|
|
} |
1368
|
|
|
|
1369
|
|
|
public function confirm_without_token() { |
1370
|
|
|
// If we want to confirm login without a token, e.g. during |
1371
|
|
|
// Facebook registration |
1372
|
|
|
// |
1373
|
|
|
// Note that this doesn't login or redirect the user. |
1374
|
|
|
|
1375
|
|
|
twfy_debug("THEUSER", "Confirming user without token: " . $this->user_id()); |
1376
|
|
|
$q = $this->db->query("SELECT email, password, postcode |
1377
|
|
|
FROM users |
1378
|
|
|
WHERE user_id = :user_id |
1379
|
|
|
", [ |
1380
|
|
|
':user_id' => $this->user_id, |
1381
|
|
|
])->first(); |
1382
|
|
|
|
1383
|
|
|
if ($q) { |
1384
|
|
|
|
1385
|
|
|
twfy_debug("THEUSER", "User with ID found to confirm: " . $this->user_id()); |
1386
|
|
|
// We'll need these to be set before logging the user in. |
1387
|
|
|
$this->email = $q['email']; |
1388
|
|
|
|
1389
|
|
|
// Set that they're confirmed in the DB. |
1390
|
|
|
$r = $this->db->query("UPDATE users |
1391
|
|
|
SET confirmed = '1' |
1392
|
|
|
WHERE user_id = :user_id |
1393
|
|
|
", [':user_id' => $this->user_id]); |
1394
|
|
|
|
1395
|
|
|
if ($q['postcode']) { |
1396
|
|
|
try { |
1397
|
|
|
$MEMBER = new MEMBER(['postcode' => $q['postcode'], 'house' => HOUSE_TYPE_COMMONS]); |
1398
|
|
|
$pid = $MEMBER->person_id(); |
1399
|
|
|
# This should probably be in the ALERT class |
1400
|
|
|
$this->db->query('update alerts set confirmed=1 where email = :email and criteria = :criteria', [ |
1401
|
|
|
':email' => $this->email, |
1402
|
|
|
':criteria' => 'speaker:' . $pid, |
1403
|
|
|
]); |
1404
|
|
|
} catch (MySociety\TheyWorkForYou\MemberException $e) { |
|
|
|
|
1405
|
|
|
} |
1406
|
|
|
} |
1407
|
|
|
|
1408
|
|
|
if ($r->success()) { |
1409
|
|
|
twfy_debug("THEUSER", "User with ID confirmed: " . $this->user_id()); |
1410
|
|
|
$this->confirmed = true; |
1411
|
|
|
return true; |
1412
|
|
|
} else { |
1413
|
|
|
twfy_debug("THEUSER", "User with ID not confirmed: " . $this->user_id()); |
1414
|
|
|
// Couldn't set them as confirmed in the DB. |
1415
|
|
|
return false; |
1416
|
|
|
} |
1417
|
|
|
|
1418
|
|
|
} else { |
1419
|
|
|
// Couldn't find this user in the DB. Maybe the token was |
1420
|
|
|
// wrong or incomplete? |
1421
|
2 |
|
twfy_debug("THEUSER", "User with ID not found to confirm: " . $this->user_id()); |
1422
|
|
|
return false; |
1423
|
|
|
} |
1424
|
|
|
} |
1425
|
|
|
|
1426
|
|
|
|
1427
|
|
|
public function set_postcode_cookie($pc) { |
1428
|
2 |
|
// Set the user's postcode. |
1429
|
|
|
// Doesn't change it in the DB, as it's probably mainly for |
1430
|
2 |
|
// not-logged-in users. |
1431
|
|
|
|
1432
|
|
|
$this->postcode = $pc; |
1433
|
|
|
if (!headers_sent()) { // if in debug mode |
1434
|
2 |
|
setcookie(POSTCODE_COOKIE, $pc, time() + 7 * 86400, "/", COOKIEDOMAIN); |
1435
|
2 |
|
} |
1436
|
1 |
|
|
1437
|
|
|
twfy_debug('USER', "Set the cookie named '" . POSTCODE_COOKIE . " to '$pc' for " . COOKIEDOMAIN . " domain"); |
1438
|
|
|
} |
1439
|
1 |
|
|
1440
|
1 |
|
public function unset_postcode_cookie() { |
1441
|
|
|
if (!headers_sent()) { // if in debug mode |
1442
|
2 |
|
setcookie(POSTCODE_COOKIE, '', time() - 3600, '/', COOKIEDOMAIN); |
1443
|
2 |
|
} |
1444
|
|
|
} |
1445
|
|
|
|
1446
|
|
|
// mostly here for updating from facebook where we do not need |
1447
|
|
|
// to confirm the email address |
1448
|
2 |
|
public function update_self_no_confirm($details) { |
1449
|
|
|
global $THEUSER; |
1450
|
|
|
|
1451
|
|
|
if ($this->isloggedin()) { |
1452
|
2 |
|
twfy_debug("THEUSER", "is logged in for update_self"); |
1453
|
2 |
|
|
1454
|
2 |
|
// this is checked elsewhere but just in case we check here and |
1455
|
2 |
|
// bail out to be on the safe side |
1456
|
2 |
|
if (isset($details['email'])) { |
1457
|
2 |
|
if ($details['email'] != $this->email() && $this->email_exists($details['email'])) { |
1458
|
|
|
return false; |
1459
|
|
|
} |
1460
|
|
|
} |
1461
|
2 |
|
|
1462
|
1 |
|
$details["user_id"] = $this->user_id; |
1463
|
1 |
|
|
1464
|
1 |
|
$newdetails = $this->_update($details); |
1465
|
|
|
|
1466
|
|
|
if ($newdetails) { |
1467
|
|
|
// The user's data was updated, so we'll change the object |
1468
|
|
|
// variables accordingly. |
1469
|
|
|
|
1470
|
|
|
$this->firstname = $newdetails["firstname"]; |
1471
|
|
|
$this->lastname = $newdetails["lastname"]; |
1472
|
|
|
$this->postcode = $newdetails["postcode"]; |
1473
|
|
|
$this->url = $newdetails["url"]; |
1474
|
1 |
|
$this->optin = $newdetails["optin"]; |
1475
|
1 |
|
$this->email = $newdetails['email']; |
1476
|
|
|
if ($newdetails["password"] != "") { |
1477
|
|
|
$this->password = $newdetails["password"]; |
1478
|
|
|
} |
1479
|
1 |
|
|
1480
|
1 |
|
return true; |
1481
|
1 |
|
} else { |
1482
|
1 |
|
return false; |
1483
|
|
|
} |
1484
|
|
|
|
1485
|
1 |
|
} else { |
1486
|
|
|
return false; |
1487
|
|
|
} |
1488
|
|
|
|
1489
|
|
|
} |
1490
|
|
|
|
1491
|
|
|
public function update_self($details, $confirm_email = true) { |
1492
|
1 |
|
// If the user wants to update their details, call this function. |
1493
|
|
|
// It checks that they're logged in before letting them. |
1494
|
|
|
|
1495
|
|
|
|
1496
|
|
|
// $details is an array like that in $this->add(). |
1497
|
|
|
|
1498
|
|
|
global $THEUSER; |
1499
|
|
|
|
1500
|
|
|
if ($this->isloggedin()) { |
1501
|
|
|
|
1502
|
|
|
// this is checked elsewhere but just in case we check here and |
1503
|
|
|
// bail out to be on the safe side |
1504
|
|
|
$email = ''; |
1505
|
|
|
if (isset($details['email'])) { |
1506
|
|
|
if ($details['email'] != $this->email() && $this->email_exists($details['email'])) { |
1507
|
|
|
return false; |
1508
|
|
|
} |
1509
|
|
|
$email = $details['email']; |
1510
|
|
|
unset($details['email']); |
1511
|
|
|
} |
1512
|
|
|
$details["user_id"] = $this->user_id; |
1513
|
|
|
$newdetails = $this->_update($details); |
1514
|
|
|
|
1515
|
|
|
// $newdetails will be an array of details if all went well, |
1516
|
|
|
// false otherwise. |
1517
|
|
|
|
1518
|
|
|
if ($newdetails) { |
1519
|
|
|
// The user's data was updated, so we'll change the object |
1520
|
|
|
// variables accordingly. |
1521
|
|
|
|
1522
|
|
|
$this->firstname = $newdetails["firstname"]; |
1523
|
|
|
$this->lastname = $newdetails["lastname"]; |
1524
|
|
|
$this->postcode = $newdetails["postcode"]; |
1525
|
|
|
$this->url = $newdetails["url"]; |
1526
|
|
|
$this->optin = $newdetails["optin"]; |
1527
|
|
|
if ($newdetails["password"] != "") { |
1528
|
|
|
$this->password = $newdetails["password"]; |
1529
|
|
|
} |
1530
|
|
|
|
1531
|
|
|
if ($email && $email != $this->email) { |
1532
|
|
|
$token = substr(password_hash($email . microtime(), PASSWORD_BCRYPT), 29, 16); |
1533
|
|
|
$data = $this->user_id() . '::' . $email; |
1534
|
|
|
$r = $this->db->query("INSERT INTO tokens |
1535
|
|
|
( expires, token, type, data ) |
1536
|
|
|
VALUES |
1537
|
|
|
( |
1538
|
|
|
DATE_ADD(CURRENT_DATE(), INTERVAL 30 DAY), |
1539
|
|
|
:token, |
1540
|
|
|
'E', |
1541
|
|
|
:data |
1542
|
|
|
) |
1543
|
|
|
", [ |
1544
|
|
|
':token' => $token, |
1545
|
|
|
':data' => $data, |
1546
|
|
|
]); |
1547
|
|
|
|
1548
|
|
|
// send confirmation email here |
1549
|
|
|
if ($r->success()) { |
1550
|
|
|
$newdetails['email'] = $email; |
1551
|
|
|
$newdetails['token'] = $token; |
1552
|
|
|
if ($confirm_email) { |
1553
|
|
|
return $this->send_email_confirmation_email($newdetails); |
1554
|
|
|
} else { |
1555
|
|
|
return true; |
1556
|
|
|
} |
1557
|
|
|
} else { |
1558
|
|
|
return false; |
1559
|
|
|
} |
1560
|
|
|
} |
1561
|
|
|
|
1562
|
|
|
return true; |
1563
|
|
|
} else { |
1564
|
|
|
return false; |
1565
|
|
|
} |
1566
|
|
|
|
1567
|
|
|
} else { |
1568
|
|
|
return false; |
1569
|
|
|
} |
1570
|
|
|
|
1571
|
|
|
} |
1572
|
|
|
|
1573
|
|
|
} |
1574
|
|
|
|
1575
|
|
|
// Yes, we instantiate a new global $THEUSER object when every page loads. |
1576
|
|
|
$THEUSER = new THEUSER(); |
1577
|
|
|
|