5 # Part of the Collection Workflow Integration System (CWIS) 6 # Copyright 2016-2017 Edward Almasy and Internet Scout Research Group 7 # http://scout.wisc.edu/cwis/ 137 # ---- PUBLIC INTERFACE -------------------------------------------------- 146 $TableCssClass = NULL)
148 # display nothing if there are no fields 149 if (!count($this->FieldParams)) {
return; }
151 # check whether table should be split into sections 152 $TableIsSectioned = FALSE;
153 foreach ($this->FieldParams as $Name => $Params)
155 if ($Params[
"Type"] == self::FTYPE_HEADING)
156 { $TableIsSectioned = TRUE; }
161 ?><table
class=
"cw-table cw-table-fullsize cw-table-sideheaders cw-table-padded cw-table-striped<?PHP 162 if ($TableIsSectioned) { print(" cw-table-sectioned
"); } 163 if (!is_null($TableCssClass)) { print(" ".$TableCssClass); } 164 ?> cw-content-sysconfigtable"<?
PHP 165 if ($TableId) { print(
" id=\"".$TableId.
"\""); }
166 if ($TableStyle) { print(
" style=\"".$TableStyle.
"\""); }
172 foreach ($this->FieldParams as $Name => $Params)
174 # generate name for field 177 # if field is actually a section heading 178 if ($Params[
"Type"] == self::FTYPE_HEADING)
180 # split table section and display heading 181 if (isset($HeadingAlreadyDisplayed)) { print(
"</tbody><tbody>"); }
182 ?><tr
id=
"section-<?= $FormFieldName 183 ?>"><th colspan=
"3" scope=
"rowspan"><?=
184 $Params[
"Label"] ?></th></tr><?
PHP 185 $HeadingAlreadyDisplayed = TRUE;
189 # determine if row may have taller content 190 $ShortRowFieldTypes = array(
192 self::FTYPE_METADATAFIELD,
194 self::FTYPE_PASSWORD,
200 ($Params[
"Type"] == self::FTYPE_QUICKSEARCH) ||
201 (!isset($Params[
"Units"])
202 && !in_array($Params[
"Type"], $ShortRowFieldTypes)
203 && (($Params[
"Type"] != self::FTYPE_OPTION)
204 || (isset($Params[
"Rows"])
205 && ($Params[
"Rows"] > 1))) );
207 # load up value(s) to go into field 210 # set up CSS classes for table row 211 $RowClass =
"cw-formui-fieldtype-".strtolower($Params[
"Type"]);
212 if ($Params[
"Type"] ==
"MetadataField")
214 $RowClass .=
" cw-formui-schemaid-" 215 .GetArrayValue($Params,
"SchemaId",
218 $RowClass .= $IsTallRow ?
" cw-content-tallrow" :
"";
219 $RowClassAttrib =
' class="'.$RowClass.
'"';
221 # set up CSS classes for row header cell 222 $HeaderClass = $IsTallRow ?
"cw-content-tallrow-th" :
"";
223 $HeaderClassAttrib = strlen($HeaderClass)
224 ?
' class="'.$HeaderClass.
'"' :
"";
226 # set up CSS classes for row label 227 $LabelClass =
"cw-form-pseudolabel" 228 .(isset(self::$ErrorMessages[$Name])
229 ?
" cw-form-error" :
"");
231 # set up min/max note if applicable 232 unset($RangeNotePieces);
233 if (isset($Params[
"MinVal"]))
235 $RangeNotePieces[] =
"Minimum: <i>".$Params[
"MinVal"].
"</i>";
237 if (isset($Params[
"MaxVal"]))
239 $RangeNotePieces[] =
"Maximum: <i>".$Params[
"MaxVal"].
"</i>";
241 if (isset($Params[
"RecVal"]))
243 $RangeNotePieces[] =
"Recommended: <i>".$Params[
"RecVal"].
"</i>";
245 if (isset($RangeNotePieces))
247 $RangeNote =
"(".implode(
", ", $RangeNotePieces).
")";
252 <tr<?= ($IsTallRow ?
" valign=\"top\"" :
"").$RowClassAttrib
253 ?>
id=
"row-<?= $FormFieldName ?>">
254 <th<?= $HeaderClassAttrib ?>>
255 <label
for=
"<?= $FormFieldName 256 ?>" class=
"<?= $LabelClass ?>"><?=
257 $Params[
"Label"] ?></label>
259 <td <?
PHP if (!isset($Params[
"Help"]) && !isset($RangeNotePieces)) {
260 print
"colspan=\"2\""; } ?>><?
PHP 262 $Name, $Value, $Params); ?></td>
263 <?
PHP if (isset($Params[
"Help"])) { ?>
264 <td
class=
"cw-content-help-cell"><?= $Params[
"Help"] ?></td>
265 <?
PHP } elseif (isset($RangeNotePieces)) { ?>
266 <td
class=
"cw-content-help-cell"><?= $RangeNote ?></td>
277 # add any hidden form fields 280 # add any needed JavaScript for toggled fields 283 # pull in WYSIWYG editor setup if needed 284 if ($this->UsingWysiwygEditor)
286 require_once($GLOBALS[
"AF"]->GUIFile(
"CKEditorSetup.php"));
296 if (count(self::$ErrorMessages))
298 print
"<ul class=\"cw-form-error\">\n";
299 $DisplayedMsgs = array();
300 foreach (self::$ErrorMessages as $Field => $Msgs)
302 foreach ($Msgs as $Msg)
304 if (!in_array($Msg, $DisplayedMsgs))
306 print
"<li>".$Msg.
"</li>\n";
307 $DisplayedMsgs[] = $Msg;
321 parent::HandleDeletes();
323 $TextFieldsToCheck = array();
325 # check for text fields that may contain images 326 foreach ($this->FieldParams as $Name => $Params)
328 if (isset($Params[
"InsertIntoField"])
329 && (($Params[
"Type"] == self::FTYPE_FILE)
330 || ($Params[
"Type"] == self::FTYPE_IMAGE)))
332 $TextFieldsToCheck[] = $Params[
"InsertIntoField"];
336 # load images to check 337 foreach ($this->DeletedImages as $ImageId)
339 $Images[$ImageId] =
new SPTImage($ImageId);
342 # load files to check 343 foreach ($this->DeletedFiles as $FileId)
345 $Files[$FileId] =
new File($FileId);
348 # for each text field potentially containing references to deleted items 349 foreach ($TextFieldsToCheck as $FieldName)
351 # get HTML form field name for field 354 # for each deleted image 355 foreach ($this->DeletedImages as $ImageId)
357 # strip out any tags referencing that image from field content 358 $_POST[$FormFieldName] = preg_replace(
360 .$Images[$ImageId]->PreviewUrl().
"\"[^>]*>%",
365 # for each deleted file 366 foreach ($this->DeletedFiles as $FileId)
368 # strip out any tags we inserted that reference that file 369 $FileLink = $Files[$FileId]->GetLink();
370 $_POST[$FormFieldName] = preg_replace(
372 .preg_quote(htmlspecialchars($FileLink),
'%')
373 .
"\"[^>]*>(.*?)</a>%",
382 # ---- PRIVATE INTERFACE ------------------------------------------------- 401 ($Params[
"Type"] != self::FTYPE_PRIVILEGES));
403 switch ($Params[
"Type"])
405 case self::FTYPE_TEXT:
406 case self::FTYPE_NUMBER:
407 case self::FTYPE_URL:
408 case self::FTYPE_PASSWORD:
409 $DefaultSize = ($Params[
"Type"] == self::FTYPE_NUMBER) ? 6 : 40;
410 $DefaultMaxLen = ($Params[
"Type"] == self::FTYPE_NUMBER) ? 12 : 80;
411 $Size = isset($Params[
"Size"]) ? $Params[
"Size"]
412 : (isset($Params[
"MaxVal"])
413 ? (strlen(intval($Params[
"MaxVal"]) + 1))
415 $MaxLen = isset($Params[
"MaxLength"]) ? $Params[
"MaxLength"]
416 : (isset($Params[
"MaxVal"])
417 ? (strlen(intval($Params[
"MaxVal"]) + 3))
419 $Placeholder = isset($Params[
"Placeholder"])
420 ? $Params[
"Placeholder"]
421 :
"(".strtolower($Params[
"Label"]).
")";
422 $InputType = ($Params[
"Type"] == self::FTYPE_PASSWORD)
423 ?
"password" :
"text";
424 print(
'<input type="'.$InputType.
'" size="'.$Size.
'" maxlength="' 425 .$MaxLen.
'" id="'.$FieldName.
'" name="'.$FieldName.
'"' 426 .
' value="'.htmlspecialchars($Value).
'"' 427 .
' placeholder=" '.htmlspecialchars($Placeholder).
'"' 428 .($Params[
"ReadOnly"] ?
" readonly" :
"").
' />');
431 case self::FTYPE_PARAGRAPH:
432 $Rows = isset($Params[
"Rows"]) ? $Params[
"Rows"]
433 : (isset($Params[
"Height"]) ? $Params[
"Height"] : 4);
434 $Columns = isset($Params[
"Columns"]) ? $Params[
"Columns"]
435 : (isset($Params[
"Width"]) ? $Params[
"Width"] : 40);
436 print(
'<textarea rows="'.$Rows.
'" cols="'.$Columns
437 .
'" id="'.$FieldName.
'" name="'.$FieldName.
'"' 438 .($Params[
"ReadOnly"] ?
" readonly" :
"")
439 .($Params[
"UseWYSIWYG"] ?
' class="ckeditor"' :
"").
'>' 440 .htmlspecialchars($Value)
442 if ($Params[
"UseWYSIWYG"])
444 $this->UsingWysiwygEditor = TRUE;
448 case self::FTYPE_FLAG:
449 if (array_key_exists(
"OnLabel", $Params)
450 && array_key_exists(
"OffLabel", $Params))
452 print(
'<input type="radio" id="'.$FieldName.
'On" name="' 453 .$FieldName.
'" value="1"' 454 .($Value ?
' checked' :
'')
455 .($Params[
"ReadOnly"] ?
' disabled' :
'')
456 .
' /> <label for="'.$FieldName.
'On">'.$Params[
"OnLabel"]
458 print(
'<input type="radio" id="'.$FieldName.
'Off" name="' 459 .$FieldName.
'" value="0"' 460 .($Value ?
'' :
' checked')
461 .($Params[
"ReadOnly"] ?
' disabled' :
'')
462 .
' /> <label for="'.$FieldName.
'Off">'.$Params[
"OffLabel"]
467 print(
'<input type="checkbox" id="'.$FieldName.
'" name="' 469 .($Value ?
' checked' :
'')
470 .($Params[
"ReadOnly"] ?
' disabled' :
'')
475 case self::FTYPE_OPTION:
476 if ($this->IsRadioButtonField($Name))
479 $FieldName, $Params[
"Options"], $Value);
484 $FieldName, $Params[
"Options"], $Value);
485 $OptList->MultipleAllowed($Params[
"AllowMultiple"]);
486 $OptList->Size(isset($Params[
"Rows"]) ? $Params[
"Rows"] : 1);
488 $OptList->Disabled($Params[
"ReadOnly"]);
489 $OptList->PrintHtml();
492 case self::FTYPE_METADATAFIELD:
493 $FieldTypes = GetArrayValue($Params,
"FieldTypes");
494 $SchemaId = GetArrayValue($Params,
"SchemaId",
497 print $Schema->GetFieldsAsOptionList(
498 $FieldName, $FieldTypes, $Value,
499 !$Params[
"AllowMultiple"] && !$Params[
"Required"],
500 NULL, $Params[
"AllowMultiple"], $Params[
"ReadOnly"]);
503 case self::FTYPE_PRIVILEGES:
504 # (convert legacy previously-stored values if necessary) 505 if (is_array($Value))
508 $PrivSet->AddPrivilege($Value);
512 $Schemas = GetArrayValue($Params,
"Schemas");
513 $MFields = GetArrayValue($Params,
"MetadataFields", array());
515 $PEditor->DisplaySet($FieldName, $Value);
518 case self::FTYPE_SEARCHPARAMS:
521 if (isset($Params[
"MaxFieldLabelLength"]))
523 $SPEditor->MaxFieldLabelLength($Params[
"MaxFieldLabelLength"]);
525 if (isset($Params[
"MaxValueLabelLength"]))
527 $SPEditor->MaxValueLabelLength($Params[
"MaxValueLabelLength"]);
530 $SPEditor->DisplayAsTable();
533 case self::FTYPE_USER:
534 case self::FTYPE_QUICKSEARCH:
540 # set up some helpers that abstract over the 541 # differences between a USER and a QUICKSEARCH field 542 if ($Params[
"Type"] == self::FTYPE_USER)
544 $Search =
"UserSearch";
545 $AllowMultiple = $Params[
"AllowMultiple"];
547 $NameFn =
function($Key, $Val) use ($UFactory) {
548 return $UFactory->UserExists($Val) ?
549 (
new CWUser($Val))->Name() :
"" ;
551 $IdFn =
function($Key, $Val) {
558 $Search = $Params[
"Field"];
559 $AllowMultiple = $MField->AllowMultlple();
560 $NameFn =
function($Key, $Val) use ($MField) {
564 return $Resource->GetMapped(
"Title");
571 $IdFn =
function($Key, $Val) {
576 # filter out empty incoming values 577 $Value = array_filter(
578 $Value,
function($x) {
584 # iterate over incoming values 585 foreach ($Value as $Key => $Val)
587 # pull out the corresponding name/id 588 $VName = $NameFn($Key, $Val);
589 $VId = $IdFn($Key, $Val);
592 if ($Params[
"ReadOnly"])
594 print
"<p>".defaulthtmlentities($VName).
"</p>";
601 defaulthtmlentities($VName),
608 if (!$Params[
"ReadOnly"])
610 # display a blank row for adding more values 611 # when we have no values or when we allow more 612 if (count($Value)==0 || $AllowMultiple)
624 case self::FTYPE_FILE:
628 case self::FTYPE_IMAGE:
633 if (isset($Params[
"Units"]))
636 print $Params[
"Units"];
649 # normalize incoming value 650 $Images = is_array($Value) ? $Value
651 : (($Value === NULL) ? array() : array($Value));
654 print
'<table border="0" cellspacing="0" cellpadding="0" width="100%">';
656 # for each incoming value 657 $ImagesDisplayed = 0;
658 $InsertButtonHtml =
"";
659 foreach ($Images as $Image)
661 # skip if image is a placeholder to indicate no images for field 662 if ($Image == self::NO_VALUE_FOR_FIELD)
667 # load up image object if ID supplied 668 if (is_numeric($Image))
673 # skip image if it has been deleted 679 # load various image attributes for use in HTML 680 $ImageUrl = defaulthtmlentities($Image->ThumbnailUrl());
681 $ImageId = $Image->Id();
682 $ImageAltTextFieldName = $FieldName.
"_AltText_".$ImageId;
683 $ImageAltText = defaulthtmlentities(
684 isset($_POST[$ImageAltTextFieldName])
685 ? $_POST[$ImageAltTextFieldName]
686 : $Image->AltText());
690 # build up HTML for any insert buttons 691 if (isset($Params[
"InsertIntoField"]))
694 $InsertRightCommand = defaulthtmlentities(
695 "CKEDITOR.instances['".$InsertField
697 .
"'<img src=\"".$Image->PreviewUrl().
"\" alt=\"" 698 .htmlspecialchars($Image->AltText())
699 .
"\" class=\"cw-formui-image-right\" />');");
700 $InsertLeftCommand = defaulthtmlentities(
701 "CKEDITOR.instances['".$InsertField
703 .
"'<img src=\"".$Image->PreviewUrl().
"\" alt=\"" 704 .htmlspecialchars($Image->AltText())
705 .
"\" class=\"cw-formui-image-left\" />');");
706 $InsertButtonHtml =
'<button type="button" onclick="' 707 .$InsertLeftCommand.
'">Insert-L</button>' 708 .
'<button type="button" onclick="' 709 .$InsertRightCommand.
'">Insert-R</button>';
712 # add table row for image 714 <td><img src=
"<?= $ImageUrl ?>"></td>
715 <td style=
"white-space: nowrap;"><label
for=
"<?= 716 $ImageAltTextFieldName ?>" class=
"cw-form-pseudolabel">
717 Alt Text:</label><input type=
"text" size=
"20" 718 maxlength=
"120" name=
"<?= $ImageAltTextFieldName ?>" 719 value=
"<?= $ImageAltText ?>" 720 placeholder=
" (alternate text for image)"></td>
721 <td><?= $InsertButtonHtml ?><input type=
"submit" name=
"Submit" 722 onclick=
"$('#<?= $DeleteFieldName ?>').val('<?= $ImageId 723 ?>');" value=
"Delete"></td>
727 # add image ID to hidden fields 728 $this->HiddenFields[$FieldName.
"_ID"][] = $Image->Id();
730 # add container to hold ID of any image to be deleted 731 if (!isset($this->HiddenFields[$DeleteFieldName]))
733 $this->HiddenFields[$DeleteFieldName] =
"";
737 # if no images were displayed and an image entry was skipped 738 if (($ImagesDisplayed == 0) && count($Images))
740 # add marker to indicate no images to hidden fields 741 $this->HiddenFields[$FieldName.
"_ID"][] = self::NO_VALUE_FOR_FIELD;
744 # add table row for new image upload 745 if ($Params[
"AllowMultiple"] || ($ImagesDisplayed == 0))
747 $ImageAltTextFieldName = $FieldName.
"_AltText_NEW";
749 <td><input type=
"file" name=
"<?= $FieldName ?>" /></td>
750 <td style=
"white-space: nowrap;"><label
for=
"<?= 751 $ImageAltTextFieldName ?>" class=
"cw-form-pseudolabel">
752 Alt Text:</label><input type=
"text" size=
"20" 753 maxlength=
"120" name=
"<?= $ImageAltTextFieldName ?>" 754 placeholder=
" (alternate text for image)"></td>
755 <td><input type=
"submit" name=
"Submit" value=
"Upload" /></td>
771 # normalize incoming value 772 $Files = is_array($Value) ? $Value
773 : (($Value === NULL) ? array() : array($Value));
776 print
'<table border="0" cellspacing="0" cellpadding="0" width="100%">';
778 # for each incoming value 780 $InsertButtonHtml =
"";
781 foreach ($Files as $File)
783 # skip if file is a placeholder to indicate no files for field 784 if ($File == self::NO_VALUE_FOR_FIELD)
789 # load up file object if ID supplied 790 if (is_numeric($File))
792 $File =
new File($File);
795 # skip file if it has been deleted 801 # load various attributes for use in HTML 802 $FileId = $File->Id();
803 $FileUrl = $File->GetLink();
804 $FileName = $File->Name();
805 $FileLinkTag =
"<a href=\"".htmlspecialchars($FileUrl)
806 .
"\" target=\"_blank\">" 807 .htmlspecialchars($FileName).
"</a>";
810 # build up HTML for any insert buttons 811 if (isset($Params[
"InsertIntoField"]))
814 $InsertCommand = defaulthtmlentities(
815 "CKEDITOR.instances['".$InsertField
816 .
"'].insertHtml('".$FileLinkTag.
"');");
817 $InsertButtonHtml =
'<button type="button" onclick="' 818 .$InsertCommand.
'">Insert</button>';
821 # add table row for file 823 <td><?= $FileLinkTag ?></td>
824 <td><?= $InsertButtonHtml ?><input type=
"submit" name=
"Submit" 825 onclick=
"$('#<?= $DeleteFieldName ?>').val('<?= $FileId 826 ?>');" value=
"Delete"></td>
830 # add file ID to hidden fields 831 $this->HiddenFields[$FieldName.
"_ID"][] = $FileId;
833 # add container to hold ID of any file to be deleted 834 if (!isset($this->HiddenFields[$DeleteFieldName]))
836 $this->HiddenFields[$DeleteFieldName] =
"";
840 # if no files were displayed and a file entry was skipped 841 if (($FilesDisplayed == 0) && count($Files))
843 # add marker to indicate no files to hidden fields 844 $this->HiddenFields[$FieldName.
"_ID"][] = self::NO_VALUE_FOR_FIELD;
847 # add table row for new file upload 848 if ($Params[
"AllowMultiple"] || ($FilesDisplayed == 0))
851 <td><input type=
"file" name=
"<?= $FieldName ?>" /></td>
852 <td><input type=
"submit" name=
"Submit" value=
"Upload" /></td>
866 # for each form field 867 foreach ($this->FieldParams as $ToggledField => $Params)
869 # if field has togglers (other fields that can toggle this field) 870 if (isset($Params[
"DisplayIf"]))
873 foreach ($Params[
"DisplayIf"] as $Toggler => $ToggleValues)
875 # add field to list of fields toggled by this toggler 876 $FieldsToggled[$Toggler][] = $ToggledField;
878 # add values to list of values that toggle this field 879 if (!is_array($ToggleValues))
880 { $ToggleValues = array($ToggleValues); }
881 $FieldToggleValues[$ToggledField][$Toggler] = $ToggleValues;
886 # if there were fields that toggle other fields 887 if (isset($FieldsToggled))
889 # start JavaScript code 891 <script type=
"text/javascript">
896 foreach ($FieldsToggled as $Toggler => $ToggledFields)
898 # begin function called when toggler changes 901 $(
"[id^=<?= $TogglerFFName ?>]").change(
function(){
904 # for each togglee (field being toggled) 905 foreach ($ToggledFields as $ToggledField)
907 # get JavaScript condition for this togglee 908 $ConditionJS = $this->GetFieldToggleConditionJS(
909 $FieldToggleValues[$ToggledField]);
911 # add toggle code for togglee 914 $(
"#row-<?= $ToggledFieldFFName ?>")[<?=
915 $ConditionJS ?> ?
"show" :
"hide"]();
919 # end function for field changing 925 # end JavaScript code 939 private function GetFieldToggleConditionJS($ToggleValues)
942 foreach ($ToggleValues as $Toggler => $ToggleValues)
944 # start with fresh subcondition list 945 $SubConditions = array();
947 # for each toggle value 949 foreach ($ToggleValues as $Value)
951 # build subcondition for value 952 if ($this->FieldParams[$Toggler][
"Type"] == self::FTYPE_FLAG)
956 $SubConditions[] =
"($(\"input[name=".$TogglerFFName
957 .
"]\").is(\":checked:visible\"))";
961 $SubConditions[] =
"(!$(\"input[name=".$TogglerFFName
962 .
"]\").is(\":checked:visible\"))";
967 if ($this->IsRadioButtonField($Toggler))
969 $SubConditions[] =
"($(\"input[name=".$TogglerFFName
970 .
"]:checked\").val() == \"".$Value.
"\")";
974 $SubConditions[] =
"($(\"#".$TogglerFFName
975 .
"\").val() == \"".$Value.
"\")";
980 # assemble subconditions into condition 981 if (count($SubConditions) > 1)
983 $SubConditionStrings[] =
"(".implode(
" || ", $SubConditions).
")";
987 $SubConditionStrings[] = $SubConditions[0];
991 # assemble conditions into condition string 992 $ConditionString = implode(
" && ", $SubConditionStrings);
994 return $ConditionString;
1002 private function IsRadioButtonField($FieldName)
1004 $Params = $this->FieldParams[$FieldName];
1005 if ($Params[
"Type"] == self::FTYPE_OPTION)
1007 if (isset($Params[
"RadioButtons"]))
1009 return $Params[
"RadioButtons"] ? TRUE : FALSE;
1011 elseif (isset($Params[
"AllowMultiple"]) && $Params[
"AllowMultiple"])
1017 return (count($Params[
"Options"])
1018 <= self::OPTION_RADIO_BUTTON_THRESHOLD) ? TRUE : FALSE;
User interface element for editing PrivilegeSets.
Set of privileges used to access resource information or other parts of the system.
static PrintQuickSearchField($FieldId, $CurrentValue, $CurrentDisplayValue, $CloneAfter=FALSE, $FormFieldName=NULL)
Print the blank text field quick search field for the QuickSearch JS object.
CWIS-specific user factory class.
Encapsulates a full-size, preview, and thumbnail image.
Represents a "resource" in CWIS.
Class representing a stored (usually uploaded) file.
CWIS-specific user class.
Convenience class for generating an HTML select/option form element.
Class to create a user interface for editing SearchParameterSets.