3 # FILE: PrivilegeEditingUI.php 5 # Part of the Collection Workflow Integration System (CWIS) 6 # Copyright 2015-2016 Edward Almasy and Internet Scout Research Group 7 # http://scout.wisc.edu/cwis/ 26 public function __construct($Schemas = NULL, $MetadataFields = array())
28 $this->Fields = array();
30 # if Schemas was NULL, use all schemas 31 if ($Schemas === NULL)
37 # ensure incoming value is an array 38 if (!is_array($Schemas))
40 $Schemas = array($Schemas);
43 # if we have an array of ints, convert to an array of MetadataSchema objects 44 if (is_numeric(reset($Schemas)))
46 $NewSchemas = array();
47 foreach ($Schemas as $SchemaId)
51 $Schemas = $NewSchemas;
55 # ensure incoming value is an array 56 if (!is_array($MetadataFields))
58 $MetadataFields = array($MetadataFields);
61 # if we have an array of ints, convert to an array of MetadataField objects 62 if (is_numeric(reset($MetadataFields)))
64 $NewMetadataFields = array();
65 foreach ($MetadataFields as $FieldId)
69 $MetadataFields = $NewMetadataFields;
72 # types we support, in the order they should be displayed 73 $SupportedFieldTypesInOrder = array(
80 # add all requested Schemas 81 foreach ($Schemas as $SchemaId => $Schema)
83 # iterate over the supported types so that fields are 84 # returned grouped by type 85 foreach ($SupportedFieldTypesInOrder as $Type)
87 $this->Fields += $Schema->GetFields($Type);
91 # and add requested fields 92 foreach ($MetadataFields as $FieldId => $Field)
94 if (!in_array($Field->Type(), $SupportedFieldTypesInOrder))
97 "Field ".$Field->Name().
" (Id=".$Field->Id().
")" 98 .
" is invalid for PrivilegeEditing -- ".$Field->TypeAsName()
99 .
" fields are not supported.");
101 $this->Fields[$FieldId] = $Field;
114 # include needed JavaScript 115 $GLOBALS[
"AF"]->RequireUIFile(__CLASS__.
".js");
117 # build form field prefix 118 $FFPrefix =
"F_Priv_".$Identifier.
"_";
120 # retrieve privilege info as an array 123 # add "Top-Level Logic" option list if we are at the top of the hierarchy 126 $Logic = $PrivilegeInfo[
"Logic"];
128 print
'<div class="priv-set">' 129 .
'<fieldset class="priv-fieldset priv-logic">' 130 .
'<label for="'.$FFPrefix.
'Logic">Top-Level Logic:</label>';
133 array(
"AND" =>
"AND",
"OR" =>
"OR"), $Logic);
134 $OptList->PrintHtml();
139 # discard logic so that the rest of the array can be iterated over 140 unset($PrivilegeInfo[
"Logic"]);
142 # if there are no conditions set 143 if (count($PrivilegeInfo) == 0)
145 # print out message indicating no conditions yet set 146 print(
"<i>(no requirements)</i><br/>");
150 # print out each condition 151 foreach ($PrivilegeInfo as $Condition)
154 <fieldset
class=
"priv-fieldset cw-peui-fieldset">
157 # if condition tests against a user privilege 158 if (is_numeric($Condition))
160 $this->DisplaySubjectField($FFPrefix,
"current_user");
161 $this->DisplayOperatorField($FFPrefix);
162 $this->DisplayValueField($FFPrefix, $Condition);
164 # else if condition tests against a metadata field value 165 else if (is_array($Condition))
167 $this->DisplaySubjectField($FFPrefix, $Condition[
"FieldId"]);
168 $this->DisplayOperatorField($FFPrefix, $Condition[
"Operator"]);
176 # do nothing here, but we'd like to continue 181 # Option fields use the selector menu, rather than a 183 # Values are ControlledName Ids, prefixed with a "C" 184 # to distinguish them from privilge flag numbers. 185 $this->DisplayValueField($FFPrefix,
186 "C".$Condition[
"Value"],
"NULL");
190 $this->DisplayValueField($FFPrefix, NULL, $Condition[
"Value"]);
193 # else if condition is a privilege subset 196 $this->DisplaySubjectField($FFPrefix,
"set_entry");
197 $this->DisplayOperatorField($FFPrefix);
198 $this->DisplayValueField($FFPrefix,
199 $Condition->AllRequired() ?
"AND" :
"OR");
201 # end the fieldset for the set entry row 204 # print the nested fields 205 $this->
DisplaySet($Identifier, $Condition, TRUE);
207 # begin a new fieldset for the set exit row 208 ?><fieldset
class=
"priv-fieldset cw-peui-fieldset"><?
PHP 210 $this->DisplaySubjectField($FFPrefix,
"set_exit");
211 $this->DisplayOperatorField($FFPrefix);
212 $this->DisplayValueField($FFPrefix);
219 # if we are at the top level 224 # print a number of blank rows to be used if JavaScript is disabled 225 for ($Index = 0; $Index < $NumBlankRows; $Index++)
227 ?><fieldset
class=
"priv-fieldset cw-peui-fieldset priv-extra"><?
PHP 228 $this->DisplaySubjectField($FFPrefix);
229 $this->DisplayOperatorField($FFPrefix);
230 $this->DisplayValueField($FFPrefix);
234 # print a blank row for cloning within JavaScript 235 ?><fieldset
class=
"priv-fieldset cw-peui-fieldset priv-js-clone_target"><?
PHP 236 $this->DisplaySubjectField($FFPrefix);
237 $this->DisplayOperatorField($FFPrefix);
238 $this->DisplayValueField($FFPrefix);
241 # print the button to add a new row when using JavaScript 242 ?><button
class=
"cw-button cw-button-elegant cw-button-constrained 243 priv-js-add">Add Condition</button>
246 # print the closing div for the set 257 # for each form field 260 foreach ($_POST as $FieldName => $FieldValue)
262 # if field looks like privilege set data 263 if (preg_match(
"/^F_Priv_/", $FieldName))
265 # extract identifier from field name 266 $Pieces = explode(
"_", $FieldName);
267 $Identifier = $Pieces[2];
269 # if field looks like privilege set top-level logic 270 if (preg_match(
"/_Logic\$/", $FieldName))
272 # save logic for later use 273 $Logics[$Identifier] = $FieldValue;
277 # retrieve privilege set from field 279 $this->ExtractPrivilegeSetFromFormData($FieldValue);
284 # for each top-level logic found 285 foreach ($Logics as $Identifier => $Logic)
287 # if no corresponding privilege set was found 288 if (!isset($Sets[$Identifier]))
290 # load empty set for this identifier 294 # set logic in corresponding privilege set 295 $Sets[$Identifier]->AllRequired(($Logic ==
"AND") ? TRUE : FALSE);
298 # return any privilege sets found to caller 311 return isset($Sets[$Identifier]) ? $Sets[$Identifier] : FALSE;
314 # ---- PRIVATE INTERFACE ------------------------------------------------- 317 private $OptionValues;
326 private function DisplaySubjectField($FFPrefix, $Selected=NULL)
328 # construct the list of options to present for this field 329 # present all the metadata fields using their FieldIds 330 $ValidSelections = array_keys($this->Fields);
332 # represent other elements as strings, which need to match the 333 # values in GetPrivilegeSetFromFormData() 334 $ValidSelections[] =
"current_user";
335 $ValidSelections[] =
"set_entry";
336 $ValidSelections[] =
"set_exit";
340 # construct 2d array of our fields keyed by schemaid 342 foreach ($this->Fields as $Id => $Field)
344 $Fields[$Field->SchemaId()][$Id]= $Field;
347 # build up the list options to included 349 $OptionCSS = array();
351 foreach ($Fields as $ScId => $ScFields)
353 $FieldOptions = array();
354 foreach ($ScFields as $Id => $Field)
356 $SafeClassType = strtolower($Field->TypeAsName());
357 $FieldOptions[$Id] =
"[".$AllSchemas[$ScId]->AbbreviatedName().
"] " 358 .$Field->GetDisplayName();
359 $OptionCSS[$Id] =
"priv priv-option priv-field-subject " 360 .
"priv-type-".$SafeClassType.
"_field";
363 $OptLabel = $AllSchemas[$ScId]->Name();
364 $Options[$OptLabel] = $FieldOptions;
367 # add Current User entry 368 $Options[
"current_user"] =
"Current User";
369 $OptionCSS[
"current_user"] =
"priv priv-option priv-field-subject " 370 .
"priv-type-privilege";
372 # add subgroup begin marker 373 $Options[
"set_entry"] =
"(";
374 $OptionCSS[
"set_entry"] =
"priv priv-option priv-field-subject " 375 .
"priv-type-set_entry";
377 # add subgroup end marker 378 $Options[
"set_exit"] =
")";
379 $OptionCSS[
"set_exit"] =
"priv priv-option priv-field-subject " 380 .
"priv-type-set_exit";
382 # check if the data we were given contains an invalid field, 384 if (!is_null($Selected) && !in_array($Selected, $ValidSelections, TRUE))
386 $Options[$Selected] =
"INVALID FIELD";
387 $OptionCSS[$Selected] =
"priv priv-option priv-field-subject " 388 .
"priv-type-user_field";
392 $OptionList =
new HtmlOptionList($FFPrefix.
"[]", $Options, $Selected);
393 $OptionList->ClassForOptions($OptionCSS);
394 $OptionList->ClassForList(
395 "priv priv-field priv-select priv-field-subject priv-type-user_field " 396 .
"priv-type-flag_field priv-type-option_field priv-type-timestamp_field " 397 .
"priv-type-date_field priv-type-number_field priv-type-set_entry " 398 .
"priv-type-set_exit");
400 $OptionList->PrintHtml();
408 private function DisplayOperatorField($FFPrefix, $Selected=NULL)
411 $OptionCSS = array();
412 $CommonStyles =
"priv priv-option priv-field-operator";
414 # use css styles on each option to indicate which fields it applies to 416 # equal and not equal work for User, Flag, Option, and Number fields 417 foreach (array(
"==",
"!=") as $Op)
420 $OptionCSS[$Op] = $CommonStyles.
" priv-type-user_field " 421 .
"priv-type-flag_field priv-type-option_field priv-type-number_field";
424 # less and greater work for Timestamp, Date, and Number fields 425 foreach (array(
"<",
">") as $Op)
428 $OptionCSS[$Op] = $CommonStyles
429 .
" priv-type-timestamp_field priv-type-date_field priv-type-number_field";
432 $OptionList =
new HtmlOptionList($FFPrefix.
"[]", $Options, $Selected);
433 $OptionList->ClassForOptions($OptionCSS);
434 $OptionList->ClassForList(
435 "priv priv-field priv-select priv-field-operator priv-type-user_field " 436 .
"priv-type-flag_field priv-type-option_field priv-type-timestamp_field " 437 .
"priv-type-date_field priv-type-number_field");
439 $OptionList->PrintHtml();
448 private function DisplayValueField($FFPrefix, $Selected=NULL, $Value=NULL)
450 $this->PrintPrivilegeValueSelectorField($FFPrefix, $Selected);
451 $this->PrintPrivilegeValueInputField($FFPrefix, $Value);
465 private function ExtractPrivilegeSetFromFormData(array &$FormData)
468 $Privileges = $this->GetPrivileges();
469 $SupportedOperators = array(
"==",
"!=",
"<",
">");
471 while (count($FormData))
473 # extract the form fields 474 $SubjectField = array_shift($FormData);
475 $OperatorField = array_shift($FormData);
476 $ValueSelectField = array_shift($FormData);
477 $ValueInputField = array_shift($FormData);
479 # privilege condition 480 if ($SubjectField ==
"current_user")
482 # invalid privilege ID 483 if (!isset($Privileges[$ValueSelectField])
484 || is_null($ValueSelectField))
486 throw new Exception(
"Invalid privilege (".$ValueSelectField.
")");
489 $NewPrivilegeSet->AddPrivilege($ValueSelectField);
492 # metadata field condition 493 else if (is_numeric($SubjectField))
496 if (!isset($this->Fields[$SubjectField]) || is_null($SubjectField))
498 throw new Exception(
"Invalid or unsupported field (" 503 if (!in_array($OperatorField, $SupportedOperators))
505 throw new Exception(
"Invalid or unsupported operator (" 506 .$OperatorField.
")");
509 $MetadataField = $this->Fields[$SubjectField];
511 switch ($MetadataField->Type())
524 $Value = $ValueInputField;
528 # strip the "C" prefix used to distinguish controlled 529 # names from priv flags 530 $Value = intval( substr( $ValueSelectField, 1));
538 $NewPrivilegeSet->AddCondition($MetadataField, $Value, $OperatorField);
541 # entering a nested privilege set 542 else if ($SubjectField ==
"set_entry")
544 # the logic is invalid 545 if ($ValueSelectField !=
"AND" && $ValueSelectField !=
"OR")
547 throw new Exception(
"Invalid privilege set logic (" 548 .$ValueSelectField.
")");
551 $NestedPrivilegeSet = $this->ExtractPrivilegeSetFromFormData($FormData);
553 # only add the nested privilege set if it's not empty. use 1 554 # because the logic is in the privilege info array 555 if (count($NestedPrivilegeSet->GetPrivilegeInfo()) > 1)
557 $NestedPrivilegeSet->AllRequired($ValueSelectField ==
"AND");
558 $NewPrivilegeSet->AddSet($NestedPrivilegeSet);
562 # exiting a privilege set 563 else if ($SubjectField ==
"set_exit")
568 # unknown condition type 571 throw new Exception(
"Unknown condition type: ".$SubjectField);
575 return $NewPrivilegeSet;
583 private function PrintPrivilegeValueSelectorField($FFPrefix, $Selected=NULL)
585 # build up the list of options 587 $OptionCSS = array();
588 $OptionData = array();
590 # add entries for each user privilege flag 591 $Privileges = $this->GetPrivileges();
592 foreach ($Privileges as $Id => $Privilege)
594 $Options[$Id] = $Privilege->Name();
595 $OptionCSS[$Id] =
"priv priv-option priv-field-value priv-type-privilege";
598 $OptionValues = $this->GetOptionValuesForPrivset();
599 foreach ($OptionValues as $FieldId => $Values)
601 foreach ($Values as $CNId => $CName)
603 $Options[
"C".$CNId] = $CName;
604 $OptionCSS[
"C".$CNId] =
"priv priv-option priv-field-value " 605 .
"priv-type-option_field";
606 $OptionData[
"C".$CNId][
"field-id"] = $FieldId;
610 $Options[
"AND"] =
"AND";
611 $OptionCSS[
"AND"] =
"priv priv-option priv-field-value priv-type-set_entry";
613 $Options[
"OR"] =
"OR";
614 $OptionCSS[
"OR"] =
"priv priv-option priv-field-value priv-type-set_entry";
616 $OptionList =
new HtmlOptionList($FFPrefix.
"[]", $Options, $Selected);
617 $OptionList->ClassForOptions($OptionCSS);
618 $OptionList->DataForOptions($OptionData);
619 $OptionList->ClassForList(
620 "priv priv-field priv-select priv-field-value priv-type-option_field " 621 .
"priv-type-privilege priv-type-set_entry priv-type-set_exit");
623 $OptionList->PrintHtml();
631 private function PrintPrivilegeValueInputField($FFPrefix, $Value=NULL)
633 $SafeValue = defaulthtmlentities($Value);
635 <input name=
"<?PHP print $FFPrefix; ?>[]" 637 class=
"priv priv-field priv-input priv-field-value 638 priv-type-timestamp_field priv-type-date_field 639 priv-type-number_field" 640 value=
"<?PHP print $SafeValue; ?>" />
650 private function GetOptionValuesForPrivset()
652 if (!isset($this->OptionValues))
654 $this->OptionValues = array();
656 foreach ($this->Fields as $FieldId => $Field)
660 $this->OptionValues[$Field->Id()] = $Field->GetPossibleValues();
665 return $this->OptionValues;
672 private function GetPrivileges()
676 if (!isset($Privileges))
679 $Privileges = $PrivilegeFactory->GetPrivileges();
Factory which extracts all defined privileges from the database.
GetPrivilegeSetFromForm($Identifier)
Retrieve privilege set from specified form ($_POST) data fields.
User interface element for editing PrivilegeSets.
__construct($Schemas=NULL, $MetadataFields=array())
Constructor for privilege editing UI.
Set of privileges used to access resource information or other parts of the system.
GetPrivilegeSetsFromForm()
Construct new privilege sets from available form ($_POST) data.
GetPrivilegeInfo()
Get privilege information as an array, with numerical indexes except for the logic, which is contained in a element with the index "Logic".
DisplaySet($Identifier, PrivilegeSet $PrivilegeSet, $IsNested=FALSE)
Display interface for editing specified privilege set.
Convenience class for generating an HTML select/option form element.