CWIS Developer Documentation
FormUI.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # FILE: FormUI.php
4 #
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/
8 #
9 
134 class FormUI extends FormUI_Base
135 {
136 
137  # ---- PUBLIC INTERFACE --------------------------------------------------
138 
145  public function DisplayFormTable($TableId = NULL, $TableStyle = NULL,
146  $TableCssClass = NULL)
147  {
148  # display nothing if there are no fields
149  if (!count($this->FieldParams)) { return; }
150 
151  # check whether table should be split into sections
152  $TableIsSectioned = FALSE;
153  foreach ($this->FieldParams as $Name => $Params)
154  {
155  if ($Params["Type"] == self::FTYPE_HEADING)
156  { $TableIsSectioned = TRUE; }
157  }
158 
159  # begin table
160  // @codingStandardsIgnoreStart
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."\""); }
167  ?>>
168  <tbody><?PHP
169  // @codingStandardsIgnoreEnd
170 
171  # for each field
172  foreach ($this->FieldParams as $Name => $Params)
173  {
174  # generate name for field
175  $FormFieldName = $this->GetFormFieldName($Name);
176 
177  # if field is actually a section heading
178  if ($Params["Type"] == self::FTYPE_HEADING)
179  {
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;
186  }
187  else
188  {
189  # determine if row may have taller content
190  $ShortRowFieldTypes = array(
191  self::FTYPE_FLAG,
192  self::FTYPE_METADATAFIELD,
193  self::FTYPE_NUMBER,
194  self::FTYPE_PASSWORD,
195  self::FTYPE_TEXT,
196  self::FTYPE_URL,
197  self::FTYPE_USER,
198  );
199  $IsTallRow = !isset($Params["Units"])
200  && !in_array($Params["Type"], $ShortRowFieldTypes)
201  && (($Params["Type"] != self::FTYPE_OPTION)
202  || (isset($Params["Rows"])
203  && ($Params["Rows"] > 1)));
204 
205  # load up value(s) to go into field
206  $Value = $this->GetFieldValue($Name);
207 
208  # set up CSS classes for table row
209  $RowClass = "cw-formui-fieldtype-".strtolower($Params["Type"]);
210  if ($Params["Type"] == "MetadataField")
211  {
212  $RowClass .= " cw-formui-schemaid-"
213  .GetArrayValue($Params, "SchemaId",
215  }
216  $RowClass .= $IsTallRow ? " cw-content-tallrow" : "";
217  $RowClassAttrib = ' class="'.$RowClass.'"';
218 
219  # set up CSS classes for row header cell
220  $HeaderClass = $IsTallRow ? "cw-content-tallrow-th" : "";
221  $HeaderClassAttrib = strlen($HeaderClass)
222  ? ' class="'.$HeaderClass.'"' : "";
223 
224  # set up CSS classes for row label
225  $LabelClass = "cw-form-pseudolabel"
226  .(isset(self::$ErrorMessages[$Name])
227  ? " cw-form-error" : "");
228 
229  # set up min/max note if applicable
230  unset($RangeNotePieces);
231  if (isset($Params["MinVal"]))
232  {
233  $RangeNotePieces[] = "Minimum: <i>".$Params["MinVal"]."</i>";
234  }
235  if (isset($Params["MaxVal"]))
236  {
237  $RangeNotePieces[] = "Maximum: <i>".$Params["MaxVal"]."</i>";
238  }
239  if (isset($Params["RecVal"]))
240  {
241  $RangeNotePieces[] = "Recommended: <i>".$Params["RecVal"]."</i>";
242  }
243  if (isset($RangeNotePieces))
244  {
245  $RangeNote = "(".implode(", ", $RangeNotePieces).")";
246  }
247 
248  // @codingStandardsIgnoreStart
249  ?>
250  <tr<?= ($IsTallRow ? " valign=\"top\"" : "").$RowClassAttrib
251  ?> id="row-<?= $FormFieldName ?>">
252  <th<?= $HeaderClassAttrib ?>>
253  <label for="<?= $FormFieldName
254  ?>" class="<?= $LabelClass ?>"><?=
255  $Params["Label"] ?></label>
256  </th>
257  <td <?PHP if (!isset($Params["Help"]) && !isset($RangeNotePieces)) {
258  print "colspan=\"2\""; } ?>><?PHP
259  $this->DisplayFormField(
260  $Name, $Value, $Params); ?></td>
261  <?PHP if (isset($Params["Help"])) { ?>
262  <td class="cw-content-help-cell"><?= $Params["Help"] ?></td>
263  <?PHP } elseif (isset($RangeNotePieces)) { ?>
264  <td class="cw-content-help-cell"><?= $RangeNote ?></td>
265  <?PHP } ?>
266  </tr>
267  <?PHP
268  }
269  }
270 
271  # end table
272  ?></tbody>
273  </table><?PHP
274 
275  # add any hidden form fields
276  print $this->GetHiddenFieldsHtml();
277 
278  # add any needed JavaScript for toggled fields
280 
281  # pull in WYSIWYG editor setup if needed
282  if ($this->UsingWysiwygEditor)
283  {
284  require_once($GLOBALS["AF"]->GUIFile("CKEditorSetup.php"));
285  }
286  }
287  // @codingStandardsIgnoreEnd
288 
292  public static function DisplayErrorBlock()
293  {
294  if (count(self::$ErrorMessages))
295  {
296  print "<ul class=\"cw-form-error\">\n";
297  $DisplayedMsgs = array();
298  foreach (self::$ErrorMessages as $Field => $Msgs)
299  {
300  foreach ($Msgs as $Msg)
301  {
302  if (!in_array($Msg, $DisplayedMsgs))
303  {
304  print "<li>".$Msg."</li>\n";
305  $DisplayedMsgs[] = $Msg;
306  }
307  }
308  }
309  print "</ul>\n";
310  }
311  }
312 
317  public function HandleDeletes()
318  {
319  parent::HandleDeletes();
320 
321  $TextFieldsToCheck = array();
322 
323  # check for text fields that may contain images
324  foreach ($this->FieldParams as $Name => $Params)
325  {
326  if ($Params["Type"] == self::FTYPE_IMAGE &&
327  isset($Params["InsertIntoField"]))
328  {
329  $TextFieldsToCheck[]= $Params["InsertIntoField"];
330  }
331  }
332 
333  # for each image-containing text field
334  foreach ($TextFieldsToCheck as $Name)
335  {
336  # and for each deleted image
337  foreach ($this->DeletedImages as $ImageId)
338  {
339  # strip out image tags referencing that image from the values
340  # presented in $_POST
341  $Image = new SPTImage($ImageId);
342 
343  $FieldName = $this->GetFormFieldName($Name);
344  $_POST[$FieldName] = preg_replace(
345  "%<img [^>]*src=\"".$Image->PreviewUrl()."\"[^>]*>%", "",
346  $this->GetFieldValue($Name) );
347  }
348  }
349  }
350 
351 
352 
353  # ---- PRIVATE INTERFACE -------------------------------------------------
354 
355  protected $UsingWysiwygEditor = FALSE;
356 
362 
369  protected function DisplayFormField($Name, $Value, $Params)
370  {
371  $FieldName = $this->GetFormFieldName($Name,
372  ($Params["Type"] != self::FTYPE_PRIVILEGES));
373 
374  switch ($Params["Type"])
375  {
376  case self::FTYPE_TEXT:
377  case self::FTYPE_NUMBER:
378  case self::FTYPE_URL:
379  case self::FTYPE_USER:
380  case self::FTYPE_PASSWORD:
381  if ($Params["Type"] == self::FTYPE_USER)
382  {
383  if (is_numeric($Value))
384  {
385  $User = new CWUser($Value);
386  $Value = $User->Name();
387  }
388  }
389  $DefaultSize = ($Params["Type"] == self::FTYPE_NUMBER) ? 6 : 40;
390  $DefaultMaxLen = ($Params["Type"] == self::FTYPE_NUMBER) ? 12 : 80;
391  $Size = isset($Params["Size"]) ? $Params["Size"]
392  : (isset($Params["MaxVal"])
393  ? (strlen(intval($Params["MaxVal"]) + 1))
394  : $DefaultSize);
395  $MaxLen = isset($Params["MaxLength"]) ? $Params["MaxLength"]
396  : (isset($Params["MaxVal"])
397  ? (strlen(intval($Params["MaxVal"]) + 3))
398  : $DefaultMaxLen);
399  $Placeholder = isset($Params["Placeholder"])
400  ? $Params["Placeholder"]
401  : "(".strtolower($Params["Label"]).")";
402  $InputType = ($Params["Type"] == self::FTYPE_PASSWORD)
403  ? "password" : "text";
404  print('<input type="'.$InputType.'" size="'.$Size.'" maxlength="'
405  .$MaxLen.'" id="'.$FieldName.'" name="'.$FieldName.'"'
406  .' value="'.htmlspecialchars($Value).'"'
407  .' placeholder=" '.htmlspecialchars($Placeholder).'"'
408  .($Params["ReadOnly"] ? " readonly" : "").' />');
409  break;
410 
411  case self::FTYPE_PARAGRAPH:
412  $Rows = isset($Params["Rows"]) ? $Params["Rows"] : 4;
413  $Columns = isset($Params["Columns"]) ? $Params["Columns"] : 40;
414  print('<textarea rows="'.$Rows.'" cols="'.$Columns
415  .'" id="'.$FieldName.'" name="'.$FieldName.'"'
416  .($Params["ReadOnly"] ? " readonly" : "")
417  .($Params["UseWYSIWYG"] ? ' class="ckeditor"' : "").'>'
418  .htmlspecialchars($Value)
419  .'</textarea>');
420  if ($Params["UseWYSIWYG"])
421  {
422  $this->UsingWysiwygEditor = TRUE;
423  }
424  break;
425 
426  case self::FTYPE_FLAG:
427  if (array_key_exists("OnLabel", $Params)
428  && array_key_exists("OffLabel", $Params))
429  {
430  print('<input type="radio" id="'.$FieldName.'On" name="'
431  .$FieldName.'" value="1"'
432  .($Value ? ' checked' : '')
433  .($Params["ReadOnly"] ? ' disabled' : '')
434  .' /> <label for="'.$FieldName.'On">'.$Params["OnLabel"]
435  ."</label>\n");
436  print('<input type="radio" id="'.$FieldName.'Off" name="'
437  .$FieldName.'" value="0"'
438  .($Value ? '' : ' checked')
439  .($Params["ReadOnly"] ? ' disabled' : '')
440  .' /> <label for="'.$FieldName.'Off">'.$Params["OffLabel"]
441  ."</label>\n");
442  }
443  else
444  {
445  print('<input type="checkbox" id="'.$FieldName.'" name="'
446  .$FieldName.'" '
447  .($Value ? ' checked' : '')
448  .($Params["ReadOnly"] ? ' disabled' : '')
449  ." />\n");
450  }
451  break;
452 
453  case self::FTYPE_OPTION:
454  if ($this->IsRadioButtonField($Name))
455  {
456  $OptList = new HtmlRadioButtonSet(
457  $FieldName, $Params["Options"], $Value);
458  }
459  else
460  {
461  $OptList = new HtmlOptionList(
462  $FieldName, $Params["Options"], $Value);
463  $OptList->MultipleAllowed($Params["AllowMultiple"]);
464  $OptList->Size(isset($Params["Rows"]) ? $Params["Rows"] : 1);
465  }
466  $OptList->Disabled($Params["ReadOnly"]);
467  $OptList->PrintHtml();
468  break;
469 
470  case self::FTYPE_METADATAFIELD:
471  $FieldTypes = GetArrayValue($Params, "FieldTypes");
472  $SchemaId = GetArrayValue($Params, "SchemaId",
474  $Schema = new MetadataSchema($SchemaId);
475  print $Schema->GetFieldsAsOptionList(
476  $FieldName, $FieldTypes, $Value,
477  !$Params["AllowMultiple"] && !$Params["Required"],
478  NULL, $Params["AllowMultiple"], $Params["ReadOnly"]);
479  break;
480 
481  case self::FTYPE_PRIVILEGES:
482  # (convert legacy previously-stored values if necessary)
483  if (is_array($Value))
484  {
485  $PrivSet = new PrivilegeSet();
486  $PrivSet->AddPrivilege($Value);
487  $Value = $PrivSet;
488  }
489 
490  $Schemas = GetArrayValue($Params, "Schemas");
491  $MFields = GetArrayValue($Params, "MetadataFields", array());
492  $PEditor = new PrivilegeEditingUI($Schemas, $MFields);
493  $PEditor->DisplaySet($FieldName, $Value);
494  break;
495 
496  case self::FTYPE_SEARCHPARAMS:
497  $SPEditor = new SearchParameterSetEditingUI($FieldName, $Value);
498  $SPEditor->DisplayAsTable();
499  break;
500 
501  case self::FTYPE_IMAGE:
502  $this->DisplayImageField($FieldName, $Value, $Params);
503  break;
504  }
505 
506  if (isset($Params["Units"]))
507  {
508  ?>&nbsp;<span><?PHP
509  print $Params["Units"];
510  ?></span><?PHP
511  }
512  }
513 
520  protected function DisplayImageField($FieldName, $Value, $Params)
521  {
522  # normalize incoming value
523  $Images = is_array($Value) ? $Value
524  : (($Value === NULL) ? array() : array($Value));
525 
526  # begin value table
527  print '<table border="0" cellspacing="0" cellpadding="0" width="100%">';
528 
529  # for each incoming value
530  $ImagesDisplayed = 0;
531  $InsertButtonHtml = "";
532  foreach ($Images as $Image)
533  {
534  # skip if image is a placeholder to indicate no images for field
535  if ($Image == self::NO_VALUE_FOR_FIELD)
536  {
537  continue;
538  }
539 
540  # load up image object if ID supplied
541  if (is_numeric($Image))
542  {
543  $Image = new SPTImage($Image);
544  }
545 
546  # skip image if it has been deleted
547  if (in_array($Image->Id(), $this->DeletedImages))
548  {
549  continue;
550  }
551 
552  # load various image attributes for use in HTML
553  $ImageUrl = defaulthtmlentities($Image->ThumbnailUrl());
554  $ImageId = $Image->Id();
555  $ImageAltTextFieldName = $FieldName."_AltText_".$ImageId;
556  $ImageAltText = defaulthtmlentities(
557  isset($_POST[$ImageAltTextFieldName])
558  ? $_POST[$ImageAltTextFieldName]
559  : $Image->AltText());
560 
561  $DeleteFieldName = $this->GetFormFieldName("ImageToDelete");
562 
563  # build up HTML for any insert buttons
564  if (isset($Params["InsertIntoField"]))
565  {
566  $InsertField = $this->GetFormFieldName($Params["InsertIntoField"]);
567  $InsertRightCommand = defaulthtmlentities(
568  "CKEDITOR.instances['".$InsertField
569  ."'].insertHtml("
570  ."'<img src=\"".$Image->PreviewUrl()."\" alt=\""
571  .htmlspecialchars($Image->AltText())
572  ."\" class=\"cw-formui-image-right\" />');");
573  $InsertLeftCommand = defaulthtmlentities(
574  "CKEDITOR.instances['".$InsertField
575  ."'].insertHtml("
576  ."'<img src=\"".$Image->PreviewUrl()."\" alt=\""
577  .htmlspecialchars($Image->AltText())
578  ."\" class=\"cw-formui-image-left\" />');");
579  $InsertButtonHtml = '<button type="button" onclick="'
580  .$InsertLeftCommand.'">Insert-L</button>'
581  .'<button type="button" onclick="'
582  .$InsertRightCommand.'">Insert-R</button>';
583  }
584 
585  # add table row for image
586  ?><tr>
587  <td><img src="<?= $ImageUrl ?>"></td>
588  <td style="white-space: nowrap;"><label for="<?=
589  $ImageAltTextFieldName ?>" class="cw-form-pseudolabel">
590  Alt Text:</label><input type="text" size="20"
591  maxlength="120" name="<?= $ImageAltTextFieldName ?>"
592  value="<?= $ImageAltText ?>"
593  placeholder=" (alternate text for image)"></td>
594  <td><?= $InsertButtonHtml ?><input type="submit" name="Submit"
595  onclick="$('#<?= $DeleteFieldName ?>').val('<?= $ImageId
596  ?>');" value="Delete"></td>
597  </tr><?PHP
598  $ImagesDisplayed++;
599 
600  # add image ID to hidden fields
601  $this->HiddenFields[$FieldName."_ID"][] = $Image->Id();
602 
603  # add container to hold ID of any image to be deleted
604  if (!isset($this->HiddenFields[$DeleteFieldName]))
605  {
606  $this->HiddenFields[$DeleteFieldName] = "";
607  }
608  }
609 
610  # if no images were displayed and an image entry was skipped
611  if (($ImagesDisplayed == 0) && count($Images))
612  {
613  # add marker to indicate no images to hidden fields
614  $this->HiddenFields[$FieldName."_ID"][] = self::NO_VALUE_FOR_FIELD;
615  }
616 
617  # add table row for new image upload
618  if ($Params["AllowMultiple"] || ($ImagesDisplayed == 0))
619  {
620  $ImageAltTextFieldName = $FieldName."_AltText_NEW";
621  ?><tr>
622  <td><input type="file" name="<?= $FieldName ?>" /></td>
623  <td style="white-space: nowrap;"><label for="<?=
624  $ImageAltTextFieldName ?>" class="cw-form-pseudolabel">
625  Alt Text:</label><input type="text" size="20"
626  maxlength="120" name="<?= $ImageAltTextFieldName ?>"
627  placeholder=" (alternate text for image)"></td>
628  <td><input type="submit" name="Submit" value="Upload" /></td>
629  </tr><?PHP
630  }
631 
632  # end value table
633  print '</table>';
634  }
635 
640  protected function PrintFieldHidingJavascript()
641  {
642  # for each form field
643  foreach ($this->FieldParams as $ToggledField => $Params)
644  {
645  # if field has togglers (other fields that can toggle this field)
646  if (isset($Params["DisplayIf"]))
647  {
648  # for each toggler
649  foreach ($Params["DisplayIf"] as $Toggler => $ToggleValues)
650  {
651  # add field to list of fields toggled by this toggler
652  $FieldsToggled[$Toggler][] = $ToggledField;
653 
654  # add values to list of values that toggle this field
655  if (!is_array($ToggleValues))
656  { $ToggleValues = array($ToggleValues); }
657  $FieldToggleValues[$ToggledField][$Toggler] = $ToggleValues;
658  }
659  }
660  }
661 
662  # if there were fields that toggle other fields
663  if (isset($FieldsToggled))
664  {
665  # start JavaScript code
666  ?>
667  <script type="text/javascript">
668  (function($){
669  <?PHP
670 
671  # for each toggler
672  foreach ($FieldsToggled as $Toggler => $ToggledFields)
673  {
674  # begin function called when toggler changes
675  $TogglerFFName = $this->GetFormFieldName($Toggler);
676  ?>
677  $("[id^=<?= $TogglerFFName ?>]").change(function(){
678  <?PHP
679 
680  # for each togglee (field being toggled)
681  foreach ($ToggledFields as $ToggledField)
682  {
683  # get JavaScript condition for this togglee
684  $ConditionJS = $this->GetFieldToggleConditionJS(
685  $FieldToggleValues[$ToggledField]);
686 
687  # add toggle code for togglee
688  $ToggledFieldFFName = $this->GetFormFieldName($ToggledField);
689  ?>
690  $("#row-<?= $ToggledFieldFFName ?>")[<?=
691  $ConditionJS ?> ? "show" : "hide"]();
692  <?PHP
693  }
694 
695  # end function for field changing
696  ?>
697  }).change();
698  <?PHP
699  }
700 
701  # end JavaScript code
702  ?>
703  }(jQuery));
704  </script>
705  <?PHP
706  }
707  }
708 
715  private function GetFieldToggleConditionJS($ToggleValues)
716  {
717  # for each toggler
718  foreach ($ToggleValues as $Toggler => $ToggleValues)
719  {
720  # start with fresh subcondition list
721  $SubConditions = array();
722 
723  # for each toggle value
724  $TogglerFFName = $this->GetFormFieldName($Toggler);
725  foreach ($ToggleValues as $Value)
726  {
727  # build subcondition for value
728  if ($this->FieldParams[$Toggler]["Type"] == self::FTYPE_FLAG)
729  {
730  if ($Value)
731  {
732  $SubConditions[] = "($(\"input[name=".$TogglerFFName
733  ."]\").is(\":checked:visible\"))";
734  }
735  else
736  {
737  $SubConditions[] = "(!$(\"input[name=".$TogglerFFName
738  ."]\").is(\":checked:visible\"))";
739  }
740  }
741  else
742  {
743  if ($this->IsRadioButtonField($Toggler))
744  {
745  $SubConditions[] = "($(\"input[name=".$TogglerFFName
746  ."]:checked\").val() == \"".$Value."\")";
747  }
748  else
749  {
750  $SubConditions[] = "($(\"#".$TogglerFFName
751  ."\").val() == \"".$Value."\")";
752  }
753  }
754  }
755 
756  # assemble subconditions into condition
757  if (count($SubConditions) > 1)
758  {
759  $SubConditionStrings[] = "(".implode(" || ", $SubConditions).")";
760  }
761  else
762  {
763  $SubConditionStrings[] = $SubConditions[0];
764  }
765  }
766 
767  # assemble conditions into condition string
768  $ConditionString = implode(" && ", $SubConditionStrings);
769 
770  return $ConditionString;
771  }
772 
778  private function IsRadioButtonField($FieldName)
779  {
780  $Params = $this->FieldParams[$FieldName];
781  if ($Params["Type"] == self::FTYPE_OPTION)
782  {
783  if (isset($Params["RadioButtons"]))
784  {
785  return $Params["RadioButtons"] ? TRUE : FALSE;
786  }
787  elseif (isset($Params["AllowMultiple"]) && $Params["AllowMultiple"])
788  {
789  return FALSE;
790  }
791  else
792  {
793  return (count($Params["Options"])
794  <= self::OPTION_RADIO_BUTTON_THRESHOLD) ? TRUE : FALSE;
795  }
796  }
797  else
798  {
799  return FALSE;
800  }
801  }
802 }
PrintFieldHidingJavascript()
Print any JavaScript required to support toggling display of fields or sections.
Definition: FormUI.php:640
Base class (covering non-presentation elements) supplying a standard user interface for presenting an...
Definition: FormUI_Base.php:14
Metadata schema (in effect a Factory class for MetadataField).
GetHiddenFieldsHtml()
Get HTML for hidden form fields associated with form processing.
DisplayFormField($Name, $Value, $Params)
Display HTML form field for specified field.
Definition: FormUI.php:369
User interface element for editing PrivilegeSets.
Set of privileges used to access resource information or other parts of the system.
Child class (covering presentation elements only) supplying a standard user interface for presenting ...
Definition: FormUI.php:134
DisplayImageField($FieldName, $Value, $Params)
Display image form field for specified field.
Definition: FormUI.php:520
Convenience class for generating a set of HTML radio button form elements.
Encapsulates a full-size, preview, and thumbnail image.
Definition: SPTImage.php:13
HandleDeletes()
Handle image deletion, removing deleted images from text fields where they may have been inserted...
Definition: FormUI.php:317
const OPTION_RADIO_BUTTON_THRESHOLD
FTYPE_OPTION fields with this many or fewer options will display as radio buttons by default...
Definition: FormUI.php:361
static DisplayErrorBlock()
Display HTML block with error messages (if any).
Definition: FormUI.php:292
GetFormFieldName($FieldName, $IncludePrefix=TRUE)
Get HTML form field name for specified field.
GetFieldValue($FieldName)
Get value for form field.
$UsingWysiwygEditor
Definition: FormUI.php:355
DisplayFormTable($TableId=NULL, $TableStyle=NULL, $TableCssClass=NULL)
Display HTML table for form.
Definition: FormUI.php:145
CWIS-specific user class.
Definition: CWUser.php:13
Convenience class for generating an HTML select/option form element.
Class to create a user interface for editing SearchParameterSets.