-
Notifications
You must be signed in to change notification settings - Fork 0
/
email_verify.check.inc
442 lines (406 loc) · 14.1 KB
/
email_verify.check.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
<?php
/**
* @file
* User email check menu callback file for email_verify module.
*/
/**
* Look though the users table for invalid email addresses.
*
* @param array $form
* The form definition.
* @param array $form_state
* The current state of the form.
*
* @return array
* The form definition.
*/
function email_verify_user_check_form(array $form, array &$form_state) {
if (!empty($form_state['input'])) {
backdrop_set_message(t('Look for the verification results below the form.'));
}
$form['header'] = array(
'#type' => 'fieldset',
'#title' => t('User check'),
'#collapsible' => TRUE,
'#description' => t('
On this page, you can list all existing users for whom their email address
is not valid. Simply click the "Start" button to begin the process. If you
make changes to the users, you will need to click the "Start" or "Update"
buttons to see the new data.
'),
);
$form['header']['form_help'] = array(
'#markup' => t('
<p>
Because the checking process can take a very long time, especially for
sites with thousands of users, to the point of this page being entirely
useless, you may specify the number of users to check with the fields
below.<br />
<ul>
<li>If "Number" is empty and "Offset" is empty, then all users in the
database table will be verified.</li>
<li>If "Number" has a value and "Offset" is empty, then the first "Number"
of users in the database table will be verified.</li>
<li>If "Number" is empty and "Offset" has a value, then all users after
"Offset" to the end of the database table will be verified.</li>
<li>If "Number" has a value and "Offset" has a value, then the "Number"
of users after "Offset" will be verified.</li>
</ul>
</p>
'),
);
$form['header']['number'] = array(
'#type' => 'textfield',
'#title' => t("Number"),
'#size' => 15,
'#description' => t('The number of users to verify.'),
);
$form['header']['offset'] = array(
'#type' => 'textfield',
'#title' => t("Offset"),
'#size' => 15,
'#description' => t('The number of users to skip before counting the number of users to verify.'),
);
$all_user_count = db_query("SELECT COUNT(DISTINCT uid) FROM {users}")->fetchField();
$active_user_count = db_query("SELECT COUNT(DISTINCT uid) FROM {users} WHERE status = 1")->fetchField();
$form['header']['disabled'] = array(
'#type' => 'checkbox',
'#title' => t('Include blocked/disabled users'),
'#description' => t(
'There are %all_user_count users registed with this site, of which, %active_user_count are active.',
array(
'%all_user_count' => $all_user_count,
'%active_user_count' => $active_user_count,
)
),
);
$form['header']['submit'] = array(
'#type' => 'submit',
'#value' => t('Start'),
);
// Get any records that have been stored to display.
$rows = config_get('email_verify.settings', 'users_to_display');
$user_rows = $rows;
$headers = _email_verify_get_header();
$form_count = format_plural(
count($rows),
'Found 1 user whose email address is not valid.',
'Found @count users whose email addresses are not valid.'
);
if (!empty($rows)) {
// Rename the button.
$form['header']['submit']['#value'] = t('Update');
// Set up the sorting.
_email_verify_sort_rows($headers, $rows);
// Set up the pager.
$current_page = pager_default_initialize(count($rows), 25);
// Break the total data set into page sized chunks.
$pages = array_chunk($rows, 25, TRUE);
// Add the users.
if (!empty($pages)) {
$user_rows = $pages[$current_page];
}
}
// Theme and add the results.
$form['table'] = array(
'#markup' => theme(
'table',
array(
'header' => $headers,
'rows' => $user_rows,
'caption' => $form_count,
'empty' => t('All email address checked passed the verification(s).'),
)
),
);
// Add the pager.
$form['pager'] = array('#markup' => theme('pager'));
return $form;
}
/**
* Validate handler for the user check form.
*/
function email_verify_user_check_form_validate($form, &$form_state) {
if (!empty($form_state['values']['number']) && !is_numeric(trim($form_state['values']['number']))) {
form_set_error('number', t('The value in the "Number" field can only be an integer.'));
}
if (!empty($form_state['values']['offset']) && !is_numeric(trim($form_state['values']['offset']))) {
form_set_error('offset', t('The value in the "Offset" field can only be an integer.'));
}
}
/**
* Submit handler for the user check form.
*/
function email_verify_user_check_form_submit($form, &$form_state) {
// Clear any saved data.
config_set('email_verify.settings', 'users_to_display', array());
$disabled_users = FALSE;
if (isset($form_state['values']['disabled']) && $form_state['values']['disabled'] == 1) {
$disabled_users = TRUE;
}
// Prepare the operations.
$user_count = 0;
if (!empty($form_state['values']['number'])) {
$user_count = trim($form_state['values']['number']);
}
$user_offset = 0;
$current_uid = 0;
if (!empty($form_state['values']['offset'])) {
$user_offset = trim($form_state['values']['offset']);
if (!empty($user_offset)) {
// Get the user ID of the user to start the verification process with.
$current_uid = _email_verify_batch_display_get_current_uid($user_offset, $disabled_users);
}
}
// Get the number of users to verify.
$max = _email_verify_batch_display_get_max($user_count, $user_offset, $disabled_users, $current_uid);
$operations = array();
$operations[] = array(
'_email_verify_batch_display_process_batch',
array($current_uid, $max, $disabled_users),
);
// Prepare the batch.
$batch = array(
'title' => t('Checking the email addresses of @user_count users. You may want to go get a cup of coffee now. Or maybe a sandwich.', array('@user_count' => $user_count)),
'operations' => $operations,
'progress_message' => t('Completed @current of @total operations.'),
'error_message' => t('One or more errors were encountered processing the users.'),
'finished' => '_email_verify_batch_finish_batch',
'file' => backdrop_get_path('module', 'email_verify') . '/email_verify.check.inc',
);
// Set the batch.
batch_set($batch);
}
/**
* Retrieves the user ID of the user to start the verification process with.
*
* @param int $user_offset
* The number of users to skip before beginning verification.
* @param bool $disabled_users
* Indicates whether to include disabled users or not. A value of TRUE (or 1)
* includes them, where a value of FALSE (or 0) does not.
*
* @return int
* The user ID before the one to start the verification with. The verification
* process starts with the uid after this one, so that uid 0 is not verified.
*/
function _email_verify_batch_display_get_current_uid($user_offset, $disabled_users) {
$query = 'SELECT uid FROM users';
// Check for whether to include blocked users.
if (empty($disabled_users)) {
$query .= ' WHERE status = 1';
}
$query .= ' ORDER BY uid ASC LIMIT 1 OFFSET ' . $user_offset;
return db_query($query)->fetchField();
}
/**
* Retrieves the number of users to verify.
*
* @param int $user_count
* The number of user email addresses to verify.
* @param int $user_offset
* The number of users to skip before beginning verification.
* @param bool $disabled_users
* Indicates whether to include disabled users or not. A value of TRUE (or 1)
* includes them, where a value of FALSE (or 0) does not.
* @param int $current_uid
* The user ID of the user to start the verification on.
*
* @return int
* The value that goes in the batch sandbox's 'max' variable, which is the
* maximum number of records to process.
*/
function _email_verify_batch_display_get_max($user_count, $user_offset, $disabled_users, $current_uid) {
// Default to not running the batch.
$max = 0;
if (empty($user_count)) {
// Set 'max' to the total number of users in the database.
$query = 'SELECT COUNT(uid) FROM users';
// Check for whether to include blocked users.
if (empty($disabled_users)) {
$query .= ' WHERE status = 1';
}
$max = db_query($query)->fetchField();
// If the offset value is not empty, use it to modify $max.
if (!empty($user_offset)) {
$max = $max - $user_offset;
}
}
else {
if (empty($user_offset)) {
// Set 'max' to number of users specified in the form.
$max = $user_count;
}
else {
// Set 'max' to number of users specified in the form, using the offset.
$query = 'SELECT uid FROM users WHERE uid >= :start_uid';
// Check for whether to include blocked users.
if (empty($disabled_users)) {
$query .= ' AND status = 1';
}
$query .= ' ORDER BY uid ASC LIMIT ' . $user_count;
$results = db_query($query, array(':start_uid' => $current_uid))->fetchAll();
$max = count($results);
}
}
return $max;
}
/**
* The batch process for checking the users.
*
* @param int $current_uid
* The user ID of the user to start the verification on.
* @param int $max
* The maximum number of records to process.
* @param bool $disabled_users
* Indicates whether to include disabled users or not. A value of TRUE (or 1)
* includes them, where a value of FALSE (or 0) does not.
* @param array $context
* Used by the Batch API to keep track of and pass data from one operation to
* the next.
*/
function _email_verify_batch_display_process_batch($current_uid, $max, $disabled_users, array &$context) {
// Used to store information to track progression between successive calls.
if (empty($context['sandbox'])) {
$context['sandbox'] = array();
$context['sandbox']['progress'] = 0;
$context['sandbox']['current_uid'] = $current_uid;
$context['sandbox']['max'] = $max;
}
$query_limit = 5;
// Make sure no more records are processed than specified.
if ($context['sandbox']['max'] - $context['sandbox']['progress'] < $query_limit) {
$query_limit = $context['sandbox']['max'] - $context['sandbox']['progress'];
}
// Create and execute the query for selecting the user data.
$query = 'SELECT uid, name, mail FROM {users} WHERE uid > :uid';
// Check for whether to include blocked users.
if (empty($disabled_users)) {
$query .= ' AND status = 1';
}
$query .= ' ORDER BY uid ASC LIMIT ' . $query_limit;
$users = db_query(
$query,
array(':uid' => $context['sandbox']['current_uid'])
)->fetchAll();
// If there are no more user email addresses to verify, set 'progress' to
// 'max'.
if (empty($users)) {
$context['sandbox']['progress'] = $context['sandbox']['max'] = $max;
}
else {
// Process the user list.
foreach ($users as $user) {
// Check the user account.
$check_results = email_verify_check($user->mail);
if (!empty($check_results['verification_message'])) {
// Add the user to the list.
$context['results']['users_to_display'][$user->uid] = array(
'uid' => $user->uid,
'name' => $user->name,
'mail' => $user->mail,
'reason' => $check_results['verification_message'],
'link' => l(t('account'), 'user/' . $user->uid),
);
}
if (!empty($check_results['debugging_text'])) {
// Log and/or display the debugging information.
email_verify_process_debug_information($check_results['debugging_text']);
}
// Update the progress information.
$context['sandbox']['progress']++;
$context['sandbox']['current_uid'] = $user->uid;
$context['message'] = t('Processed email address @email (user ID @uid)', array('@email' => $user->mail, '@uid' => $user->uid));
}
}
// Inform the batch engine the operations have not been completed, and provide
// an estimation of the current completion level.
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
$context['finished'] = ($context['sandbox']['progress'] >= $context['sandbox']['max']);
}
}
/**
* The function that is called when the batch is complete.
*/
function _email_verify_batch_finish_batch($success, $results, $operations) {
if ($success) {
if (!empty($results['users_to_display'])) {
// Save the collected data for display.
config_set('email_verify.settings', 'users_to_display', $results['users_to_display']);
}
}
else {
// An error occurred. $operations contains the operations that remained
// unprocessed.
$error_operation = reset($operations);
backdrop_set_message(
t('An error occurred while processing @operation with arguments : @args',
array(
'@operation' => $error_operation[0],
'@args' => print_r($error_operation[0], TRUE),
)
)
);
}
}
/**
* Returns the header to use for the display table.
*
* @return array
* The header to use.
*/
function _email_verify_get_header() {
return array(
'uid' => array(
'data' => t('User Id'),
'field' => 'uid',
),
'name' => array(
'data' => t('Name'),
'field' => 'name',
),
'mail' => array(
'data' => t('Email address'),
'field' => 'mail',
),
'reason' => array(
'data' => t('Reason'),
),
'account' => array(
'data' => '',
),
);
}
/**
* Sorts the table rows.
*
* @param array $headers
* The headers of the table.
* @param array $rows
* The data to sort.
*/
function _email_verify_sort_rows(array $headers, array &$rows) {
$order_field = tablesort_get_order($headers);
$order = tablesort_get_sort($headers);
if (!empty($order_field['sql'])) {
$order_by = $order_field['sql'];
switch ($order) {
case 'desc':
uasort($rows, function ($a, $b) use ($order_by) {
if ($a[$order_by] == $b[$order_by]) {
return 0;
}
return ($a[$order_by] > $b[$order_by]) ? -1 : 1;
});
break;
case 'asc':
uasort($rows, function ($a, $b) use ($order_by) {
if ($a == $b) {
return 0;
}
return ($a[$order_by] < $b[$order_by]) ? -1 : 1;
});
break;
}
}
}