CWIS Developer Documentation
Axis--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  # ---- PUBLIC INTERFACE --------------------------------------------------
21 
25  function UserFactory()
26  {
27  # create database connection
28  $this->DB = new Database();
29  }
30 
43  function CreateNewUser(
44  $UserName, $Password, $PasswordAgain, $EMail, $EMailAgain,
45  $IgnoreErrorCodes = NULL)
46  {
47  # check incoming values
48  $ErrorCodes = $this->TestNewUserValues(
49  $UserName, $Password, $PasswordAgain, $EMail, $EMailAgain);
50 
51  # discard any errors we are supposed to ignore
52  if ($IgnoreErrorCodes)
53  {
54  $ErrorCodes = array_diff($ErrorCodes, $IgnoreErrorCodes);
55  }
56 
57  # if error found in incoming values return error codes to caller
58  if (count($ErrorCodes)) { return $ErrorCodes; }
59 
60  # add user to database
61  $UserName = User::NormalizeUserName($UserName);
62  $this->DB->Query("INSERT INTO APUsers"
63  ." (UserName, CreationDate)"
64  ." VALUES ('".addslashes($UserName)."', NOW())");
65 
66  # create new user object
67  $UserId = $this->DB->LastInsertId("APUsers");
68  $User = new User($this->DB, (int)$UserId);
69 
70  # if new user object creation failed return error code to caller
71  if ($User->Status() != U_OKAY) { return array($User->Status()); }
72 
73  # set password and e-mail address
74  $User->SetPassword($Password);
75  $User->Set("EMail", $EMail);
76 
77  # return new user object to caller
78  return $User;
79  }
80 
81  # test new user creation values (returns array of error codes)
83  $UserName, $Password, $PasswordAgain, $EMail, $EMailAgain)
84  {
85  $ErrorCodes = array();
86  if (strlen(User::NormalizeUserName($UserName)) == 0)
87  { $ErrorCodes[] = U_EMPTYUSERNAME; }
88  elseif (!User::IsValidUserName($UserName))
89  { $ErrorCodes[] = U_ILLEGALUSERNAME; }
90  elseif ($this->UserNameExists($UserName))
91  { $ErrorCodes[] = U_DUPLICATEUSERNAME; }
92 
93  if ($this->EMailAddressIsInUse($EMail))
94  { $ErrorCodes[] = U_DUPLICATEEMAIL; }
95 
96  $FoundOtherPasswordError = FALSE;
97  if (strlen(User::NormalizePassword($Password)) == 0)
98  {
99  $ErrorCodes[] = U_EMPTYPASSWORD;
100  $FoundOtherPasswordError = TRUE;
101  }
102  elseif (!User::IsValidPassword($Password))
103  {
104  $ErrorCodes[] = U_ILLEGALPASSWORD;
105  $FoundOtherPasswordError = TRUE;
106  }
107 
108  if (strlen(User::NormalizePassword($PasswordAgain)) == 0)
109  {
110  $ErrorCodes[] = U_EMPTYPASSWORDAGAIN;
111  $FoundOtherPasswordError = TRUE;
112  }
113  elseif (!User::IsValidPassword($PasswordAgain))
114  {
115  $ErrorCodes[] = U_ILLEGALPASSWORDAGAIN;
116  $FoundOtherPasswordError = TRUE;
117  }
118 
119  if ($FoundOtherPasswordError == FALSE)
120  {
121  if (User::NormalizePassword($Password)
122  != User::NormalizePassword($PasswordAgain))
123  {
124  $ErrorCodes[] = U_PASSWORDSDONTMATCH;
125  }
126  }
127 
128  $FoundOtherEMailError = FALSE;
129  if (strlen(User::NormalizeEMailAddress($EMail)) == 0)
130  {
131  $ErrorCodes[] = U_EMPTYEMAIL;
132  $FoundOtherEMailError = TRUE;
133  }
134  elseif (!User::IsValidLookingEMailAddress($EMail))
135  {
136  $ErrorCodes[] = U_ILLEGALEMAIL;
137  $FoundOtherEMailError = TRUE;
138  }
139 
140  if (strlen(User::NormalizeEMailAddress($EMailAgain)) == 0)
141  {
142  $ErrorCodes[] = U_EMPTYEMAILAGAIN;
143  $FoundOtherEMailError = TRUE;
144  }
145  elseif (!User::IsValidLookingEMailAddress($EMailAgain))
146  {
147  $ErrorCodes[] = U_ILLEGALEMAILAGAIN;
148  $FoundOtherEMailError = TRUE;
149  }
150 
151  if ($FoundOtherEMailError == FALSE)
152  {
153  if (User::NormalizeEMailAddress($EMail)
154  != User::NormalizeEMailAddress($EMailAgain))
155  {
156  $ErrorCodes[] = U_EMAILSDONTMATCH;
157  }
158  }
159 
160  return $ErrorCodes;
161  }
162 
168  function GetUserCount($Condition = NULL)
169  {
170  return $this->DB->Query("SELECT COUNT(*) AS UserCount FROM APUsers"
171  .($Condition ? " WHERE ".$Condition : ""), "UserCount");
172  }
173 
174  # return total number of user that matched last GetMatchingUsers call
175  # before the return size was limited
177  {
179  }
180 
187  function GetLoggedInUsers($InactivityTimeout = 60)
188  {
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");
196 
197  # load array of logged in users
198  $ReturnValue = array();
199  foreach ($UserIds as $Id)
200  {
201  $ReturnValue[$Id] = new User(intval($Id));
202  }
203 
204  # return array of user data to caller
205  return $ReturnValue;
206  }
207 
208  # return array of users recently logged in. returns 10 users by default
209  function GetRecentlyLoggedInUsers($Since = NULL, $Limit = 10)
210  {
211  # get users recently logged in during the last 24 hours if no date given
212  if ($Since === NULL)
213  {
214  $Date = date("Y-m-d H:i:s", time() - (24 * 60 * 60));
215  }
216 
217  else
218  {
219  $Date = date("Y-m-d H:i:s", strtotime($Since));
220  }
221 
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");
229 
230  $ReturnValue = array();
231  foreach ($UserIds as $Id)
232  {
233  $ReturnValue[$Id] = new User(intval($Id));
234  }
235 
236  # return array of user data to caller
237  return $ReturnValue;
238  }
239 
240  # return array of user names who have the specified privileges
241  # (array index is user IDs)
243  {
244  # start with query string that will return all users
245  $Args = func_get_args();
246  $QueryString = "SELECT DISTINCT APUsers.UserId, UserName FROM APUsers"
247  .(count($Args) ? ", APUserPrivileges" : "");
248 
249  # for each specified privilege
250  if (is_array(reset($Args))) { $Args = reset($Args); }
251  foreach ($Args as $Index => $Arg)
252  {
253  # add condition to query string
254  $QueryString .= ($Index == 0) ? " WHERE (" : " OR";
255  $QueryString .= " APUserPrivileges.Privilege = ".$Arg;
256  }
257 
258  # close privilege condition in query string and add user ID condition
259  $QueryString.= count($Args)
260  ? ") AND APUsers.UserId = APUserPrivileges.UserId" : "";
261 
262  # add sort by user name to query string
263  $QueryString .= " ORDER BY UserName ASC";
264 
265  # perform query
266  $this->DB->Query($QueryString);
267 
268  # copy query result into user info array
269  $Users = $this->DB->FetchColumn("UserName", "UserId");
270 
271  # return array of users to caller
272  return $Users;
273  }
274 
275  # return array of user objects who have values matching search string
276  # (array indexes are user IDs)
277  function FindUsers($SearchString, $FieldName = "UserName",
278  $SortFieldName = "UserName", $Offset = 0, $Count = 9999999)
279  {
280  # retrieve matching user IDs
281  $UserNames = $this->FindUserNames(
282  $SearchString, $FieldName, $SortFieldName, $Offset, $Count);
283 
284  # create user objects
285  $Users = array();
286  foreach ($UserNames as $UserId => $UserName)
287  {
288  $Users[$UserId] = new User($this->DB, intval($UserId));
289  }
290 
291  # return array of user objects to caller
292  return $Users;
293  }
294 
295  # return array of user names/IDs who have values matching search string
296  # (array indexes are user IDs, array values are user names)
297  function FindUserNames($SearchString, $FieldName = "UserName",
298  $SortFieldName = "UserName", $Offset = 0, $Count = 9999999,
299  $IdExclusions = array(), $ValueExclusions = array())
300  {
301  # Construct a database query:
302  $QueryString = "SELECT UserId, UserName FROM APUsers WHERE";
303 
304  # If the search string is a valid username which is shorter than the
305  # minimum word length indexed by the FTS, just do a normal
306  # equality test instead of using the index.
307  # Otherwise, FTS away.
308  $MinWordLen = $this->DB->Query(
309  "SHOW VARIABLES WHERE variable_name='ft_min_word_len'", "Value");
310  if (User::IsValidUserName($SearchString) &&
311  strlen($SearchString) < $MinWordLen )
312  {
313  $QueryString .= " UserName='".addslashes($SearchString)."'";
314  }
315  else
316  {
317  # massage search string to use AND logic
318  $Words = preg_split("/[\s]+/", trim($SearchString));
319  $NewSearchString = "";
320  $InQuotedString = FALSE;
321  foreach ($Words as $Word)
322  {
323  if ($InQuotedString == FALSE) { $NewSearchString .= "+"; }
324  if (preg_match("/^\"/", $Word)) { $InQuotedString = TRUE; }
325  if (preg_match("/\"$/", $Word)) { $InQuotedString = FALSE; }
326  $NewSearchString .= $Word." ";
327  }
328  $QueryString .= " MATCH (".$FieldName.")"
329  ." AGAINST ('".addslashes(trim($NewSearchString))."'"
330  ." IN BOOLEAN MODE)";
331  }
332 
333  # add each ID exclusion
334  foreach ($IdExclusions as $IdExclusion)
335  {
336  $QueryString .= " AND ".$this->ItemIdFieldName." != '"
337  .addslashes($IdExclusion)."' ";
338  }
339 
340  # add each value exclusion
341  foreach ($ValueExclusions as $ValueExclusion)
342  {
343  $QueryString .= " AND ".$this->ItemNameFieldName." != '"
344  .addslashes($ValueExclusion)."' ";
345  }
346 
347  $QueryString .= " ORDER BY ".$SortFieldName
348  ." LIMIT ".$Offset.", ".$Count;
349 
350  # retrieve matching user IDs
351  $this->DB->Query($QueryString);
352  $UserNames = $this->DB->FetchColumn("UserName", "UserId");
353 
354  # return names/IDs to caller
355  return $UserNames;
356  }
357 
358  # return array of users who have values matching search string (in specific field if requested)
359  # (search string respects POSIX-compatible regular expressions)
360  # optimization: $SearchString = ".*." and $FieldName = NULL will return all
361  # users ordered by $SortFieldName
362  function GetMatchingUsers($SearchString, $FieldName = NULL,
363  $SortFieldName = "UserName",
364  $ResultsStartAt = 0, $ReturnNumber = NULL)
365  {
366  # start with empty array (to prevent array errors)
367  $ReturnValue = array();
368 
369  # if empty search string supplied, return nothing
370  $TrimmedSearchString = trim($SearchString);
371  if (empty($TrimmedSearchString))
372  {
373  return $ReturnValue;
374  }
375 
376  # make sure ordering is done by user name if not specified
377  $SortFieldName = empty($SortFieldName) ? "UserName" : $SortFieldName;
378 
379  # begin constructing the query
380  $Query = "SELECT * FROM APUsers";
381  $QueryOrderBy = " ORDER BY $SortFieldName";
382  $QueryLimit = empty($ReturnNumber) ? "" : " LIMIT $ResultsStartAt, $ReturnNumber";
383 
384  # the Criteria Query will be used to get the total number of results without the
385  # limit clause
386  $CriteriaQuery = $Query;
387 
388  # if specific field comparison requested
389  if (!empty($FieldName))
390  {
391  # append queries with criteria
392  $Query .= " WHERE ".$FieldName." REGEXP '".addslashes($SearchString)."'";
393  $CriteriaQuery = $Query;
394  }
395 
396  # optimize for returning all users
397  else if ($SearchString == ".*.")
398  {
399  # set field name to username - this would be the first field
400  # returned by a field to field search using the above RegExp
401  $FieldName = "UserName";
402  }
403 
404  # add order by and limit to query for optimizing
405  $Query .= $QueryOrderBy.$QueryLimit;
406 
407  # execute query...
408  $this->DB->Query($Query);
409 
410  # ...and process query return
411  while ($Record = $this->DB->FetchRow())
412  {
413  # if specific field or all users requested
414  if (!empty($FieldName))
415  {
416  # add user to return array
417  $ReturnValue[$Record["UserId"]] = $Record;
418 
419  # add matching search field to return array
420  $ReturnValue[$Record["UserId"]]["APMatchingField"] = $FieldName;
421  }
422 
423  else
424  {
425  # for each user data field
426  foreach ($Record as $FName => $FValue)
427  {
428  # if search string appears in data field
429  if (strpos($Record[$FName], $SearchString) !== FALSE)
430  {
431  # add user to return array
432  $ReturnValue[$Record["UserId"]] = $Record;
433 
434  # add matching search field to return array
435  $ReturnValue[$Record["UserId"]]["APMatchingField"] = $FName;
436  }
437  }
438  }
439  }
440 
441  # add matching user count
442  $this->DB->Query($CriteriaQuery);
443  $this->MatchingUserCount = $this->DB->NumRowsSelected();
444 
445  # return array of matching users to caller
446  return $ReturnValue;
447  }
448 
449  # check whether user name currently exists
450  function UserNameExists($UserName)
451  {
452  # normalize user name
453  $UserName = User::NormalizeUserName($UserName);
454 
455  # check whether user name is already in use
456  $NameCount = $this->DB->Query(
457  "SELECT COUNT(*) AS NameCount FROM APUsers"
458  ." WHERE UserName = '".addslashes($UserName)."'",
459  "NameCount");
460 
461  # report to caller whether name exists
462  return ($NameCount > 0);
463  }
464 
465  # check whether e-mail address currently has account associated with it
466  function EMailAddressIsInUse($Address)
467  {
468  # normalize address
469  $UserName = User::NormalizeEMailAddress($Address);
470 
471  # check whether address is already in use
472  $AddressCount = $this->DB->Query(
473  "SELECT COUNT(*) AS AddressCount FROM APUsers"
474  ." WHERE EMail = '".addslashes($Address)."'",
475  "AddressCount");
476 
477  # report to caller whether address is in use
478  return ($AddressCount > 0);
479  }
480 
486  public function GetNewestUsers($Limit = 5)
487  {
488  # assume no users will be found
489  $Users = array();
490 
491  # fetch the newest users
492  $this->DB->Query("SELECT *"
493  ." FROM APUsers"
494  ." ORDER BY CreationDate DESC"
495  ." LIMIT ".intval($Limit));
496  $UserIds = $this->DB->FetchColumn("UserId");
497 
498  # for each user id found
499  foreach ($UserIds as $UserId)
500  {
501  $Users[$UserId] = new SPTUser($UserId);
502  }
503 
504  # return the newest users
505  return $Users;
506  }
507 
508  # ---- PRIVATE INTERFACE -------------------------------------------------
509 
510  var $DB;
513 
514  # callback function for sorting users
515  function CompareUsersForSort($UserA, $UserB)
516  {
517  return strcasecmp($UserA[$this->SortFieldName], $UserB[$this->SortFieldName]);
518  }
519 
520 }
const U_EMPTYEMAIL
Definition: Axis--User.php:34
static NormalizeUserName($UserName)
Definition: Axis--User.php:953
static IsValidLookingEMailAddress($EMail)
Definition: Axis--User.php:941
EMailAddressIsInUse($Address)
const U_ILLEGALUSERNAME
Definition: Axis--User.php:26
SQL database abstraction object with smart query caching.
CreateNewUser($UserName, $Password, $PasswordAgain, $EMail, $EMailAgain, $IgnoreErrorCodes=NULL)
Create new user.
static NormalizePassword($Password)
Definition: Axis--User.php:959
UserNameExists($UserName)
static IsValidPassword($Password)
Definition: Axis--User.php:934
GetRecentlyLoggedInUsers($Since=NULL, $Limit=10)
UserFactory()
Object constructor.
static IsValidUserName($UserName)
Definition: Axis--User.php:928
const U_DUPLICATEEMAIL
Definition: Axis--User.php:39
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)
PHP
Definition: OAIClient.php:39
const U_DUPLICATEUSERNAME
Definition: Axis--User.php:25
const U_EMPTYUSERNAME
Definition: Axis--User.php:27
FindUsers($SearchString, $FieldName="UserName", $SortFieldName="UserName", $Offset=0, $Count=9999999)
const U_EMPTYEMAILAGAIN
Definition: Axis--User.php:35
const U_PASSWORDSDONTMATCH
Definition: Axis--User.php:23
TestNewUserValues($UserName, $Password, $PasswordAgain, $EMail, $EMailAgain)
static NormalizeEMailAddress($EMailAddress)
Definition: Axis--User.php:947
const U_ILLEGALPASSWORD
Definition: Axis--User.php:28
const U_ILLEGALEMAIL
Definition: Axis--User.php:32
const U_EMPTYPASSWORDAGAIN
Definition: Axis--User.php:31
const U_ILLEGALEMAILAGAIN
Definition: Axis--User.php:33
const U_OKAY
Definition: Axis--User.php:19
GetUserCount($Condition=NULL)
Return number of users in the system.
GetLoggedInUsers($InactivityTimeout=60)
Get users who are currently logged in (i.e.
const U_EMAILSDONTMATCH
Definition: Axis--User.php:24
CompareUsersForSort($UserA, $UserB)
FindUserNames($SearchString, $FieldName="UserName", $SortFieldName="UserName", $Offset=0, $Count=9999999, $IdExclusions=array(), $ValueExclusions=array())
const U_EMPTYPASSWORD
Definition: Axis--User.php:30
const U_ILLEGALPASSWORDAGAIN
Definition: Axis--User.php:29