CWIS Developer Documentation

- Home
- Main Page
- Classes
- Files

- File List
- File Members

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
16 class PrivilegeSet {
17
18 # used as a field ID in conditions to test whether a resources is
19 # available as part of the privilege check
20 const HAVE_RESOURCE = -1;
21
29 function __construct($Data = NULL)
30 {
31 # if privilege data supplied
32 if ($Data !== NULL)
33 {
34 # if data is in legacy form (an array of privileges)
35 if (is_array($Data))
36 {
37 # set internal privilege set from array
38 $this->Privileges = $Data;
39 }
40 else
41 {
42 # set internal values from data
43 $this->LoadFromData($Data);
44 }
45 }
46 }
47
57 function Data($NewValue = NULL)
58 {
59 # if new data supplied
60 if ($NewValue !== NULL)
61 {
62 # unpack privilege data and load
63 $this->LoadFromData($NewValue);
64 }
65
66 # serialize current data and return to caller
67 $Data = array();
68 if (count($this->Privileges))
69 {
70 foreach ($this->Privileges as $Priv)
71 {
72 $Data["Privileges"][] = is_object($Priv)
73 ? array("SUBSET" => $Priv->Data())
74 : $Priv;
75 }
76 }
77 if ($this->UserId !== NULL) { $Data["UserId"] = $this->UserId; }
78 $Data["Logic"] = $this->Logic;
79 return serialize($Data);
80 }
81
93 function IsGreaterThan(PrivilegeSet $Set, $Resource = self::NO_RESOURCE)
94 {
95 # if target set has no requirements then we must be greater
96 if (!count($Set->Privileges)) { return TRUE; }
97
98 # for each privilege in target set
99 foreach ($Set->Privileges as $Priv)
100 {
101 # if privilege is actually a privilege subgroup
102 if (is_object($Priv))
103 {
104 # check if our privileges are greater than subgroup
105 $OursGreater = $this->IsGreaterThan($Priv, $Resource);
106 }
107 # else if privilege is actually a condition
108 elseif (is_array($Priv))
109 {
110 # check if privilege set meets that condition
111 $OursGreater = $this->MeetsCondition($Priv, $Resource, $Set->Logic);
112 }
113 # else privilege is actually a privilege
114 else
115 {
116 # check we have specified privilege
117 $OursGreater = $this->IncludesPrivilege($Priv);
118 }
119
120 # if either set requires that all privileges must be greater
121 if (($this->Logic == "AND") || ($Set->Logic == "AND"))
122 {
123 # if our privileges were not greater
124 if (!$OursGreater)
125 {
126 # bail out and report to caller that our privileges are not greater
127 break;
128 }
129 }
130 # else if only one privilege must be greater
131 else
132 {
133 # if our privileges were greater
134 if ($OursGreater)
135 {
136 # bail out and report to caller that our privileges are greater
137 break;
138 }
139 }
140 }
141
142 # all privileges must have been greater (if all required) or none of
143 # the privileges were greater (if only one required)
144 # so report accordingly to caller
145 return $OursGreater;
146 }
147
156 function IsLessThan(PrivilegeSet $Set, Resource $Resource = NULL)
157 {
158 # just return inverse of IsGreaterThan()
159 return $this->IsGreaterThan($Set, $Resource) ? FALSE : TRUE;
160 }
161
168 function AddPrivilege($Privilege)
169 {
170 # add privilege if not currently in set
171 if (!$this->IncludesPrivilege($Privilege))
172 {
173 if (is_object($Privilege)) { $Privilege = $Privilege->Id(); }
174 $this->Privileges[] = $Privilege;
175 }
176 }
177
184 function RemovePrivilege($Privilege)
185 {
186 # remove privilege if currently in set
187 if ($this->IncludesPrivilege($Privilege))
188 {
189 if (is_object($Privilege)) { $Privilege = $Privilege->Id(); }
190 $Index = array_search($Privilege, $this->Privileges);
191 unset($this->Privileges[$Index]);
192 }
193 }
194
200 function IncludesPrivilege($Privilege)
201 {
202 # check whether privilege is in our list and report to caller
203 if (is_object($Privilege)) { $Privilege = $Privilege->Id(); }
204 return $this->IsInPrivilegeData($Privilege) ? TRUE : FALSE;
205 }
206
215 function GetPrivilegeInfo()
216 {
217 # grab privilege information and add logic
218 $Info = $this->Privileges;
219 $Info["Logic"] = $this->Logic;
220
221 # return privilege info array to caller
222 return $Info;
223 }
224
231 function GetPrivilegeList()
232 {
233 # create list of privileges with conditions stripped out
234 $List = array();
235 foreach ($this->Privileges as $Priv)
236 {
237 if (!is_array($Priv)) { $List[] = $Priv; }
238 }
239
240 # return list of privileges to caller
241 return $List;
242 }
243
258 function AddCondition($Field, $Value = NULL, $Operator = "==")
259 {
260 # get field ID
261 $FieldId = is_object($Field) ? $Field->Id() : $Field;
262
263 # set up condition array
264 $Condition = array(
265 "FieldId" => intval($FieldId),
266 "Operator" => trim($Operator),
267 "Value" => $Value);
268
269 # if condition is not already in set
270 if (!$this->IsInPrivilegeData($Condition))
271 {
272 # add condition to privilege set
273 $this->Privileges[] = $Condition;
274 }
275 }
276
288 function RemoveCondition($Field, $Value = NULL, $Operator = "==")
289 {
290 # get field ID
291 $FieldId = is_object($Field) ? $Field->Id() : $Field;
292
293 # set up condition array
294 $Condition = array(
295 "FieldId" => intval($FieldId),
296 "Operator" => trim($Operator),
297 "Value" => $Value);
298
299 # if condition is in set
300 if ($this->IsInPrivilegeData($Condition))
301 {
302 # remove condition from privilege set
303 $Index = array_search($Condition, $this->Privileges);
304 unset($this->Privileges[$Index]);
305 }
306 }
307
312 function AddSet(PrivilegeSet $Set)
313 {
314 # if subgroup is not already in set
315 if (!$this->IsInPrivilegeData($Set))
316 {
317 # add subgroup to privilege set
318 $this->Privileges[] = $Set;
319 }
320 }
321
331 function AllRequired($NewValue = NULL)
332 {
333 if ($NewValue !== NULL)
334 {
335 $this->Logic = $NewValue ? "AND" : "OR";
336 }
337 return ($this->Logic == "AND") ? TRUE : FALSE;
338 }
339
346 function AssociatedUserId($NewValue = NULL)
347 {
348 # if new associated user specified
349 if ($NewValue !== NULL)
350 {
351 # save ID of new associated user
352 $this->UserId = $NewValue;
353 }
354
355 # return ID of currently associated user to caller
356 return $this->UserId;
357 }
358
359
360 # ---- PRIVATE INTERFACE -------------------------------------------------
361
362 private $Privileges = array();
363 private $Logic = "OR";
364 private $UserId = NULL;
365
366 const NO_RESOURCE = "XXX NO RESOURCE XXX";
367
372 private function LoadFromData($Serialized)
373 {
374 # save calling context in case load causes out-of-memory crash
375 $GLOBALS["AF"]->RecordContextInCaseOfCrash();
376
377 # unpack new data
378 $Data = unserialize($Serialized);
379
380 # unpack privilege data (if available) and load
381 if (array_key_exists("Privileges", $Data))
382 {
383 $this->Privileges = array();
384 foreach ($Data["Privileges"] as $Priv)
385 {
386 if (is_array($Priv) && array_key_exists("SUBSET", $Priv))
387 {
388 $Subset = new PrivilegeSet();
389 $Subset->LoadFromData($Priv["SUBSET"]);
390 $this->Privileges[] = $Subset;
391 }
392 else
393 {
394 $this->Privileges[] = $Priv;
395 }
396 }
397 }
398
399 # load associated user ID if available
400 if (array_key_exists("UserId", $Data))
401 {
402 $this->UserId = $Data["UserId"];
403 }
404
405 # load logic if available
406 if (array_key_exists("Logic", $Data))
407 {
408 $this->Logic = $Data["Logic"];
409 }
410 }
411
420 private function MeetsCondition($Condition, $Resource, $Logic)
421 {
422 # if condition is a check for whether a resource is available
423 if ($Condition["FieldId"] == self::HAVE_RESOURCE)
424 {
425 # return a result based on whether a resource is available
426 return ((bool)($Resource == self::NO_RESOURCE)
427 != (bool)$Condition["Value"]) ? TRUE : FALSE;
428 }
429 # else if no resource is available
430 elseif ($Resource == self::NO_RESOURCE)
431 {
432 # return a result that in effect ignores the condition
433 return ($Logic == "AND") ? TRUE : FALSE;
434 }
435 # else if resource is valid
436 elseif ($Resource instanceof Resource)
437 {
438 # pre-process condition parameters based on type of field
439 try
440 {
441 $Field = new MetadataField($Condition["FieldId"]);
442 }
443 catch (Exception $e)
444 {
445 # if the field in a condition was invalid, the condition fails
446 return FALSE;
447 }
448
449 $Operator = $Condition["Operator"];
450 $Value = $Condition["Value"];
451 $FieldValue = $Resource->Get($Field, TRUE);
452 switch ($Field->Type())
453 {
454 case MetadataSchema::MDFTYPE_USER:
455 # if supplied value is NULL
456 if ($Value === NULL)
457 {
458 # if local associated user ID is available
459 if ($this->UserId !== NULL)
460 {
461 # use ID of associated user
462 $Value = $this->UserId;
463 }
464 # else if global user ID available
465 elseif ($GLOBALS["G_User"]->IsLoggedIn())
466 {
467 # use global user ID
468 $Value = $GLOBALS["G_User"]->Id();
469 }
470 else
471 {
472 # report to caller that condition was not met
473 return FALSE;
474 }
475 }
476
477 # convert field value to user ID
478 $FieldValue = $FieldValue->Id();
479 break;
480
481 case MetadataSchema::MDFTYPE_DATE:
482 case MetadataSchema::MDFTYPE_TIMESTAMP:
483 # date field values are Date objects, so handle those
484 if ($FieldValue instanceof Date)
485 {
486 $FieldValue = strtotime($FieldValue->Formatted());
487 }
488
489 # timestamp field values are just the date/time string
490 else
491 {
492 $FieldValue = strtotime($FieldValue);
493 }
494
495 # use the current time for the value if it's NULL
496 if ($Value === NULL)
497 {
498 $Value = time();
499 }
500
501 # otherwise, parse the value to get a numeric timestamp
502 else
503 {
504 $Value = strtotime($Value);
505 }
506 break;
507
508 case MetadataSchema::MDFTYPE_NUMBER:
509 case MetadataSchema::MDFTYPE_FLAG:
510 break;
511
512 case MetadataSchema::MDFTYPE_OPTION:
513 # for options, construct a list of the CNIDs in this field
514 $NewValue = array();
515 foreach ($FieldValue as $CName)
516 {
517 $NewValue []= $CName->Id();
518 }
519 $FieldValue = $NewValue;
520 break;
521
522 default:
523 throw new Exception("Unsupported metadata field type ("
524 .print_r($Field->Type(), TRUE)
525 .") for condition in privilege set.");
526 break;
527 }
528
529 # compare field value and supplied value using specified operator
530 switch ($Operator)
531 {
532 case "==":
533 if (is_array($FieldValue))
534 {
535 # equality against an option field is a 'contains' condition,
536 # true if the specified value is one of those set
537 $Result = FALSE;
538 foreach ($FieldValue as $FieldValue_i)
539 {
540 $Result |= ($FieldValue_i == $Value);
541 }
542 }
543 else
544 {
545 $Result = ($FieldValue == $Value);
546 }
547 break;
548
549 case "!=":
550 if (is_array($FieldValue))
551 {
552 # not equal against an option field is 'does not contains',
553 # true as long as the spcified value is not one of those set
554 $Result = TRUE;
555 foreach ($FieldValue as $FieldValue_i)
556 {
557 $Result &= ($FieldValue_i != $Value);
558 }
559 }
560 else
561 {
562 $Result = ($FieldValue != $Value);
563 }
564 break;
565
566 case "<":
567 $Result = ($FieldValue < $Value);
568 break;
569
570 case ">":
571 $Result = ($FieldValue > $Value);
572 break;
573
574 case "<=":
575 $Result = ($FieldValue <= $Value);
576 break;
577
578 case ">=":
579 $Result = ($FieldValue >= $Value);
580 break;
581
582 default:
583 throw new Exception("Unsupported condition operator ("
584 .print_r($Operator, TRUE).") in privilege set.");
585 break;
586 }
587
588 # report to caller whether condition was met
589 return $Result ? TRUE : FALSE;
590 }
591 else
592 {
593 # error out because resource was illegal
594 throw new Exception("Invalid Resource passed in for privilege"
595 ." set comparison.");
596 }
597 }
598
607 private function IsInPrivilegeData($Item)
608 {
609 # step through privilege data
610 foreach ($this->Privileges as $Priv)
611 {
612 # report to caller if item is found
613 if (is_object($Item))
614 {
615 if (is_object($Priv) && ($Item == $Priv)) { return TRUE; }
616 }
617 elseif (is_array($Item))
618 {
619 if (is_array($Priv) && ($Item == $Priv)) { return TRUE; }
620 }
621 elseif ($Item == $Priv) { return TRUE; }
622 }
623
624 # report to caller that item is not in privilege data
625 return FALSE;
626 }
627 }
MetadataSchema\MDFTYPE_TIMESTAMP
const MDFTYPE_TIMESTAMP
Definition: MetadataSchema.php:24
PrivilegeSet\AssociatedUserId
AssociatedUserId($NewValue=NULL)
Get/set ID of user associated with privilege set.
Definition: PrivilegeSet.php:346
PrivilegeSet\AddSet
AddSet(PrivilegeSet $Set)
Add subgroup of privileges/conditions to set.
Definition: PrivilegeSet.php:312
MetadataSchema\MDFTYPE_NUMBER
const MDFTYPE_NUMBER
Definition: MetadataSchema.php:22
PrivilegeSet\NO_RESOURCE
const NO_RESOURCE
Definition: PrivilegeSet.php:366
PrivilegeSet
Set of privileges used to access resource information or other parts of the system.
Definition: PrivilegeSet.php:16
PrivilegeSet\IsLessThan
IsLessThan(PrivilegeSet $Set, Resource $Resource=NULL)
Check whether a privilege set is less than another privilege set.
Definition: PrivilegeSet.php:156
Date
Definition: Axis--Date.php:18
MetadataSchema\MDFTYPE_OPTION
const MDFTYPE_OPTION
Definition: MetadataSchema.php:28
MetadataSchema\MDFTYPE_FLAG
const MDFTYPE_FLAG
Definition: MetadataSchema.php:25
PHP
PHP
Definition: OAIClient.php:39
PrivilegeSet\__construct
__construct($Data=NULL)
Class constructor, used to create a new set or reload an existing set from previously-constructed dat...
Definition: PrivilegeSet.php:29
PrivilegeSet\IncludesPrivilege
IncludesPrivilege($Privilege)
Check whether this privilege set includes the specified privilege.
Definition: PrivilegeSet.php:200
PrivilegeSet\GetPrivilegeInfo
GetPrivilegeInfo()
Get privilege information as an array, with numerical indexes except for the logic, which is contained in a element with the index "Logic".
Definition: PrivilegeSet.php:215
PrivilegeSet\GetPrivilegeList
GetPrivilegeList()
Get list of privileges.
Definition: PrivilegeSet.php:231
MetadataField
Object representing a locally-defined type of metadata field.
Definition: MetadataField.php:13
MetadataSchema\MDFTYPE_DATE
const MDFTYPE_DATE
Definition: MetadataSchema.php:23
PrivilegeSet\Data
Data($NewValue=NULL)
Get/set privilege set data, in the form of an opaque string.
Definition: PrivilegeSet.php:57
Resource
Represents a "resource" in CWIS.
Definition: Resource.php:13
PrivilegeSet\IsGreaterThan
IsGreaterThan(PrivilegeSet $Set, $Resource=self::NO_RESOURCE)
Check whether a privilege set is greater than or equal to another privilege set.
Definition: PrivilegeSet.php:93
MetadataSchema\MDFTYPE_USER
const MDFTYPE_USER
Definition: MetadataSchema.php:29
PrivilegeSet\AddPrivilege
AddPrivilege($Privilege)
Add specified privilege to set.
Definition: PrivilegeSet.php:168
PrivilegeSet\AddCondition
AddCondition($Field, $Value=NULL, $Operator="==")
Add condition to privilege set.
Definition: PrivilegeSet.php:258
PrivilegeSet\RemovePrivilege
RemovePrivilege($Privilege)
Remove specified privilege from set.
Definition: PrivilegeSet.php:184
PrivilegeSet\HAVE_RESOURCE
const HAVE_RESOURCE
Definition: PrivilegeSet.php:20
PrivilegeSet\AllRequired
AllRequired($NewValue=NULL)
Get/set whether all privileges/conditions in set are required (i.e.
Definition: PrivilegeSet.php:331
PrivilegeSet\RemoveCondition
RemoveCondition($Field, $Value=NULL, $Operator="==")
Remove condition from privilege set.
Definition: PrivilegeSet.php:288