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/
20 # ---- PUBLIC INTERFACE --------------------------------------------------
27 # create database connection
44 $UserName, $Password, $PasswordAgain, $EMail, $EMailAgain,
45 $IgnoreErrorCodes = NULL)
47 # check incoming values
49 $UserName, $Password, $PasswordAgain, $EMail, $EMailAgain);
51 # discard any errors we are supposed to ignore
52 if ($IgnoreErrorCodes)
54 $ErrorCodes = array_diff($ErrorCodes, $IgnoreErrorCodes);
57 # if error found in incoming values return error codes to caller
58 if (count($ErrorCodes)) {
return $ErrorCodes; }
60 # add user to database
62 $this->DB->Query(
"INSERT INTO APUsers"
63 .
" (UserName, CreationDate)"
64 .
" VALUES ('".addslashes($UserName).
"', NOW())");
66 # create new user object
67 $UserId = $this->DB->LastInsertId();
68 $User =
new User($this->DB, (
int)$UserId);
70 # if new user object creation failed return error code to caller
71 if ($User->Status() !=
U_OKAY) {
return array($User->Status()); }
73 # set password and e-mail address
74 $User->SetPassword($Password);
75 $User->Set(
"EMail", $EMail);
77 # return new user object to caller
81 # test new user creation values (returns array of error codes)
83 $UserName, $Password, $PasswordAgain, $EMail, $EMailAgain)
85 $ErrorCodes = array();
96 $FoundOtherPasswordError = FALSE;
100 $FoundOtherPasswordError = TRUE;
105 $FoundOtherPasswordError = TRUE;
111 $FoundOtherPasswordError = TRUE;
116 $FoundOtherPasswordError = TRUE;
119 if ($FoundOtherPasswordError == FALSE)
128 $FoundOtherEMailError = FALSE;
132 $FoundOtherEMailError = TRUE;
137 $FoundOtherEMailError = TRUE;
143 $FoundOtherEMailError = TRUE;
148 $FoundOtherEMailError = TRUE;
151 if ($FoundOtherEMailError == FALSE)
170 return $this->DB->Query(
"SELECT COUNT(*) AS UserCount FROM APUsers"
171 .($Condition ?
" WHERE ".$Condition :
""),
"UserCount");
174 # return total number of user that matched last GetMatchingUsers call
175 # before the return size was limited
189 # query IDs of logged-in users from database
190 $LoggedInCutoffTime = date(
"Y-m-d H:i:s",
191 time() - ($InactivityTimeout * 60));
192 $this->DB->Query(
"SELECT UserId FROM APUsers"
193 .
" WHERE LastActiveDate > '".$LoggedInCutoffTime.
"'"
194 .
" AND LoggedIn != '0'");
195 $UserIds = $this->DB->FetchColumn(
"UserId");
197 # load array of logged in users
198 $ReturnValue = array();
199 foreach ($UserIds as $Id)
201 $ReturnValue[$Id] =
new User(intval($Id));
204 # return array of user data to caller
208 # return array of users recently logged in. returns 10 users by default
211 # get users recently logged in during the last 24 hours if no date given
214 $Date = date(
"Y-m-d H:i:s", time() - (24 * 60 * 60));
219 $Date = date(
"Y-m-d H:i:s", strtotime($Since));
222 # query for the users who were logged in since the given date
223 $this->DB->Query(
"SELECT UserId FROM APUsers"
224 .
" WHERE LastActiveDate > '".$Date.
"'"
225 .
" AND LoggedIn != '1'"
226 .
" ORDER BY LastActiveDate DESC"
227 .
" LIMIT ".intval($Limit));
228 $UserIds = $this->DB->FetchColumn(
"UserId");
230 $ReturnValue = array();
231 foreach ($UserIds as $Id)
233 $ReturnValue[$Id] =
new User(intval($Id));
236 # return array of user data to caller
249 # retrieve privileges
250 $Args = func_get_args();
251 if (is_array(reset($Args))) { $Args = reset($Args); }
253 foreach ($Args as $Arg)
257 $Privs = array_merge($Privs, $Args);
265 # start with query string that will return all users
266 $QueryString =
"SELECT DISTINCT APUsers.UserId, UserName FROM APUsers"
267 .(count($Privs) ?
", APUserPrivileges" :
"");
269 # for each specified privilege
270 foreach ($Privs as $Index => $Priv)
272 # add condition to query string
273 $QueryString .= ($Index == 0) ?
" WHERE (" :
" OR";
274 $QueryString .=
" APUserPrivileges.Privilege = ".$Priv;
277 # close privilege condition in query string and add user ID condition
278 $QueryString.= count($Privs)
279 ?
") AND APUsers.UserId = APUserPrivileges.UserId" :
"";
281 # add sort by user name to query string
282 $QueryString .=
" ORDER BY UserName ASC";
285 $this->DB->Query($QueryString);
287 # copy query result into user info array
288 $Users = $this->DB->FetchColumn(
"UserName",
"UserId");
290 # return array of users to caller
294 # return array of user objects who have values matching search string
295 # (array indexes are user IDs)
296 function FindUsers($SearchString, $FieldName =
"UserName",
299 # retrieve matching user IDs
303 # create user objects
305 foreach ($UserNames as $UserId => $UserName)
307 $Users[$UserId] =
new User($this->DB, intval($UserId));
310 # return array of user objects to caller
314 # return array of user names/IDs who have values matching search string
315 # (array indexes are user IDs, array values are user names)
318 $IdExclusions = array(), $ValueExclusions = array())
320 # Construct a database query:
321 $QueryString =
"SELECT UserId, UserName FROM APUsers WHERE";
323 # If the search string is a valid username which is shorter than the
324 # minimum word length indexed by the FTS, just do a normal
325 # equality test instead of using the index.
326 # Otherwise, FTS away.
327 $MinWordLen = $this->DB->Query(
328 "SHOW VARIABLES WHERE variable_name='ft_min_word_len'",
"Value");
330 strlen($SearchString) < $MinWordLen )
332 $QueryString .=
" UserName='".addslashes($SearchString).
"'";
336 # massage search string to use AND logic
337 $Words = preg_split(
"/[\s]+/", trim($SearchString));
338 $NewSearchString =
"";
339 $InQuotedString = FALSE;
340 foreach ($Words as $Word)
342 if ($InQuotedString == FALSE) { $NewSearchString .=
"+"; }
343 if (preg_match(
"/^\"/", $Word)) { $InQuotedString = TRUE; }
344 if (preg_match(
"/\"$/", $Word)) { $InQuotedString = FALSE; }
345 $NewSearchString .= $Word.
" ";
347 $QueryString .=
" MATCH (".$FieldName.
")"
348 .
" AGAINST ('".addslashes(trim($NewSearchString)).
"'"
349 .
" IN BOOLEAN MODE)";
352 # add each ID exclusion
353 foreach ($IdExclusions as $IdExclusion)
355 $QueryString .=
" AND ".$this->ItemIdFieldName.
" != '"
356 .addslashes($IdExclusion).
"' ";
359 # add each value exclusion
360 foreach ($ValueExclusions as $ValueExclusion)
362 $QueryString .=
" AND ".$this->ItemNameFieldName.
" != '"
363 .addslashes($ValueExclusion).
"' ";
366 $QueryString .=
" ORDER BY ".$SortFieldName
367 .
" LIMIT ".$Offset.
", ".$Count;
369 # retrieve matching user IDs
370 $this->DB->Query($QueryString);
371 $UserNames = $this->DB->FetchColumn(
"UserName",
"UserId");
373 # return names/IDs to caller
377 # return array of users who have values matching search string (in specific field if requested)
378 # (search string respects POSIX-compatible regular expressions)
379 # optimization: $SearchString = ".*." and $FieldName = NULL will return all
380 # users ordered by $SortFieldName
383 $ResultsStartAt = 0, $ReturnNumber = NULL)
385 # start with empty array (to prevent array errors)
386 $ReturnValue = array();
388 # if empty search string supplied, return nothing
389 $TrimmedSearchString = trim($SearchString);
390 if (empty($TrimmedSearchString))
395 # make sure ordering is done by user name if not specified
398 # begin constructing the query
399 $Query =
"SELECT * FROM APUsers";
400 $QueryOrderBy =
" ORDER BY $SortFieldName";
401 $QueryLimit = empty($ReturnNumber) ?
"" :
" LIMIT $ResultsStartAt, $ReturnNumber";
403 # the Criteria Query will be used to get the total number of results without the
405 $CriteriaQuery = $Query;
407 # if specific field comparison requested
408 if (!empty($FieldName))
410 # append queries with criteria
411 $Query .=
" WHERE ".$FieldName.
" REGEXP '".addslashes($SearchString).
"'";
412 $CriteriaQuery = $Query;
415 # optimize for returning all users
416 else if ($SearchString ==
".*.")
418 # set field name to username - this would be the first field
419 # returned by a field to field search using the above RegExp
420 $FieldName =
"UserName";
423 # add order by and limit to query for optimizing
424 $Query .= $QueryOrderBy.$QueryLimit;
427 $this->DB->Query($Query);
429 # ...and process query return
430 while ($Record = $this->DB->FetchRow())
432 # if specific field or all users requested
433 if (!empty($FieldName))
435 # add user to return array
436 $ReturnValue[$Record[
"UserId"]] = $Record;
438 # add matching search field to return array
439 $ReturnValue[$Record[
"UserId"]][
"APMatchingField"] = $FieldName;
444 # for each user data field
445 foreach ($Record as $FName => $FValue)
447 # if search string appears in data field
448 if (strpos($Record[$FName], $SearchString) !== FALSE)
450 # add user to return array
451 $ReturnValue[$Record[
"UserId"]] = $Record;
453 # add matching search field to return array
454 $ReturnValue[$Record[
"UserId"]][
"APMatchingField"] = $FName;
460 # add matching user count
461 $this->DB->Query($CriteriaQuery);
462 $this->MatchingUserCount = $this->DB->NumRowsSelected();
464 # return array of matching users to caller
468 # check whether user name currently exists
471 # normalize user name
474 # check whether user name is already in use
475 $NameCount = $this->DB->Query(
476 "SELECT COUNT(*) AS NameCount FROM APUsers"
477 .
" WHERE UserName = '".addslashes($UserName).
"'",
480 # report to caller whether name exists
481 return ($NameCount > 0);
484 # check whether e-mail address currently has account associated with it
490 # check whether address is already in use
491 $AddressCount = $this->DB->Query(
492 "SELECT COUNT(*) AS AddressCount FROM APUsers"
493 .
" WHERE EMail = '".addslashes($Address).
"'",
496 # report to caller whether address is in use
497 return ($AddressCount > 0);
507 # assume no users will be found
510 # fetch the newest users
511 $this->DB->Query(
"SELECT *"
513 .
" ORDER BY CreationDate DESC"
514 .
" LIMIT ".intval($Limit));
515 $UserIds = $this->DB->FetchColumn(
"UserId");
517 # for each user id found
518 foreach ($UserIds as $UserId)
520 $Users[$UserId] =
new SPTUser($UserId);
523 # return the newest users
527 # ---- PRIVATE INTERFACE -------------------------------------------------
533 # callback function for sorting users
536 return strcasecmp($UserA[$this->SortFieldName], $UserB[$this->SortFieldName]);
static NormalizeUserName($UserName)
static IsValidLookingEMailAddress($EMail)
EMailAddressIsInUse($Address)
SQL database abstraction object with smart query caching.
CreateNewUser($UserName, $Password, $PasswordAgain, $EMail, $EMailAgain, $IgnoreErrorCodes=NULL)
Create new user.
static NormalizePassword($Password)
UserNameExists($UserName)
static IsValidPassword($Password)
GetRecentlyLoggedInUsers($Since=NULL, $Limit=10)
UserFactory()
Object constructor.
static IsValidUserName($UserName)
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)
const U_DUPLICATEUSERNAME
FindUsers($SearchString, $FieldName="UserName", $SortFieldName="UserName", $Offset=0, $Count=9999999)
const U_PASSWORDSDONTMATCH
TestNewUserValues($UserName, $Password, $PasswordAgain, $EMail, $EMailAgain)
static NormalizeEMailAddress($EMailAddress)
const U_EMPTYPASSWORDAGAIN
const U_ILLEGALEMAILAGAIN
GetUserCount($Condition=NULL)
Return number of users in the system.
GetLoggedInUsers($InactivityTimeout=60)
Get users who are currently logged in (i.e.
CompareUsersForSort($UserA, $UserB)
FindUserNames($SearchString, $FieldName="UserName", $SortFieldName="UserName", $Offset=0, $Count=9999999, $IdExclusions=array(), $ValueExclusions=array())
const U_ILLEGALPASSWORDAGAIN