CWIS Developer Documentation

- Home
- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

UserFactory.php
Go to the documentation of this file.
1 <?PHP
2
3 #
4 # Axis--UserFactory.php
5 # An Meta-Object for Handling User Information
6 #
7 # Copyright 2003-2012 Axis Data
8 # This code is free software that can be used or redistributed under the
9 # terms of Version 2 of the GNU General Public License, as published by the
10 # Free Software Foundation (http://www.fsf.org).
11 #
12 # Author: Edward Almasy (ealmasy@axisdata.com)
13 #
14 # Part of the AxisPHP library v1.2.4
15 # For more information see http://www.axisdata.com/AxisPHP/
16 #
17
18 class UserFactory
19 {
20
21 # ---- PUBLIC INTERFACE --------------------------------------------------
22
26 public function __construct()
27 {
28 # create database connection
29 $this->DB = new Database();
30 }
31
44 public function CreateNewUser(
45 $UserName, $Password, $PasswordAgain, $EMail, $EMailAgain,
46 $IgnoreErrorCodes = NULL)
47 {
48 # check incoming values
49 $ErrorCodes = $this->TestNewUserValues(
50 $UserName, $Password, $PasswordAgain, $EMail, $EMailAgain);
51
52 # discard any errors we are supposed to ignore
53 if ($IgnoreErrorCodes)
54 {
55 $ErrorCodes = array_diff($ErrorCodes, $IgnoreErrorCodes);
56 }
57
58 # if error found in incoming values return error codes to caller
59 if (count($ErrorCodes)) { return $ErrorCodes; }
60
61 # add user to database
62 $UserName = User::NormalizeUserName($UserName);
63 $this->DB->Query("INSERT INTO APUsers"
64 ." (UserName, CreationDate)"
65 ." VALUES ('".addslashes($UserName)."', NOW())");
66
67 # create new user object
68 $UserId = $this->DB->LastInsertId();
69 $User = new User($this->DB, (int)$UserId);
70
71 # if new user object creation failed return error code to caller
72 if ($User->Status() != U_OKAY) { return array($User->Status()); }
73
74 # set password and e-mail address
75 $User->SetPassword($Password);
76 $User->Set("EMail", $EMail);
77
78 # return new user object to caller
79 return $User;
80 }
81
91 public function TestNewUserValues(
92 $UserName, $Password, $PasswordAgain, $EMail, $EMailAgain)
93 {
94 $ErrorCodes = array();
95 if (strlen(User::NormalizeUserName($UserName)) == 0)
96 { $ErrorCodes[] = U_EMPTYUSERNAME; }
97 elseif (!User::IsValidUserName($UserName))
98 { $ErrorCodes[] = U_ILLEGALUSERNAME; }
99 elseif ($this->UserNameExists($UserName))
100 { $ErrorCodes[] = U_DUPLICATEUSERNAME; }
101
102 if ($this->EMailAddressIsInUse($EMail))
103 { $ErrorCodes[] = U_DUPLICATEEMAIL; }
104
105 $FoundOtherPasswordError = FALSE;
106 if (strlen(User::NormalizePassword($Password)) == 0)
107 {
108 $ErrorCodes[] = U_EMPTYPASSWORD;
109 $FoundOtherPasswordError = TRUE;
110 }
111 elseif (!User::IsValidPassword($Password))
112 {
113 $ErrorCodes[] = U_ILLEGALPASSWORD;
114 $FoundOtherPasswordError = TRUE;
115 }
116
117 if (strlen(User::NormalizePassword($PasswordAgain)) == 0)
118 {
119 $ErrorCodes[] = U_EMPTYPASSWORDAGAIN;
120 $FoundOtherPasswordError = TRUE;
121 }
122 elseif (!User::IsValidPassword($PasswordAgain))
123 {
124 $ErrorCodes[] = U_ILLEGALPASSWORDAGAIN;
125 $FoundOtherPasswordError = TRUE;
126 }
127
128 if ($FoundOtherPasswordError == FALSE)
129 {
130 if (User::NormalizePassword($Password)
131 != User::NormalizePassword($PasswordAgain))
132 {
133 $ErrorCodes[] = U_PASSWORDSDONTMATCH;
134 }
135 }
136
137 $FoundOtherEMailError = FALSE;
138 if (strlen(User::NormalizeEMailAddress($EMail)) == 0)
139 {
140 $ErrorCodes[] = U_EMPTYEMAIL;
141 $FoundOtherEMailError = TRUE;
142 }
143 elseif (!User::IsValidLookingEMailAddress($EMail))
144 {
145 $ErrorCodes[] = U_ILLEGALEMAIL;
146 $FoundOtherEMailError = TRUE;
147 }
148
149 if (strlen(User::NormalizeEMailAddress($EMailAgain)) == 0)
150 {
151 $ErrorCodes[] = U_EMPTYEMAILAGAIN;
152 $FoundOtherEMailError = TRUE;
153 }
154 elseif (!User::IsValidLookingEMailAddress($EMailAgain))
155 {
156 $ErrorCodes[] = U_ILLEGALEMAILAGAIN;
157 $FoundOtherEMailError = TRUE;
158 }
159
160 if ($FoundOtherEMailError == FALSE)
161 {
162 if (User::NormalizeEMailAddress($EMail)
163 != User::NormalizeEMailAddress($EMailAgain))
164 {
165 $ErrorCodes[] = U_EMAILSDONTMATCH;
166 }
167 }
168
169 return $ErrorCodes;
170 }
171
178 public function GetUserCount($Condition = NULL)
179 {
180 return $this->DB->Query("SELECT COUNT(*) AS UserCount FROM APUsers"
181 .($Condition ? " WHERE ".$Condition : ""), "UserCount");
182 }
183
189 public function GetMatchingUserCount()
190 {
191 return $this->MatchingUserCount;
192 }
193
200 public function GetLoggedInUsers($InactivityTimeout = 60)
201 {
202 # query IDs of logged-in users from database
203 $LoggedInCutoffTime = date("Y-m-d H:i:s",
204 time() - ($InactivityTimeout * 60));
205 $this->DB->Query("SELECT UserId FROM APUsers"
206 ." WHERE LastActiveDate > '".$LoggedInCutoffTime."'"
207 ." AND LoggedIn != '0'");
208 $UserIds = $this->DB->FetchColumn("UserId");
209
210 # load array of logged in users
211 $ReturnValue = array();
212 foreach ($UserIds as $Id)
213 {
214 $ReturnValue[$Id] = new User(intval($Id));
215 }
216
217 # return array of user data to caller
218 return $ReturnValue;
219 }
220
228 public function GetRecentlyLoggedInUsers($Since = NULL, $Limit = 10)
229 {
230 # get users recently logged in during the last 24 hours if no date given
231 if ($Since === NULL)
232 {
233 $Date = date("Y-m-d H:i:s", time() - (24 * 60 * 60));
234 }
235
236 else
237 {
238 $Date = date("Y-m-d H:i:s", strtotime($Since));
239 }
240
241 # query for the users who were logged in since the given date
242 $this->DB->Query("SELECT UserId FROM APUsers"
243 ." WHERE LastActiveDate > '".$Date."'"
244 ." AND LoggedIn != '1'"
245 ." ORDER BY LastActiveDate DESC"
246 ." LIMIT ".intval($Limit));
247 $UserIds = $this->DB->FetchColumn("UserId");
248
249 $ReturnValue = array();
250 foreach ($UserIds as $Id)
251 {
252 $ReturnValue[$Id] = new User(intval($Id));
253 }
254
255 # return array of user data to caller
256 return $ReturnValue;
257 }
258
265 public function GetUsersWithPrivileges()
266 {
267 # retrieve privileges
268 $Args = func_get_args();
269 if (is_array(reset($Args))) { $Args = reset($Args); }
270 $Privs = array();
271 foreach ($Args as $Arg)
272 {
273 if (is_array($Args))
274 {
275 $Privs = array_merge($Privs, $Args);
276 }
277 else
278 {
279 $Privs[] = $Arg;
280 }
281 }
282
283 # start with query string that will return all users
284 $QueryString = "SELECT DISTINCT APUsers.UserId, UserName FROM APUsers"
285 .(count($Privs) ? ", APUserPrivileges" : "");
286
287 # for each specified privilege
288 foreach ($Privs as $Index => $Priv)
289 {
290 # add condition to query string
291 $QueryString .= ($Index == 0) ? " WHERE (" : " OR";
292 $QueryString .= " APUserPrivileges.Privilege = ".$Priv;
293 }
294
295 # close privilege condition in query string and add user ID condition
296 $QueryString.= count($Privs)
297 ? ") AND APUsers.UserId = APUserPrivileges.UserId" : "";
298
299 # add sort by user name to query string
300 $QueryString .= " ORDER BY UserName ASC";
301
302 # perform query
303 $this->DB->Query($QueryString);
304
305 # copy query result into user info array
306 $Users = $this->DB->FetchColumn("UserName", "UserId");
307
308 # return array of users to caller
309 return $Users;
310 }
311
324 public function FindUsers($SearchString, $FieldName = "UserName",
325 $SortFieldName = "UserName", $Offset = 0, $Count = 9999999)
326 {
327 # retrieve matching user IDs
328 $UserNames = $this->FindUserNames(
329 $SearchString, $FieldName, $SortFieldName, $Offset, $Count);
330
331 # create user objects
332 $Users = array();
333 foreach ($UserNames as $UserId => $UserName)
334 {
335 $Users[$UserId] = new User($this->DB, intval($UserId));
336 }
337
338 # return array of user objects to caller
339 return $Users;
340 }
341
356 public function FindUserNames($SearchString, $FieldName = "UserName",
357 $SortFieldName = "UserName", $Offset = 0, $Count = 9999999,
358 $IdExclusions = array(), $ValueExclusions = array())
359 {
360 # Construct a database query:
361 $QueryString = "SELECT UserId, UserName FROM APUsers WHERE";
362
363 # If the search string is a valid username which is shorter than the
364 # minimum word length indexed by the FTS, just do a normal
365 # equality test instead of using the index.
366 # Otherwise, FTS away.
367 $MinWordLen = $this->DB->Query(
368 "SHOW VARIABLES WHERE variable_name='ft_min_word_len'", "Value");
369 if (User::IsValidUserName($SearchString) &&
370 strlen($SearchString) < $MinWordLen )
371 {
372 $QueryString .= " UserName='".addslashes($SearchString)."'";
373 }
374 else
375 {
376 # massage search string to use AND logic
377 $Words = preg_split("/[\s]+/", trim($SearchString));
378 $NewSearchString = "";
379 $InQuotedString = FALSE;
380 foreach ($Words as $Word)
381 {
382 if ($InQuotedString == FALSE) { $NewSearchString .= "+"; }
383 if (preg_match("/^\"/", $Word)) { $InQuotedString = TRUE; }
384 if (preg_match("/\"$/", $Word)) { $InQuotedString = FALSE; }
385 $NewSearchString .= $Word." ";
386 }
387 $QueryString .= " MATCH (".$FieldName.")"
388 ." AGAINST ('".addslashes(trim($NewSearchString))."'"
389 ." IN BOOLEAN MODE)";
390 }
391
392 # add each ID exclusion
393 foreach ($IdExclusions as $IdExclusion)
394 {
395 $QueryString .= " AND ".$this->ItemIdFieldName." != '"
396 .addslashes($IdExclusion)."' ";
397 }
398
399 # add each value exclusion
400 foreach ($ValueExclusions as $ValueExclusion)
401 {
402 $QueryString .= " AND ".$this->ItemNameFieldName." != '"
403 .addslashes($ValueExclusion)."' ";
404 }
405
406 $QueryString .= " ORDER BY ".$SortFieldName
407 ." LIMIT ".$Offset.", ".$Count;
408
409 # retrieve matching user IDs
410 $this->DB->Query($QueryString);
411 $UserNames = $this->DB->FetchColumn("UserName", "UserId");
412
413 # return names/IDs to caller
414 return $UserNames;
415 }
416
432 public function GetMatchingUsers($SearchString, $FieldName = NULL,
433 $SortFieldName = "UserName",
434 $ResultsStartAt = 0, $ReturnNumber = NULL)
435 {
436 # start with empty array (to prevent array errors)
437 $ReturnValue = array();
438
439 # if empty search string supplied, return nothing
440 $TrimmedSearchString = trim($SearchString);
441 if (empty($TrimmedSearchString))
442 {
443 return $ReturnValue;
444 }
445
446 # make sure ordering is done by user name if not specified
447 $SortFieldName = empty($SortFieldName) ? "UserName" : $SortFieldName;
448
449 # begin constructing the query
450 $Query = "SELECT * FROM APUsers";
451 $QueryOrderBy = " ORDER BY $SortFieldName";
452 $QueryLimit = empty($ReturnNumber) ? "" : " LIMIT $ResultsStartAt, $ReturnNumber";
453
454 # the Criteria Query will be used to get the total number of results without the
455 # limit clause
456 $CriteriaQuery = $Query;
457
458 # if specific field comparison requested
459 if (!empty($FieldName))
460 {
461 # append queries with criteria
462 $Query .= " WHERE ".$FieldName." REGEXP '".addslashes($SearchString)."'";
463 $CriteriaQuery = $Query;
464 }
465
466 # optimize for returning all users
467 else if ($SearchString == ".*.")
468 {
469 # set field name to username - this would be the first field
470 # returned by a field to field search using the above RegExp
471 $FieldName = "UserName";
472 }
473
474 # add order by and limit to query for optimizing
475 $Query .= $QueryOrderBy.$QueryLimit;
476
477 # execute query...
478 $this->DB->Query($Query);
479
480 # ...and process query return
481 while ($Record = $this->DB->FetchRow())
482 {
483 # if specific field or all users requested
484 if (!empty($FieldName))
485 {
486 # add user to return array
487 $ReturnValue[$Record["UserId"]] = $Record;
488
489 # add matching search field to return array
490 $ReturnValue[$Record["UserId"]]["APMatchingField"] = $FieldName;
491 }
492
493 else
494 {
495 # for each user data field
496 foreach ($Record as $FName => $FValue)
497 {
498 # if search string appears in data field
499 if (strpos($Record[$FName], $SearchString) !== FALSE)
500 {
501 # add user to return array
502 $ReturnValue[$Record["UserId"]] = $Record;
503
504 # add matching search field to return array
505 $ReturnValue[$Record["UserId"]]["APMatchingField"] = $FName;
506 }
507 }
508 }
509 }
510
511 # add matching user count
512 $this->DB->Query($CriteriaQuery);
513 $this->MatchingUserCount = $this->DB->NumRowsSelected();
514
515 # return array of matching users to caller
516 return $ReturnValue;
517 }
518
524 public function UserNameExists($UserName)
525 {
526 # normalize user name
527 $UserName = User::NormalizeUserName($UserName);
528
529 # check whether user name is already in use
530 $NameCount = $this->DB->Query(
531 "SELECT COUNT(*) AS NameCount FROM APUsers"
532 ." WHERE UserName = '".addslashes($UserName)."'",
533 "NameCount");
534
535 # report to caller whether name exists
536 return ($NameCount > 0) ? TRUE : FALSE;
537 }
538
544 public function EMailAddressIsInUse($Address)
545 {
546 # normalize address
547 $UserName = User::NormalizeEMailAddress($Address);
548
549 # check whether address is already in use
550 $AddressCount = $this->DB->Query(
551 "SELECT COUNT(*) AS AddressCount FROM APUsers"
552 ." WHERE EMail = '".addslashes($Address)."'",
553 "AddressCount");
554
555 # report to caller whether address is in use
556 return ($AddressCount > 0) ? TRUE : FALSE;
557 }
558
564 public function GetNewestUsers($Limit = 5)
565 {
566 # assume no users will be found
567 $Users = array();
568
569 # fetch the newest users
570 $this->DB->Query("SELECT *"
571 ." FROM APUsers"
572 ." ORDER BY CreationDate DESC"
573 ." LIMIT ".intval($Limit));
574 $UserIds = $this->DB->FetchColumn("UserId");
575
576 # for each user id found
577 foreach ($UserIds as $UserId)
578 {
579 $Users[$UserId] = new SPTUser($UserId);
580 }
581
582 # return the newest users
583 return $Users;
584 }
585
586 # ---- PRIVATE INTERFACE -------------------------------------------------
587
588 protected $DB;
589 protected $SortFieldName;
590 protected $MatchingUserCount;
591 }
User\NormalizeUserName
static NormalizeUserName($UserName)
Definition: User.php:1031
User\IsValidLookingEMailAddress
static IsValidLookingEMailAddress($EMail)
Definition: User.php:1011
U_EMPTYUSERNAME
const U_EMPTYUSERNAME
Definition: User.php:26
U_ILLEGALEMAILAGAIN
const U_ILLEGALEMAILAGAIN
Definition: User.php:32
UserFactory\EMailAddressIsInUse
EMailAddressIsInUse($Address)
Check whether e-mail address currently has account associated with it.
Definition: UserFactory.php:544
Database
SQL database abstraction object with smart query caching.
Definition: Database.php:22
UserFactory\CreateNewUser
CreateNewUser($UserName, $Password, $PasswordAgain, $EMail, $EMailAgain, $IgnoreErrorCodes=NULL)
Create new user.
Definition: UserFactory.php:44
U_EMAILSDONTMATCH
const U_EMAILSDONTMATCH
Definition: User.php:23
User\NormalizePassword
static NormalizePassword($Password)
Definition: User.php:1037
UserFactory\UserNameExists
UserNameExists($UserName)
Check whether user name currently exists.
Definition: UserFactory.php:524
U_EMPTYPASSWORD
const U_EMPTYPASSWORD
Definition: User.php:29
U_ILLEGALPASSWORDAGAIN
const U_ILLEGALPASSWORDAGAIN
Definition: User.php:28
User\IsValidPassword
static IsValidPassword($Password)
Definition: User.php:998
UserFactory\GetRecentlyLoggedInUsers
GetRecentlyLoggedInUsers($Since=NULL, $Limit=10)
Get users recently logged in.
Definition: UserFactory.php:228
U_ILLEGALEMAIL
const U_ILLEGALEMAIL
Definition: User.php:31
UserFactory\$MatchingUserCount
$MatchingUserCount
Definition: UserFactory.php:590
User
Definition: User.php:41
UserFactory\$DB
$DB
Definition: UserFactory.php:588
UserFactory\$SortFieldName
$SortFieldName
Definition: UserFactory.php:589
User\IsValidUserName
static IsValidUserName($UserName)
Definition: User.php:985
U_EMPTYPASSWORDAGAIN
const U_EMPTYPASSWORDAGAIN
Definition: User.php:30
UserFactory\GetUsersWithPrivileges
GetUsersWithPrivileges()
Return array of user names who have the specified privileges.
Definition: UserFactory.php:265
UserFactory\GetNewestUsers
GetNewestUsers($Limit=5)
Get the users sorted by when they signed up, starting with those who signed up most recently...
Definition: UserFactory.php:564
UserFactory\GetMatchingUsers
GetMatchingUsers($SearchString, $FieldName=NULL, $SortFieldName="UserName", $ResultsStartAt=0, $ReturnNumber=NULL)
Return array of users who have values matching search string (in specific field if requested)...
Definition: UserFactory.php:432
U_EMPTYEMAIL
const U_EMPTYEMAIL
Definition: User.php:33
PHP
PHP
Definition: RSSClient--Test.php:12
UserFactory\FindUsers
FindUsers($SearchString, $FieldName="UserName", $SortFieldName="UserName", $Offset=0, $Count=9999999)
Get users who have values matching specified string in specified field.
Definition: UserFactory.php:324
SPTUser
Definition: SPTUser.php:11
UserFactory
Definition: UserFactory.php:18
U_DUPLICATEUSERNAME
const U_DUPLICATEUSERNAME
Definition: User.php:24
U_OKAY
const U_OKAY
Definition: User.php:18
U_EMPTYEMAILAGAIN
const U_EMPTYEMAILAGAIN
Definition: User.php:34
UserFactory\TestNewUserValues
TestNewUserValues($UserName, $Password, $PasswordAgain, $EMail, $EMailAgain)
Test new user values (usually used before creating new user).
Definition: UserFactory.php:91
User\NormalizeEMailAddress
static NormalizeEMailAddress($EMailAddress)
Definition: User.php:1025
U_DUPLICATEEMAIL
const U_DUPLICATEEMAIL
Definition: User.php:38
UserFactory\GetUserCount
GetUserCount($Condition=NULL)
Return number of users in the system.
Definition: UserFactory.php:178
UserFactory\GetLoggedInUsers
GetLoggedInUsers($InactivityTimeout=60)
Get users who are currently logged in (i.e.
Definition: UserFactory.php:200
U_ILLEGALUSERNAME
const U_ILLEGALUSERNAME
Definition: User.php:25
UserFactory\__construct
__construct()
Object constructor.
Definition: UserFactory.php:26
UserFactory\GetMatchingUserCount
GetMatchingUserCount()
Get total number of user that matched last GetMatchingUsers() call.
Definition: UserFactory.php:189
U_ILLEGALPASSWORD
const U_ILLEGALPASSWORD
Definition: User.php:27
UserFactory\FindUserNames
FindUserNames($SearchString, $FieldName="UserName", $SortFieldName="UserName", $Offset=0, $Count=9999999, $IdExclusions=array(), $ValueExclusions=array())
Get users who have values matching specified string in specified field.
Definition: UserFactory.php:356
U_PASSWORDSDONTMATCH
const U_PASSWORDSDONTMATCH
Definition: User.php:22