3
3
Q: What is going on with the regex for email validation in
4
4
validate::validate_row()?
5
5
A: The regex is intending to match an email address as
6
+ 1. An empty string. Obviously not a real email address, but we are allowing
7
+ enrollments in the database with "inactive" or "pending" email addresses.
8
+ -- OR --
6
9
1. Address recipient may not contain characters (),:;<>@\"[]
7
10
2. Address recipient may not start or end with characters !#$%'*+-/=?^_`{|
8
11
3. Address recipient and hostname must be delimited with @ character
13
16
8. The entire email address is case insensitive
14
17
15
18
Peter Bailie, Oct 29 2021
19
+ Last Updated May 12, 2022 by Peter Bailie
16
20
----------------------------------------------------------------------------- */
17
21
18
22
namespace ssaf ;
@@ -48,24 +52,24 @@ public static function validate_row($row, $row_num) : bool {
48
52
case is_null (EXPECTED_TERM_CODE ) ? true : $ row [COLUMN_TERM_CODE ] === EXPECTED_TERM_CODE :
49
53
self ::$ error = "Row {$ row_num } failed validation for unexpected term code \"{$ row [COLUMN_TERM_CODE ]}\". " ;
50
54
return false ;
51
- // User ID must contain only lowercase alpha, numbers, underscore, and hyphen
52
- case boolval (preg_match ("/^[a-z0-9_\-]+$/ " , $ row [COLUMN_USER_ID ])):
55
+ // User ID must contain only alpha characters , numbers, underscore, hyphen, and period.
56
+ case boolval (preg_match ("/^[a-z0-9_\-\. ]+$/i " , $ row [COLUMN_USER_ID ])):
53
57
self ::$ error = "Row {$ row_num } failed user ID validation \"{$ row [COLUMN_USER_ID ]}\". " ;
54
58
return false ;
55
59
// First name must be alpha characters, white-space, or certain punctuation.
56
- case boolval (preg_match ("/^[a-zA-Z '`\-\. ]+$/ " , $ row [COLUMN_FIRSTNAME ])):
60
+ case boolval (preg_match ("/^[a-z '`\-\. ]+$/i " , $ row [COLUMN_FIRSTNAME ])):
57
61
self ::$ error = "Row {$ row_num } failed validation for student first name \"{$ row [COLUMN_FIRSTNAME ]}\". " ;
58
62
return false ;
59
63
// Last name must be alpha characters, white-space, or certain punctuation.
60
- case boolval (preg_match ("/^[a-zA-Z '`\-\. ]+$/ " , $ row [COLUMN_LASTNAME ])):
64
+ case boolval (preg_match ("/^[a-z '`\-\. ]+$/i " , $ row [COLUMN_LASTNAME ])):
61
65
self ::$ error = "Row {$ row_num } failed validation for student last name \"{$ row [COLUMN_LASTNAME ]}\". " ;
62
66
return false ;
63
67
// Student registration section must be alphanumeric, '_', or '-'.
64
- case boolval (preg_match ("/^[a-zA-Z0- 9_\-]+$/ " , $ row [COLUMN_SECTION ])):
68
+ case boolval (preg_match ("/^[a-z0- 9_\-]+$/i " , $ row [COLUMN_SECTION ])):
65
69
self ::$ error = "Row {$ row_num } failed validation for student section \"{$ row [COLUMN_SECTION ]}\". " ;
66
70
return false ;
67
- // Check email address is properly formed.
68
- case boolval (preg_match ("/^(?![!#$%'*+\-\/=?^_`{|])[^(),:;<>@ \\\"\[\]]+(?<![!#$%'*+\-\/=?^_`{|])@(?:(?!\-)[a-z0-9\-]+(?<!\-)\.)+[a-z]{2,}$/i " , $ row [COLUMN_EMAIL ])):
71
+ // Check email address is properly formed. Blank email addresses are also accepted.
72
+ case boolval (preg_match ("/^$|^ (?![!#$%'*+\-\/=?^_`{|])[^(),:;<>@ \\\"\[\]]+(?<![!#$%'*+\-\/=?^_`{|])@(?:(?!\-)[a-z0-9\-]+(?<!\-)\.)+[a-z]{2,}$/i " , $ row [COLUMN_EMAIL ])):
69
73
self ::$ error = "Row {$ row_num } failed validation for student email \"{$ row [COLUMN_EMAIL ]}\". " ;
70
74
return false ;
71
75
}
@@ -85,24 +89,34 @@ public static function validate_row($row, $row_num) : bool {
85
89
* False, as in error found, otherwise. $user_ids is filled when return
86
90
* is FALSE.
87
91
*
88
- * @param array $rows Data rows to check (presumably an entire couse)
89
- * @param string[] &$user_id Duplicated user ID, when found
92
+ * @param array $rows Data rows to check (presumably an entire couse).
93
+ * @param string[] &$user_id Duplicated user ID, when found.
94
+ * @param string[] &$d_rows Rows containing duplicate user IDs, indexed by user ID.
90
95
* @return bool TRUE when all user IDs are unique, FALSE otherwise.
91
96
*/
92
- public static function check_for_duplicate_user_ids (array $ rows , &$ user_ids ) : bool {
97
+ public static function check_for_duplicate_user_ids (array $ rows , &$ user_ids, & $ d_rows ) : bool {
93
98
usort ($ rows , function ($ a , $ b ) { return $ a [COLUMN_USER_ID ] <=> $ b [COLUMN_USER_ID ]; });
94
99
95
100
$ user_ids = array ();
101
+ $ d_rows = array ();
96
102
$ are_all_unique = true ; // Unless proven FALSE
97
103
$ length = count ($ rows );
98
104
for ($ i = 1 ; $ i < $ length ; $ i ++) {
99
105
$ j = $ i - 1 ;
100
106
if ($ rows [$ i ][COLUMN_USER_ID ] === $ rows [$ j ][COLUMN_USER_ID ]) {
101
107
$ are_all_unique = false ;
102
- $ user_ids [] = $ rows [$ i ][COLUMN_USER_ID ];
108
+ $ user_id = $ rows [$ i ][COLUMN_USER_ID ];
109
+ $ user_ids [] = $ user_id ;
110
+ $ d_rows [$ user_id ][] = $ j ;
111
+ $ d_rows [$ user_id ][] = $ i ;
103
112
}
104
113
}
105
114
115
+ foreach ($ d_rows as &$ d_row ) {
116
+ array_unique ($ d_row , SORT_REGULAR );
117
+ }
118
+ unset($ d_row );
119
+
106
120
return $ are_all_unique ;
107
121
}
108
122
0 commit comments