CWIS Developer Documentation
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 
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  {
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;
591 }
static NormalizeUserName($UserName)
Definition: User.php:1032
static IsValidLookingEMailAddress($EMail)
Definition: User.php:1012
const U_EMPTYUSERNAME
Definition: User.php:26
const U_ILLEGALEMAILAGAIN
Definition: User.php:32
EMailAddressIsInUse($Address)
Check whether e-mail address currently has account associated with it.
SQL database abstraction object with smart query caching.
Definition: Database.php:22
CreateNewUser($UserName, $Password, $PasswordAgain, $EMail, $EMailAgain, $IgnoreErrorCodes=NULL)
Create new user.
Definition: UserFactory.php:44
const U_EMAILSDONTMATCH
Definition: User.php:23
static NormalizePassword($Password)
Definition: User.php:1038
UserNameExists($UserName)
Check whether user name currently exists.
const U_EMPTYPASSWORD
Definition: User.php:29
const U_ILLEGALPASSWORDAGAIN
Definition: User.php:28
static IsValidPassword($Password)
Definition: User.php:999
GetRecentlyLoggedInUsers($Since=NULL, $Limit=10)
Get users recently logged in.
const U_ILLEGALEMAIL
Definition: User.php:31
Definition: User.php:41
static IsValidUserName($UserName)
Definition: User.php:986
const U_EMPTYPASSWORDAGAIN
Definition: User.php:30
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)...
const U_EMPTYEMAIL
Definition: User.php:33
FindUsers($SearchString, $FieldName="UserName", $SortFieldName="UserName", $Offset=0, $Count=9999999)
Get users who have values matching specified string in specified field.
const U_DUPLICATEUSERNAME
Definition: User.php:24
const U_OKAY
Definition: User.php:18
const U_EMPTYEMAILAGAIN
Definition: User.php:34
TestNewUserValues($UserName, $Password, $PasswordAgain, $EMail, $EMailAgain)
Test new user values (usually used before creating new user).
Definition: UserFactory.php:91
static NormalizeEMailAddress($EMailAddress)
Definition: User.php:1026
const U_DUPLICATEEMAIL
Definition: User.php:38
GetUserCount($Condition=NULL)
Return number of users in the system.
GetLoggedInUsers($InactivityTimeout=60)
Get users who are currently logged in (i.e.
const U_ILLEGALUSERNAME
Definition: User.php:25
__construct()
Object constructor.
Definition: UserFactory.php:26
GetMatchingUserCount()
Get total number of user that matched last GetMatchingUsers() call.
const U_ILLEGALPASSWORD
Definition: User.php:27
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
Definition: User.php:22