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 # figure out user class name
32 $this->UserClassName = preg_replace(
33 '/Factory$/', '', get_called_class());
34 }
35
48 public function CreateNewUser(
49 $UserName, $Password, $PasswordAgain, $EMail, $EMailAgain,
50 $IgnoreErrorCodes = NULL)
51 {
52 # check incoming values
53 $ErrorCodes = $this->TestNewUserValues(
54 $UserName, $Password, $PasswordAgain, $EMail, $EMailAgain);
55
56 # discard any errors we are supposed to ignore
57 if ($IgnoreErrorCodes)
58 {
59 $ErrorCodes = array_diff($ErrorCodes, $IgnoreErrorCodes);
60 }
61
62 # if error found in incoming values return error codes to caller
63 if (count($ErrorCodes)) { return $ErrorCodes; }
64
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())");
71
72 # create new user object
73 $UserId = $this->DB->LastInsertId();
74 $User = new User($this->DB, (int)$UserId);
75
76 # if new user object creation failed return error code to caller
77 if ($User->Status() != U_OKAY) { return array($User->Status()); }
78
79 # set password and e-mail address
80 $User->SetPassword($Password);
81 $User->Set("EMail", $EMail);
82
83 # return new user object to caller
84 return $User;
85 }
86
96 public function TestNewUserValues(
97 $UserName, $Password, $PasswordAgain, $EMail, $EMailAgain)
98 {
99 $UserClass = $this->UserClassName;
100
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);
107
108 # start off assuming success
109 $ErrorCodes = array();
110
111 # check that provided username is valid
112 if (strlen($UserName) == 0)
113 {
114 $ErrorCodes[] = U_EMPTYUSERNAME;
115 }
116 elseif (!$UserClass::IsValidUserName($UserName))
117 {
118 $ErrorCodes[] = U_ILLEGALUSERNAME;
119 }
120 elseif ($this->UserNameExists($UserName))
121 {
122 $ErrorCodes[] = U_DUPLICATEUSERNAME;
123 }
124
125 # check that email is not already in use
126 if ($this->EMailAddressIsInUse($EMail))
127 {
128 $ErrorCodes[] = U_DUPLICATEEMAIL;
129 }
130
131 # check for password problems
132 $FoundOtherPasswordError = FALSE;
133 $PasswordErrors = $UserClass::CheckPasswordForErrors(
134 $Password, $UserName, $EMail);
135
136 # if there were problems, merge those in to our error list
137 if (count($PasswordErrors))
138 {
139 $ErrorCodes = array_merge($ErrorCodes, $PasswordErrors);
140 $FoundOtherPasswordError = TRUE;
141 }
142
143 # check that PasswordAgain was provided
144 if (strlen($PasswordAgain) == 0)
145 {
146 $ErrorCodes[]= U_EMPTYPASSWORDAGAIN;
147 $FoundOtherPasswordError = TRUE;
148 }
149 # and that PasswordAgain matches Password
150 elseif ($Password != $PasswordAgain)
151 {
152 $ErrorCodes[] = U_PASSWORDSDONTMATCH;
153 }
154
155 # check that provided email is valid
156 $FoundOtherEMailError = FALSE;
157 if (strlen($EMail) == 0)
158 {
159 $ErrorCodes[] = U_EMPTYEMAIL;
160 $FoundOtherEMailError = TRUE;
161 }
162 elseif (!$UserClass::IsValidLookingEMailAddress($EMail))
163 {
164 $ErrorCodes[] = U_ILLEGALEMAIL;
165 $FoundOtherEMailError = TRUE;
166 }
167
168 if (strlen($EMailAgain) == 0)
169 {
170 $ErrorCodes[] = U_EMPTYEMAILAGAIN;
171 $FoundOtherEMailError = TRUE;
172 }
173 elseif (!$UserClass::IsValidLookingEMailAddress($EMailAgain))
174 {
175 $ErrorCodes[] = U_ILLEGALEMAILAGAIN;
176 $FoundOtherEMailError = TRUE;
177 }
178
179 if ($FoundOtherEMailError == FALSE &&
180 $EMail != $EMailAgain)
181 {
182 $ErrorCodes[] = U_EMAILSDONTMATCH;
183 }
184
185 return $ErrorCodes;
186 }
187
194 public function GetUserCount($Condition = NULL)
195 {
196 return $this->DB->Query("SELECT COUNT(*) AS UserCount FROM APUsers"
197 .($Condition ? " WHERE ".$Condition : ""), "UserCount");
198 }
199
205 public function GetMatchingUserCount()
206 {
207 return $this->MatchingUserCount;
208 }
209
214 public function GetUserIds()
215 {
216 $this->DB->Query("SELECT UserId FROM APUsers");
217 return $this->DB->FetchColumn("UserId");
218 }
219
226 public function GetLoggedInUsers($InactivityTimeout = 60)
227 {
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");
235
236 # load array of logged in users
237 $ReturnValue = array();
238 foreach ($UserIds as $Id)
239 {
240 $ReturnValue[$Id] = new User(intval($Id));
241 }
242
243 # return array of user data to caller
244 return $ReturnValue;
245 }
246
254 public function GetRecentlyLoggedInUsers($Since = NULL, $Limit = 10)
255 {
256 # get users recently logged in during the last 24 hours if no date given
257 if ($Since === NULL)
258 {
259 $Date = date("Y-m-d H:i:s", time() - (24 * 60 * 60));
260 }
261
262 else
263 {
264 $Date = date("Y-m-d H:i:s", strtotime($Since));
265 }
266
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");
274
275 $ReturnValue = array();
276 foreach ($UserIds as $Id)
277 {
278 $ReturnValue[$Id] = new User(intval($Id));
279 }
280
281 # return array of user data to caller
282 return $ReturnValue;
283 }
284
291 public function GetUsersWithPrivileges()
292 {
293 # retrieve privileges
294 $Args = func_get_args();
295 if (is_array(reset($Args))) { $Args = reset($Args); }
296 $Privs = array();
297 foreach ($Args as $Arg)
298 {
299 if (is_array($Args))
300 {
301 $Privs = array_merge($Privs, $Args);
302 }
303 else
304 {
305 $Privs[] = $Arg;
306 }
307 }
308
309 # start with query string that will return all users
310 $QueryString = "SELECT DISTINCT APUsers.UserId, UserName FROM APUsers"
311 .(count($Privs) ? ", APUserPrivileges" : "");
312
313 # for each specified privilege
314 foreach ($Privs as $Index => $Priv)
315 {
316 # add condition to query string
317 $QueryString .= ($Index == 0) ? " WHERE (" : " OR";
318 $QueryString .= " APUserPrivileges.Privilege = ".$Priv;
319 }
320
321 # close privilege condition in query string and add user ID condition
322 $QueryString.= count($Privs)
323 ? ") AND APUsers.UserId = APUserPrivileges.UserId" : "";
324
325 # add sort by user name to query string
326 $QueryString .= " ORDER BY UserName ASC";
327
328 # perform query
329 $this->DB->Query($QueryString);
330
331 # copy query result into user info array
332 $Users = $this->DB->FetchColumn("UserName", "UserId");
333
334 # return array of users to caller
335 return $Users;
336 }
337
350 public function FindUsers($SearchString, $FieldName = "UserName",
351 $SortFieldName = "UserName", $Offset = 0, $Count = 9999999)
352 {
353 # retrieve matching user IDs
354 $UserNames = $this->FindUserNames(
355 $SearchString, $FieldName, $SortFieldName, $Offset, $Count);
356
357 # create user objects
358 $Users = array();
359 foreach ($UserNames as $UserId => $UserName)
360 {
361 $Users[$UserId] = new User($this->DB, intval($UserId));
362 }
363
364 # return array of user objects to caller
365 return $Users;
366 }
367
382 public function FindUserNames($SearchString, $FieldName = "UserName",
383 $SortFieldName = "UserName", $Offset = 0, $Count = 9999999,
384 $IdExclusions = array(), $ValueExclusions = array())
385 {
386 $UserClass = $this->UserClassName;
387
388 # construct a database query
389 $QueryString = "SELECT UserId, UserName FROM APUsers WHERE";
390
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 )
399 {
400 $QueryString .= " UserName='".addslashes($SearchString)."'";
401 }
402 else
403 {
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)
409 {
410 if ($InQuotedString == FALSE) { $NewSearchString .= "+"; }
411 if (preg_match("/^\"/", $Word)) { $InQuotedString = TRUE; }
412 if (preg_match("/\"$/", $Word)) { $InQuotedString = FALSE; }
413 $NewSearchString .= $Word." ";
414 }
415 $QueryString .= " MATCH (".$FieldName.")"
416 ." AGAINST ('".addslashes(trim($NewSearchString))."'"
417 ." IN BOOLEAN MODE)";
418 }
419
420 # add each ID exclusion
421 foreach ($IdExclusions as $IdExclusion)
422 {
423 $QueryString .= " AND ".$this->ItemIdFieldName." != '"
424 .addslashes($IdExclusion)."' ";
425 }
426
427 # add each value exclusion
428 foreach ($ValueExclusions as $ValueExclusion)
429 {
430 $QueryString .= " AND ".$this->ItemNameFieldName." != '"
431 .addslashes($ValueExclusion)."' ";
432 }
433
434 $QueryString .= " ORDER BY ".$SortFieldName
435 ." LIMIT ".$Offset.", ".$Count;
436
437 # retrieve matching user IDs
438 $this->DB->Query($QueryString);
439 $UserNames = $this->DB->FetchColumn("UserName", "UserId");
440
441 # return names/IDs to caller
442 return $UserNames;
443 }
444
460 public function GetMatchingUsers($SearchString, $FieldName = NULL,
461 $SortFieldName = "UserName",
462 $ResultsStartAt = 0, $ReturnNumber = NULL)
463 {
464 # start with empty array (to prevent array errors)
465 $ReturnValue = array();
466
467 # if empty search string supplied, return nothing
468 $TrimmedSearchString = trim($SearchString);
469 if (empty($TrimmedSearchString))
470 {
471 return $ReturnValue;
472 }
473
474 # make sure ordering is done by user name if not specified
475 $SortFieldName = empty($SortFieldName) ? "UserName" : $SortFieldName;
476
477 # begin constructing the query
478 $Query = "SELECT * FROM APUsers";
479 $QueryOrderBy = " ORDER BY $SortFieldName";
480 $QueryLimit = empty($ReturnNumber) ? "" : " LIMIT $ResultsStartAt, $ReturnNumber";
481
482 # the Criteria Query will be used to get the total number of results without the
483 # limit clause
484 $CriteriaQuery = $Query;
485
486 # if specific field comparison requested
487 if (!empty($FieldName))
488 {
489 # append queries with criteria
490 $Query .= " WHERE ".$FieldName." REGEXP '".addslashes($SearchString)."'";
491 $CriteriaQuery = $Query;
492 }
493
494 # optimize for returning all users
495 else if ($SearchString == ".*.")
496 {
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";
500 }
501
502 # add order by and limit to query for optimizing
503 $Query .= $QueryOrderBy.$QueryLimit;
504
505 # execute query...
506 $this->DB->Query($Query);
507
508 # ...and process query return
509 while ($Record = $this->DB->FetchRow())
510 {
511 # if specific field or all users requested
512 if (!empty($FieldName))
513 {
514 # add user to return array
515 $ReturnValue[$Record["UserId"]] = $Record;
516
517 # add matching search field to return array
518 $ReturnValue[$Record["UserId"]]["APMatchingField"] = $FieldName;
519 }
520
521 else
522 {
523 # for each user data field
524 foreach ($Record as $FName => $FValue)
525 {
526 # if search string appears in data field
527 if (strpos($Record[$FName], $SearchString) !== FALSE)
528 {
529 # add user to return array
530 $ReturnValue[$Record["UserId"]] = $Record;
531
532 # add matching search field to return array
533 $ReturnValue[$Record["UserId"]]["APMatchingField"] = $FName;
534 }
535 }
536 }
537 }
538
539 # add matching user count
540 $this->DB->Query($CriteriaQuery);
541 $this->MatchingUserCount = $this->DB->NumRowsSelected();
542
543 # return array of matching users to caller
544 return $ReturnValue;
545 }
546
552 public function UserExists($UserId)
553 {
554 if (!is_numeric($UserId))
555 {
556 return FALSE;
557 }
558 $UserCount = $this->DB->Query("SELECT COUNT(*) AS UserCount"
559 ." FROM APUsers WHERE UserId = ".intval($UserId), "UserCount");
560 return ($UserCount > 0) ? TRUE : FALSE;
561 }
562
568 public function UserNameExists($UserName)
569 {
570 # normalize user name
571 $UserClass = $this->UserClassName;
572 $UserName = $UserClass::NormalizeUserName($UserName);
573
574 # check whether user name is already in use
575 $NameCount = $this->DB->Query(
576 "SELECT COUNT(*) AS NameCount FROM APUsers"
577 ." WHERE UserName = '".addslashes($UserName)."'",
578 "NameCount");
579
580 # report to caller whether name exists
581 return ($NameCount > 0) ? TRUE : FALSE;
582 }
583
589 public function EMailAddressIsInUse($Address)
590 {
591 # normalize address
592 $UserClass = $this->UserClassName;
593 $UserName = $UserClass::NormalizeEMailAddress($Address);
594
595 # check whether address is already in use
596 $AddressCount = $this->DB->Query(
597 "SELECT COUNT(*) AS AddressCount FROM APUsers"
598 ." WHERE EMail = '".addslashes($Address)."'",
599 "AddressCount");
600
601 # report to caller whether address is in use
602 return ($AddressCount > 0) ? TRUE : FALSE;
603 }
604
610 public function GetNewestUsers($Limit = 5)
611 {
612 $UserClass = $this->UserClassName;
613
614 # assume no users will be found
615 $Users = array();
616
617 # fetch the newest users
618 $this->DB->Query("SELECT *"
619 ." FROM APUsers"
620 ." ORDER BY CreationDate DESC"
621 ." LIMIT ".intval($Limit));
622 $UserIds = $this->DB->FetchColumn("UserId");
623
624 # for each user id found
625 foreach ($UserIds as $UserId)
626 {
627 $Users[$UserId] = new $UserClass($UserId);
628 }
629
630 # return the newest users
631 return $Users;
632 }
633
634 # ---- PRIVATE INTERFACE -------------------------------------------------
635
636 protected $DB;
637 protected $SortFieldName;
638 protected $MatchingUserCount;
639 private $UserClassName;
640 }
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:589
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:48
U_EMAILSDONTMATCH
const U_EMAILSDONTMATCH
Definition: User.php:23
UserFactory\UserNameExists
UserNameExists($UserName)
Check whether user name currently exists.
Definition: UserFactory.php:568
UserFactory\GetUserIds
GetUserIds()
Get IDs for all users.
Definition: UserFactory.php:214
UserFactory\GetRecentlyLoggedInUsers
GetRecentlyLoggedInUsers($Since=NULL, $Limit=10)
Get users recently logged in.
Definition: UserFactory.php:254
U_ILLEGALEMAIL
const U_ILLEGALEMAIL
Definition: User.php:31
UserFactory\$MatchingUserCount
$MatchingUserCount
Definition: UserFactory.php:638
User
Definition: User.php:48
UserFactory\$DB
$DB
Definition: UserFactory.php:636
UserFactory\$SortFieldName
$SortFieldName
Definition: UserFactory.php:637
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:291
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:610
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:460
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:350
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:96
U_DUPLICATEEMAIL
const U_DUPLICATEEMAIL
Definition: User.php:38
UserFactory\UserExists
UserExists($UserId)
Check whether user currently exists with specified ID.
Definition: UserFactory.php:552
UserFactory\GetUserCount
GetUserCount($Condition=NULL)
Return number of users in the system.
Definition: UserFactory.php:194
UserFactory\GetLoggedInUsers
GetLoggedInUsers($InactivityTimeout=60)
Get users who are currently logged in (i.e.
Definition: UserFactory.php:226
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:205
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:382
U_PASSWORDSDONTMATCH
const U_PASSWORDSDONTMATCH
Definition: User.php:22