CWIS Developer Documentation
MetadataField.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # FILE: MetadataField.php
4 #
5 # Part of the Collection Workflow Integration System (CWIS)
6 # Copyright 2012-2013 Edward Almasy and Internet Scout Research Group
7 # http://scout.wisc.edu/cwis/
8 #
9 
14 {
15  # ---- PUBLIC INTERFACE --------------------------------------------------
16 
17  # update methods for timestamp fields
18  const UPDATEMETHOD_NOAUTOUPDATE = "NoAutoUpdate";
19  const UPDATEMETHOD_ONRECORDCREATE = "OnRecordCreate";
20  const UPDATEMETHOD_BUTTON = "Button";
21  const UPDATEMETHOD_ONRECORDEDIT = "OnRecordEdit";
22  const UPDATEMETHOD_ONRECORDCHANGE = "OnRecordChange";
23 
24  # values for the *UserIsValue fields
25  const USERISVALUE_OR = -1;
26  const USERISVALUE_UNSET = 0;
27  const USERISVALUE_AND = 1;
28 
34  public function Status()
35  {
36  return $this->ErrorStatus;
37  }
38 
45  public function Type($NewValue = DB_NOVALUE)
46  {
47  # if new value supplied
48  $FTFieldName = $this->DBFields["FieldType"];
49  if (($NewValue != DB_NOVALUE)
50  && ($NewValue != self::$FieldTypePHPEnums[$FTFieldName]))
51  {
52  # update database fields and store new type
53  $this->ModifyField(NULL, $NewValue);
54  }
55 
56  # return type to caller
57  return self::$FieldTypePHPEnums[$FTFieldName];
58  }
59 
64  public function TypeAsName()
65  {
66  return $this->DBFields["FieldType"];
67  }
68 
74  public function IsControlledVocabularyField()
75  {
76  switch ($this->Type())
77  {
81  return TRUE;
82 
83  default:
84  return FALSE;
85  }
86  }
87 
92  public function SchemaId()
93  {
94  return $this->DBFields["SchemaId"];
95  }
96 
102  public function GetDisplayName()
103  {
104  return strlen($this->Label()) ? $this->Label() : $this->Name();
105  }
106 
113  public function Name($NewName = DB_NOVALUE)
114  {
115  # if new name specified
116  if ($NewName != DB_NOVALUE
117  && trim($NewName) != $this->DBFields["FieldName"])
118  {
119  $NewName = trim($NewName);
120  $NormalizedName = $this->NormalizeFieldNameForDB(strtolower($NewName));
121 
122  # if field name is invalid
123  if (!preg_match("/^[[:alnum:] \(\)]+$/", $NewName))
124  {
125  # set error status to indicate illegal name
126  $this->ErrorStatus = MetadataSchema::MDFSTAT_ILLEGALNAME;
127  }
128 
129  # if the new name is a reserved word
130  else if ($NormalizedName == "resourceid" || $NormalizedName == "schemaid")
131  {
132  # set error status to indicate illegal name
133  $this->ErrorStatus = MetadataSchema::MDFSTAT_ILLEGALNAME;
134  }
135 
136  # the name is okay but might be a duplicate
137  else
138  {
139  # check for duplicate name
140  $DuplicateCount = $this->DB->Query(
141  "SELECT COUNT(*) AS RecordCount FROM MetadataFields"
142  ." WHERE FieldName = '".addslashes($NewName)."'"
143  ." AND SchemaId = ".intval($this->DBFields["SchemaId"]),
144  "RecordCount");
145 
146  # if field name is duplicate
147  if ($DuplicateCount > 0)
148  {
149  # set error status to indicate duplicate name
150  $this->ErrorStatus = MetadataSchema::MDFSTAT_DUPLICATENAME;
151  }
152  else
153  {
154  # modify database declaration to reflect new field name
155  $this->ErrorStatus = MetadataSchema::MDFSTAT_OK;
156  $this->ModifyField($NewName);
157  }
158  }
159  }
160 
161  # return value to caller
162  return $this->DBFields["FieldName"];
163  }
164 
170  public function Label($NewLabel = DB_NOVALUE)
171  {
172  $ValidValueExp = '/^[[:alnum:] ]*$/';
173  $Value = $this->DBFields["Label"];
174 
175  # if a new label was specified
176  if ($NewLabel !== DB_NOVALUE && trim($NewLabel) != $Value)
177  {
178  $NewLabel = trim($NewLabel);
179 
180  # if field label is valid
181  if (preg_match($ValidValueExp, $NewLabel))
182  {
183  $this->UpdateValue("Label", $NewLabel);
184  $Value = $NewLabel;
185  }
186  # the field label is invalid
187  else
188  {
189  $this->ErrorStatus = MetadataSchema::MDFSTAT_ILLEGALLABEL;
190  }
191  }
192 
193  return $Value;
194  }
195 
201  public function GetAllowedConversionTypes()
202  {
203  # determine type list based on our type
204  switch ($this->Type())
205  {
211  $AllowedTypes = array(
213  MetadataSchema::MDFTYPE_PARAGRAPH => "Paragraph",
214  MetadataSchema::MDFTYPE_NUMBER => "Number",
217  );
218  break;
219 
222  $AllowedTypes = array(
223  MetadataSchema::MDFTYPE_CONTROLLEDNAME => "ControlledName",
224  MetadataSchema::MDFTYPE_OPTION => "Option",
225  );
226  break;
227 
229  $AllowedTypes = array(
232  );
233  break;
234 
236  $AllowedTypes = array(
238  MetadataSchema::MDFTYPE_IMAGE => "Still Image",
239  );
240  break;
241 
247  default:
248  $AllowedTypes = array();
249  break;
250  }
251 
252  # return type list to caller
253  return $AllowedTypes;
254  }
255 
263  public function IsTempItem($NewSetting = NULL)
264  {
265  $Schema = new MetadataSchema($this->SchemaId());
266  $ItemTableName = "MetadataFields";
267  $ItemIdFieldName = "FieldId";
268  $ItemFactoryObjectName = "MetadataSchema";
269  $ItemAssociationTables = array(
270  "FieldQualifierInts",
271  );
272  $ItemAssociationFieldName = "MetadataFieldId";
273 
274  # if new temp item setting supplied
275  if (!is_null($NewSetting))
276  {
277  # if caller requested to switch
278  if (($this->Id() < 0 && $NewSetting == FALSE)
279  || ($this->Id() >= 0 && $NewSetting == TRUE))
280  {
281  # if field name is invalid
282  if (strlen($this->NormalizeFieldNameForDB($this->Name())) < 1)
283  {
284  # set error status to indicate illegal name
285  $this->ErrorStatus = MetadataSchema::MDFSTAT_ILLEGALNAME;
286  }
287  else
288  {
289  # lock DB tables to prevent next ID from being grabbed
290  $DB = $this->DB;
291  $DB->Query("
292  LOCK TABLES ".$ItemTableName." WRITE,
293  APSessions WRITE, APSessionData WRITE,
294  MetadataSchemas WRITE");
295 
296  # nuke stale field cache
297  self::$FieldCache = NULL;
298 
299  # get next temp item ID
300  $OldItemId = $this->Id();
301  $Factory = new $ItemFactoryObjectName();
302  if ($NewSetting == TRUE)
303  {
304  $NewId = $Factory->GetNextTempItemId();
305  }
306  else
307  {
308  $NewId = $Factory->GetNextItemId();
309  }
310 
311  # change item ID
312  $DB->Query("UPDATE ".$ItemTableName." SET ".$ItemIdFieldName." = ".
313  $NewId. " WHERE ".$ItemIdFieldName." = ".$OldItemId);
314 
315  # release DB tables
316  $DB->Query("UNLOCK TABLES");
317 
318  # change associations
319  foreach ($ItemAssociationTables as $TableName)
320  {
321  $DB->Query("UPDATE ".$TableName." ".
322  "SET ".$ItemAssociationFieldName." = ".$NewId." ".
323  "WHERE ".$ItemAssociationFieldName." = ".$OldItemId);
324  }
325 
326  # if changing item from temp to non-temp
327  if ($NewSetting == FALSE)
328  {
329  # add any needed database fields and/or entries
330  $this->AddDatabaseFields();
331 
332  # Signal that a new (real) field was added:
333  global $AF;
334  $AF->SignalEvent(
335  "EVENT_FIELD_ADDED",
336  array("FieldId" => $NewId ) );
337 
338  # set field order values for new field
339  $Schema->GetDisplayOrder()->AppendItem($NewId, "MetadataField");
340  $Schema->GetEditOrder()->AppendItem($NewId, "MetadataField");
341  }
342 
343  # update metadata field id
344  $this->DBFields["FieldId"] = $NewId;
345  $this->Id = $NewId;
346  }
347  }
348 
349  # clear caches in MetadataSchema
351  }
352 
353  # report to caller whether we are a temp item
354  return ($this->Id() < 0) ? TRUE : FALSE;
355  }
356 
362  public function AuthoringPrivileges($NewValue = NULL)
363  {
364  # if new privileges supplied
365  if ($NewValue !== NULL)
366  {
367  # store new privileges in database
368  $this->UpdateValue("AuthoringPrivileges", $NewValue->Data());
369  $this->AuthoringPrivileges = $NewValue;
370  }
371 
372  # return current value to caller
373  return $this->AuthoringPrivileges;
374  }
375 
381  public function EditingPrivileges($NewValue = NULL)
382  {
383  # if new privileges supplied
384  if ($NewValue !== NULL)
385  {
386  # store new privileges in database
387  $this->UpdateValue("EditingPrivileges", $NewValue->Data());
388  $this->EditingPrivileges = $NewValue;
389  }
390 
391  # return current value to caller
392  return $this->EditingPrivileges;
393  }
394 
400  public function ViewingPrivileges($NewValue = NULL)
401  {
402  # if new privileges supplied
403  if ($NewValue !== NULL)
404  {
405  # store new privileges in database
406  $this->UpdateValue("ViewingPrivileges", $NewValue->Data());
407  $this->ViewingPrivileges = $NewValue;
408  }
409 
410  # return current value to caller
411  return $this->ViewingPrivileges;
412  }
413 
419  public function PreviewingPrivileges($NewValue = NULL)
420  {
421  # if new privileges supplied
422  if ($NewValue !== NULL)
423  {
424  # store new privileges in database
425  $this->UpdateValue("PreviewingPrivileges", $NewValue->Data());
426  $this->PreviewingPrivileges = $NewValue;
427  }
428 
429  # return current value to caller
430  return $this->PreviewingPrivileges;
431  }
432 
437  public function Id()
438  {
439  return $this->Id;
440  }
441 
447  public function DBFieldName()
448  {
449  return $this->DBFields["DBFieldName"];
450  }
451 
457  public function Description($NewValue = DB_NOVALUE)
458  {
459  return $this->UpdateValue("Description", $NewValue);
460  }
461 
467  public function Instructions($NewValue = DB_NOVALUE)
468  {
469  return $this->UpdateValue("Instructions", $NewValue);
470  }
471 
477  public function Owner($NewValue = DB_NOVALUE)
478  {
479  return $this->UpdateValue("Owner", $NewValue);
480  }
481 
488  public function Enabled($NewValue = DB_NOVALUE)
489  {
490  return $this->UpdateBoolValue("Enabled", $NewValue);
491  }
492 
499  public function Optional($NewValue = DB_NOVALUE)
500  {
501  return $this->UpdateBoolValue("Optional", $NewValue);
502  }
503 
510  public function Editable($NewValue = DB_NOVALUE)
511  {
512  return $this->UpdateBoolValue("Editable", $NewValue);
513  }
514 
521  public function AllowMultiple($NewValue = DB_NOVALUE)
522  {
523  return $this->UpdateBoolValue("AllowMultiple", $NewValue);
524  }
525 
532  public function IncludeInKeywordSearch($NewValue = DB_NOVALUE)
533  {
534  return $this->UpdateBoolValue("IncludeInKeywordSearch", $NewValue);
535  }
536 
543  public function IncludeInAdvancedSearch($NewValue = DB_NOVALUE)
544  {
545  return $this->UpdateBoolValue("IncludeInAdvancedSearch", $NewValue);
546  }
547 
554  public function IncludeInFacetedSearch($NewValue = DB_NOVALUE)
555  {
556  return $this->UpdateBoolValue("IncludeInFacetedSearch", $NewValue);
557  }
558 
566  public function SearchGroupLogic($NewValue = DB_NOVALUE)
567  {
568  if ($NewValue !== DB_NOVALUE)
569  {
570  # if a new value was passed, verify that it's a legal value
571  if ($NewValue != SearchEngine::LOGIC_AND &&
572  $NewValue != SearchEngine::LOGIC_OR)
573  {
574  throw new Exception(
575  "Invalid NewValue for SearchGroupLogic(). "
576  ."Must be a SearchEngine::LOGIC_* constant.");
577  }
578  }
579 
580  return $this->UpdateIntValue("SearchGroupLogic", $NewValue);
581  }
582 
589  public function IncludeInSortOptions($NewValue = DB_NOVALUE)
590  {
591  return $this->UpdateBoolValue("IncludeInSortOptions", $NewValue);
592  }
593 
600  public function IncludeInRecommender($NewValue = DB_NOVALUE)
601  {
602  return $this->UpdateBoolValue("IncludeInRecommender", $NewValue);
603  }
604 
610  public function CopyOnResourceDuplication($NewValue = DB_NOVALUE)
611  {
612  return $this->UpdateBoolValue("CopyOnResourceDuplication", $NewValue);
613  }
614 
620  public function TextFieldSize($NewValue = DB_NOVALUE)
621  {
622  return $this->UpdateIntValue("TextFieldSize", $NewValue);
623  }
624 
630  public function MaxLength($NewValue = DB_NOVALUE)
631  {
632  return $this->UpdateIntValue("MaxLength", $NewValue);
633  }
634 
640  public function ParagraphRows($NewValue = DB_NOVALUE)
641  {
642  return $this->UpdateIntValue("ParagraphRows", $NewValue);
643  }
644 
650  public function ParagraphCols($NewValue = DB_NOVALUE)
651  {
652  return $this->UpdateIntValue("ParagraphCols", $NewValue);
653  }
654 
660  public function MinValue($NewValue = DB_NOVALUE)
661  {
662  return $this->UpdateFloatValue("MinValue", $NewValue);
663  }
664 
670  public function MaxValue($NewValue = DB_NOVALUE)
671  {
672  return $this->UpdateFloatValue("MaxValue", $NewValue);
673  }
674 
680  public function FlagOnLabel($NewValue = DB_NOVALUE)
681  {
682  return $this->UpdateValue("FlagOnLabel", $NewValue);
683  }
684 
690  public function FlagOffLabel($NewValue = DB_NOVALUE)
691  {
692  return $this->UpdateValue("FlagOffLabel", $NewValue);
693  }
694 
700  public function DateFormat($NewValue = DB_NOVALUE)
701  {
702  return $this->UpdateValue("DateFormat", $NewValue);
703  }
704 
711  public function SearchWeight($NewValue = DB_NOVALUE)
712  {
713  return $this->UpdateIntValue("SearchWeight", $NewValue);
714  }
715 
722  public function RecommenderWeight($NewValue = DB_NOVALUE)
723  {
724  return $this->UpdateIntValue("RecommenderWeight", $NewValue);
725  }
726 
732  public function MaxHeight($NewValue = DB_NOVALUE)
733  {
734  return $this->UpdateIntValue("MaxHeight", $NewValue);
735  }
736 
742  public function MaxWidth($NewValue = DB_NOVALUE)
743  {
744  return $this->UpdateIntValue("MaxWidth", $NewValue);
745  }
746 
752  public function MaxPreviewHeight($NewValue = DB_NOVALUE)
753  {
754  return $this->UpdateIntValue("MaxPreviewHeight", $NewValue);
755  }
756 
762  public function MaxPreviewWidth($NewValue = DB_NOVALUE)
763  {
764  return $this->UpdateIntValue("MaxPreviewWidth", $NewValue);
765  }
766 
772  public function MaxThumbnailHeight($NewValue = DB_NOVALUE)
773  {
774  return $this->UpdateIntValue("MaxThumbnailHeight", $NewValue);
775  }
776 
782  public function MaxThumbnailWidth($NewValue = DB_NOVALUE)
783  {
784  return $this->UpdateIntValue("MaxThumbnailWidth", $NewValue);
785  }
786 
792  public function DefaultAltText($NewValue = DB_NOVALUE)
793  {
794  return $this->UpdateValue("DefaultAltText", $NewValue);
795  }
796 
802  public function UsesQualifiers($NewValue = DB_NOVALUE)
803  {
804  return $this->UpdateBoolValue("UsesQualifiers", $NewValue);
805  }
806 
812  public function ShowQualifiers($NewValue = DB_NOVALUE)
813  {
814  return $this->UpdateBoolValue("ShowQualifiers", $NewValue);
815  }
816 
822  public function DefaultQualifier($NewValue = DB_NOVALUE)
823  {
824  return $this->UpdateValue("DefaultQualifier", $NewValue);
825  }
826 
832  public function AllowHTML($NewValue = DB_NOVALUE)
833  {
834  return $this->UpdateBoolValue("AllowHTML", $NewValue);
835  }
836 
842  public function UseWysiwygEditor($NewValue = DB_NOVALUE)
843  {
844  return $this->UpdateBoolValue("UseWysiwygEditor", $NewValue);
845  }
846 
852  public function UseForOaiSets($NewValue = DB_NOVALUE)
853  {
854  return $this->UpdateBoolValue("UseForOaiSets", $NewValue);
855  }
856 
863  public function DisplayAsListForAdvancedSearch($NewValue = DB_NOVALUE)
864  {
865  return $this->UpdateBoolValue("DisplayAsListForAdvancedSearch", $NewValue);
866  }
867 
874  public function MaxDepthForAdvancedSearch($NewValue = DB_NOVALUE)
875  {
876  return $this->UpdateIntValue("MaxDepthForAdvancedSearch", $NewValue);
877  }
878 
884  public function OptionListThreshold($NewValue = DB_NOVALUE)
885  {
886  return $this->UpdateIntValue("OptionListThreshold", $NewValue);
887  }
888 
894  public function AjaxThreshold($NewValue = DB_NOVALUE)
895  {
896  return $this->UpdateIntValue("AjaxThreshold", $NewValue);
897  }
898 
905  public function NumAjaxResults($NewValue = DB_NOVALUE)
906  {
907  return $this->UpdateIntValue("NumAjaxResults", $NewValue);
908  }
909 
910 
911 
917  public function RequiredBySPT($NewValue = DB_NOVALUE)
918  {
919  return $this->UpdateBoolValue("RequiredBySPT", $NewValue);
920  }
921 
927  public function PointPrecision($NewValue = DB_NOVALUE)
928  {
929  if ($NewValue !== DB_NOVALUE && $this->Id() >= 0
930  && $this->Type() == MetadataSchema::MDFTYPE_POINT)
931  {
932  $OldValue = $this->UpdateValue("PointPrecision", DB_NOVALUE);
933 
934  if ($NewValue != $OldValue)
935  {
936  $Decimals = $this->UpdateValue("PointDecimalDigits", DB_NOVALUE);
937  $TotalDigits = $NewValue + $Decimals;
938 
939  $this->DB->Query("ALTER TABLE Resources MODIFY COLUMN "
940  ."`".$this->DBFields["DBFieldName"]."X` "
941  ."DECIMAL(".$TotalDigits.",".$Decimals.")");
942  $this->DB->Query("ALTER TABLE Resources MODIFY COLUMN "
943  ."`".$this->DBFields["DBFieldName"]."Y` "
944  ."DECIMAL(".$TotalDigits.",".$Decimals.")");
945  }
946  }
947 
948  return $this->UpdateValue("PointPrecision", $NewValue);
949  }
950 
956  public function PointDecimalDigits($NewValue = DB_NOVALUE)
957  {
958  if ($NewValue !== DB_NOVALUE && $this->Id() >= 0
959  && $this->Type() == MetadataSchema::MDFTYPE_POINT)
960  {
961  $OldValue = $this->UpdateValue("PointDecimalDigits", DB_NOVALUE);
962 
963  if ($NewValue != $OldValue)
964  {
965  $Precision = $this->UpdateValue("PointPrecision", DB_NOVALUE);
966 
967  $TotalDigits = $NewValue + $Precision;
968 
969  $this->DB->Query("ALTER TABLE Resources MODIFY COLUMN "
970  ."`".$this->DBFields["DBFieldName"]."X` "
971  ."DECIMAL(".$TotalDigits.",".$NewValue.")");
972  $this->DB->Query("ALTER TABLE Resources MODIFY COLUMN "
973  ."`".$this->DBFields["DBFieldName"]."Y` "
974  ."DECIMAL(".$TotalDigits.",".$NewValue.")");
975  }
976  }
977 
978  return $this->UpdateValue("PointDecimalDigits", $NewValue);
979  }
980 
986  public function DefaultValue($NewValue = DB_NOVALUE)
987  {
988  if ($this->Type() == MetadataSchema::MDFTYPE_POINT)
989  {
990  # valid value given
991  if ($NewValue !== DB_NOVALUE &&
992  isset($NewValue["X"]) && isset($NewValue["Y"]))
993  {
994  $NewValue = $NewValue["X"].",".$NewValue["Y"];
995  }
996 
997  # invalid value given
998  else
999  {
1000  $NewValue = DB_NOVALUE;
1001  }
1002 
1003  $Value = $this->UpdateValue("DefaultValue", $NewValue);
1004 
1005  if (is_array($Value))
1006  {
1007  $tmp = explode(",", $Value);
1008 
1009  if (count($tmp)==2)
1010  {
1011  return array("X" => $tmp[0], "Y" => $tmp[1]);
1012  }
1013  }
1014 
1015  return array("X" => NULL, "Y" => NULL);
1016  }
1017 
1018  else if ($this->Type() == MetadataSchema::MDFTYPE_OPTION)
1019  {
1020  # multiple default values to set
1021  if (is_array($NewValue))
1022  {
1023  # empty array
1024  if (count($NewValue) == 0)
1025  {
1026  $NewValue = NULL;
1027  }
1028 
1029  # multiple defaults are allowed
1030  else if ($this->AllowMultiple())
1031  {
1032  $NewValue = serialize($NewValue);
1033  }
1034 
1035  # only one default is allowed so get the first one
1036  else
1037  {
1038  $NewValue = array_shift($NewValue);
1039  }
1040  }
1041 
1042  $Result = $this->UpdateValue("DefaultValue", $NewValue);
1043 
1044  return empty($Result) || is_numeric($Result) ?
1045  $Result : unserialize($Result);
1046  }
1047 
1048  return $this->UpdateValue("DefaultValue", $NewValue);
1049  }
1050 
1056  public function UpdateMethod($NewValue = DB_NOVALUE)
1057  {
1058  return $this->UpdateValue("UpdateMethod", $NewValue);
1059  }
1060 
1068  public function GetPossibleValues($MaxNumberOfValues = NULL, $Offset=0)
1069  {
1070  # retrieve values based on field type
1071  switch ($this->Type())
1072  {
1074  $QueryString = "SELECT ClassificationId, ClassificationName"
1075  ." FROM Classifications WHERE FieldId = ".$this->Id()
1076  ." ORDER BY ClassificationName";
1077  if ($MaxNumberOfValues)
1078  {
1079  $QueryString .= " LIMIT ".intval($MaxNumberOfValues)." OFFSET "
1080  .intval($Offset);
1081  }
1082  $this->DB->Query($QueryString);
1083  $PossibleValues = $this->DB->FetchColumn(
1084  "ClassificationName", "ClassificationId");
1085  break;
1086 
1089  $QueryString = "SELECT ControlledNameId, ControlledName"
1090  ." FROM ControlledNames WHERE FieldId = ".$this->Id()
1091  ." ORDER BY ControlledName";
1092  if ($MaxNumberOfValues)
1093  {
1094  $QueryString .= " LIMIT ".intval($MaxNumberOfValues)." OFFSET "
1095  .intval($Offset);
1096  }
1097  $this->DB->Query($QueryString);
1098  $PossibleValues = $this->DB->FetchColumn(
1099  "ControlledName", "ControlledNameId");
1100  break;
1101 
1103  $PossibleValues[0] = $this->FlagOffLabel();
1104  $PossibleValues[1] = $this->FlagOnLabel();
1105  break;
1106 
1108  $UserFactory = new CWUserFactory();
1109  $Restrictions = $this->UserPrivilegeRestrictions();
1110  $PossibleValues = array();
1111 
1112  if (count($Restrictions))
1113  {
1114  $PossibleValues = call_user_func_array(
1115  array($UserFactory, "GetUsersWithPrivileges"),
1116  $Restrictions);
1117  }
1118 
1119  else
1120  {
1121  $Users = $UserFactory->GetMatchingUsers(".*.");
1122 
1123  foreach ($Users as $Id => $Data)
1124  {
1125  $PossibleValues[$Id] = $Data["UserName"];
1126  }
1127  }
1128 
1129  break;
1130 
1131  default:
1132  # for everything else return an empty array
1133  $PossibleValues = array();
1134  break;
1135  }
1136 
1137  # return array of possible values to caller
1138  return $PossibleValues;
1139  }
1140 
1146  public function GetCountOfPossibleValues()
1147  {
1148  # retrieve values based on field type
1149  switch ($this->Type())
1150  {
1152  $Count = $this->DB->Query("SELECT count(*) AS ValueCount"
1153  ." FROM Classifications WHERE FieldId = ".$this->Id(),
1154  "ValueCount");
1155  break;
1156 
1159  $Count = $this->DB->Query("SELECT count(*) AS ValueCount"
1160  ." FROM ControlledNames WHERE FieldId = ".$this->Id(),
1161  "ValueCount");
1162  break;
1163 
1165  $Count = 2;
1166  break;
1167 
1169  $Count = count($this->GetPossibleValues());
1170  break;
1171 
1172  default:
1173  # for everything else return an empty array
1174  $Count = 0;
1175  break;
1176  }
1177 
1178  # return count of possible values to caller
1179  return $Count;
1180  }
1181 
1188  public function LoadVocabulary($Vocab)
1189  {
1190  $ValidTypes = array(
1194  );
1195 
1196  if (!in_array($this->Type(), $ValidTypes))
1197  {
1198  throw new Exception(
1199  "Attempt to add a vocabulary to a type of field that does not "
1200  ."support vocabularies.");
1201  }
1202 
1203  if ($this->Id() < 0)
1204  {
1205  throw new Exception(
1206  "Attempt to load a vocabulary into a temporary field");
1207  }
1208 
1209  if (!$Vocab instanceof Vocabulary)
1210  {
1211  $Vocab = new Vocabulary($Vocab);
1212  }
1213 
1214  $Terms = $Vocab->TermList();
1215 
1216  # if new vocabulary has a qualifier
1217  if ($Vocab->HasQualifier())
1218  {
1219  # if we already have a qualifier with the same name
1220  $QualFact = new QualifierFactory();
1221  if ($QualFact->NameIsInUse($Vocab->QualifierName()))
1222  {
1223  # if details for existing and new qualifier do not match
1224  $Qualifier = $QualFact->GetItemByName(
1225  $Vocab->QualifierName());
1226  if ($Vocab->QualifierNamespace() != $Qualifier->NSpace()
1227  || ($Vocab->QualifierUrl() != $Qualifier->Url()))
1228  {
1229  # error out
1230  throw new Exception(
1231  "The vocabulary <i>".$Vocab->Name()
1232  ."</i> specifies a qualifier <i>"
1233  .$Vocab->QualifierName()."</i> that conflicts"
1234  ." with an existing qualifier (has the same name but"
1235  ." a different namespace or URL or both).");
1236 
1237  }
1238 
1239  # add new vocabulary with qualifier
1240  $AddedItemCount = $this->AddTerms($Terms, $Qualifier);
1241  $this->AddQualifier($Qualifier);
1242  }
1243  else
1244  {
1245  # add new vocabulary with qualifier
1246  $Qualifier = Qualifier::Create();
1247  $Qualifier->Name($Vocab->QualifierName());
1248  $Qualifier->NSpace($Vocab->QualifierNamespace());
1249  $Qualifier->Url($Vocab->QualifierUrl());
1250  $AddedItemCount = $this->AddTerms($Terms, $Qualifier);
1251  $this->AddQualifier($Qualifier);
1252  }
1253  }
1254  else
1255  {
1256  # add new vocabulary
1257  $AddedItemCount = $this->AddTerms($Terms);
1258  }
1259 
1260  return $AddedItemCount;
1261  }
1262 
1268  public function GetIdForValue($Value)
1269  {
1270  # retrieve ID based on field type
1271  switch ($this->Type())
1272  {
1274  $Id = $this->DB->Query("SELECT ClassificationId FROM Classifications"
1275  ." WHERE ClassificationName = '".addslashes($Value)."'"
1276  ." AND FieldId = ".$this->Id(),
1277  "ClassificationId");
1278  break;
1279 
1282  $Id = $this->DB->Query("SELECT ControlledNameId FROM ControlledNames"
1283  ." WHERE ControlledName = '".addslashes($Value)."'"
1284  ." AND FieldId = ".$this->Id(),
1285  "ControlledNameId");
1286  break;
1287 
1288  default:
1289  # for everything else return NULL
1290  $Id = NULL;
1291  break;
1292  }
1293 
1294  # return ID for value to caller
1295  return $Id;
1296  }
1297 
1303  public function GetValueForId($Id)
1304  {
1305  # retrieve ID based on field type
1306  switch ($this->Type())
1307  {
1309  $Value = $this->DB->Query("SELECT ClassificationName FROM Classifications"
1310  ." WHERE ClassificationId = '".intval($Id)."'"
1311  ." AND FieldId = ".$this->Id(),
1312  "ClassificationName");
1313  break;
1314 
1317  $Value = $this->DB->Query("SELECT ControlledName FROM ControlledNames"
1318  ." WHERE ControlledNameId = '".intval($Id)."'"
1319  ." AND FieldId = ".$this->Id(),
1320  "ControlledName");
1321  break;
1322 
1323  default:
1324  # for everything else return NULL
1325  $Value = NULL;
1326  break;
1327  }
1328 
1329  # return ID for value to caller
1330  return $Value;
1331  }
1332 
1343  public function ValueUseCount($Value)
1344  {
1345  # retrieve ID if object passed in
1346  if (is_object($Value) && method_exists($Value, "Id"))
1347  {
1348  $Value = $Value->Id();
1349  }
1350 
1351  # check value based on field type
1352  $DBFieldName = $this->DBFields["DBFieldName"];
1353  switch ($this->Type())
1354  {
1364  $UseCount = $this->DB->Query("SELECT COUNT(*) AS UseCount"
1365  ." FROM Resources"
1366  ." WHERE `".$DBFieldName."` = '".addslashes($Value)."'"
1367  ." AND SchemaId = ".intval($this->DBFields["SchemaId"]),
1368  "UseCount");
1369  break;
1370 
1372  $UseCount = $this->DB->Query("SELECT COUNT(*) AS UseCount"
1373  ." FROM ResourceClassInts"
1374  ." WHERE ClassificationId = ".intval($Value),
1375  "UseCount");
1376  break;
1377 
1380  $UseCount = $this->DB->Query("SELECT COUNT(*) AS UseCount"
1381  ." FROM ResourceNameInts"
1382  ." WHERE ControlledNameId = ".intval($Value),
1383  "UseCount");
1384  break;
1385 
1387  $UseCount = $this->DB->Query("SELECT COUNT(*) AS UseCount"
1388  ." FROM Resources"
1389  ." WHERE `".$DBFieldName."X` = '".$Value["X"]."'"
1390  ." AND `".$DBFieldName."Y` = '".$Value["Y"]."'"
1391  ." AND SchemaId = ".intval($this->DBFields["SchemaId"]),
1392  "UseCount");
1393  break;
1394 
1395  default:
1396  throw new Exception(__CLASS__."::".__METHOD__."() called for"
1397  ." unsupported field type (".$this->Type().").");
1398  break;
1399  }
1400 
1401  # report use count to caller
1402  return $UseCount;
1403  }
1404 
1411  public function HasItemLevelQualifiers($NewValue = DB_NOVALUE)
1412  {
1413  # if value provided different from present value
1414  if (($NewValue != DB_NOVALUE)
1415  && ($NewValue != $this->DBFields["HasItemLevelQualifiers"]))
1416  {
1417  # check if qualifier column currently exists
1418  $QualColName = $this->DBFieldName()."Qualifier";
1419  $QualColExists = $this->DB->FieldExists("Resources", $QualColName);
1420 
1421  # if new value indicates qualifiers should now be used
1422  if ($NewValue == TRUE)
1423  {
1424  # if qualifier column does not exist in DB for this field
1425  if ($QualColExists == FALSE)
1426  {
1427  # add qualifier column in DB for this field
1428  $this->DB->Query("ALTER TABLE Resources ADD COLUMN `"
1429  .$QualColName."` INT");
1430  }
1431  }
1432  else
1433  {
1434  # if qualifier column exists in DB for this field
1435  if ($QualColExists == TRUE)
1436  {
1437  # remove qualifier column from DB for this field
1438  $this->DB->Query("ALTER TABLE Resources DROP COLUMN `"
1439  .$QualColName."`");
1440  }
1441  }
1442  }
1443 
1444  return $this->UpdateValue("HasItemLevelQualifiers", $NewValue);
1445  }
1446 
1451  public function AssociatedQualifierList()
1452  {
1453  # start with empty list
1454  $List = array();
1455 
1456  # for each associated qualifier
1457  $this->DB->Query("SELECT QualifierId FROM FieldQualifierInts"
1458  ." WHERE MetadataFieldId = ".$this->DBFields["FieldId"]);
1459  while ($Record = $this->DB->FetchRow())
1460  {
1461  # load qualifier object
1462  $Qual = new Qualifier($Record["QualifierId"]);
1463 
1464  # add qualifier ID and name to list
1465  $List[$Qual->Id()] = $Qual->Name();
1466  }
1467 
1468  # return list to caller
1469  return $List;
1470  }
1471 
1476  public function UnassociatedQualifierList()
1477  {
1478  # grab list of associated qualifiers
1479  $AssociatedQualifiers = $this->AssociatedQualifierList();
1480 
1481  # get list of all qualifiers
1482  $QFactory = new QualifierFactory();
1483  $AllQualifiers = $QFactory->GetItemNames();
1484 
1485  # return list of unassociated qualifiers
1486  return array_diff($AllQualifiers, $AssociatedQualifiers);
1487  }
1488 
1494  public function AddQualifier($Qualifier)
1495  {
1496  # if qualifier object passed in
1497  if (is_object($Qualifier))
1498  {
1499  # grab qualifier ID from object
1500  $Qualifier = $Qualifier->Id();
1501  }
1502  # else if string passed in does not look like ID
1503  elseif (!is_numeric($Qualifier))
1504  {
1505  # assume string passed in is name and use it to retrieve ID
1506  $QFact = new QualifierFactory();
1507  $Qualifier = $QFact->GetItemIdByName($Qualifier);
1508  if ($Qualifier === FALSE)
1509  {
1510  throw new InvalidArgumentException("Unknown qualifier name (\""
1511  .$Qualifier."\").");
1512  }
1513  }
1514 
1515  # if not already associated
1516  $RecordCount = $this->DB->Query(
1517  "SELECT COUNT(*) AS RecordCount FROM FieldQualifierInts"
1518  ." WHERE QualifierId = ".$Qualifier
1519  ." AND MetadataFieldId = ".$this->Id(), "RecordCount");
1520  if ($RecordCount < 1)
1521  {
1522  # associate field with qualifier
1523  $this->DB->Query("INSERT INTO FieldQualifierInts SET"
1524  ." QualifierId = ".$Qualifier.","
1525  ." MetadataFieldId = ".$this->Id());
1526  }
1527  }
1528 
1529 
1530 
1535  public function UnassociateWithQualifier($QualifierIdOrObject)
1536  {
1537  # if qualifier object passed in
1538  if (is_object($QualifierIdOrObject))
1539  {
1540  # grab qualifier ID from object
1541  $QualifierIdOrObject = $QualifierIdOrObject->Id();
1542  }
1543 
1544  # delete intersection record from database
1545  $this->DB->Query("DELETE FROM FieldQualifierInts WHERE QualifierId = "
1546  .$QualifierIdOrObject." AND MetadataFieldId = ".
1547  $this->Id());
1548  }
1549 
1554  public function GetFactory()
1555  {
1556  switch ($this->Type())
1557  {
1559  $Factory = new ClassificationFactory($this->Id());
1560  break;
1561 
1564  $Factory = new ControlledNameFactory($this->Id());
1565  break;
1566 
1567  default:
1568  $Factory = NULL;
1569  break;
1570  }
1571 
1572  return $Factory;
1573  }
1574 
1583  public function UserCanView($User, $AllowHooksToModify=TRUE)
1584  {
1585  $CacheKey = "View".$User->Id() ."-".
1586  ($AllowHooksToModify ? "1" : "0");
1587 
1588  # see if we have a cached permission for this field and user
1589  if (!isset($this->PermissionCache[$CacheKey]))
1590  {
1591  if (!$this->Enabled())
1592  {
1593  # the field should not be viewed if it is disabled
1594  $this->PermissionCache[$CacheKey] = FALSE;
1595  }
1596  else
1597  {
1598 
1599  $Schema = new MetadataSchema($this->SchemaId());
1600 
1601  # otherwise, evaluate the perms
1602  $CheckResult =
1603  $Schema->ViewingPrivileges()->MeetsRequirements($User) &&
1604  $this->ViewingPrivileges()->MeetsRequirements($User);
1605 
1606  # and optionally
1607  if ($AllowHooksToModify)
1608  {
1609  $SignalResult = $GLOBALS["AF"]->SignalEvent(
1610  "EVENT_FIELD_VIEW_PERMISSION_CHECK", array(
1611  "Field" => $this,
1612  "Resource" => NULL,
1613  "User" => $User,
1614  "CanView" => $CheckResult));
1615  $CheckResult = $SignalResult["CanView"];
1616  }
1617 
1618  $this->PermissionCache[$CacheKey] = $CheckResult;
1619  }
1620  }
1621 
1622  return $this->PermissionCache[$CacheKey];
1623  }
1624 
1631  public function ReferenceableSchemaIds($Ids = DB_NOVALUE)
1632  {
1633  # if a new value was provided, convert it to a string
1634  if ($Ids != DB_NOVALUE)
1635  {
1636  if (is_array($Ids))
1637  {
1638  $Ids = implode(",", $Ids);
1639  }
1640  }
1641 
1642  # update/retrieve the value
1643  $Value = $this->UpdateValue(
1644  "ReferenceableSchemaIds", $Ids);
1645 
1646  # and convert stored string to an array
1647  return explode(",", $Value);
1648  }
1649 
1650  # ---- PRIVATE INTERFACE -------------------------------------------------
1651 
1652  private $DB;
1653  private $Id;
1654  private $DBFields;
1655  private $ErrorStatus;
1656  private $AuthoringPrivileges;
1657  private $EditingPrivileges;
1658  private $ViewingPrivileges;
1659  private $PreviewingPrivileges;
1660  private $PermissionCache;
1661 
1666  public static $FieldTypeHumanEnums = array(
1667  MetadataSchema::MDFTYPE_TEXT => "Text",
1668  MetadataSchema::MDFTYPE_PARAGRAPH => "Paragraph",
1669  MetadataSchema::MDFTYPE_NUMBER => "Number",
1670  MetadataSchema::MDFTYPE_DATE => "Date",
1671  MetadataSchema::MDFTYPE_TIMESTAMP => "Timestamp",
1672  MetadataSchema::MDFTYPE_FLAG => "Flag",
1673  MetadataSchema::MDFTYPE_TREE => "Tree",
1674  MetadataSchema::MDFTYPE_CONTROLLEDNAME => "Controlled Name",
1675  MetadataSchema::MDFTYPE_OPTION => "Option",
1676  MetadataSchema::MDFTYPE_USER => "User",
1677  MetadataSchema::MDFTYPE_IMAGE => "Image",
1678  MetadataSchema::MDFTYPE_FILE => "File",
1679  MetadataSchema::MDFTYPE_URL => "URL",
1680  MetadataSchema::MDFTYPE_POINT => "Point",
1681  MetadataSchema::MDFTYPE_REFERENCE => "Reference");
1682 
1683  # field type DB/PHP enum translations
1684  public static $FieldTypeDBEnums = array(
1685  MetadataSchema::MDFTYPE_TEXT => "Text",
1686  MetadataSchema::MDFTYPE_PARAGRAPH => "Paragraph",
1687  MetadataSchema::MDFTYPE_NUMBER => "Number",
1688  MetadataSchema::MDFTYPE_DATE => "Date",
1689  MetadataSchema::MDFTYPE_TIMESTAMP => "TimeStamp",
1690  MetadataSchema::MDFTYPE_FLAG => "Flag",
1691  MetadataSchema::MDFTYPE_TREE => "Tree",
1692  MetadataSchema::MDFTYPE_CONTROLLEDNAME => "ControlledName",
1693  MetadataSchema::MDFTYPE_OPTION => "Option",
1694  MetadataSchema::MDFTYPE_USER => "User",
1695  MetadataSchema::MDFTYPE_IMAGE => "Still Image",
1696  MetadataSchema::MDFTYPE_FILE => "File",
1697  MetadataSchema::MDFTYPE_URL => "Url",
1698  MetadataSchema::MDFTYPE_POINT => "Point",
1699  MetadataSchema::MDFTYPE_REFERENCE => "Reference"
1700  );
1701  public static $FieldTypeDBAllowedEnums = array(
1702  MetadataSchema::MDFTYPE_TEXT => "Text",
1703  MetadataSchema::MDFTYPE_PARAGRAPH => "Paragraph",
1704  MetadataSchema::MDFTYPE_NUMBER => "Number",
1705  MetadataSchema::MDFTYPE_DATE => "Date",
1706  MetadataSchema::MDFTYPE_TIMESTAMP => "TimeStamp",
1707  MetadataSchema::MDFTYPE_FLAG => "Flag",
1708  MetadataSchema::MDFTYPE_TREE => "Tree",
1709  MetadataSchema::MDFTYPE_CONTROLLEDNAME => "ControlledName",
1710  MetadataSchema::MDFTYPE_OPTION => "Option",
1711  MetadataSchema::MDFTYPE_USER => "User",
1712  MetadataSchema::MDFTYPE_IMAGE => "Still Image",
1713  MetadataSchema::MDFTYPE_FILE => "File",
1714  MetadataSchema::MDFTYPE_URL => "Url",
1715  MetadataSchema::MDFTYPE_POINT => "Point",
1716  MetadataSchema::MDFTYPE_REFERENCE => "Reference"
1717  );
1718  public static $FieldTypePHPEnums = array(
1719  "Text" => MetadataSchema::MDFTYPE_TEXT,
1720  "Paragraph" => MetadataSchema::MDFTYPE_PARAGRAPH,
1721  "Number" => MetadataSchema::MDFTYPE_NUMBER,
1722  "Date" => MetadataSchema::MDFTYPE_DATE,
1723  "TimeStamp" => MetadataSchema::MDFTYPE_TIMESTAMP,
1724  "Flag" => MetadataSchema::MDFTYPE_FLAG,
1725  "Tree" => MetadataSchema::MDFTYPE_TREE,
1726  "ControlledName" => MetadataSchema::MDFTYPE_CONTROLLEDNAME,
1727  "Option" => MetadataSchema::MDFTYPE_OPTION,
1728  "User" => MetadataSchema::MDFTYPE_USER,
1729  "Still Image" => MetadataSchema::MDFTYPE_IMAGE,
1730  "File" => MetadataSchema::MDFTYPE_FILE,
1731  "Url" => MetadataSchema::MDFTYPE_URL,
1732  "Point" => MetadataSchema::MDFTYPE_POINT,
1733  "Reference" => MetadataSchema::MDFTYPE_REFERENCE
1734  );
1735 
1736  public static $UpdateTypes = array(
1737  self::UPDATEMETHOD_NOAUTOUPDATE => "Do not update automatically",
1738  self::UPDATEMETHOD_ONRECORDCREATE => "Update on record creation",
1739  self::UPDATEMETHOD_BUTTON => "Provide an update button",
1740  self::UPDATEMETHOD_ONRECORDEDIT => "Update when record is edited",
1741  self::UPDATEMETHOD_ONRECORDCHANGE => "Update when record is changed"
1742  );
1743 
1757  public static function Create($SchemaId, $FieldType, $FieldName,
1758  $Optional = NULL, $DefaultValue = NULL)
1759  {
1760  # error out if field type is bad
1761  if (empty(self::$FieldTypeDBEnums[$FieldType]))
1762  {
1763  throw new InvalidArgumentException("Bad field type (".$FieldType.").");
1764  }
1765 
1766  # error out if field name is duplicate
1767  $DB = new Database();
1768  $FieldName = trim($FieldName);
1769  $DuplicateCount = $DB->Query(
1770  "SELECT COUNT(*) AS RecordCount FROM MetadataFields"
1771  ." WHERE FieldName = '".addslashes($FieldName)."'"
1772  ." AND SchemaId = ".intval($SchemaId),
1773  "RecordCount");
1774  if ($DuplicateCount > 0)
1775  {
1776  throw new InvalidArgumentException("Duplicate field name (".$FieldName.").");
1777  }
1778 
1779  # grab current user ID
1780  $UserId = $GLOBALS["G_User"]->Get("UserId");
1781 
1782  # normalize schema ID
1783  $Schema = new MetadataSchema($SchemaId);
1784  $SchemaId = $Schema->Id();
1785 
1786  # use schema privileges as starting privilege values
1787  $AuthorPrivs = $Schema->AuthoringPrivileges();
1788  $EditPrivs = $Schema->EditingPrivileges();
1789  $ViewPrivs = $Schema->ViewingPrivileges();
1790  $PreviewPrivs = $Schema->ViewingPrivileges();
1791 
1792  # lock DB tables and get next temporary field ID
1793  $DB->Query("LOCK TABLES MetadataFields WRITE");
1794  $FieldId = $Schema->GetNextTempItemId();
1795 
1796  # add field to MDF table in database
1797  $DB->Query("INSERT INTO MetadataFields"
1798  ." (FieldId, SchemaId, FieldName, FieldType, LastModifiedById,"
1799  ." Optional, AuthoringPrivileges, EditingPrivileges,"
1800  ." ViewingPrivileges, PreviewingPrivileges)"
1801  ." VALUES ("
1802  .intval($FieldId).", "
1803  .intval($SchemaId).","
1804  ." '".addslashes($FieldName)."',"
1805  ." '".self::$FieldTypeDBEnums[$FieldType]."', "
1806  .intval($UserId).", "
1807  .($Optional ? "1" : "0").","
1808  ."'".$DB->EscapeString($AuthorPrivs->Data())."',"
1809  ."'".$DB->EscapeString($EditPrivs->Data())."',"
1810  ."'".$DB->EscapeString($ViewPrivs->Data())."',"
1811  ."'".$DB->EscapeString($PreviewPrivs->Data())."')");
1812 
1813  # release DB tables
1814  $DB->Query("UNLOCK TABLES");
1815 
1816  # nuke potentially stale cache information
1817  self::$FieldCache = NULL;
1818 
1819  # load field object
1820  $Field = new MetadataField($FieldId);
1821 
1822  # set field defaults
1823  $Field->SetDefaults();
1824 
1825  # set the default value if specified
1826  if ($DefaultValue !== NULL)
1827  {
1828  $Field->DefaultValue($DefaultValue);
1829  }
1830 
1831  # clear caches in MetadataSchema
1833 
1834  # return newly-constructed field to caller
1835  return $Field;
1836  }
1837 
1846  public function Duplicate()
1847  {
1848  # create new field
1849  $NewName = $this->Name()." (duplicate ".date("ymd-His").")";
1850  $NewField = self::Create($this->SchemaId(), $this->Type(), $NewName);
1851 
1852  # copy all attributes to database record for new field
1853  $TableName = "MetadataFields";
1854  $IdColumn = "FieldId";
1855  $SrcId = $this->Id();
1856  $DstId = $NewField->Id();
1857  $ColumnsToExclude = array("FieldName");
1858  $this->DB->CopyValues(
1859  $TableName, $IdColumn, $SrcId, $DstId, $ColumnsToExclude);
1860 
1861  # clear caches in MetadataSchema
1863 
1864  # reload new field and return to caller
1865  return new MetadataField($NewField->Id());
1866  }
1867 
1874  public function __construct($FieldId)
1875  {
1876  # assume everything will be okay
1877  $this->ErrorStatus = MetadataSchema::MDFSTAT_OK;
1878 
1879  # check if we have cached field info
1880  $this->DB = new Database();
1881  if (self::$FieldCache === NULL)
1882  {
1883  # if not, retrieve field info from database
1884  $this->DB->Query("SELECT * FROM MetadataFields");
1885  while ($Row = $this->DB->FetchRow())
1886  {
1887  self::$FieldCache[$Row["FieldId"]] = $Row;
1888  }
1889  }
1890 
1891  # error if requested field did not exist
1892  if (!array_key_exists($FieldId, self::$FieldCache) )
1893  {
1894  throw new InvalidArgumentException("Invalid metadata field ID ("
1895  .$FieldId.") from "
1896  .StdLib::GetMyCaller().".");
1897  }
1898  $Row = self::$FieldCache[$FieldId];
1899  $this->DBFields = $Row;
1900  $this->Id = $FieldId;
1901 
1902  # if privileges have not yet been initialized
1903  if (!strlen($this->DBFields["AuthoringPrivileges"]))
1904  {
1905  # set default values for privileges from metadata schema
1906  $Schema = new MetadataSchema($Row["SchemaId"]);
1907  $this->AuthoringPrivileges($Schema->AuthoringPrivileges());
1908  $this->EditingPrivileges($Schema->EditingPrivileges());
1909  $this->ViewingPrivileges($Schema->ViewingPrivileges());
1910  $this->PreviewingPrivileges($Schema->ViewingPrivileges());
1911  }
1912  else
1913  {
1914  # set privileges from stored values
1915  $this->AuthoringPrivileges = new PrivilegeSet(
1916  $Row["AuthoringPrivileges"]);
1917  $this->EditingPrivileges = new PrivilegeSet(
1918  $Row["EditingPrivileges"]);
1919  $this->ViewingPrivileges = new PrivilegeSet(
1920  $Row["ViewingPrivileges"]);
1921  $this->PreviewingPrivileges = new PrivilegeSet(
1922  $Row["PreviewingPrivileges"]);
1923  }
1924 
1925  # set database column name
1926  $this->DBFields["DBFieldName"] =
1927  $this->NormalizeFieldNameForDB($this->DBFields["FieldName"]);
1928  }
1929 
1934  public static $FixedDefaults = array(
1935  "Label" => NULL,
1936  "Description" => NULL,
1937  "Instructions" => NULL,
1938  "Enabled" => TRUE,
1939  "Optional" => TRUE,
1940  "Editable" => TRUE,
1941  "CopyOnResourceDuplication" => TRUE,
1942  "AllowMultiple" => FALSE,
1943  "IncludeInKeywordSearch" => FALSE,
1944  "IncludeInAdvancedSearch" => FALSE,
1945  "IncludeInFacetedSearch" => FALSE,
1946  "SearchGroupLogic" => SearchEngine::LOGIC_OR,
1947  "IncludeInSortOptions" => TRUE,
1948  "IncludeInRecommender" => FALSE,
1949  "ParagraphRows" => 4,
1950  "ParagraphCols" => 50,
1951  "MinValue" => 1,
1952  "FlagOnLabel" => "On",
1953  "FlagOffLabel" => "Off",
1954  "DateFormat" => NULL,
1955  "RecommenderWeight" => 1,
1956  "MaxHeight" => 500,
1957  "MaxWidth" => 500,
1958  "MaxPreviewHeight" => 100,
1959  "MaxPreviewWidth" => 100,
1960  "MaxThumbnailHeight" => 50,
1961  "MaxThumbnailWidth" => 50,
1962  "DefaultAltText" => NULL,
1963  "UsesQualifiers" => FALSE,
1964  "HasItemLevelQualifiers" => FALSE,
1965  "ShowQualifiers" => FALSE,
1966  "DefaultQualifier" => NULL,
1967  "AllowHTML" => FALSE,
1968  "UseWysiwygEditor" => FALSE,
1969  "UseForOaiSets" => FALSE,
1970  "DisplayAsListForAdvancedSearch" => FALSE,
1971  "MaxDepthForAdvancedSearch" => 1,
1972  "OptionListThreshold" => 25,
1973  "AjaxThreshold" => 50,
1974  "NumAjaxResults" => 50,
1975  "PointPrecision" => 8,
1976  "PointDecimalDigits" => 5,
1977  "UserPrivilegeRestrictions" => array(),
1978  "UpdateMethod" => "NoAutoUpdate",
1979  # 9999 is the default max value because default number field length is 4
1980  "MaxValue" => 9999);
1981 
1986  public static $TypeBasedDefaults = array(
1988  "DefaultValue" => NULL,
1989  "SearchWeight" => 1,
1990  "TextFieldSize" => 50,
1991  "MaxLength" => 100),
1993  "DefaultValue" => NULL,
1994  "SearchWeight" => 1,
1995  "TextFieldSize" => 50,
1996  "MaxLength" => 100),
1998  "DefaultValue" => NULL,
1999  "SearchWeight" => 1,
2000  "TextFieldSize" => 4,
2001  "MaxLength" => 100),
2003  "DefaultValue" => NULL,
2004  "SearchWeight" => 1,
2005  "TextFieldSize" => 10,
2006  "MaxLength" => 100),
2008  "DefaultValue" => NULL,
2009  "SearchWeight" => 1,
2010  "TextFieldSize" => 50,
2011  "MaxLength" => 100),
2013  "DefaultValue" => NULL,
2014  "SearchWeight" => 1,
2015  "TextFieldSize" => 50,
2016  "MaxLength" => 100),
2018  "DefaultValue" => NULL,
2019  "SearchWeight" => 1,
2020  "AllowMultiple" => TRUE,
2021  "TextFieldSize" => 50,
2022  "MaxLength" => 100),
2024  "DefaultValue" => NULL,
2025  "SearchWeight" => 3,
2026  "AllowMultiple" => TRUE,
2027  "TextFieldSize" => 50,
2028  "MaxLength" => 100),
2030  "DefaultValue" => NULL,
2031  "SearchWeight" => 3,
2032  "TextFieldSize" => 50,
2033  "MaxLength" => 100),
2035  "DefaultValue" => NULL,
2036  "SearchWeight" => 1,
2037  "TextFieldSize" => 50,
2038  "MaxLength" => 100),
2040  "DefaultValue" => NULL,
2041  "CopyOnResourceDuplication" => FALSE,
2042  "SearchWeight" => 1,
2043  "TextFieldSize" => 50,
2044  "MaxLength" => 100),
2046  "DefaultValue" => NULL,
2047  "CopyOnResourceDuplication" => FALSE,
2048  "AllowMultiple" => TRUE,
2049  "SearchWeight" => 1,
2050  "TextFieldSize" => 50,
2051  "MaxLength" => 100),
2052  MetadataSchema::MDFTYPE_URL => array(
2053  "DefaultValue" => NULL,
2054  "SearchWeight" => 1,
2055  "TextFieldSize" => 50,
2056  "MaxLength" => 255),
2058  "DefaultValue" => array("X" => NULL, "Y" => NULL),
2059  "SearchWeight" => 1,
2060  "TextFieldSize" => 10,
2061  "MaxLength" => 100),
2063  "DefaultValue" => NULL,
2064  "SearchWeight" => 1,
2065  "TextFieldSize" => 50,
2066  "MaxLength" => 100,
2067  "ReferenceableSchemaIds" => array(
2069 
2073  public function SetDefaults()
2074  {
2075  # set defaults that are the same for every field
2076  foreach (self::$FixedDefaults as $Key => $Value)
2077  {
2078  $this->$Key($Value);
2079  }
2080 
2081  # set defaults that depend on the type of the field
2082  foreach (self::$TypeBasedDefaults[$this->Type()] as $Key => $Value)
2083  {
2084  $this->$Key($Value);
2085  }
2086 
2087  # tweak the update method if dealing with the date of record creation
2088  if ($this->Name() == "Date Of Record Creation")
2089  {
2090  $this->UpdateMethod("OnRecordCreate");
2091  }
2092  }
2093 
2094 
2098  public function Drop()
2099  {
2101  "MetadataSchema",
2102  "Attempt to update drop Metadata Field at %FILE%:%LINE%."
2103  ." (Fields may only be dropped by MetadataSchema.)");
2104 
2105  # clear other database entries as appropriate for field type
2106  $DB = $this->DB;
2107  $DBFieldName = $this->DBFields["DBFieldName"];
2108  $Schema = new MetadataSchema($this->SchemaId());
2109  switch (self::$FieldTypePHPEnums[$this->DBFields["FieldType"]])
2110  {
2119  # remove field from resources table
2120  if ($DB->FieldExists("Resources", $DBFieldName))
2121  {
2122  $DB->Query("ALTER TABLE Resources DROP COLUMN `".$DBFieldName."`");
2123  }
2124  break;
2125 
2127  if ($DB->FieldExists("Resources", $DBFieldName."X"))
2128  {
2129  $DB->Query("ALTER TABLE Resources DROP COLUMN `".$DBFieldName."X`");
2130  $DB->Query("ALTER TABLE Resources DROP COLUMN `".$DBFieldName."Y`");
2131  }
2132  break;
2133 
2135  # remove fields from resources table
2136  if ($DB->FieldExists("Resources", $DBFieldName."Begin"))
2137  {
2138  $DB->Query("ALTER TABLE Resources "
2139  ."DROP COLUMN `".$DBFieldName."Begin`");
2140  $DB->Query("ALTER TABLE Resources "
2141  ."DROP COLUMN `".$DBFieldName."End`");
2142  $DB->Query("ALTER TABLE Resources "
2143  ."DROP COLUMN `".$DBFieldName."Precision`");
2144  }
2145  break;
2146 
2148  $DB->Query("SELECT ClassificationId FROM Classifications "
2149  ."WHERE FieldId = ".$this->Id());
2150  $TempDB = new Database();
2151  while ($ClassificationId = $DB->FetchField("ClassificationId"))
2152  {
2153  # remove any resource / name intersections
2154  $TempDB->Query("DELETE FROM ResourceClassInts WHERE "
2155  ."ClassificationId = ".$ClassificationId);
2156 
2157  # remove controlled name
2158  $TempDB->Query("DELETE FROM Classifications WHERE "
2159  ."ClassificationId = ".$ClassificationId);
2160  }
2161  break;
2162 
2165  $DB->Query("SELECT ControlledNameId FROM ControlledNames "
2166  ."WHERE FieldId = ".$this->Id());
2167  $TempDB = new Database();
2168  while ($ControlledNameId = $DB->FetchField("ControlledNameId"))
2169  {
2170  # remove any resource / name intersections
2171  $TempDB->Query("DELETE FROM ResourceNameInts WHERE "
2172  ."ControlledNameId = ".$ControlledNameId);
2173 
2174  # remove any variant names
2175  $TempDB->Query("DELETE FROM VariantNames WHERE "
2176  ."ControlledNameId = ".$ControlledNameId);
2177 
2178  # remove controlled name
2179  $TempDB->Query("DELETE FROM ControlledNames WHERE "
2180  ."ControlledNameId = ".$ControlledNameId);
2181  }
2182  break;
2183 
2185  # for each file associated with this field
2186  $DB->Query("SELECT FileId FROM Files WHERE FieldId = '".$this->Id()."'");
2187  while ($FileId = $DB->FetchRow())
2188  {
2189  # delete file
2190  $File = new File(intval($FileId));
2191  $File->Delete();
2192  }
2193  break;
2194 
2196  # remove any resource references for the field
2197  $DB->Query("
2198  DELETE FROM ReferenceInts
2199  WHERE FieldId = '".addslashes($this->Id())."'");
2200  break;
2201  }
2202 
2203  # remove field from database
2204  $DB->Query("DELETE FROM MetadataFields "
2205  ."WHERE FieldId = '".$this->DBFields["FieldId"]."'");
2206 
2207  # remove any qualifier associations
2208  $DB->Query("DELETE FROM FieldQualifierInts WHERE MetadataFieldId = '"
2209  .$this->DBFields["FieldId"]."'");
2210 
2211  # get the order objects the field is part of
2212  foreach (MetadataFieldOrder::GetOrdersForSchema($Schema) as $Order)
2213  {
2214  # remove it if it's a direct descendant
2215  $Order->RemoveItem($this->Id(), "MetadataField");
2216 
2217  # also make sure to remove it if it's part of a group
2218  foreach ($Order->GetItemIds() as $Item)
2219  {
2220  if ($Item["Type"] == "MetadataFieldGroup")
2221  {
2222  $Group = new MetadataFieldGroup($Item["ID"]);
2223  $Group->RemoveItem($this->Id(), "MetadataField");
2224  }
2225  }
2226  }
2227 
2228  # nuke stale field cache
2229  self::$FieldCache = NULL;
2230 
2231  # clear caches in MetadataSchema
2233  }
2234 
2242  private function ModifyField($NewName = NULL, $NewType = NULL)
2243  {
2244  # grab old DB field name
2245  $OldDBFieldName = $this->DBFields["DBFieldName"];
2246  $OldFieldType = NULL;
2247 
2248  # if new field name supplied
2249  if ($NewName != NULL)
2250  {
2251  # cache the old name for options and controllednames below
2252  $OldName = $this->DBFields["FieldName"];
2253 
2254  # store new name
2255  $this->UpdateValue("FieldName", $NewName);
2256 
2257  # determine new DB field name
2258  $NewDBFieldName = $this->NormalizeFieldNameForDB($NewName);
2259 
2260  # store new database field name
2261  $this->DBFields["DBFieldName"] = $NewDBFieldName;
2262 
2263  # clear caches in MetadataSchema
2265  }
2266  else
2267  {
2268  # set new field name equal to old field name
2269  $NewDBFieldName = $OldDBFieldName;
2270  }
2271 
2272  # if new type supplied
2273  if ($NewType != NULL)
2274  {
2275  # grab old field type
2276  $OldFieldType = self::$FieldTypePHPEnums[$this->DBFields["FieldType"]];
2277 
2278  # store new field type
2279  $this->UpdateValue("FieldType", self::$FieldTypeDBEnums[$NewType]);
2280  }
2281 
2282  # if this is not a temporary field
2283  if ($this->Id() >= 0)
2284  {
2285  # modify field in DB as appropriate for field type
2286  $DB = $this->DB;
2287  $FieldType = self::$FieldTypePHPEnums[$this->DBFields["FieldType"]];
2288  switch ($FieldType)
2289  {
2293  # alter field declaration in Resources table
2294  $DB->Query("ALTER TABLE Resources CHANGE COLUMN `"
2295  .$OldDBFieldName."` `"
2296  .$NewDBFieldName."` TEXT DEFAULT NULL");
2297  break;
2298 
2300  # alter field declaration in Resources table
2301  $DB->Query("ALTER TABLE Resources CHANGE COLUMN `"
2302  .$OldDBFieldName."` `"
2303  .$NewDBFieldName."` INT DEFAULT NULL");
2304 
2305  break;
2306 
2308  $Precision = $this->UpdateValue("PointPrecision",
2309  DB_NOVALUE);
2310  $Digits = $this->UpdateValue("PointDecimalDigits",
2311  DB_NOVALUE);
2312  $DB->Query("ALTER TABLE Resources CHANGE COLUMN "
2313  ."`".$OldDBFieldName."X` "
2314  ."`".$NewDBFieldName."X`".
2315  " DECIMAL(".$Precision.",".$Digits.")");
2316  $DB->Query("ALTER TABLE Resources CHANGE COLUMN "
2317  ."`".$OldDBFieldName."Y` "
2318  ."`".$NewDBFieldName."Y`".
2319  " DECIMAL(".$Precision.",".$Digits.")");
2320  break;
2321 
2323  # alter field declaration in Resources table
2324  $DB->Query("ALTER TABLE Resources CHANGE COLUMN `"
2325  .$OldDBFieldName."` `"
2326  .$NewDBFieldName."` INT"
2327  ." DEFAULT ".intval($this->DefaultValue()));
2328 
2329  # set any unset values to default
2330  $DB->Query("UPDATE Resources SET `".$NewDBFieldName
2331  ."` = ".intval($this->DefaultValue())
2332  ." WHERE `".$NewDBFieldName."` IS NULL");
2333  break;
2334 
2336  # if new type supplied and new type is different from old
2337  if (($NewType != NULL) && ($NewType != $OldFieldType))
2338  {
2339  # if old type was time stamp
2340  if ($OldFieldType == MetadataSchema::MDFTYPE_TIMESTAMP)
2341  {
2342  # change time stamp field in resources table to begin date
2343  $DB->Query("ALTER TABLE Resources CHANGE COLUMN `"
2344  .$OldDBFieldName."` `"
2345  .$NewDBFieldName."Begin` DATE "
2346  ."DEFAULT NULL");
2347 
2348  # add end date and precision fields
2349  $DB->Query("ALTER TABLE Resources "
2350  ."ADD COLUMN `".$NewDBFieldName."End` DATE");
2351  $DB->Query("ALTER TABLE Resources "
2352  ."ADD COLUMN `".$NewDBFieldName."Precision`"
2353  ."INT DEFAULT NULL");
2354 
2355 
2356  # set precision to reflect time stamp content
2357  $DB->Query("UPDATE Resources "
2358  ."SET `".$NewDBFieldName."Precision` = "
2359  .(Date::PRE_BEGINYEAR|Date::PRE_BEGINMONTH
2360  |Date::PRE_BEGINDAY));
2361  }
2362  else
2363  {
2364  exit("<br>ERROR: Attempt to convert metadata field "
2365  ."to date from type other than timestamp<br>\n");
2366  }
2367  }
2368  else
2369  {
2370  # change name of fields
2371  $DB->Query("ALTER TABLE Resources CHANGE COLUMN `"
2372  .$OldDBFieldName."Begin` `"
2373  .$NewDBFieldName."Begin` DATE "
2374  ."DEFAULT NULL");
2375  $DB->Query("ALTER TABLE Resources CHANGE COLUMN `"
2376  .$OldDBFieldName."End` `"
2377  .$NewDBFieldName."End` DATE "
2378  ."DEFAULT NULL");
2379  $DB->Query("ALTER TABLE Resources CHANGE COLUMN `"
2380  .$OldDBFieldName."Precision` `"
2381  .$NewDBFieldName."Precision` INT "
2382  ."DEFAULT NULL");
2383  }
2384  break;
2385 
2387  # if new type supplied and new type is different from old
2388  if (($NewType != NULL) && ($NewType != $OldFieldType))
2389  {
2390  # if old type was date
2391  if ($OldFieldType == MetadataSchema::MDFTYPE_DATE)
2392  {
2393  # change begin date field in resource table to time stamp
2394  $DB->Query("ALTER TABLE Resources CHANGE COLUMN `"
2395  .$OldDBFieldName."Begin` `"
2396  .$NewDBFieldName."` DATETIME "
2397  ."DEFAULT NULL");
2398 
2399  # drop end date and precision fields
2400  $DB->Query("ALTER TABLE Resources DROP COLUMN `"
2401  .$OldDBFieldName."End`");
2402  $DB->Query("ALTER TABLE Resources DROP COLUMN `"
2403  .$OldDBFieldName."Precision`");
2404  }
2405  else
2406  {
2407  exit("<br>ERROR: Attempt to convert metadata field to "
2408  ."time stamp from type other than date<br>\n");
2409  }
2410  }
2411  else
2412  {
2413  # change name of field
2414  $DB->Query("ALTER TABLE Resources CHANGE COLUMN `"
2415  .$OldDBFieldName."` `"
2416  .$NewDBFieldName."` DATETIME "
2417  ."DEFAULT NULL");
2418  }
2419  break;
2420 
2427  break;
2428  }
2429 
2430  # if qualifier DB field exists
2431  if ($DB->FieldExists("Resources", $OldDBFieldName."Qualifier"))
2432  {
2433  # rename qualifier DB field
2434  $DB->Query("ALTER TABLE Resources CHANGE COLUMN `"
2435  .$OldDBFieldName."Qualifier` `"
2436  .$NewDBFieldName."Qualifier` INT ");
2437  }
2438  }
2439  }
2440 
2447  private function UpdateValue($FieldName, $NewValue)
2448  {
2449  # nuke stale field cache
2450  if ($NewValue !== DB_NOVALUE)
2451  {
2452  self::$FieldCache = NULL;
2453  }
2454 
2455  return $this->DB->UpdateValue("MetadataFields", $FieldName, $NewValue,
2456  "FieldId = ".intval($this->DBFields["FieldId"]),
2457  $this->DBFields);
2458  }
2459 
2466  private function UpdateIntValue($FieldName, $NewValue)
2467  {
2468  # nuke stale field cache
2469  if ($NewValue !== DB_NOVALUE)
2470  {
2471  self::$FieldCache = NULL;
2472  }
2473 
2474  return $this->DB->UpdateIntValue("MetadataFields", $FieldName, $NewValue,
2475  "FieldId = ".intval($this->DBFields["FieldId"]),
2476  $this->DBFields);
2477  }
2478 
2485  private function UpdateFloatValue($FieldName, $NewValue)
2486  {
2487  # nuke stale field cache
2488  if ($NewValue !== DB_NOVALUE)
2489  {
2490  self::$FieldCache = NULL;
2491  }
2492 
2493  return $this->DB->UpdateFloatValue("MetadataFields", $FieldName, $NewValue,
2494  "FieldId = ".intval($this->DBFields["FieldId"]),
2495  $this->DBFields);
2496  }
2497 
2504  private function UpdateBoolValue($FieldName, $NewValue)
2505  {
2506  # nuke stale field cache
2507  if ($NewValue !== DB_NOVALUE)
2508  {
2509  self::$FieldCache = NULL;
2510  }
2511 
2512  $NewValue = $this->TranslateStringToConstants($NewValue);
2513  return $this->DB->UpdateIntValue("MetadataFields", $FieldName, $NewValue,
2514  "FieldId = ".intval($this->DBFields["FieldId"]),
2515  $this->DBFields);
2516  }
2517 
2525  private function UpdateConstValue($FieldName, $NewValue, $ClassName=NULL)
2526  {
2527  # nuke stale field cache
2528  if ($NewValue !== DB_NOVALUE)
2529  {
2530  self::$FieldCache = NULL;
2531  }
2532 
2533  $NewValue = $this->TranslateStringToConstants($NewValue, $ClassName);
2534  return $this->DB->UpdateIntValue("MetadataFields", $FieldName, $NewValue,
2535  "FieldId = ".intval($this->DBFields["FieldId"]),
2536  $this->DBFields);
2537  }
2538 
2544  private function NormalizeFieldNameForDB($Name)
2545  {
2546  return preg_replace("/[^a-z0-9]/i", "", $Name)
2547  .(($this->SchemaId() != MetadataSchema::SCHEMAID_DEFAULT)
2548  ? $this->SchemaId() : "");
2549  }
2550 
2554  private function AddDatabaseFields()
2555  {
2556  # grab values for common use
2557  $DB = $this->DB;
2558  $DBFieldName = $this->DBFieldName();
2559 
2560  # set up field(s) based on field type
2561  switch ($this->Type())
2562  {
2566  # add field to resources table (if not already present)
2567  if (!$DB->FieldExists("Resources", $DBFieldName))
2568  {
2569  $DB->Query("ALTER TABLE Resources ADD COLUMN `".$DBFieldName
2570  ."` TEXT DEFAULT NULL");
2571  }
2572 
2573  break;
2574 
2576  # add field to resources table (if not already present)
2577  if (!$DB->FieldExists("Resources", $DBFieldName))
2578  {
2579  $DB->Query("ALTER TABLE Resources ADD COLUMN `".$DBFieldName
2580  ."` INT DEFAULT NULL");
2581  }
2582  break;
2583 
2585  if (!$DB->FieldExists("Resources", $DBFieldName."X"))
2586  {
2587  $Precision = $this->UpdateValue("PointPrecision",
2588  DB_NOVALUE);
2589  $Digits = $this->UpdateValue("PointDecimalDigits",
2590  DB_NOVALUE);
2591 
2592  $DB->Query("ALTER TABLE Resources ADD COLUMN `"
2593  .$DBFieldName."X`".
2594  " DECIMAL(".$Precision.",".$Digits.") DEFAULT NULL");
2595  $DB->Query("ALTER TABLE Resources ADD COLUMN `"
2596  .$DBFieldName."Y`".
2597  " DECIMAL(".$Precision.",".$Digits.") DEFAULT NULL");
2598  }
2599 
2600  break;
2602  # if field is not already present in database
2603  if (!$DB->FieldExists("Resources", $DBFieldName))
2604  {
2605  # add field to resources table
2606  $DB->Query("ALTER TABLE Resources ADD COLUMN `".$DBFieldName
2607  ."` INT DEFAULT NULL");
2608  }
2609  break;
2610 
2612  # add fields to resources table (if not already present)
2613  if (!$DB->FieldExists("Resources", $DBFieldName."Begin"))
2614  {
2615  $DB->Query("ALTER TABLE Resources ADD COLUMN `".$DBFieldName."Begin`"
2616  ." DATE DEFAULT NULL");
2617  }
2618  if (!$DB->FieldExists("Resources", $DBFieldName."End"))
2619  {
2620  $DB->Query("ALTER TABLE Resources ADD COLUMN `".$DBFieldName."End`"
2621  ." DATE DEFAULT NULL");
2622  }
2623  if (!$DB->FieldExists("Resources", $DBFieldName."Precision"))
2624  {
2625  $DB->Query("ALTER TABLE Resources "
2626  ."ADD COLUMN `".$DBFieldName."Precision`"
2627  ." INT DEFAULT NULL");
2628  }
2629  break;
2630 
2632  # add fields to resources table (if not already present)
2633  if (!$DB->FieldExists("Resources", $DBFieldName))
2634  {
2635  $DB->Query("ALTER TABLE Resources ADD COLUMN `".$DBFieldName
2636  ."` DATETIME DEFAULT NULL");
2637  }
2638  break;
2639 
2647  break;
2648 
2649  default:
2650  exit("<br>ERROR: Attempt to add database fields "
2651  ."for illegal metadata field type<br>\n");
2652  break;
2653  }
2654  }
2655 
2663  private function AddTerms($TermNames, $Qualifier=NULL)
2664  {
2665  $Factory = $this->GetFactory();
2666 
2667  if ($Factory === NULL)
2668  {
2669  throw new Exception(
2670  "Attempt to add terms to a field that does not "
2671  ."support them.");
2672  }
2673 
2674  # for each supplied term name
2675  $ItemClassName = $Factory->GetItemClassName();
2676  $TermCount = 0;
2677 
2678  foreach ($TermNames as $Name)
2679  {
2680  # if term does not exist with this name
2681  $Name = trim($Name);
2682  if ($Factory->GetItemByName($Name) === NULL)
2683  {
2684  # add term
2685  $NewTerm = ($ItemClassName == "ControlledName") ?
2686  ControlledName::Create($Name, $this->Id()) :
2687  Classification::Create($Name, $this->Id());
2688 
2689  $TermCount++;
2690 
2691  # assign qualifier to term if supplied
2692  if ($Qualifier !== NULL)
2693  {
2694  $NewTerm->Qualifier($Qualifier);
2695  }
2696  }
2697  }
2698 
2699  # return count of terms added to caller
2700  return $TermCount;
2701  }
2702 
2710  private function TranslateStringToConstants($CString, $ClassName = NULL)
2711  {
2712  # if not a string return value unchanged to caller
2713  if (!is_string($CString) || ($CString === DB_NOVALUE))
2714  {
2715  $ReturnValue = $CString;
2716  }
2717  # handle booleans as a special case
2718  elseif (strtoupper(trim($CString)) == "TRUE")
2719  {
2720  $ReturnValue = TRUE;
2721  }
2722  elseif (strtoupper(trim($CString)) == "FALSE")
2723  {
2724  $ReturnValue = FALSE;
2725  }
2726  else
2727  {
2728  # assume no values will be found
2729  $ReturnValue = NULL;
2730 
2731  # split apart any ORed-together values
2732  $Values = explode("|", $CString);
2733 
2734  # for each value found
2735  foreach ($Values as $Value)
2736  {
2737  # trim off any extraneous whitespace
2738  $Value = trim($Value);
2739 
2740  # add class name prefix to constant name if requested
2741  if ($ClassName) { $Value = $ClassName."::".$Value; }
2742 
2743  # if value corresponds to a constant
2744  if (defined($Value))
2745  {
2746  # add constant to return value
2747  $ReturnValue = ($ReturnValue === NULL)
2748  ? constant($Value)
2749  : ($ReturnValue | constant($Value));
2750  }
2751  }
2752 
2753  # if no corresponding constants were found
2754  if ($ReturnValue === NULL)
2755  {
2756  # return original value to caller
2757  $ReturnValue = $CString;
2758  }
2759  }
2760 
2761  # return result to caller
2762  return $ReturnValue;
2763  }
2764 
2768  private static $FieldCache = NULL;
2769 
2770 
2771  # ---- DEPRECATED METHODS ------------------------------------------------
2772  #
2773  # These are maintained only for backward compatibility with older
2774  # code. Newer code should not use them.
2775  #
2776  // @codingStandardsIgnoreStart
2777 
2778  public function Viewable()
2779  {
2780  return $this->UserCanView( $GLOBALS["G_User"] );
2781  }
2782 
2786  public function AssociateWithQualifier($Qualifier)
2787  {
2788  $this->AddQualifier($Qualifier);
2789  }
2790 
2791  public function UserPrivilegeRestrictions($NewValue = DB_NOVALUE)
2792  {
2793  # new value
2794  if ($NewValue != DB_NOVALUE)
2795  {
2796  $NewValue = serialize((array) $NewValue);
2797  }
2798 
2799  $Value = $this->UpdateValue("UserPrivilegeRestrictions", $NewValue);
2800 
2801  # value set
2802  if (strlen($Value))
2803  {
2804  $Value = (array) unserialize($Value);
2805  }
2806 
2807  # no value set, set it to an empty array
2808  else
2809  {
2810  $Value = $this->UserPrivilegeRestrictions(array());
2811  }
2812 
2813  return $Value;
2814  }
2815 
2816  public function AuthoringUserIsValue($NewValue = DB_NOVALUE)
2817  {
2818  return $this->UpdateConstValue(
2819  "AuthoringUserIsValue", $NewValue, "MetadataField");
2820  }
2821 
2822  public function EditingUserIsValue($NewValue = DB_NOVALUE)
2823  {
2824  return $this->UpdateConstValue("EditingUserIsValue", $NewValue, "MetadataField");
2825  }
2826 
2827  public function ViewingUserValue($NewValue = DB_NOVALUE)
2828  {
2829  return $this->UpdateIntValue("ViewingUserValue", $NewValue);
2830  }
2831 
2832  public function AuthoringUserValue($NewValue = DB_NOVALUE)
2833  {
2834  return $this->UpdateIntValue("AuthoringUserValue", $NewValue);
2835  }
2836 
2837  public function EditingUserValue($NewValue = DB_NOVALUE)
2838  {
2839  return $this->UpdateIntValue("EditingUserValue", $NewValue);
2840  }
2841 
2842  public function ViewingUserIsValue($NewValue = DB_NOVALUE)
2843  {
2844  return $this->UpdateConstValue("ViewingUserIsValue", $NewValue, "MetadataField");
2845  }
2846 
2847  public function EnableOnOwnerReturn($NewValue = DB_NOVALUE)
2848  {
2849  return $this->UpdateBoolValue("EnableOnOwnerReturn", $NewValue);
2850  }
2851 
2852  public function ViewingPrivilege($NewValue = DB_NOVALUE)
2853  {
2854  if ($NewValue === DB_NOVALUE)
2855  {
2856  return $this->ViewingPrivileges();
2857  }
2858  else
2859  {
2860  throw new Exception("Deprecated ".__METHOD__."() called -- ".
2861  __METHOD__."s() should be used instead.");
2862  }
2863  }
2864 
2865  public function AuthoringPrivilege($NewValue = DB_NOVALUE)
2866  {
2867  if ($NewValue === DB_NOVALUE)
2868  {
2869  return $this->AuthoringPrivileges();
2870  }
2871  else
2872  {
2873  throw new Exception("Deprecated ".__METHOD__."() called -- ".
2874  __METHOD__."s() should be used instead.");
2875  }
2876  }
2877 
2878  public function EditingPrivilege($NewValue = DB_NOVALUE)
2879  {
2880  if ($NewValue === DB_NOVALUE)
2881  {
2882  return $this->EditingPrivileges();
2883  }
2884  else
2885  {
2886  throw new Exception("Deprecated ".__METHOD__."() called -- ".
2887  __METHOD__."s() should be used instead.");
2888  }
2889  }
2890 
2891  public function ImagePreviewPrivilege($NewValue = DB_NOVALUE)
2892  {
2893  if ($NewValue === DB_NOVALUE)
2894  {
2895  return $this->ViewingPrivileges();
2896  }
2897  else
2898  {
2899  throw new Exception("Deprecated ".__METHOD__."() called -- ".
2900  "ViewingPrivileges() should be used instead.");
2901  }
2902  }
2903 
2904  public function TreeBrowsingPrivilege($NewValue = DB_NOVALUE)
2905  {
2906  if ($NewValue === DB_NOVALUE)
2907  {
2908  return $this->ViewingPrivileges();
2909  }
2910  else
2911  {
2912  throw new Exception("Deprecated ".__METHOD__."() called -- ".
2913  "this should probably be using ViewingPrivileges() instead.");
2914  }
2915  }
2916 
2917 
2918  // @codingStandardsIgnoreEnd
2919 }
const MDFSTAT_ILLEGALLABEL
DefaultQualifier($NewValue=DB_NOVALUE)
Get/set the default qualifier for this field.
static $FieldTypeDBEnums
static $FixedDefaults
The metadata field defaults that are the same for all field types.
static $FieldTypeDBAllowedEnums
SetDefaults()
Set defaults values for the field.
Owner($NewValue=DB_NOVALUE)
Get/set field owner.
MaxPreviewHeight($NewValue=DB_NOVALUE)
Get/set the max height (in pixels) of thumbnail images.
Metadata schema (in effect a Factory class for MetadataField).
static $FieldTypePHPEnums
Status()
Get current error status of object.
IncludeInFacetedSearch($NewValue=DB_NOVALUE)
Get/set whether to include field in faceted search.
const UPDATEMETHOD_ONRECORDCHANGE
GetValueForId($Id)
Get value for specified ID (only meaningful for Trees / Controlled Names / Options) ...
static CheckMyCaller($DesiredCaller, $ExceptionMsg=NULL)
Check the caller of the current function.
Definition: StdLib.php:69
__construct($FieldId)
Object contstructor, used to load an existing metadata field.
Instructions($NewValue=DB_NOVALUE)
Get/set field instructions.
static Create($SchemaId, $FieldType, $FieldName, $Optional=NULL, $DefaultValue=NULL)
Create a new metadata field.
ValueUseCount($Value)
Check how many times a specific value is currently used for this field.
UseForOaiSets($NewValue=DB_NOVALUE)
Get/set if this field should be used to create OAI sets.
AllowHTML($NewValue=DB_NOVALUE)
Get/set if this field should allow HTML.
UnassociatedQualifierList()
Get list of qualifiers not associated with field.
static Create($Term, $FieldId)
Create a new empty ControlledName if it&#39;s not already present.
const USERISVALUE_UNSET
IncludeInRecommender($NewValue=DB_NOVALUE)
Get/set whether to include field in recommender system comparisons.
SQL database abstraction object with smart query caching.
Definition: Database.php:22
static Create($Name, $FieldId, $ParentId=NULL)
Add new classification to the hierarchy.
GetFactory()
Retrieve item factory object for this field.
ShowQualifiers($NewValue=DB_NOVALUE)
Get/set if this field should display qualifiers on EditResource.
FlagOffLabel($NewValue=DB_NOVALUE)
Get/set the label displayed when a flag field is &#39;off&#39;.
PointPrecision($NewValue=DB_NOVALUE)
Get/set the current number of digits after the decimal point.
OptionListThreshold($NewValue=DB_NOVALUE)
Get/set the number of results necessary to active option list menus.
ViewingPrivileges($NewValue=NULL)
Get/set privileges that allowing viewing values for this field.
ViewingUserValue($NewValue=DB_NOVALUE)
const USERISVALUE_OR
const USERISVALUE_AND
AllowMultiple($NewValue=DB_NOVALUE)
Get/set whether to allow multiple values for field.
static $TypeBasedDefaults
The metadata field defaults that vary depending on the field type.
Description($NewValue=DB_NOVALUE)
Get/set field description.
ReferenceableSchemaIds($Ids=DB_NOVALUE)
Get/set the list of SchemaIds that provide allowable values for a reference field.
EditingUserValue($NewValue=DB_NOVALUE)
MaxThumbnailHeight($NewValue=DB_NOVALUE)
Get/set the max height (in pixels) of thumbnail images.
UserCanView($User, $AllowHooksToModify=TRUE)
Determine if a user can view a specified field in the absence of a resource.
SearchWeight($NewValue=DB_NOVALUE)
Get/set the weight this field has for search results (higher weights have a larger impact)...
Set of privileges used to access resource information or other parts of the system.
HasItemLevelQualifiers($NewValue=DB_NOVALUE)
Get/set whether field uses item-level qualifiers.
AssociateWithQualifier($Qualifier)
AuthoringPrivilege($NewValue=DB_NOVALUE)
DefaultAltText($NewValue=DB_NOVALUE)
Get/set the default alt text for this field.
SearchGroupLogic($NewValue=DB_NOVALUE)
Get/set the search group logic, used for both facets and advanced search when more than one value is ...
Class that builds on the foldering functionality to provide groups of metadata fields.
AjaxThreshold($NewValue=DB_NOVALUE)
Get/set the number of results necessary to activate the AJAX dropdown.
Factory class for Qualifier.
const MDFTYPE_CONTROLLEDNAME
CWIS-specific user factory class.
const PRE_BEGINDAY
Definition: Date.php:24
LoadVocabulary($Vocab)
Load new from a Vocabulary or a vocabulary file.
static $FieldTypeHumanEnums
A map of metadata field types to human-readable strings.
MaxPreviewWidth($NewValue=DB_NOVALUE)
Get/set the max width (in pixels) of thumbnail images.
const UPDATEMETHOD_ONRECORDEDIT
UserPrivilegeRestrictions($NewValue=DB_NOVALUE)
AddQualifier($Qualifier)
Associate qualifier with field.
SchemaId()
Get ID of schema for field.
IncludeInSortOptions($NewValue=DB_NOVALUE)
Get/set whether to include field in search result sort options.
DefaultValue($NewValue=DB_NOVALUE)
Get/set default value.
DisplayAsListForAdvancedSearch($NewValue=DB_NOVALUE)
Get/set if this field should be displayed as a list on the advanced search page.
const DB_NOVALUE
Definition: Database.php:1738
PreviewingPrivileges($NewValue=NULL)
Get/set privileges that allowing previewing values for this field.
TypeAsName()
Get type of field as string.
MaxLength($NewValue=DB_NOVALUE)
Get/set maximum length to store in a text field.
IsControlledVocabularyField()
Check whether field is a type that uses controlled vocabularies.
Controlled vocabulary.
Definition: Vocabulary.php:13
MaxValue($NewValue=DB_NOVALUE)
Get/set the maximum allowed value for a number field.
PointDecimalDigits($NewValue=DB_NOVALUE)
Get/set the total number of digits a point field should store.
GetAllowedConversionTypes()
Get metadata field types that this field can be converted to.
Optional($NewValue=DB_NOVALUE)
Get/set whether a value is required for this field.
ViewingPrivilege($NewValue=DB_NOVALUE)
ParagraphRows($NewValue=DB_NOVALUE)
Get/set the number of rows to display for a paragraph field.
EditingPrivilege($NewValue=DB_NOVALUE)
RequiredBySPT($NewValue=DB_NOVALUE)
Get/set &#39;RequiredBySPT&#39;.
AuthoringUserIsValue($NewValue=DB_NOVALUE)
UsesQualifiers($NewValue=DB_NOVALUE)
Get/set if this field uses qualifiers.
MaxThumbnailWidth($NewValue=DB_NOVALUE)
Get/set the max width (in pixels) of thumbnail images.
Enabled($NewValue=DB_NOVALUE)
Get/set whether field is enabled.
Duplicate()
Create duplicate of field.
AssociatedQualifierList()
Get list of qualifiers associated with field.
EditingPrivileges($NewValue=NULL)
Get/set privileges that allowing editing values for this field.
Factory for manipulating ControlledName objects.
const UPDATEMETHOD_NOAUTOUPDATE
Object representing a locally-defined type of metadata field.
NumAjaxResults($NewValue=DB_NOVALUE)
Get/set the maximum number of results to display in an AJAX dropdown.
static Create()
Initialize a new qualifier.
Definition: Qualifier.php:19
Drop()
Remove field from database (only for use by MetadataSchema object).
TextFieldSize($NewValue=DB_NOVALUE)
Get/set the width of text fields.
ViewingUserIsValue($NewValue=DB_NOVALUE)
EnableOnOwnerReturn($NewValue=DB_NOVALUE)
FlagOnLabel($NewValue=DB_NOVALUE)
Get/set the label displayed when a flag field is &#39;on&#39;.
TreeBrowsingPrivilege($NewValue=DB_NOVALUE)
const UPDATEMETHOD_BUTTON
UseWysiwygEditor($NewValue=DB_NOVALUE)
Get/set if this field should enable WYSIWYG editing.
EditingUserIsValue($NewValue=DB_NOVALUE)
const PRE_BEGINMONTH
Definition: Date.php:23
GetPossibleValues($MaxNumberOfValues=NULL, $Offset=0)
get possible values (only meaningful for Trees, Controlled Names, Options, Flags, and Users) ...
const MDFSTAT_ILLEGALNAME
static GetOrdersForSchema(MetadataSchema $Schema)
Get all of the orders associated with a schema.
GetIdForValue($Value)
Get ID for specified value (only meaningful for Trees / Controlled Names / Options) ...
RecommenderWeight($NewValue=DB_NOVALUE)
Get/set the weight this field has for recommendations (higher weights have a larger impact)...
Label($NewLabel=DB_NOVALUE)
Get/set label for field.
Type($NewValue=DB_NOVALUE)
Get/set type of metadata field (enumerated value).
Id()
Get metadata field ID.
DBFieldName()
Get base name of database column used to store metadata field value.
ImagePreviewPrivilege($NewValue=DB_NOVALUE)
DateFormat($NewValue=DB_NOVALUE)
Get/set the date format.
MaxWidth($NewValue=DB_NOVALUE)
Get/set the max width (in pixels) of images.
MaxHeight($NewValue=DB_NOVALUE)
Get/set the max width (in pixels) of images.
const UPDATEMETHOD_ONRECORDCREATE
const MDFSTAT_DUPLICATENAME
Factory for producing and manipulating Classification objects.
ParagraphCols($NewValue=DB_NOVALUE)
Get/set the number of columns to display for a paragraph field.
UnassociateWithQualifier($QualifierIdOrObject)
Delete a qualifier association.
Class representing a stored (usually uploaded) file.
Definition: File.php:13
IncludeInKeywordSearch($NewValue=DB_NOVALUE)
Get/set whether to include field in keyword search.
Editable($NewValue=DB_NOVALUE)
Get/set whether this field is editable.
CopyOnResourceDuplication($NewValue=DB_NOVALUE)
Get/set whether to duplciate this field when a resource is duplicated.
IsTempItem($NewSetting=NULL)
Get/set whether field is temporary instance.
Name($NewName=DB_NOVALUE)
Get/set name of field.
MaxDepthForAdvancedSearch($NewValue=DB_NOVALUE)
Get/set maximum depth of classifications to display in the list view on the AdvancedSearch page...
IncludeInAdvancedSearch($NewValue=DB_NOVALUE)
Get/set whether to include field in advanced search.
GetCountOfPossibleValues()
Get count of possible values (only meaningful for Trees, Controlled Names, Options, and Users)
GetDisplayName()
Get display name for field.
AuthoringPrivileges($NewValue=NULL)
Get/set privileges that allowing authoring values for this field.
MinValue($NewValue=DB_NOVALUE)
Get/set the minimum value allowed for a number field.
AuthoringUserValue($NewValue=DB_NOVALUE)
static ClearStaticCaches()
Clear internal caches.
UpdateMethod($NewValue=DB_NOVALUE)
Get/set method by which field is updated.