CWIS Developer Documentation
PrivilegeSet.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # FILE: PrivilegeSet.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 
17 {
27  public function __construct($Data = NULL)
28  {
29  # if privilege data supplied
30  if ($Data !== NULL)
31  {
32  # if data is an array of privileges
33  if (is_array($Data))
34  {
35  # set internal privilege set from array
36  $this->Privileges = $Data;
37  }
38  # else if data is a single privilege
39  elseif (is_numeric($Data))
40  {
41  # set internal privilege set from data
42  $this->Privileges = array($Data);
43  }
44  else
45  {
46  # set internal values from data
47  $this->LoadFromData($Data);
48  }
49  }
50  }
51 
62  public function Data($NewValue = NULL)
63  {
64  # if new data supplied
65  if ($NewValue !== NULL)
66  {
67  # unpack privilege data and load
68  $this->LoadFromData($NewValue);
69  }
70 
71  # serialize current data and return to caller
72  $Data = array();
73  if (count($this->Privileges))
74  {
75  foreach ($this->Privileges as $Priv)
76  {
77  $Data["Privileges"][] = is_object($Priv)
78  ? array("SUBSET" => $Priv->Data())
79  : $Priv;
80  }
81  }
82  $Data["Logic"] = $this->Logic;
83  return serialize($Data);
84  }
85 
96  public function MeetsRequirements(CWUser $User, $Resource = self::NO_RESOURCE)
97  {
98  # when there are no requirements, then every user meets them
99  $Satisfied = TRUE;
100 
101  # for each privilege requirement
102  foreach ($this->Privileges as $Priv)
103  {
104  # if privilege is actually a privilege subgroup
105  if (is_object($Priv))
106  {
107  # check if the subgroup is satisfied
108  $Satisfied = $Priv->MeetsRequirements($User, $Resource);
109  }
110  # else if privilege is actually a condition
111  elseif (is_array($Priv))
112  {
113  # check if condition is satisfied for the given resource
114  $Satisfied = $this->MeetsCondition($Priv, $Resource, $User);
115  }
116  # else privilege is actually a privilege
117  else
118  {
119  # check if user has the spcified privilege
120  $Satisfied = $User->HasPriv( $Priv );
121  }
122 
123  # for AND logic, we can bail as soon as the first
124  # condition is not met
125  if ($this->Logic == "AND")
126  {
127  if (!$Satisfied)
128  {
129  break;
130  }
131  }
132  # conversely, for OR logic, we can bail as soon as any
133  # condition is met
134  else
135  {
136  if ($Satisfied)
137  {
138  break;
139  }
140  }
141  }
142 
143  # report result of the test back to caller
144  return $Satisfied;
145  }
146 
156  public function FindUsersThatMeetRequirements($ResourceIds = array())
157  {
158  # if there are necessary privileges for this privilege set
159  $ReqPrivs = $this->GetPossibleNecessaryPrivileges();
160  $UFactory = new CWUserFactory();
161  if (count($ReqPrivs))
162  {
163  # start with only those users who have at least one of those privileges
164  $UserIds = array_keys($UFactory->GetUsersWithPrivileges($ReqPrivs));
165  }
166  else
167  {
168  # start with all users
169  $UserIds = $UFactory->GetUserIds();
170  }
171 
172  # determine of individual resources will need to be checked
173  $NeedToCheckResources =
174  (count($ResourceIds) && count($this->FieldsWithUserComparisons()))
175  ? TRUE : FALSE ;
176 
177  # build up a list of matching users
178  $UsersThatMeetReqs = array();
179 
180  # iterate over all the users
181  foreach ($UserIds as $UserId)
182  {
183  # load user
184  $User = new CWUser($UserId);
185 
186  if ($NeedToCheckResources)
187  {
188  # iterate over all the resources
189  foreach ($ResourceIds as $ResourceId)
190  {
191  # if we're running low on memory, nuke the resource cache
192  if ($GLOBALS["AF"]->GetFreeMemory() /
193  $GLOBALS["AF"]->GetPhpMemoryLimit() < self::$LowMemoryThresh)
194  {
195  self::$ResourceCache = [];
196  }
197 
198  # load resource
199  if (!isset(self::$ResourceCache[$ResourceId]))
200  {
201  self::$ResourceCache[$ResourceId] = new Resource($ResourceId);
202  }
203 
204  # if user meets requirements for set
205  if ($this->MeetsRequirements(
206  $User, self::$ResourceCache[$ResourceId]))
207  {
208  # add resource to user's list
209  $UsersThatMeetReqs[$UserId][] = $ResourceId;
210  }
211  }
212  }
213  else
214  {
215  # if user meets requirements for set
216  if ($this->MeetsRequirements($User))
217  {
218  # add user to list
219  $UsersThatMeetReqs[$UserId] = $ResourceIds;
220  }
221  }
222  }
223 
224  # return IDs for users that meet requirements to caller
225  return $UsersThatMeetReqs;
226  }
227 
234  public function AddPrivilege($Privileges)
235  {
236  # convert incoming value to array if needed
237  if (!is_array($Privileges))
238  {
239  $Privileges = array($Privileges);
240  }
241 
242  # for each privilege passed in
243  foreach ($Privileges as $Privilege)
244  {
245  # add privilege if not currently in set
246  if (!$this->IncludesPrivilege($Privilege))
247  {
248  if (is_object($Privilege)) { $Privilege = $Privilege->Id(); }
249  $this->Privileges[] = $Privilege;
250  }
251  }
252  }
253 
260  public function RemovePrivilege($Privilege)
261  {
262  # remove privilege if currently in set
263  if ($this->IncludesPrivilege($Privilege))
264  {
265  if (is_object($Privilege)) { $Privilege = $Privilege->Id(); }
266  $Index = array_search($Privilege, $this->Privileges);
267  unset($this->Privileges[$Index]);
268  }
269  }
270 
276  public function IncludesPrivilege($Privilege)
277  {
278  # check whether privilege is in our list and report to caller
279  if (is_object($Privilege)) { $Privilege = $Privilege->Id(); }
280  return $this->IsInPrivilegeData($Privilege) ? TRUE : FALSE;
281  }
282 
291  public function GetPrivilegeInfo()
292  {
293  # grab privilege information and add logic
294  $Info = $this->Privileges;
295  $Info["Logic"] = $this->Logic;
296 
297  # return privilege info array to caller
298  return $Info;
299  }
300 
307  public function GetPrivilegeList()
308  {
309  # create list of privileges with conditions stripped out
310  $List = array();
311  foreach ($this->Privileges as $Priv)
312  {
313  if (!is_array($Priv)) { $List[] = $Priv; }
314  }
315 
316  # return list of privileges to caller
317  return $List;
318  }
319 
336  public function AddCondition($Field, $Value = NULL, $Operator = "==")
337  {
338  # get field ID
339  $FieldId = is_object($Field) ? $Field->Id() : $Field;
340 
341  # make sure we were not passed an invalid field
342  if ($FieldId <= -1)
343  {
344  throw new InvalidArgumentException("Field with negative ID supplied.");
345  }
346 
347  # set up condition array
348  $Condition = array(
349  "FieldId" => intval($FieldId),
350  "Operator" => trim($Operator),
351  "Value" => $Value);
352 
353  # if condition is not already in set
354  if (!$this->IsInPrivilegeData($Condition))
355  {
356  # add condition to privilege set
357  $this->Privileges[] = $Condition;
358  return TRUE;
359  }
360  return FALSE;
361  }
362 
376  public function RemoveCondition(
377  $Field, $Value = NULL, $Operator = "==",
378  $IncludeSubsets = FALSE)
379  {
380  $Result = FALSE;
381 
382  # get field ID
383  $FieldId = is_object($Field) ? $Field->Id() : $Field;
384 
385  # set up condition array
386  $Condition = array(
387  "FieldId" => intval($FieldId),
388  "Operator" => trim($Operator),
389  "Value" => $Value);
390 
391  # if condition is in set
392  if ($this->IsInPrivilegeData($Condition))
393  {
394  # remove condition from privilege set
395  $Index = array_search($Condition, $this->Privileges);
396  unset($this->Privileges[$Index]);
397  $Result = TRUE;
398  }
399 
400  if ($IncludeSubsets)
401  {
402  foreach ($this->Privileges as $Priv)
403  {
404  if ($Priv instanceof PrivilegeSet)
405  {
406  $Result |= $Priv->RemoveCondition(
407  $FieldId, $Value, $Operator, TRUE);
408  }
409  }
410  }
411 
412  return $Result;
413  }
414 
419  public function AddSet(PrivilegeSet $Set)
420  {
421  # if subgroup is not already in set
422  if (!$this->IsInPrivilegeData($Set))
423  {
424  # add subgroup to privilege set
425  $this->Privileges[] = $Set;
426  }
427  }
428 
438  public function AllRequired($NewValue = NULL)
439  {
440  if ($NewValue !== NULL)
441  {
442  $this->Logic = $NewValue ? "AND" : "OR";
443  }
444  return ($this->Logic == "AND") ? TRUE : FALSE;
445  }
446 
452  public function PrivilegeFlagsChecked()
453  {
454  $Info = $this->GetPrivilegeInfo();
455  unset($Info["Logic"]);
456 
457  $Result = array();
458  foreach ($Info as $Item)
459  {
460  if (is_object($Item))
461  {
462  $Result = array_merge($Result, $Item->PrivilegeFlagsChecked() );
463  }
464  elseif (!is_array($Item))
465  {
466  $Result[]= $Item;
467  }
468  }
469  return array_unique($Result);
470  }
471 
479  public function FieldsWithUserComparisons($ComparisonType = NULL)
480  {
481  $Info = $this->GetPrivilegeInfo();
482  unset($Info["Logic"]);
483 
484  $Result = array();
485  foreach ($Info as $Item)
486  {
487  if (is_object($Item))
488  {
489  $Result = array_merge(
490  $Result,
491  $Item->FieldsWithUserComparisons($ComparisonType));
492  }
493  elseif (is_array($Item))
494  {
495  if ( (($Item["Operator"] == $ComparisonType)
496  || ($ComparisonType === NULL)) &&
497  MetadataSchema::FieldExistsInAnySchema($Item["FieldId"]))
498  {
499  $Field = new MetadataField($Item["FieldId"]);
500 
501  if ($Field->Type() == MetadataSchema::MDFTYPE_USER)
502  {
503  $Result[]= $Item["FieldId"];
504  }
505  }
506  }
507  }
508 
509  return array_unique($Result);
510  }
511 
516  public function ComparisonCount()
517  {
518  $Count = 0;
519  foreach ($this->Privileges as $Priv)
520  {
521  $Count += is_object($Priv) ? $Priv->ComparisonCount() : 1;
522  }
523  return $Count;
524  }
525 
535  {
536  # for each privilege requirement
537  $NecessaryPrivs = array();
538  foreach ($this->Privileges as $Priv)
539  {
540  # if requirement is comparison
541  if (is_array($Priv))
542  {
543  # if logic is OR
544  if ($this->Logic == "OR")
545  {
546  # bail out because no privileges are required
547  return array();
548  }
549  }
550  # else if requirement is subgroup
551  elseif (is_object($Priv))
552  {
553  # retrieve possible needed privileges from subgroup
554  $SubPrivs = $Priv->GetPossibleNecessaryPrivileges();
555 
556  # if no privileges were required by subgroup
557  if (!count($SubPrivs))
558  {
559  # if logic is OR
560  if ($this->Logic == "OR")
561  {
562  # bail out because no privileges are required
563  return array();
564  }
565  }
566  else
567  {
568  # add subgroup privileges to required list
569  $NecessaryPrivs = array_merge($NecessaryPrivs, $SubPrivs);
570  }
571  }
572  # else requirement is privilege
573  else
574  {
575  # add privilege to required list
576  $NecessaryPrivs[] = $Priv;
577  }
578  }
579 
580  # return possible needed privileges to caller
581  return $NecessaryPrivs;
582  }
583 
589  public function ChecksField($FieldId)
590  {
591  # iterate over all the privs in this privset
592  foreach ($this->Privileges as $Priv)
593  {
594  # if this priv is a field condition that references the
595  # provided FieldId, return true
596  if (is_array($Priv) && $Priv["FieldId"] == $FieldId)
597  {
598  return TRUE;
599  }
600  # otherwise, if this was a privset then call ourself recursively
601  elseif ($Priv instanceof PrivilegeSet &&
602  $Priv->ChecksField($FieldId))
603  {
604  return TRUE;
605  }
606  }
607 
608  # found no references to this field, return FALSE
609  return FALSE;
610  }
611 
616  public static function ClearCaches()
617  {
618  self::$MetadataFieldCache = array();
619  self::$ResourceCache = array();
620  self::$ValueCache = array();
621  }
622 
623  # ---- PRIVATE INTERFACE -------------------------------------------------
624 
625  private $RFactories = array();
626  private $Privileges = array();
627  private $Logic = "OR";
628 
629  private static $MetadataFieldCache;
630  private static $ResourceCache;
631  private static $ValueCache;
632 
633  private static $LowMemoryThresh = 0.25;
634 
635  const NO_RESOURCE = "XXX NO RESOURCE XXX";
636 
642  private function LoadFromData($Serialized)
643  {
644  # save calling context in case load causes out-of-memory crash
645  $GLOBALS["AF"]->RecordContextInCaseOfCrash();
646 
647  # unpack new data
648  $Data = unserialize($Serialized);
649  if ($Data === FALSE)
650  {
651  throw new InvalidArgumentException(
652  "Invalid serialized data supplied (\"".$Serialized."\").");
653  }
654 
655  # unpack privilege data (if available) and load
656  if (array_key_exists("Privileges", $Data))
657  {
658  $this->Privileges = array();
659  foreach ($Data["Privileges"] as $Priv)
660  {
661  if (is_array($Priv) && array_key_exists("SUBSET", $Priv))
662  {
663  $Subset = new PrivilegeSet();
664  $Subset->LoadFromData($Priv["SUBSET"]);
665  $this->Privileges[] = $Subset;
666  }
667  else
668  {
669  $this->Privileges[] = $Priv;
670  }
671  }
672  }
673 
674  # load logic if available
675  if (array_key_exists("Logic", $Data))
676  {
677  $this->Logic = $Data["Logic"];
678  }
679  }
680 
688  private function MeetsCondition($Condition, $Resource, $User)
689  {
690  # make sure metadata field is loaded
691  $MFieldId = $Condition["FieldId"];
692  if (!isset(self::$MetadataFieldCache[$MFieldId]))
693  {
694  self::$MetadataFieldCache[$MFieldId] =
695  !MetadataSchema::FieldExistsInAnySchema($Condition["FieldId"])
696  ? FALSE
697  : new MetadataField($MFieldId);
698  }
699 
700  # if the specified field does not exist
701  if (self::$MetadataFieldCache[$MFieldId] === FALSE)
702  {
703  # return a result that in effect ignores the condition
704  return ($this->Logic == "AND") ? TRUE : FALSE;
705  }
706 
707  # pull out provided field
708  $Field = self::$MetadataFieldCache[$MFieldId];
709  $Operator = $Condition["Operator"];
710  $Value = $Condition["Value"];
711 
712  # determine if the provided operator is valid for the provided field
713  if (!in_array($Operator, $this->ValidOperatorsForFieldType($Field->Type()) ))
714  {
715  throw new Exception("Operator ".$Operator." not supported for "
716  .$Field->TypeAsName()." fields");
717  }
718 
719  # if we don't have a specific resource to check, then we want
720  # to determine if this condition would be satisfied by any
721  # resource
722  if ($Resource == self::NO_RESOURCE)
723  {
724  $Count = $this->CountResourcesThatSatisfyCondition(
725  $User, $Field, $Operator, $Value);
726  return $Count > 0 ? TRUE : FALSE;
727  }
728  # else if resource is valid
729  elseif ($Resource instanceof Resource)
730  {
731  # if this field is from a different schema than our resource
732  # and also this field is not from the User schema, then there's
733  # no comparison for us to do
734  if ($Field->SchemaId() != $Resource->SchemaId() &&
735  $Field->SchemaId() != MetadataSchema::SCHEMAID_USER)
736  {
737  # return a result that in effect ignores the condition
738  return ($this->Logic == "AND") ? TRUE : FALSE;
739  }
740 
741  # normalize the incoming value for comparison
742  $Value = $this->NormalizeTargetValue($Field->Type(), $User, $Value);
743  $FieldValue = $this->GetNormalizedFieldValue($Field, $Resource, $User);
744 
745  # perform comparison, returning result
746  return $this->CompareNormalizedFieldValues($FieldValue, $Operator, $Value);
747  }
748  else
749  {
750  # error out because resource was illegal
751  throw new Exception("Invalid Resource passed in for privilege"
752  ." set comparison.");
753  }
754  }
755 
762  private function ValidOperatorsForFieldType($FieldType)
763  {
764  switch ($FieldType)
765  {
767  $ValidOps = ["=="];
768  break;
769 
773  $ValidOps = ["==", "!=", "<=", "<", ">=", ">"];
774  break;
775 
778  $ValidOps = ["==", "!="];
779  break;
780 
781  default:
782  $ValidOps = [];
783  break;
784  }
785 
786  return $ValidOps;
787  }
788 
797  private function NormalizeTargetValue($FieldType, $User, $Value)
798  {
799  switch ($FieldType)
800  {
803  # "Now" is encoded as NULL for timestamp and date comparisons
804  if ($Value === NULL)
805  {
806  $Value = time();
807  }
808  # otherwise, parse the value to get a numeric timestamp
809  else
810  {
811  $Value = strtotime($Value);
812  }
813  break;
814 
816  # "Current user" is encoded as NULL for user comparisons
817  if ($Value === NULL)
818  {
819  $Value = $User->Id();
820  }
821  break;
822 
823  default:
824  # no normalization needed for other field types
825  break;
826  }
827 
828  return $Value;
829  }
830 
845  private function GetNormalizedFieldValue($Field, $Resource, $User)
846  {
847  # if we have a cached normalized value for this field,
848  # use that for comparisons
849  $CacheKey = $Resource->Id()."_".$Field->Id();
850  if (!isset(self::$ValueCache[$CacheKey]))
851  {
852  # if the given field comes from the User schema and our
853  # resource does not, evaluate this comparison against the
854  # provided $User rather than the provided $Resource
855  # (this allows conditions like User: Zip Code = XXX to
856  # work as expected rather than being skipped)
857  if ($Field->SchemaId() != $Resource->SchemaId() &&
858  $Field->SchemaId() == MetadataSchema::SCHEMAID_USER)
859  {
860  $FieldValue = $User->Get($Field);
861  }
862  else
863  {
864  # Note: Resource::Get() on a ControlledName with
865  # IncludeVariants=TRUE does not return CNIds for
866  # array indexes, which will break the normalization
867  # below, so do not change this to add $IncludeVariants
868  # without revising the normalization code below
869  $FieldValue = $Resource->Get($Field);
870  }
871 
872  # normalize field value for comparison
873  switch ($Field->Type())
874  {
877  # get the UserIds or CNIds from this field
878  $FieldValue = array_keys($FieldValue);
879  break;
880 
883  # convert returned value to a numeric timestamp
884  $FieldValue = strtotime($FieldValue);
885  break;
886 
889  # no conversion needed
890  break;
891 
892  default:
893  throw new Exception("Unsupported metadata field type ("
894  .print_r($Field->Type(), TRUE)
895  .") for condition in privilege set with resource.");
896  break;
897  }
898 
899  # cache the normalized value for subsequent reuse
900  self::$ValueCache[$CacheKey] = $FieldValue;
901  }
902 
903  return self::$ValueCache[$CacheKey];
904  }
905 
914  private function CompareNormalizedFieldValues($FieldValue, $Operator, $Value)
915  {
916  # compare field value and supplied value using specified operator
917 
918  # if this is a multi-value field, be sure that the provided
919  # operator makes sense
920  if (is_array($FieldValue) && !in_array($Operator, ["==", "!="]) )
921  {
922  throw new Exception(
923  "Multiple-value fields ony support == and != operators");
924  }
925 
926  switch ($Operator)
927  {
928  case "==":
929  if (is_array($FieldValue))
930  {
931  # equality against multi-value fields is
932  # interpreted as 'contains', true if the
933  # target value is one of those set
934  $Result = in_array($Value, $FieldValue);
935  }
936  else
937  {
938  $Result = ($FieldValue == $Value);
939  }
940  break;
941 
942  case "!=":
943  if (is_array($FieldValue))
944  {
945  # not equal against multi-value fields is
946  # interpreted as 'does not contain', true as long as
947  # the target value is not one of those set
948  $Result = !in_array($Value, $FieldValue);
949  }
950  else
951  {
952  $Result = ($FieldValue != $Value);
953  }
954  break;
955 
956  case "<":
957  $Result = ($FieldValue < $Value);
958  break;
959 
960  case ">":
961  $Result = ($FieldValue > $Value);
962  break;
963 
964  case "<=":
965  $Result = ($FieldValue <= $Value);
966  break;
967 
968  case ">=":
969  $Result = ($FieldValue >= $Value);
970  break;
971 
972  default:
973  throw new Exception("Unsupported condition operator ("
974  .print_r($Operator, TRUE).") in privilege set.");
975  break;
976  }
977 
978  # report to caller whether condition was met
979  return $Result ? TRUE : FALSE;
980  }
981 
992  private function CountResourcesThatSatisfyCondition(
993  $User, $Field, $Operator, $Value)
994  {
995  # get the SchemaId for this field
996  $ScId = $Field->SchemaId();
997 
998  # pull out an RFactory for the field's schema
999  if (!isset($this->RFactories[$ScId]))
1000  {
1001  $this->RFactories[$ScId] = new ResourceFactory($ScId);
1002  }
1003 
1004  switch ($Field->Type())
1005  {
1011  $ValuesToMatch = array(
1012  $Field->Id() => $Value,
1013  );
1014 
1015  $Matches = $this->RFactories[$ScId]->GetMatchingResources(
1016  $ValuesToMatch, TRUE, FALSE, $Operator);
1017 
1018  $Count = count($Matches);
1019  break;
1020 
1022  # find the number of resources associated with this option
1023  $Count = $this->RFactories[$ScId]->AssociatedVisibleResourceCount(
1024  $Value, $User, TRUE);
1025 
1026  # if our Op was !=, then subtract the resources
1027  # that have the spec'd option out of the total to
1028  # figure out how many lack the option
1029  if ($Operator == "!=")
1030  {
1031  $Count = $this->RFactories[$ScId]->GetVisibleResourcesCount(
1032  $User) - $Count;
1033  }
1034 
1035  break;
1036 
1037  default:
1038  throw new Exception("Unsupported metadata field type ("
1039  .print_r($Field->Type(), TRUE)
1040  .") for condition in privilege set without resource.");
1041  break;
1042  }
1043 
1044  return $Count;
1045  }
1046 
1055  private function IsInPrivilegeData($Item)
1056  {
1057  # step through privilege data
1058  foreach ($this->Privileges as $Priv)
1059  {
1060  # report to caller if item is found
1061  if (is_object($Item))
1062  {
1063  if (is_object($Priv) && ($Item == $Priv)) { return TRUE; }
1064  }
1065  elseif (is_array($Item))
1066  {
1067  if (is_array($Priv) && ($Item == $Priv)) { return TRUE; }
1068  }
1069  elseif ($Item == $Priv) { return TRUE; }
1070  }
1071 
1072  # report to caller that item is not in privilege data
1073  return FALSE;
1074  }
1075 }
RemoveCondition($Field, $Value=NULL, $Operator="==", $IncludeSubsets=FALSE)
Remove condition from privilege set.
AddSet(PrivilegeSet $Set)
Add subgroup of privileges/conditions to set.
GetPossibleNecessaryPrivileges()
Get all privileges that could be necessary to fulfill privilege set requirements. ...
FindUsersThatMeetRequirements($ResourceIds=array())
Find all users that meet the requirements for this privilege set.
ComparisonCount()
Get number of privilege comparisons in set, including those in subgroups.
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
Set of privileges used to access resource information or other parts of the system.
MeetsRequirements(CWUser $User, $Resource=self::NO_RESOURCE)
Determine if a given user meets the requirements specified by this PrivilegeSet.
ChecksField($FieldId)
Determine if a PrivilegeSet checks values from a specified field.
CWIS-specific user factory class.
__construct($Data=NULL)
Class constructor, used to create a new set or reload an existing set from previously-constructed dat...
IncludesPrivilege($Privilege)
Check whether this privilege set includes the specified privilege.
GetPrivilegeInfo()
Get privilege information as an array, with numerical indexes except for the logic, which is contained in a element with the index "Logic".
static FieldExistsInAnySchema($Field)
Determine if a Field exists in any schema.
AddPrivilege($Privileges)
Add specified privilege to set.
PrivilegeFlagsChecked()
List which privilege flags (e.g.
GetPrivilegeList()
Get list of privileges.
Object representing a locally-defined type of metadata field.
Data($NewValue=NULL)
Get/set privilege set data, in the form of an opaque string.
Represents a "resource" in CWIS.
Definition: Resource.php:13
FieldsWithUserComparisons($ComparisonType=NULL)
List which fields in this privset are involved in UserIs or UserIsNot comparisons for this privilege ...
static ClearCaches()
Clear internal caches.
Factory for Resource objects.
CWIS-specific user class.
Definition: CWUser.php:13
AddCondition($Field, $Value=NULL, $Operator="==")
Add condition to privilege set.
RemovePrivilege($Privilege)
Remove specified privilege from set.
AllRequired($NewValue=NULL)
Get/set whether all privileges/conditions in set are required (i.e.