4 # Axis--UserFactory.php 5 # An Meta-Object for Handling User Information 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). 12 # Author: Edward Almasy (ealmasy@axisdata.com) 14 # Part of the AxisPHP library v1.2.4 15 # For more information see http://www.axisdata.com/AxisPHP/ 21 # ---- PUBLIC INTERFACE -------------------------------------------------- 28 # create database connection 31 # figure out user class name 32 $this->UserClassName = preg_replace(
33 '/Factory$/',
'', get_called_class());
49 $UserName, $Password, $PasswordAgain, $EMail, $EMailAgain,
50 $IgnoreErrorCodes = NULL)
52 # check incoming values 54 $UserName, $Password, $PasswordAgain, $EMail, $EMailAgain);
56 # discard any errors we are supposed to ignore 57 if ($IgnoreErrorCodes)
59 $ErrorCodes = array_diff($ErrorCodes, $IgnoreErrorCodes);
62 # if error found in incoming values return error codes to caller 63 if (count($ErrorCodes)) {
return $ErrorCodes; }
65 # add user to database 66 $UserClass = $this->UserClassName;
67 $UserName = $UserClass::NormalizeUserName($UserName);
68 $this->DB->Query(
"INSERT INTO APUsers" 69 .
" (UserName, CreationDate)" 70 .
" VALUES ('".addslashes($UserName).
"', NOW())");
72 # create new user object 73 $UserId = $this->DB->LastInsertId();
74 $User =
new User($this->DB, (
int)$UserId);
76 # if new user object creation failed return error code to caller 77 if ($User->Status() !=
U_OKAY) {
return array($User->Status()); }
79 # set password and e-mail address 80 $User->SetPassword($Password);
81 $User->Set(
"EMail", $EMail);
83 # return new user object to caller 97 $UserName, $Password, $PasswordAgain, $EMail, $EMailAgain)
99 $UserClass = $this->UserClassName;
101 # normalize incoming values 102 $UserName = $UserClass::NormalizeUserName($UserName);
103 $Password = $UserClass::NormalizePassword($Password);
104 $PasswordAgain = $UserClass::NormalizePassword($PasswordAgain);
105 $EMail = $UserClass::NormalizeEMailAddress($EMail);
106 $EMailAgain = $UserClass::NormalizeEMailAddress($EMailAgain);
108 # start off assuming success 109 $ErrorCodes = array();
111 # check that provided username is valid 112 if (strlen($UserName) == 0)
116 elseif (!$UserClass::IsValidUserName($UserName))
125 # check that email is not already in use 131 # check for password problems 132 $FoundOtherPasswordError = FALSE;
133 $PasswordErrors = $UserClass::CheckPasswordForErrors(
134 $Password, $UserName, $EMail);
136 # if there were problems, merge those in to our error list 137 if (count($PasswordErrors))
139 $ErrorCodes = array_merge($ErrorCodes, $PasswordErrors);
140 $FoundOtherPasswordError = TRUE;
143 # check that PasswordAgain was provided 144 if (strlen($PasswordAgain) == 0)
147 $FoundOtherPasswordError = TRUE;
149 # and that PasswordAgain matches Password 150 elseif ($Password != $PasswordAgain)
155 # check that provided email is valid 156 $FoundOtherEMailError = FALSE;
157 if (strlen($EMail) == 0)
160 $FoundOtherEMailError = TRUE;
162 elseif (!$UserClass::IsValidLookingEMailAddress($EMail))
165 $FoundOtherEMailError = TRUE;
168 if (strlen($EMailAgain) == 0)
171 $FoundOtherEMailError = TRUE;
173 elseif (!$UserClass::IsValidLookingEMailAddress($EMailAgain))
176 $FoundOtherEMailError = TRUE;
179 if ($FoundOtherEMailError == FALSE &&
180 $EMail != $EMailAgain)
196 return $this->DB->Query(
"SELECT COUNT(*) AS UserCount FROM APUsers" 197 .($Condition ?
" WHERE ".$Condition :
""),
"UserCount");
216 $this->DB->Query(
"SELECT UserId FROM APUsers");
217 return $this->DB->FetchColumn(
"UserId");
228 # query IDs of logged-in users from database 229 $LoggedInCutoffTime = date(
"Y-m-d H:i:s",
230 time() - ($InactivityTimeout * 60));
231 $this->DB->Query(
"SELECT UserId FROM APUsers" 232 .
" WHERE LastActiveDate > '".$LoggedInCutoffTime.
"'" 233 .
" AND LoggedIn != '0'");
234 $UserIds = $this->DB->FetchColumn(
"UserId");
236 # load array of logged in users 237 $ReturnValue = array();
238 foreach ($UserIds as $Id)
240 $ReturnValue[$Id] =
new User(intval($Id));
243 # return array of user data to caller 256 # get users recently logged in during the last 24 hours if no date given 259 $Date = date(
"Y-m-d H:i:s", time() - (24 * 60 * 60));
264 $Date = date(
"Y-m-d H:i:s", strtotime($Since));
267 # query for the users who were logged in since the given date 268 $this->DB->Query(
"SELECT UserId FROM APUsers" 269 .
" WHERE LastActiveDate > '".$Date.
"'" 270 .
" AND LoggedIn != '1'" 271 .
" ORDER BY LastActiveDate DESC" 272 .
" LIMIT ".intval($Limit));
273 $UserIds = $this->DB->FetchColumn(
"UserId");
275 $ReturnValue = array();
276 foreach ($UserIds as $Id)
278 $ReturnValue[$Id] =
new User(intval($Id));
281 # return array of user data to caller 293 # retrieve privileges 294 $Args = func_get_args();
295 if (is_array(reset($Args))) { $Args = reset($Args); }
297 foreach ($Args as $Arg)
301 $Privs = array_merge($Privs, $Args);
309 # start with query string that will return all users 310 $QueryString =
"SELECT DISTINCT APUsers.UserId, UserName FROM APUsers" 311 .(count($Privs) ?
", APUserPrivileges" :
"");
313 # for each specified privilege 314 foreach ($Privs as $Index => $Priv)
316 # add condition to query string 317 $QueryString .= ($Index == 0) ?
" WHERE (" :
" OR";
318 $QueryString .=
" APUserPrivileges.Privilege = ".$Priv;
321 # close privilege condition in query string and add user ID condition 322 $QueryString.= count($Privs)
323 ?
") AND APUsers.UserId = APUserPrivileges.UserId" :
"";
325 # add sort by user name to query string 326 $QueryString .=
" ORDER BY UserName ASC";
329 $this->DB->Query($QueryString);
331 # copy query result into user info array 332 $Users = $this->DB->FetchColumn(
"UserName",
"UserId");
334 # return array of users to caller 350 public function FindUsers($SearchString, $FieldName =
"UserName",
353 # retrieve matching user IDs 357 # create user objects 359 foreach ($UserNames as $UserId => $UserName)
361 $Users[$UserId] =
new User($this->DB, intval($UserId));
364 # return array of user objects to caller 384 $IdExclusions = array(), $ValueExclusions = array())
386 $UserClass = $this->UserClassName;
388 # construct a database query 389 $QueryString =
"SELECT UserId, UserName FROM APUsers WHERE";
391 # If the search string is a valid username which is shorter than the 392 # minimum word length indexed by the FTS, just do a normal 393 # equality test instead of using the index. 394 # Otherwise, FTS away. 395 $MinWordLen = $this->DB->Query(
396 "SHOW VARIABLES WHERE variable_name='ft_min_word_len'",
"Value");
397 if ($UserClass::IsValidUserName($SearchString) &&
398 strlen($SearchString) < $MinWordLen )
400 $QueryString .=
" UserName='".addslashes($SearchString).
"'";
404 # massage search string to use AND logic 405 $Words = preg_split(
"/[\s]+/", trim($SearchString));
406 $NewSearchString =
"";
407 $InQuotedString = FALSE;
408 foreach ($Words as $Word)
410 if ($InQuotedString == FALSE) { $NewSearchString .=
"+"; }
411 if (preg_match(
"/^\"/", $Word)) { $InQuotedString = TRUE; }
412 if (preg_match(
"/\"$/", $Word)) { $InQuotedString = FALSE; }
413 $NewSearchString .= $Word.
" ";
415 $QueryString .=
" MATCH (".$FieldName.
")" 416 .
" AGAINST ('".addslashes(trim($NewSearchString)).
"'" 417 .
" IN BOOLEAN MODE)";
420 # add each ID exclusion 421 foreach ($IdExclusions as $IdExclusion)
423 $QueryString .=
" AND ".$this->ItemIdFieldName.
" != '" 424 .addslashes($IdExclusion).
"' ";
427 # add each value exclusion 428 foreach ($ValueExclusions as $ValueExclusion)
430 $QueryString .=
" AND ".$this->ItemNameFieldName.
" != '" 431 .addslashes($ValueExclusion).
"' ";
434 $QueryString .=
" ORDER BY ".$SortFieldName
435 .
" LIMIT ".$Offset.
", ".$Count;
437 # retrieve matching user IDs 438 $this->DB->Query($QueryString);
439 $UserNames = $this->DB->FetchColumn(
"UserName",
"UserId");
441 # return names/IDs to caller 462 $ResultsStartAt = 0, $ReturnNumber = NULL)
464 # start with empty array (to prevent array errors) 465 $ReturnValue = array();
467 # if empty search string supplied, return nothing 468 $TrimmedSearchString = trim($SearchString);
469 if (empty($TrimmedSearchString))
474 # make sure ordering is done by user name if not specified 477 # begin constructing the query 478 $Query =
"SELECT * FROM APUsers";
479 $QueryOrderBy =
" ORDER BY $SortFieldName";
480 $QueryLimit = empty($ReturnNumber) ?
"" :
" LIMIT $ResultsStartAt, $ReturnNumber";
482 # the Criteria Query will be used to get the total number of results without the 484 $CriteriaQuery = $Query;
486 # if specific field comparison requested 487 if (!empty($FieldName))
489 # append queries with criteria 490 $Query .=
" WHERE ".$FieldName.
" REGEXP '".addslashes($SearchString).
"'";
491 $CriteriaQuery = $Query;
494 # optimize for returning all users 495 else if ($SearchString ==
".*.")
497 # set field name to username - this would be the first field 498 # returned by a field to field search using the above RegExp 499 $FieldName =
"UserName";
502 # add order by and limit to query for optimizing 503 $Query .= $QueryOrderBy.$QueryLimit;
506 $this->DB->Query($Query);
508 # ...and process query return 509 while ($Record = $this->DB->FetchRow())
511 # if specific field or all users requested 512 if (!empty($FieldName))
514 # add user to return array 515 $ReturnValue[$Record[
"UserId"]] = $Record;
517 # add matching search field to return array 518 $ReturnValue[$Record[
"UserId"]][
"APMatchingField"] = $FieldName;
523 # for each user data field 524 foreach ($Record as $FName => $FValue)
526 # if search string appears in data field 527 if (strpos($Record[$FName], $SearchString) !== FALSE)
529 # add user to return array 530 $ReturnValue[$Record[
"UserId"]] = $Record;
532 # add matching search field to return array 533 $ReturnValue[$Record[
"UserId"]][
"APMatchingField"] = $FName;
539 # add matching user count 540 $this->DB->Query($CriteriaQuery);
541 $this->MatchingUserCount = $this->DB->NumRowsSelected();
543 # return array of matching users to caller 554 # normalize user name 555 $UserClass = $this->UserClassName;
556 $UserName = $UserClass::NormalizeUserName($UserName);
558 # check whether user name is already in use 559 $NameCount = $this->DB->Query(
560 "SELECT COUNT(*) AS NameCount FROM APUsers" 561 .
" WHERE UserName = '".addslashes($UserName).
"'",
564 # report to caller whether name exists 565 return ($NameCount > 0) ? TRUE : FALSE;
576 $UserClass = $this->UserClassName;
577 $UserName = $UserClass::NormalizeEMailAddress($Address);
579 # check whether address is already in use 580 $AddressCount = $this->DB->Query(
581 "SELECT COUNT(*) AS AddressCount FROM APUsers" 582 .
" WHERE EMail = '".addslashes($Address).
"'",
585 # report to caller whether address is in use 586 return ($AddressCount > 0) ? TRUE : FALSE;
596 $UserClass = $this->UserClassName;
598 # assume no users will be found 601 # fetch the newest users 602 $this->DB->Query(
"SELECT *" 604 .
" ORDER BY CreationDate DESC" 605 .
" LIMIT ".intval($Limit));
606 $UserIds = $this->DB->FetchColumn(
"UserId");
608 # for each user id found 609 foreach ($UserIds as $UserId)
611 $Users[$UserId] =
new $UserClass($UserId);
614 # return the newest users 618 # ---- PRIVATE INTERFACE ------------------------------------------------- 623 private $UserClassName;
const U_ILLEGALEMAILAGAIN
EMailAddressIsInUse($Address)
Check whether e-mail address currently has account associated with it.
SQL database abstraction object with smart query caching.
CreateNewUser($UserName, $Password, $PasswordAgain, $EMail, $EMailAgain, $IgnoreErrorCodes=NULL)
Create new user.
UserNameExists($UserName)
Check whether user name currently exists.
GetUserIds()
Get IDs for all users.
GetRecentlyLoggedInUsers($Since=NULL, $Limit=10)
Get users recently logged in.
const U_EMPTYPASSWORDAGAIN
GetUsersWithPrivileges()
Return array of user names who have the specified privileges.
GetNewestUsers($Limit=5)
Get the users sorted by when they signed up, starting with those who signed up most recently...
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)...
FindUsers($SearchString, $FieldName="UserName", $SortFieldName="UserName", $Offset=0, $Count=9999999)
Get users who have values matching specified string in specified field.
const U_DUPLICATEUSERNAME
TestNewUserValues($UserName, $Password, $PasswordAgain, $EMail, $EMailAgain)
Test new user values (usually used before creating new user).
GetUserCount($Condition=NULL)
Return number of users in the system.
GetLoggedInUsers($InactivityTimeout=60)
Get users who are currently logged in (i.e.
__construct()
Object constructor.
GetMatchingUserCount()
Get total number of user that matched last GetMatchingUsers() call.
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.
const U_PASSWORDSDONTMATCH