CWIS Developer Documentation

- Home
- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

FormUI_Base.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # FILE: FormUI_Base.php
4 #
5 # Part of the Collection Workflow Integration System (CWIS)
6 # Copyright 2016 Edward Almasy and Internet Scout Research Group
7 # http://scout.wisc.edu/cwis/
8 #
9
14 abstract class FormUI_Base
15 {
16 # ---- PUBLIC INTERFACE --------------------------------------------------
17
19 const FTYPE_FILE = "File";
20 const FTYPE_FLAG = "Flag";
21 const FTYPE_IMAGE = "Image";
22 const FTYPE_METADATAFIELD = "MetadataField";
23 const FTYPE_NUMBER = "Number";
24 const FTYPE_OPTION = "Option";
25 const FTYPE_PARAGRAPH = "Paragraph";
26 const FTYPE_PASSWORD = "Password";
27 const FTYPE_PRIVILEGES = "Privileges";
28 const FTYPE_SEARCHPARAMS = "Search Parameters";
29 const FTYPE_TEXT = "Text";
30 const FTYPE_URL = "URL";
31 const FTYPE_USER = "User";
32 const FTYPE_QUICKSEARCH = "Quick Search";
34 const FTYPE_HEADING = "Heading";
35
46 public function __construct(
47 $FieldParams, $FieldValues = array(), $UniqueKey = NULL)
48 {
49 # make sure parameters are legal and complete
50 $BooleanParams = array(
51 "AllowMultiple",
52 "ReadOnly",
53 "Required",
54 "UseWYSIWYG",
55 );
56 foreach ($FieldParams as $FieldName => $Params)
57 {
58 if (!isset($Params["Type"]))
59 {
60 $ErrMsgs[] = "Type missing for form field ".$FieldName.".";
61 }
62 elseif (($Params["Type"] == self::FTYPE_OPTION)
63 && !isset($Params["Options"]))
64 {
65 $ErrMsgs[] = "Option values missing for form field ".$FieldName.".";
66 }
67 elseif ($Params["Type"] == self::FTYPE_QUICKSEARCH)
68 {
69 if (!isset($Params["Field"]))
70 {
71 $ErrMsgs[]= "Field to search missing for quicksearch form field "
72 .$FieldName.".";
73 }
74 elseif (!MetadataSchema::FieldExistsInAnySchema($Params["Field"]))
75 {
76 $ErrMsgs[]= "Specified search field for quicksearch form field "
77 .$FieldName." does not exist.";
78 }
79 else
80 {
81 $FieldParams[$FieldName]["Field"] =
82 MetadataSchema::GetCanonicalFieldIdentifier($Params["Field"]);
83 $MField = new MetadataField(
84 $FieldParams[$FieldName]["Field"]);
85
86 $AllowedMFieldTypes = [
87 MetadataSchema::MDFTYPE_TREE,
88 MetadataSchema::MDFTYPE_CONTROLLEDNAME,
89 MetadataSchema::MDFTYPE_USER,
90 MetadataSchema::MDFTYPE_REFERENCE ];
91 if (!in_array($MField->Type(), $AllowedMFieldTypes))
92 {
93 $ErrMsgs[]= "Specified search field for quicksearch form field "
94 .$FieldName." is not a type that supports quicksearches.";
95 }
96 }
97 }
98
99 if (!isset($Params["Label"]))
100 {
101 $ErrMsgs[] = "Label missing for form field ".$FieldName.".";
102 }
103 if (isset($Params["ValidateFunction"])
104 && !is_callable($Params["ValidateFunction"]))
105 {
106 $ErrMsgs[] = "Uncallable validation function for form field "
107 .$FieldName.".";
108 }
109 if (isset($Params["InsertIntoField"])
110 && !isset($FieldParams[$Params["InsertIntoField"]]))
111 {
112 $ErrMsgs[] = "Unknown insertion field (".$Params["InsertIntoField"]
113 .") found for form field ".$FieldName.".";
114 }
115 foreach ($BooleanParams as $ParamName)
116 {
117 if (!isset($Params[$ParamName]))
118 {
119 $FieldParams[$FieldName][$ParamName] = FALSE;
120 }
121 }
122 }
123 if (isset($ErrMsgs))
124 {
125 $ErrMsgString = implode(" ", $ErrMsgs);
126 throw new InvalidArgumentException($ErrMsgString);
127 }
128
129 # save form parameters and values
130 $this->FieldParams = $FieldParams;
131 $this->FieldValues = $FieldValues;
132 $this->UniqueKey = $UniqueKey;
133 }
134
140 abstract public function DisplayFormTable($TableId = NULL, $TableStyle = NULL);
141
148 public static function LogError($Msg, $Field = NULL)
149 {
150 self::$ErrorMessages[$Field][] = $Msg;
151 }
152
159 public static function GetLoggedErrors()
160 {
161 return self::$ErrorMessages;
162 }
163
170 public static function ErrorsLogged($Field = FALSE)
171 {
172 if ($Field === FALSE)
173 {
174 return count(self::$ErrorMessages) ? TRUE : FALSE;
175 }
176 else
177 {
178 return isset(self::$ErrorMessages[$Field]) ? TRUE : FALSE;
179 }
180 }
181
186 public static function ClearLoggedErrors($Field = FALSE)
187 {
188 if ($Field === FALSE)
189 {
190 self::$ErrorMessages = array();
191 }
192 else
193 {
194 unset(self::$ErrorMessages[$Field]);
195 }
196 }
197
205 public function ValidateFieldInput()
206 {
207 # retrieve field values
208 $Values = $this->GetNewValuesFromForm();
209
210 # for each field
211 $ErrorsFound = 0;
212 foreach ($this->FieldParams as $Name => $Params)
213 {
214 # skip header fields
215 if ($Params["Type"] == self::FTYPE_HEADING) { continue; }
216
217 # determine if field has a value set
218 switch ($Params["Type"])
219 {
220 case self::FTYPE_SEARCHPARAMS:
221 $IsEmpty = !$Values[$Name]->ParameterCount();
222 break;
223
224 case self::FTYPE_PRIVILEGES:
225 $IsEmpty = !$Values[$Name]->ComparisonCount();
226 break;
227
228 default:
229 if (is_array($Values[$Name]))
230 {
231 $IsEmpty = !count($Values[$Name]);
232 }
233 else
234 {
235 $IsEmpty = !strlen(trim($Values[$Name]));
236 }
237 break;
238 }
239
240 # if field has validation function
241 if (isset($Params["ValidateFunction"]))
242 {
243 # swap in our object if this is one of our methods
244 $VFunc = $Params["ValidateFunction"];
245 if (is_array($VFunc) && ($VFunc[0] == "FormUI"))
246 {
247 $VFunc[0] = $this;
248 }
249
250 # call validation function for value
251 $Args = array_merge(array($Name, $Values[$Name], $Values),
252 $this->ExtraValidationParams);
253 $ErrMsg = call_user_func_array($VFunc, $Args);
254 if ($ErrMsg === FALSE)
255 {
256 throw new Exception("Calling validation function for"
257 ." parameter \"".$Name."\" failed.");
258 }
259
260 # log any resulting error
261 if ($ErrMsg !== NULL)
262 {
263 self::LogError($ErrMsg, $Name);
264 $ErrorsFound++;
265 }
266 }
267
268 # if field is required and empty
269 if ($IsEmpty && isset($Params["Required"]) && $Params["Required"])
270 {
271 # log error to indicate required value is missing
272 self::LogError("<i>".$Params["Label"]."</i> is required.", $Name);
273 $ErrorsFound++;
274 }
275 # else validate based on field type
276 else
277 {
278 switch ($Params["Type"])
279 {
280 case self::FTYPE_NUMBER:
281 # make sure value is within any specified range
282 if ((isset($Params["MinVal"])
283 && ($Values[$Name] < $Params["MinVal"]))
284 || (isset($Params["MaxVal"])
285 && ($Values[$Name] > $Params["MaxVal"])))
286 {
287 if (!isset($Params["MaxVal"]))
288 {
289 self::LogError("<i>".$Params["Label"]."</i> must be "
290 .$Params["MinVal"]." or greater.", $Name);
291 }
292 elseif (!isset($Params["MinVal"]))
293 {
294 self::LogError("<i>".$Params["Label"]."</i> must be "
295 .$Params["MaxVal"]." or less.", $Name);
296 }
297 else
298 {
299 self::LogError("<i>".$Params["Label"]."</i> must be"
300 ." in the range ".$Params["MinVal"]
301 ." to ".$Params["MaxVal"].".", $Name);
302 }
303 $ErrorsFound++;
304 }
305 break;
306
307 case self::FTYPE_URL:
308 # make sure URL entered looks valid
309 if (!$IsEmpty && (filter_var(
310 $Values[$Name], FILTER_VALIDATE_URL) === FALSE))
311 {
312 self::LogError("Value \"".$Values[$Name]
313 ."\" does not appear to be a valid URL for <i>"
314 .$Params["Label"]."</i>.", $Name);
315 $ErrorsFound++;
316 }
317 break;
318
319 case self::FTYPE_USER:
320 # make sure user name entered is valid
321 $UFactory = new CWUserFactory();
322 foreach ($Values[$Name] as $UId)
323 {
324 if (strlen($UId) && !$UFactory->UserExists($UId))
325 {
326 self::LogError("User ID \"".$UId
327 ."\" not found for <i>"
328 .$Params["Label"]."</i>.", $Name);
329 $ErrorsFound++;
330 }
331 }
332 break;
333 }
334 }
335 }
336
337 # report number of fields with invalid values found to caller
338 return $ErrorsFound;
339 }
340
346 public function AddValidationParameters()
347 {
348 $this->ExtraValidationParams = func_get_args();
349 }
350
356 public function GetNewValuesFromForm()
357 {
358 # for each form field
359 $NewSettings = array();
360 foreach ($this->FieldParams as $Name => $Params)
361 {
362 # skip header fields
363 if ($Params["Type"] == self::FTYPE_HEADING) { continue; }
364
365 # determine form field name (matches mechanism in HTML)
366 $FieldName = $this->GetFormFieldName($Name,
367 ($Params["Type"] != self::FTYPE_PRIVILEGES));
368
369 # assume the value will not change
370 $DidValueChange = FALSE;
371 $OldValue = isset($this->FieldValues[$Name])
372 ? $this->FieldValues[$Name]
373 : (isset($Params["Value"]) ? $Params["Value"] : NULL);
374 $NewSettings[$Name] = $OldValue;
375
376 # retrieve value based on configuration parameter type
377 switch ($Params["Type"])
378 {
379 case self::FTYPE_FLAG:
380 # if radio buttons were used
381 if (array_key_exists("OnLabel", $Params)
382 && array_key_exists("OffLabel", $Params))
383 {
384 if (isset($_POST[$FieldName]))
385 {
386 $NewValue = ($_POST[$FieldName] == "1") ? TRUE : FALSE;
387
388 # flag that the values changed if they did
389 $DidValueChange = self::DidValueChange(
390 $OldValue, $NewValue);
391
392 $NewSettings[$Name] = $NewValue;
393 }
394 }
395 # else checkbox was used
396 else
397 {
398 $NewValue = isset($_POST[$FieldName]) ? TRUE : FALSE;
399
400 # flag that the values changed if they did
401 $DidValueChange = self::DidValueChange($OldValue, $NewValue);
402
403 $NewSettings[$Name] = $NewValue;
404 }
405 break;
406
407 case self::FTYPE_OPTION:
408 $NewValue = GetArrayValue($_POST, $FieldName, array());
409
410 # flag that the values changed if they did
411 $DidValueChange = self::DidValueChange($OldValue, $NewValue);
412
413 $NewSettings[$Name] = $NewValue;
414 break;
415
416 case self::FTYPE_METADATAFIELD:
417 $NewValue = GetArrayValue($_POST, $FieldName, array());
418 if ($NewValue == "-1") { $NewValue = array(); }
419
420 # flag that the values changed if they did
421 $DidValueChange = self::DidValueChange($OldValue, $NewValue);
422
423 $NewSettings[$Name] = $NewValue;
424 break;
425
426 case self::FTYPE_PRIVILEGES:
427 $Schemas = GetArrayValue($Params, "Schemas");
428 $MFields = GetArrayValue($Params, "MetadataFields", array());
429 $PEditor = new PrivilegeEditingUI($Schemas, $MFields);
430 $NewValues = $PEditor->GetPrivilegeSetsFromForm();
431 $NewValue = $NewValues[$FieldName];
432 $DidValueChange = self::DidValueChange($OldValue, $NewValue);
433 $NewSettings[$Name] = $NewValue;
434 break;
435
436 case self::FTYPE_SEARCHPARAMS:
437 $SPEditor = new SearchParameterSetEditingUI($FieldName);
438 $NewValue = $SPEditor->GetValuesFromFormData();
439 $DidValueChange = self::DidValueChange($OldValue, $NewValue);
440 $NewSettings[$Name] = $NewValue;
441 break;
442
443 case self::FTYPE_FILE:
444 $NewSettings[$Name] = GetArrayValue(
445 $_POST, $FieldName."_ID", array());
446 foreach ($NewSettings[$Name] as $Index => $FileId)
447 {
448 if ($FileId == self::NO_VALUE_FOR_FIELD ||
449 in_array($FileId, $this->DeletedFiles))
450 {
451 unset($NewSettings[$Name][$Index]);
452 }
453 }
454
455 # if we have any files in ExtraValues after a HandleUploads,
456 # include those too
457 $ExtraSettings = GetArrayValue(
458 $this->ExtraValues, $FieldName."_ID", []);
459 foreach ($ExtraSettings as $FileId)
460 {
461 if (!in_array($FileId, $NewSettings[$Name]) &&
462 !in_array($FileId, $this->DeletedFiles))
463 {
464 $NewSettings[$Name][]= $FileId;
465 }
466 }
467
468 break;
469
470 case self::FTYPE_IMAGE:
471 $NewSettings[$Name] = GetArrayValue(
472 $_POST, $FieldName."_ID", array());
473
474 foreach ($NewSettings[$Name] as $Index => $ImageId)
475 {
476 if ($ImageId == self::NO_VALUE_FOR_FIELD ||
477 in_array($ImageId, $this->DeletedImages) )
478 {
479 unset($NewSettings[$Name][$Index]);
480 }
481 elseif (isset($_POST[$FieldName."_AltText_".$ImageId]))
482 {
483 $Image = new SPTImage($ImageId);
484 $Image->AltText($_POST[$FieldName."_AltText_".$ImageId]);
485 }
486 }
487
488 # if we have any images in ExtraValues after a HandleUploads,
489 # include those too
490 $ExtraSettings = GetArrayValue(
491 $this->ExtraValues, $FieldName."_ID", []);
492 foreach ($ExtraSettings as $ImageId)
493 {
494 if (!in_array($ImageId, $NewSettings[$Name]) &&
495 !in_array($ImageId, $this->DeletedImages))
496 {
497 $NewSettings[$Name][]= $ImageId;
498 $AltTextKey = $FieldName."_AltText_".$ImageId;
499 if (isset($this->ExtraValues[$AltTextKey]))
500 {
501 $Image = new SPTImage($ImageId);
502 $Image->AltText(
503 $this->ExtraValues[$AltTextKey]);
504 }
505 }
506 }
507
508 break;
509
510 case self::FTYPE_USER:
511 if (isset($_POST[$FieldName]))
512 {
513 # filter blank entries out of input
514 # (these come up when a user was deleted from the list)
515 $NewValue = array_filter(
516 $_POST[$FieldName],
517 function($v) {
518 return strlen($v) > 0 ? TRUE : FALSE;
519 });
520
521 $DidValueChange = self::DidValueChange($OldValue, $NewValue);
522
523 $NewSettings[$Name] = $NewValue;
524 }
525 break;
526
527 default:
528 if (isset($_POST[$FieldName]))
529 {
530 $NewValue = $_POST[$FieldName];
531
532 # flag that the values changed if they did
533 $DidValueChange = self::DidValueChange($OldValue, $NewValue);
534
535 $NewSettings[$Name] = $NewValue;
536 }
537 break;
538 }
539
540 # if value changed and there is an event to signal for changes
541 if ($DidValueChange && $this->SettingChangeEventName)
542 {
543 # set info about changed value in event parameters if appropriate
544 $EventParams = $this->SettingChangeEventParams;
545 foreach ($EventParams as $ParamName => $ParamValue)
546 {
547 switch ($ParamName)
548 {
549 case "SettingName":
550 $EventParams[$ParamName] = $Name;
551 break;
552
553 case "OldValue":
554 $EventParams[$ParamName] = $OldValue;
555 break;
556
557 case "NewValue":
558 $EventParams[$ParamName] = $NewValue;
559 break;
560 }
561 }
562
563 # signal event
564 $GLOBALS["AF"]->SignalEvent(
565 $this->SettingChangeEventName, $EventParams);
566 }
567 }
568
569 # return updated setting values to caller
570 return $NewSettings;
571 }
572
578 public function GetFieldValue($FieldName)
579 {
580 # get base form field name
581 $FieldType = $this->FieldParams[$FieldName]["Type"];
582 $FormFieldName = $this->GetFormFieldName($FieldName,
583 ($FieldType != self::FTYPE_PRIVILEGES));
584
585 # get fallback value for field (in case no value from form)
586 if (isset($this->FieldValues[$FieldName]))
587 {
588 $Value = $this->FieldValues[$FieldName];
589 }
590 elseif (isset($this->FieldParams[$FieldName]["Value"]))
591 {
592 $Value = self::LoadValue($FieldType,
593 $this->FieldParams[$FieldName]["Value"]);
594 }
595 elseif (isset($this->FieldParams[$FieldName]["Default"]))
596 {
597 $Value = self::LoadValue($FieldType,
598 $this->FieldParams[$FieldName]["Default"]);
599 }
600 else
601 {
602 $Value = self::LoadValue($FieldType, NULL);
603 }
604
605 switch ($FieldType)
606 {
607 case self::FTYPE_FILE:
608 case self::FTYPE_IMAGE:
609 # get name of image ID form field
610 $FileIdFieldName = $FormFieldName."_ID";
611
612 # use an updated value for this field if available
613 if (isset($this->HiddenFields[$FileIdFieldName]))
614 {
615 $Value = $this->HiddenFields[$FileIdFieldName];
616 }
617 # else use a value from form if available
618 elseif (isset($_POST[$FileIdFieldName]))
619 {
620 $Value = $_POST[$FileIdFieldName];
621 }
622
623 # add in any previously-set extra values
624 if (isset($this->ExtraValues[$FileIdFieldName])
625 && count($this->ExtraValues[$FileIdFieldName]))
626 {
627 if (!is_array($Value))
628 {
629 $Value = array($Value);
630 }
631 $Value = array_merge($Value,
632 $this->ExtraValues[$FileIdFieldName]);
633 }
634 break;
635
636 case self::FTYPE_SEARCHPARAMS:
637 # use incoming form value if available
638 if (isset($_POST[$FormFieldName]))
639 {
640 # use incoming form value
641 $SPEditor = new SearchParameterSetEditingUI($FormFieldName);
642 $Value = $SPEditor->GetValuesFromFormData();
643 }
644 break;
645
646 case self::FTYPE_PRIVILEGES:
647 # use incoming form value if available
648 $Schemas = GetArrayValue(
649 $this->FieldParams[$FieldName], "Schemas");
650 $MFields = GetArrayValue(
651 $this->FieldParams[$FieldName], "MetadataFields", array());
652 $PEditor = new PrivilegeEditingUI($Schemas, $MFields);
653 $PSet = $PEditor->GetPrivilegeSetFromForm($FormFieldName);
654 if ($PSet instanceof PrivilegeSet)
655 {
656 # use incoming form value
657 $Value = $PSet;
658 }
659 break;
660
661 case self::FTYPE_QUICKSEARCH:
662 $MField = new MetadataField(
663 $this->FieldParams[$FieldName]["Field"]);
664
665 # use incoming values if available
666 if (isset($_POST[$FormFieldName]))
667 {
668 $Value = $this->ConvertItemIdsToNames(
669 $MField, $_POST[$FormFieldName]);
670 }
671 break;
672
673 default:
674 # use incoming form value if available
675 if (isset($_POST[$FormFieldName]))
676 {
677 # use incoming form value
678 $Value = $_POST[$FormFieldName];
679 }
680 break;
681 }
682
683 # return value found to caller
684 return $Value;
685 }
686
690 public function HandleUploads()
691 {
692 # for each form field
693 foreach ($this->FieldParams as $FieldName => $FieldParams)
694 {
695 # move on to next field if this field does not allow uploads
696 if (($FieldParams["Type"] != self::FTYPE_FILE)
697 && ($FieldParams["Type"] != self::FTYPE_IMAGE))
698 {
699 continue;
700 }
701
702 # move on to next field if this field does not have an uploaded file
703 $FormFieldName = $this->GetFormFieldName($FieldName);
704 if (!isset($_FILES[$FormFieldName]["name"]))
705 {
706 continue;
707 }
708 $UploadedFileName = $_FILES[$FormFieldName]["name"];
709 if (!strlen($UploadedFileName))
710 {
711 continue;
712 }
713
714 # create temp copy of file with correct name
715 $TmpFile = "tmp/".$UploadedFileName;
716 $CopyResult = copy($_FILES[$FormFieldName]["tmp_name"], $TmpFile);
717
718 switch ($FieldParams["Type"])
719 {
720 case self::FTYPE_FILE:
721 # create new file object from uploaded file
722 $File = File::Create($TmpFile, $UploadedFileName);
723
724 # check for errors during file object creation
725 if (!is_object($File))
726 {
727 switch ($File)
728 {
729 case File::FILESTAT_ZEROLENGTH:
730 $this->LogError("Uploaded file "
731 .$UploadedFileName." was empty"
732 ." (zero length).", $FieldName);
733 break;
734
735 default:
736 $this->LogError("Error encountered with"
737 ." uploaded file "
738 .$UploadedFileName." ("
739 .$File.").", $FieldName);
740 break;
741 }
742 unlink($TmpFile);
743 }
744 else
745 {
746 # add file ID to extra values
747 $this->ExtraValues[$FormFieldName."_ID"][] = $File->Id();
748 }
749 break;
750
751 case self::FTYPE_IMAGE:
752 # create new image object from uploaded file
753 $Image = new SPTImage($TmpFile,
754 $FieldParams["MaxWidth"],
755 $FieldParams["MaxHeight"],
756 $FieldParams["MaxPreviewWidth"],
757 $FieldParams["MaxPreviewHeight"],
758 $FieldParams["MaxThumbnailWidth"],
759 $FieldParams["MaxThumbnailHeight"]);
760
761 # check for errors during image object creation
762 if ($Image->Status() != AI_OKAY)
763 {
764 switch ($Image->Status())
765 {
766 case AI_UNKNOWNTYPE:
767 $this->LogError("Unknown format for image file "
768 .$UploadedFileName.".", $FieldName);
769 break;
770
771 case AI_UNSUPPORTEDFORMAT:
772 $this->LogError("Unsupported format for image file "
773 .$UploadedFileName." ("
774 .$Image->Format().").", $FieldName);
775 break;
776
777 default:
778 $this->LogError("Error encountered when"
779 ." processing uploaded image file "
780 .$UploadedFileName.".", $FieldName);
781 break;
782 }
783 unlink($TmpFile);
784 }
785 else
786 {
787 # set image object alternate text
788 $Image->AltText($_POST[$FormFieldName."_AltText_NEW"]);
789
790 # add image ID to extra values
791 $this->ExtraValues[$FormFieldName."_ID"][] = $Image->Id();
792 }
793 break;
794 }
795 }
796 }
797
801 public function HandleDeletes()
802 {
803 # if image ID to delete was supplied
804 $DeleteFieldName = $this->GetFormFieldName("ImageToDelete");
805 $IncomingValue = GetFormValue($DeleteFieldName);
806 if (is_numeric($IncomingValue)
807 || (is_array($IncomingValue) && count($IncomingValue)))
808 {
809 # retrieve ID of image
810 $ImageId = is_array($IncomingValue)
811 ? array_shift($IncomingValue)
812 : $IncomingValue;
813
814 # add ID to deleted images list
815 if (is_numeric($ImageId))
816 {
817 $this->DeletedImages[] = $ImageId;
818 }
819 }
820
821 # if file ID to delete was supplied
822 $DeleteFieldName = $this->GetFormFieldName("FileToDelete");
823 $IncomingValue = GetFormValue($DeleteFieldName);
824 if (is_numeric($IncomingValue)
825 || (is_array($IncomingValue) && count($IncomingValue)))
826 {
827 # retrieve ID of file
828 $FileId = is_array($IncomingValue)
829 ? array_shift($IncomingValue)
830 : $IncomingValue;
831
832 # add ID to deleted files list
833 if (is_numeric($FileId))
834 {
835 $this->DeletedFiles[] = $FileId;
836 }
837 }
838 }
839
851 public function SetEventToSignalOnChange($EventName, $EventParams = array())
852 {
853 $this->SettingChangeEventName = $EventName;
854 $this->SettingChangeEventParams = $EventParams;
855 }
856
863 public static function DidValueChange($OldValue, $NewValue)
864 {
865 # didn't change if they are identical
866 if ($OldValue === $NewValue)
867 {
868 return FALSE;
869 }
870
871 # need special cases from this point because PHP returns some odd results
872 # when performing loose equality comparisons:
873 # http://php.net/manual/en/types.comparisons.php#types.comparisions-loose
874
875 # consider NULL and an empty string to be the same. this is in case a field
876 # is currently set to NULL and receives an empty value from the form.
877 # $_POST values are always strings
878 if ((is_null($OldValue) && is_string($NewValue) && !strlen($NewValue))
879 || (is_null($NewValue) && is_string($OldValue) && !strlen($OldValue)))
880 {
881 return FALSE;
882 }
883
884 # if they both appear to be numbers and are equal
885 if (is_numeric($OldValue) && is_numeric($NewValue) && $OldValue == $NewValue)
886 {
887 return FALSE;
888 }
889
890 # true-like values
891 if (($OldValue === TRUE && ($NewValue === 1 || $NewValue === "1"))
892 || ($NewValue === TRUE && ($OldValue === 1 || $OldValue === "1")))
893 {
894 return FALSE;
895 }
896
897 # false-like values
898 if (($OldValue === FALSE && ($NewValue === 0 || $NewValue === "0"))
899 || ($NewValue === FALSE && ($OldValue === 0 || $OldValue === "0")))
900 {
901 return FALSE;
902 }
903
904 # arrays
905 if (is_array($OldValue) && is_array($NewValue))
906 {
907 # they certainly changed if the counts are different
908 if (count($OldValue) != count($NewValue))
909 {
910 return TRUE;
911 }
912
913 # the algorithm for associative arrays is slightly different from
914 # sequential ones. the values for associative arrays must match the keys
915 if (count(array_filter(array_keys($OldValue), "is_string")))
916 {
917 foreach ($OldValue as $Key => $Value)
918 {
919 # it changed if the keys don't match
920 if (!array_key_exists($Key, $NewValue))
921 {
922 return TRUE;
923 }
924
925 # the arrays changed if a value changed
926 if (self::DidValueChange($Value, $NewValue[$Key]))
927 {
928 return TRUE;
929 }
930 }
931 }
932
933 # sequential values don't have to have the same keys, just the same
934 # values
935 else
936 {
937 # sort them so all the values match up if they're equal
938 sort($OldValue);
939 sort($NewValue);
940
941 foreach ($OldValue as $Key => $Value)
942 {
943 # the arrays changed if a value changed
944 if (self::DidValueChange($Value, $NewValue[$Key]))
945 {
946 return TRUE;
947 }
948 }
949 }
950
951 # the arrays are equal
952 return FALSE;
953 }
954
955 # they changed
956 return TRUE;
957 }
958
965 static public function LoadValue($Type, $Data)
966 {
967 switch ($Type)
968 {
969 case self::FTYPE_FILE:
970 case self::FTYPE_IMAGE:
971 $Value = ($Data === NULL) ? array() : $Data;
972 break;
973
974 case self::FTYPE_PRIVILEGES:
975 $Value = ($Data instanceof PrivilegeSet) ? $Data
976 : new PrivilegeSet($Data);
977 break;
978
979 case self::FTYPE_SEARCHPARAMS:
980 $Value = ($Data instanceof SearchParameterSet) ? $Data
981 : new SearchParameterSet($Data);
982 break;
983
984 default:
985 $Value = $Data;
986 break;
987 }
988
989 return $Value;
990 }
991
1004 public function ValidateEmail($FieldName, $FieldValues)
1005 {
1006 if (!is_array($FieldValues)) { $FieldValues = array($FieldValues); }
1007 foreach ($FieldValues as $Value)
1008 {
1009 if (trim($Value) == "") { continue; }
1010 if (filter_var($Value, FILTER_VALIDATE_EMAIL) === FALSE)
1011 {
1012 return "The value for <i>".$this->FieldParams[$FieldName]["Label"]
1013 ."</i> does not appear to be a valid email address.";
1014 }
1015 }
1016 return NULL;
1017 }
1018
1031 public function ValidateUrl($FieldName, $FieldValues)
1032 {
1033 if (!is_array($FieldValues)) { $FieldValues = array($FieldValues); }
1034 foreach ($FieldValues as $Value)
1035 {
1036 if (trim($Value) == "") { continue; }
1037 if (filter_var($Value, FILTER_VALIDATE_URL) === FALSE)
1038 {
1039 return "The value for <i>".$this->FieldParams[$FieldName]["Label"]
1040 ."</i> does not appear to be a valid URL.";
1041 }
1042 }
1043 return NULL;
1044 }
1045
1059 public function ValidateHostName($FieldName, $FieldValues)
1060 {
1061 if (!is_array($FieldValues)) { $FieldValues = array($FieldValues); }
1062 foreach ($FieldValues as $Value)
1063 {
1064 if (trim($Value) == "") { continue; }
1065 if (gethostbyname($Value) === $Value)
1066 {
1067 return "The value for <i>".$this->FieldParams[$FieldName]["Label"]
1068 ."</i> does not appear to be a valid host name.";
1069 }
1070 }
1071 return NULL;
1072 }
1073
1074
1075 # ---- PRIVATE INTERFACE -------------------------------------------------
1076
1077 protected $DeletedFiles = array();
1078 protected $DeletedImages = array();
1079 protected $ExtraValidationParams = array();
1080 protected $ExtraValues = array();
1081 protected $FieldParams;
1082 protected $FieldValues;
1083 protected $HiddenFields = array();
1084 protected $SettingChangeEventName = NULL;
1085 protected $SettingChangeEventParams = array();
1086
1087 protected static $ErrorMessages = array();
1088
1090 const NO_VALUE_FOR_FIELD = "NO VALUE";
1091
1098 abstract protected function DisplayFormField($Name, $Value, $Params);
1099
1107 protected function GetFormFieldName($FieldName, $IncludePrefix = TRUE)
1108 {
1109 return ($IncludePrefix ? "F_" : "")
1110 .($this->UniqueKey ? $this->UniqueKey."_" : "")
1111 .preg_replace("/[^a-zA-Z0-9]/", "", $FieldName);
1112 }
1113
1117 protected function GetHiddenFieldsHtml()
1118 {
1119 $Html = "";
1120 if (count($this->HiddenFields))
1121 {
1122 foreach ($this->HiddenFields as $FieldName => $Value)
1123 {
1124 if (is_array($Value))
1125 {
1126 foreach ($Value as $EachValue)
1127 {
1128 $Html .= '<input type="hidden" name="'.$FieldName
1129 .'[]" value="'.htmlspecialchars($EachValue).'">';
1130 }
1131 }
1132 else
1133 {
1134 $Html .= '<input type="hidden" name="'.$FieldName
1135 .'[]" id="'.$FieldName.'" value="'
1136 .htmlspecialchars($Value).'">';
1137 }
1138 }
1139 }
1140 return $Html;
1141 }
1142
1149 protected function ConvertItemIdsToNames($MField, $ItemIds)
1150 {
1151 # define $ExistsFn to determine if an ItemId exists and
1152 # $NameFn to get its name
1153 switch ($MField->Type())
1154 {
1155 case MetadataSchema::MDFTYPE_TREE:
1156 case MetadataSchema::MDFTYPE_CONTROLLEDNAME:
1157 $Factory = $MField->GetFactory();
1158
1159 $ExistsFn = function($Id) use ($Factory) {
1160 return $Factory->ItemExists($Id);
1161 };
1162
1163 $NameFn = function ($Id) use ($Factory) {
1164 return ($Factory->GetItem($Id)->Name());
1165 };
1166 break;
1167
1168 case MetadataSchema::MDFTYPE_USER:
1169 $Factory = new CWUserFactory();
1170
1171 $ExistsFn = function($Id) use ($Factory) {
1172 return $Factory->UserExists($Id);
1173 };
1174
1175 $NameFn = function ($Id) {
1176 return (new CWUser($Id))->Name();
1177 };
1178 break;
1179
1180 case MetadataSchema::MDFTYPE_REFERENCE:
1181 $ExistsFn = function($Id) {
1182 return Resource::ItemExists($Id);
1183 };
1184
1185 $NameFn = function ($Id) {
1186 return (new Resource($Id))->GetMapped("Title");
1187 };
1188 break;
1189
1190 default:
1191 throw new Exception(
1192 "Invalid field type for ItemId to ItemName conversion.");
1193 }
1194
1195 # iterate over incoming values, extracting names for all the ones that exist
1196 $Value = [];
1197 foreach ($ItemIds as $Id)
1198 {
1199 if ($ExistsFn($Id))
1200 {
1201 $Value[$Id] = $NameFn($Id);
1202 }
1203 }
1204
1205 return $Value;
1206 }
1207 }
FormUI_Base\LogError
static LogError($Msg, $Field=NULL)
Log error message for later display.
Definition: FormUI_Base.php:148
File\FILESTAT_ZEROLENGTH
const FILESTAT_ZEROLENGTH
Definition: File.php:22
FormUI_Base
Base class (covering non-presentation elements) supplying a standard user interface for presenting an...
Definition: FormUI_Base.php:14
FormUI_Base\FTYPE_NUMBER
const FTYPE_NUMBER
Definition: FormUI_Base.php:23
AI_UNKNOWNTYPE
const AI_UNKNOWNTYPE
Definition: Image.php:556
FormUI_Base\GetNewValuesFromForm
GetNewValuesFromForm()
Retrieve values set by form.
Definition: FormUI_Base.php:356
SearchParameterSet
Set of parameters used to perform a search.
Definition: SearchParameterSet.php:13
FormUI_Base\FTYPE_SEARCHPARAMS
const FTYPE_SEARCHPARAMS
Definition: FormUI_Base.php:28
FormUI_Base\FTYPE_OPTION
const FTYPE_OPTION
Definition: FormUI_Base.php:24
MetadataSchema\MDFTYPE_REFERENCE
const MDFTYPE_REFERENCE
Definition: MetadataSchema.php:35
File\Create
static Create($SourceFile, $DesiredFileName=NULL)
Create a new File object using an existing file.
Definition: File.php:34
AI_OKAY
const AI_OKAY
Definition: Image.php:551
FormUI_Base\GetHiddenFieldsHtml
GetHiddenFieldsHtml()
Get HTML for hidden form fields associated with form processing.
Definition: FormUI_Base.php:1117
FormUI_Base\ValidateHostName
ValidateHostName($FieldName, $FieldValues)
Validate value as valid host name (i.e.
Definition: FormUI_Base.php:1059
FormUI_Base\__construct
__construct($FieldParams, $FieldValues=array(), $UniqueKey=NULL)
Class constructor.
Definition: FormUI_Base.php:46
FormUI_Base\SetEventToSignalOnChange
SetEventToSignalOnChange($EventName, $EventParams=array())
Set event to signal when retrieving values from form when settings have changed.
Definition: FormUI_Base.php:851
FormUI_Base\FTYPE_IMAGE
const FTYPE_IMAGE
Definition: FormUI_Base.php:21
FormUI_Base\ConvertItemIdsToNames
ConvertItemIdsToNames($MField, $ItemIds)
Take an array of ItemIds and convert it to [ ItemId => ItemName ].
Definition: FormUI_Base.php:1149
MetadataSchema\GetCanonicalFieldIdentifier
static GetCanonicalFieldIdentifier($Field, $SchemaId=NULL)
Retrieve canonical identifier for field.
Definition: MetadataSchema.php:1581
FormUI_Base\FTYPE_PARAGRAPH
const FTYPE_PARAGRAPH
Definition: FormUI_Base.php:25
FormUI_Base\ValidateFieldInput
ValidateFieldInput()
Validate field values on submitted form.
Definition: FormUI_Base.php:205
FormUI_Base\$FieldParams
$FieldParams
Definition: FormUI_Base.php:1081
FormUI_Base\FTYPE_QUICKSEARCH
const FTYPE_QUICKSEARCH
Definition: FormUI_Base.php:32
FormUI_Base\FTYPE_TEXT
const FTYPE_TEXT
Definition: FormUI_Base.php:29
PrivilegeEditingUI
User interface element for editing PrivilegeSets.
Definition: PrivilegeEditingUI.php:14
PrivilegeSet
Set of privileges used to access resource information or other parts of the system.
Definition: PrivilegeSet.php:16
FormUI_Base\FTYPE_PRIVILEGES
const FTYPE_PRIVILEGES
Definition: FormUI_Base.php:27
FormUI_Base\$ErrorMessages
static $ErrorMessages
Definition: FormUI_Base.php:1087
MetadataSchema\MDFTYPE_TREE
const MDFTYPE_TREE
Definition: MetadataSchema.php:27
FormUI_Base\$FieldValues
$FieldValues
Definition: FormUI_Base.php:1082
MetadataSchema\MDFTYPE_CONTROLLEDNAME
const MDFTYPE_CONTROLLEDNAME
Definition: MetadataSchema.php:28
FormUI_Base\LoadValue
static LoadValue($Type, $Data)
Load value of requested type from supplied data.
Definition: FormUI_Base.php:965
CWUserFactory
CWIS-specific user factory class.
Definition: CWUserFactory.php:13
FormUI_Base\NO_VALUE_FOR_FIELD
const NO_VALUE_FOR_FIELD
Marker used to indicate currently no value for field.
Definition: FormUI_Base.php:1090
FormUI_Base\ValidateEmail
ValidateEmail($FieldName, $FieldValues)
Validate value as valid-appearing email address.
Definition: FormUI_Base.php:1004
FormUI_Base\FTYPE_PASSWORD
const FTYPE_PASSWORD
Definition: FormUI_Base.php:26
FormUI_Base\ClearLoggedErrors
static ClearLoggedErrors($Field=FALSE)
Clear logged errors.
Definition: FormUI_Base.php:186
FormUI_Base\FTYPE_FLAG
const FTYPE_FLAG
Definition: FormUI_Base.php:20
PHP
PHP
Definition: RSSClient--Test.php:12
FormUI_Base\FTYPE_URL
const FTYPE_URL
Definition: FormUI_Base.php:30
FormUI_Base\FTYPE_USER
const FTYPE_USER
Definition: FormUI_Base.php:31
MetadataSchema\FieldExistsInAnySchema
static FieldExistsInAnySchema($Field)
Determine if a Field exists in any schema.
Definition: MetadataSchema.php:1538
SPTImage
Encapsulates a full-size, preview, and thumbnail image.
Definition: SPTImage.php:13
FormUI_Base\$SettingChangeEventParams
$SettingChangeEventParams
Definition: FormUI_Base.php:1085
FormUI_Base\FTYPE_FILE
const FTYPE_FILE
Supported field types.
Definition: FormUI_Base.php:19
FormUI_Base\$HiddenFields
$HiddenFields
Definition: FormUI_Base.php:1083
FormUI_Base\$DeletedImages
$DeletedImages
Definition: FormUI_Base.php:1078
MetadataField
Object representing a locally-defined type of metadata field.
Definition: MetadataField.php:13
FormUI_Base\$DeletedFiles
$DeletedFiles
Definition: FormUI_Base.php:1077
Resource
Represents a "resource" in CWIS.
Definition: Resource.php:13
FormUI_Base\$ExtraValidationParams
$ExtraValidationParams
Definition: FormUI_Base.php:1079
FormUI_Base\ErrorsLogged
static ErrorsLogged($Field=FALSE)
Report whether errors have been logged.
Definition: FormUI_Base.php:170
FormUI_Base\HandleUploads
HandleUploads()
Handle image and file uploads.
Definition: FormUI_Base.php:690
FormUI_Base\GetFormFieldName
GetFormFieldName($FieldName, $IncludePrefix=TRUE)
Get HTML form field name for specified field.
Definition: FormUI_Base.php:1107
FormUI_Base\GetLoggedErrors
static GetLoggedErrors()
Get logged errors.
Definition: FormUI_Base.php:159
MetadataSchema\MDFTYPE_USER
const MDFTYPE_USER
Definition: MetadataSchema.php:30
FormUI_Base\FTYPE_HEADING
const FTYPE_HEADING
Supported field pseudo-types.
Definition: FormUI_Base.php:34
FormUI_Base\ValidateUrl
ValidateUrl($FieldName, $FieldValues)
Validate value as valid-appearing URL.
Definition: FormUI_Base.php:1031
FormUI_Base\GetFieldValue
GetFieldValue($FieldName)
Get value for form field.
Definition: FormUI_Base.php:578
FormUI_Base\$SettingChangeEventName
$SettingChangeEventName
Definition: FormUI_Base.php:1084
FormUI_Base\DidValueChange
static DidValueChange($OldValue, $NewValue)
Determine if a new form field value is different from an old one.
Definition: FormUI_Base.php:863
FormUI_Base\FTYPE_METADATAFIELD
const FTYPE_METADATAFIELD
Definition: FormUI_Base.php:22
FormUI_Base\DisplayFormTable
DisplayFormTable($TableId=NULL, $TableStyle=NULL)
Display HTML table with settings parameters.
FormUI_Base\HandleDeletes
HandleDeletes()
Handle image and file deletions.
Definition: FormUI_Base.php:801
Item\ItemExists
static ItemExists($Id)
Check whether an item exists with the specified ID.
Definition: Item.php:162
CWUser
CWIS-specific user class.
Definition: CWUser.php:13
FormUI_Base\AddValidationParameters
AddValidationParameters()
Add values to be passed to input validation functions, in addition to field name and value...
Definition: FormUI_Base.php:346
FormUI_Base\$ExtraValues
$ExtraValues
Definition: FormUI_Base.php:1080
SearchParameterSetEditingUI
Class to create a user interface for editing SearchParameterSets.
Definition: SearchParameterSetEditingUI.php:13
FormUI_Base\DisplayFormField
DisplayFormField($Name, $Value, $Params)
Display HTML form field for specified field.
AI_UNSUPPORTEDFORMAT
const AI_UNSUPPORTEDFORMAT
Definition: Image.php:557