CWIS Developer Documentation
CWUser.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # FILE: CWUser.php
4 #
5 # Part of the Collection Workflow Integration System (CWIS)
6 # Copyright 2013 Edward Almasy and Internet Scout Research Group
7 # http://scout.wisc.edu/cwis/
8 #
9 
13 class CWUser extends User
14 {
15 
16  # ---- PUBLIC INTERFACE --------------------------------------------------
17 
22  public function __construct($UserInfo=NULL)
23  {
24  static $EmailWrapperSet = FALSE;
25  if (!$EmailWrapperSet)
26  {
27  User::SetEmailFunction(array("CWUser", "EmailWrapper"));
28  $EmailWrapperSet = TRUE;
29  }
30 
31  parent::__construct($UserInfo);
32 
33  if ($this->Result !== U_OKAY)
34  {
35  throw new Exception(
36  "Unable to load user information.");
37  }
38 
39  # try to fetch the associated resource if the user was found
40  if (!$this->IsAnonymous())
41  {
42  $Resource = $this->FetchAssociatedResource($this->UserId);
43 
44  # the associated resource was successfully found
45  if ($Resource instanceof Resource)
46  {
47  $this->Resource = $Resource;
48  }
49  # there was a problem finding the resource
50  else
51  {
52  throw new Exception(
53  "Unable to load corresponding resource for user.");
54  }
55  }
56  else
57  {
58  $this->Resource = NULL;
59  }
60  }
61 
70  public function Login($UserName, $Password, $IgnorePassword = FALSE)
71  {
72  parent::Login($UserName, $Password, $IgnorePassword);
73 
74  if ($this->Result == U_OKAY)
75  {
76  $Resource = $this->FetchAssociatedResource($this->UserId);
77 
78  # the associated resource was successfully found
79  if ($Resource instanceof Resource)
80  {
81  $this->Resource = $Resource;
82  }
83  # there was a problem finding the resource
84  else
85  {
86  throw new Exception(
87  "Unable to load corresponding resource for user.");
88  }
89  }
90 
91  return $this->Result;
92  }
93 
97  public function Logout()
98  {
99  parent::Logout();
100  $this->Resource = NULL;
101  }
102 
110  public function Privileges(PrivilegeSet $NewValue = NULL)
111  {
112  if ($NewValue !== NULL)
113  {
114  throw new Exception(
115  "Attempt to set user privileges with CWUser::Privileges(), "
116  ."which is no longer supported");
117  }
118 
119  return new PrivilegeSetCompatibilityShim($this);
120  }
121 
127  public function ResourceId()
128  {
129  return ($this->Resource !== NULL) ? $this->Resource->Id() : NULL;
130  }
131 
137  public function GetResource()
138  {
139  return ($this->Resource !== NULL) ? $this->Resource : NULL;
140  }
141 
154  public function HasPriv($Privilege, $Privileges = NULL)
155  {
156  if ($Privilege instanceof PrivilegeSet)
157  {
158  if ($Privileges instanceof Resource)
159  {
160  return $Privilege->MeetsRequirements($this, $Privileges);
161  }
162  else
163  {
164  return $Privilege->MeetsRequirements($this);
165  }
166  }
167  else
168  {
169  $Args = func_get_args();
170  if (in_array(PRIV_ISLOGGEDIN, $Args) && $this->IsLoggedIn())
171  {
172  return TRUE;
173  }
174 
175  $Args = self::FilterPrivileges($Args);
176  if (count($Args)>0)
177  {
178  return call_user_func_array( "parent::HasPriv", $Args);
179  }
180 
181  return FALSE;
182  }
183  }
184 
191  public function GrantPriv($Privilege)
192  {
193  if (self::IsPseudoPrivilege($Privilege))
194  {
195  throw new Exception("Attempt to grant pseudo-privilege to user");
196  }
197 
198  return parent::GrantPriv($Privilege);
199  }
200 
207  public function SetPrivList($NewPrivileges)
208  {
209  parent::SetPrivList( self::FilterPrivileges($NewPrivileges) );
210  }
211 
222  public static function EmailWrapper($To, $Subject, $Message, $AdditionalHeaders)
223  {
224  # extract "From" address from supplied headers if available
225  if (strlen($AdditionalHeaders))
226  {
227  $HeaderLines = explode("\n", $AdditionalHeaders);
228  $Headers = array();
229  foreach ($HeaderLines as $Line)
230  {
231  $HeaderLine = trim($Line);
232  if (preg_match("/^from:/i", $Line))
233  {
234  $From = preg_replace("/^from:/i", "", $Line);
235  }
236  else
237  {
238  $Headers[] = $HeaderLine;
239  }
240  }
241  }
242 
243  # send message
244  $Msg = new Email();
245  if (isset($From)) { $Msg->From($From); }
246  $Msg->To($To);
247  $Msg->Subject($Subject);
248  $Msg->AddHeaders($Headers);
249  $Msg->Body($Message);
250  $Result = $Msg->Send();
251 
252  # report success to caller
253  return $Result;
254  }
255 
260  public static function GetCustomUserFields()
261  {
262  static $CustomFields;
263 
264  if (!isset($CustomFields))
265  {
266  $CustomFields = array();
268 
269  foreach ($Schema->GetFields() as $Field)
270  {
271  # they're custom if not owned by CWIS
272  if ($Field->Owner() != "CWISCore")
273  {
274  $CustomFields[$Field->Id()] = $Field;
275  }
276  }
277  }
278 
279  return $CustomFields;
280  }
281 
286  public static function GetDefaultUserFields()
287  {
288  static $DefaultFields;
289 
290  if (!isset($DefaultFields))
291  {
292  $DefaultFields = array();
294 
295  foreach ($Schema->GetFields() as $Field)
296  {
297  # they're default if owned by CWIS
298  if ($Field->Owner() == "CWISCore")
299  {
300  $DefaultFields[$Field->Id()] = $Field;
301  }
302  }
303  }
304 
305  return $DefaultFields;
306  }
307 
308  # ---- OVERRIDDEN METHODS ------------------------------------------------
309 
315  public function Delete()
316  {
317  # delete the associated user resource if set
318  if (isset($this->Resource))
319  {
320  $this->Resource->Delete();
321  $this->Result = U_OKAY;
322  }
323 
324  return parent::Delete();
325  }
326 
333  public function Get($FieldName)
334  {
335  # all values are NULL for anonymous users
336  if ($this->IsAnonymous())
337  {
338  return NULL;
339  }
340 
341  if (in_array($FieldName, self::$FieldsOnlyInAPUsers))
342  {
343  return parent::Get($FieldName);
344  }
345  else
346  {
347  return $this->Resource->Get($FieldName);
348  }
349  }
350 
357  public function Set($Field, $NewValue)
358  {
359  if ($this->IsAnonymous())
360  {
361  throw new Exception(
362  "Attempt to set User field value when "
363  ."no user is logged in.");
364  }
365 
366  # make sure Field is a FieldName
367  if ($Field instanceof MetadataField)
368  {
369  $Field = $Field->Name();
370  }
371 
372  # if this field is not among those that should only exists in
373  # the APUsers table
374  if (!in_array($Field, self::$FieldsOnlyInAPUsers))
375  {
376  # set it in our corresponding resource
377  $this->Resource->Set($Field, $NewValue);
378  }
379 
380  # if the given field exists in the APUsers table, update that too
381  if ($this->DB->FieldExists("APUsers", $Field))
382  {
383  parent::Set($Field, $NewValue);
384  }
385  else
386  {
387  # indicate success for fields that don't have a column in APUsers
388  $this->Result = U_OKAY;
389  }
390 
391  return $this->Result;
392  }
393 
394  # ---- PRIVATE INTERFACE -------------------------------------------------
395 
400  protected $Resource = NULL;
401 
402  # list of fields that exist in APUsers that are not mirrored as MetadataFields
403  private static $FieldsOnlyInAPUsers = [
404  # fields necessary to for user identification
405  "UserId", "UserName", "EMail", "EMailNew",
406 
407  # fields necessary for authentication
408  "UserPassword", "RegistrationConfirmed",
409 
410  # fields that can't be in a schema because they are updated by User
411  "LastLoginDate", "LastActiveDate", "LastIPAddress", "LastLocation", "LoggedIn",
412 
413  # user preferences
414  "ActiveUI", "BrowsingFieldId", "RecordsPerPage", "SearchSelections",
415  ];
416 
423  protected function FetchAssociatedResource($UserId)
424  {
425  if (self::$UserIdFieldId === NULL)
426  {
427  # get the user schema
429 
430  # pull out the UserId field, which should only be one
431  $Field = $Schema->GetField("UserId");
432 
433  # and get its FieldId
434  self::$UserIdFieldId = intval($Field->Id());
435  }
436 
437  # find the matching Resources (should only be one)
438  $this->DB->Query(
439  "SELECT ResourceId FROM ResourceUserInts WHERE ".
440  "FieldId=".self::$UserIdFieldId.
441  " AND UserId=".intval($UserId) );
442  $ResourceIds = $this->DB->FetchColumn("ResourceId");
443  $ResourceIdCount = count($ResourceIds);
444 
445  # no resource found
446  if ($ResourceIdCount < 1)
447  {
448  return U_NOSUCHUSER;
449  }
450 
451  # too many resources found
452  if ($ResourceIdCount > 1)
453  {
454  throw new Exception(
455  "Multiple resources exist for a single user, "
456  ."which should be impossible");
457  }
458 
459  # construct the associated resource and return it
460  return new Resource(array_shift($ResourceIds));
461  }
462 
469  public static function IsStandardPrivilege($Priv)
470  {
471  return (self::MIN_STANDARD_PRIV <= $Priv &&
472  $Priv <= self::MAX_STANDARD_PRIV) ? TRUE : FALSE;
473  }
474 
481  public static function IsPseudoPrivilege($Priv)
482  {
483  return (self::MIN_PSEUDO_PRIV <= $Priv &&
484  $Priv <= self::MAX_PSEUDO_PRIV) ? TRUE : FALSE;
485  }
486 
493  public static function IsCustomPrivilege($Priv)
494  {
495  return (self::MIN_CUSTOM_PRIV <= $Priv &&
496  $Priv <= self::MAX_CUSTOM_PRIV) ? TRUE : FALSE;
497  }
498 
504  protected function FilterPrivileges($Privs)
505  {
506  $Result = [];
507  foreach ($Privs as $Priv)
508  {
509  if (!self::IsPseudoPrivilege($Priv))
510  {
511  $Result[]= $Priv;
512  }
513  }
514 
515  return $Result;
516  }
517 
518  const MIN_STANDARD_PRIV = 1;
519  const MAX_STANDARD_PRIV = 74;
520 
521  const MIN_PSEUDO_PRIV = 75;
522  const MAX_PSEUDO_PRIV = 99;
523 
524  const MIN_CUSTOM_PRIV = 100;
525  const MAX_CUSTOM_PRIV = PHP_INT_MAX;
526 
527  # ---- MAINTAINED FOR BACKWARD COMPATIBILITY IN INTERFACES (BEGIN)
528 
529  # ---- user interface preference mnemonics
530  # color avoidance flags
531  const UIPREF_AVOID_RED = 1;
532  const UIPREF_AVOID_REDGREEN = 2;
533  const UIPREF_AVOID_BLUEYELLOW = 4;
534  const UIPREF_AVOID_GREENYELLOW = 8;
535  const UIPREF_AVOID_ORANGE = 16;
536  const UIPREF_AVOID_REDBLACK = 32;
537  const UIPREF_AVOID_PURPLEGREY = 64;
538  const UIPREF_AVOID_USEMAXMONOCHR = 128;
539 
540  # content display options
541  const UIPREF_CONTENTDENSITY_NOPREFERENCE = 0;
542  const UIPREF_CONTENTDENSITY_DETAILED = 1;
543  const UIPREF_CONTENTDENSITY_OVERVIEW = 2;
544 
545  # content view options
546  const UIPREF_CONTENTVIEW_NOPREFERENCE = 0;
547  const UIPREF_CONTENTVIEW_TEXTINTENSIVE = 1;
548  const UIPREF_CONTENTVIEW_IMAGEINTENSIVE = 2;
549 
550  # audio description options
551  const UIPREF_AUDIODESCRIPTION_NONE = 0;
552  const UIPREF_AUDIODESCRIPTION_STANDARD = 1;
553  const UIPREF_AUDIODESCRIPTION_EXPANDED = 2;
554 
555  # caption type options
556  const UIPREF_CAPTIONTYPE_NONE = 0;
557  const UIPREF_CAPTIONTYPE_VERBATIM = 1;
558  const UIPREF_CAPTIONTYPE_REDUCEDREADINGLEVEL = 2;
559 
560  // @codingStandardsIgnoreStart
561 
562  # user interface / accessibility preferences
563  function PrefFontSize($NewValue = DB_NOVALUE)
564  { return 0; }
565 
566  function PrefFontTypeFace($NewValue = DB_NOVALUE)
567  { return 0; }
568 
569  function PrefFontColor($NewValue = DB_NOVALUE)
570  { return 0; }
571 
572  function PrefBackgroundColor($NewValue = DB_NOVALUE)
573  { return 0; }
574 
575  function PrefColorAvoidanceFlags($NewValue = DB_NOVALUE)
576  { return 0; }
577 
578  function PrefContentDensity($NewValue = DB_NOVALUE)
579  { return 0; }
580 
581  function PrefContentView($NewValue = DB_NOVALUE)
582  { return 0; }
583 
584  function PrefAudioDescriptionLevel($NewValue = DB_NOVALUE)
585  { return 0; }
586 
587  function PrefAudioDescriptionLanguage($NewValue = DB_NOVALUE)
588  { return 0; }
589 
590  function PrefVisualDescriptionLanguage($NewValue = DB_NOVALUE)
591  { return 0; }
592 
593  function PrefImageDescriptionLanguage($NewValue = DB_NOVALUE)
594  { return 0; }
595 
596  function PrefUseGraphicAlternatives($NewValue = DB_NOVALUE)
597  { return 0; }
598 
599  function PrefSignLanguage($NewValue = DB_NOVALUE)
600  { return 0; }
601 
602  function PrefCaptionType($NewValue = DB_NOVALUE)
603  { return 0; }
604 
605  function PrefCaptionRate($NewValue = DB_NOVALUE)
606  { return 0; }
607 
608  // @codingStandardsIgnoreEnd
609  # ---- MAINTAINED FOR BACKWARD COMPATIBILITY IN INTERFACES (END)
610 
611  private static $UserIdFieldId = NULL;
612 }
IsLoggedIn()
Report whether user is currently logged in.
Definition: User.php:474
Metadata schema (in effect a Factory class for MetadataField).
$Resource
The user resource associated with the user or NULL if the user isn&#39;t logged in.
Definition: CWUser.php:400
Privileges(PrivilegeSet $NewValue=NULL)
THIS FUNCTION HAS BEEN DEPRECATED This provides compatibility for interfaces written to use a version...
Definition: CWUser.php:110
ResourceId()
Get the ID of the user resource associated with the user.
Definition: CWUser.php:127
Delete()
Delete the user and its associated user resource.
Definition: CWUser.php:315
Id()
Retrieve numerical resource ID.
Definition: Resource.php:294
HasPriv($Privilege, $Privileges=NULL)
Determine if a user has a given privilege, or satisfies the conditions specified by a given privilege...
Definition: CWUser.php:154
Get($FieldName)
Get a value from the specified field.
Definition: CWUser.php:333
Set($Field, $NewValue)
Set a value for the specified field.
Definition: CWUser.php:357
Definition: User.php:48
SetPrivList($NewPrivileges)
Clear current user privs and replace them with the specified list.
Definition: CWUser.php:207
Set of privileges used to access resource information or other parts of the system.
Login($UserName, $Password, $IgnorePassword=FALSE)
Log the specified user in and associate the underlying Resource with this CWUser. ...
Definition: CWUser.php:70
Electronic mail message.
Definition: Email.php:14
Get($Field, $ReturnObject=FALSE, $IncludeVariants=FALSE)
Retrieve value using field name or field object.
Definition: Resource.php:420
__construct($UserInfo=NULL)
Load user data from the given user info or from the session if available.
Definition: CWUser.php:22
const DB_NOVALUE
Definition: Database.php:1784
IsAnonymous()
Report whether user is anonymous user.
Definition: User.php:500
static EmailWrapper($To, $Subject, $Message, $AdditionalHeaders)
Adapter method to bridge between User class and Email class.
Definition: CWUser.php:222
static SetEmailFunction($NewValue)
Set email function to use instead of mail().
Definition: User.php:208
const U_OKAY
Definition: User.php:18
$Result
Definition: User.php:990
Compatibility layer allowing interfaces built against the privilege system from CWIS 3...
Object representing a locally-defined type of metadata field.
Represents a "resource" in CWIS.
Definition: Resource.php:13
static GetDefaultUserFields()
Get the default user fields.
Definition: CWUser.php:286
const U_NOSUCHUSER
Definition: User.php:21
$UserId
Definition: User.php:989
static GetCustomUserFields()
Get all custom user fields.
Definition: CWUser.php:260
Set($Field, $NewValue, $Reset=FALSE)
Set value using field name or field object.
Definition: Resource.php:1153
GetResource()
Get the associated user resource for this user.
Definition: CWUser.php:137
CWIS-specific user class.
Definition: CWUser.php:13
GrantPriv($Privilege)
Grant privilege to a a user.
Definition: CWUser.php:191
Logout()
Log this user out and disassociate their underlying Resource from this CWUser.
Definition: CWUser.php:97
Delete()
Remove resource (and accompanying associations) from database and delete any associated files...
Definition: Resource.php:142