3 # FILE: MetadataField.php
5 # Part of the Collection Workflow Integration System (CWIS)
6 # Copyright 2012 Edward Almasy and Internet Scout
7 # http://scout.wisc.edu
12 # ---- PUBLIC INTERFACE --------------------------------------------------
14 # Update methods for timestamp fields
21 # values for the *UserIsValue fields
26 # get current error status of object
27 function Status() {
return $this->ErrorStatus; }
29 # get/set type of field as enumerated value
32 # if new value supplied
35 $this->DBFields[
"FieldType"]]))
37 # update database fields and store new type
38 $this->ModifyField(NULL, $NewValue);
41 # return type to caller
45 # get type of field as type name (string)
48 return $this->DBFields[
"FieldType"];
51 # get displayable name for the field
52 # first tries to get label but uses field name if label isn't set
58 # get/set name of field
59 # once the name is set to a valid value, it cannot be changed
62 # if new name specified
64 && trim($NewName) != $this->DBFields[
"FieldName"])
66 # if field name is invalid
67 $NewName = trim($NewName);
68 if (!preg_match(
"/^[[:alnum:] \(\)]+$/", $NewName))
70 # set error status to indicate illegal name
75 # check for duplicate name
76 $DuplicateCount = $this->DB->Query(
"
77 SELECT COUNT(*) AS RecordCount FROM MetadataFields
78 WHERE FieldName = '".addslashes($NewName).
"'",
81 # if field name is duplicate
82 if ($DuplicateCount > 0)
84 # set error status to indicate duplicate name
89 # modify database declaration to reflect new field name
91 $this->ModifyField($NewName);
96 # return value to caller
97 return $this->DBFields[
"FieldName"];
100 # get/set label of field
103 $ValidValueExp =
'/^[[:alnum:] ]*$/';
104 $Value = $this->DBFields[
"Label"];
106 # if a new label was specified
107 if ($NewLabel !==
DB_NOVALUE && trim($NewLabel) != $Value)
109 $NewLabel = trim($NewLabel);
111 # if field label is valid
112 if (preg_match($ValidValueExp, $NewLabel))
114 $this->UpdateValue(
"Label", $NewLabel);
118 # the field label is invalid
128 # get associative array (enumeration => string) containing field types we can convert to
131 # determine type list based on our type
132 switch ($this->
Type())
139 $AllowedTypes = array(
150 $AllowedTypes = array(
157 $AllowedTypes = array(
164 $AllowedTypes = array(
175 $AllowedTypes = array();
179 # return type list to caller
180 return $AllowedTypes;
183 # get/set whether item is temporary instance
186 $ItemTableName =
"MetadataFields";
187 $ItemIdFieldName =
"FieldId";
188 $ItemFactoryObjectName =
"MetadataSchema";
189 $ItemAssociationTables = array(
190 "FieldQualifierInts",
192 $ItemAssociationFieldName =
"MetadataFieldId";
194 # if new temp item setting supplied
195 if (!is_null($NewSetting))
197 # if caller requested to switch
198 if (($this->
Id() < 0 && $NewSetting == FALSE)
199 || ($this->
Id() >= 0 && $NewSetting == TRUE))
201 # if field name is invalid
202 if (strlen($this->NormalizeFieldNameForDB($this->
Name())) < 1)
204 # set error status to indicate illegal name
209 # lock DB tables to prevent next ID from being grabbed
211 $DB->Query(
"LOCK TABLES ".$ItemTableName.
" WRITE,".
212 "APSessions WRITE, APSessionData WRITE");
214 # get next temp item ID
215 $OldItemId = $this->
Id();
216 $Factory =
new $ItemFactoryObjectName();
217 if ($NewSetting == TRUE)
219 $NewId = $Factory->GetNextTempItemId();
223 $NewId = $Factory->GetNextItemId();
227 $DB->Query(
"UPDATE ".$ItemTableName.
" SET ".$ItemIdFieldName.
" = ".
228 $NewId.
" WHERE ".$ItemIdFieldName.
" = ".$OldItemId);
231 $DB->Query(
"UNLOCK TABLES");
233 # change associations
234 foreach ($ItemAssociationTables as $TableName)
236 $DB->Query(
"UPDATE ".$TableName.
" SET ".$ItemAssociationFieldName.
" = ".
237 $NewId.
" WHERE ".$ItemAssociationFieldName.
" = ".$OldItemId);
240 # if changing item from temp to non-temp
241 if ($NewSetting == FALSE)
243 # add any needed database fields and/or entries
244 $this->AddDatabaseFields();
246 # set field order values for new field
252 $DisplayOrder->AppendItem($NewId,
"MetadataField");
253 $EditOrder->AppendItem($NewId,
"MetadataField");
254 }
catch (Exception $Exception) {}
257 # update metadata field id
258 $this->DBFields[
"FieldId"] = $NewId;
263 # report to caller whether we are a temp item
264 return ($this->
Id() < 0) ? TRUE : FALSE;
267 # get field attributes
268 function Id() {
return $this->DBFields[
"FieldId"]; }
271 # get/set field attributes
273 {
return $this->UpdateValue(
"Description", $NewValue); }
275 {
return $this->UpdateValue(
"Instructions", $NewValue); }
277 {
return $this->UpdateValue(
"Owner", $NewValue); }
279 {
return $this->UpdateBoolValue(
"RequiredBySPT", $NewValue); }
281 {
return $this->UpdateBoolValue(
"Enabled", $NewValue); }
283 {
return $this->UpdateBoolValue(
"Optional", $NewValue); }
285 {
return $this->UpdateBoolValue(
"Editable", $NewValue); }
287 {
return $this->UpdateBoolValue(
"Viewable", $NewValue); }
289 {
return $this->UpdateBoolValue(
"AllowMultiple", $NewValue); }
291 {
return $this->UpdateBoolValue(
"IncludeInKeywordSearch", $NewValue); }
293 {
return $this->UpdateBoolValue(
"IncludeInAdvancedSearch", $NewValue); }
295 {
return $this->UpdateBoolValue(
"IncludeInSortOptions", $NewValue); }
297 {
return $this->UpdateBoolValue(
"IncludeInRecommender", $NewValue); }
299 {
return $this->UpdateIntValue(
"TextFieldSize", $NewValue); }
301 {
return $this->UpdateIntValue(
"MaxLength", $NewValue); }
303 {
return $this->UpdateIntValue(
"ParagraphRows", $NewValue); }
305 {
return $this->UpdateIntValue(
"ParagraphCols", $NewValue); }
307 {
return $this->UpdateFloatValue(
"MinValue", $NewValue); }
309 {
return $this->UpdateFloatValue(
"MaxValue", $NewValue); }
311 {
return $this->UpdateValue(
"FlagOnLabel", $NewValue); }
313 {
return $this->UpdateValue(
"FlagOffLabel", $NewValue); }
315 {
return $this->UpdateValue(
"DateFormat", $NewValue); }
317 {
return $this->UpdateIntValue(
"SearchWeight", $NewValue); }
319 {
return $this->UpdateIntValue(
"RecommenderWeight", $NewValue); }
321 {
return $this->UpdateIntValue(
"MaxHeight", $NewValue); }
323 {
return $this->UpdateIntValue(
"MaxWidth", $NewValue); }
325 {
return $this->UpdateIntValue(
"MaxPreviewHeight", $NewValue); }
327 {
return $this->UpdateIntValue(
"MaxPreviewWidth", $NewValue); }
329 {
return $this->UpdateIntValue(
"MaxThumbnailHeight", $NewValue); }
331 {
return $this->UpdateIntValue(
"MaxThumbnailWidth", $NewValue); }
333 {
return $this->UpdateValue(
"DefaultAltText", $NewValue); }
335 {
return $this->UpdateBoolValue(
"UsesQualifiers", $NewValue); }
337 {
return $this->UpdateBoolValue(
"ShowQualifiers", $NewValue); }
339 {
return $this->UpdateValue(
"DefaultQualifier", $NewValue); }
341 {
return $this->UpdateBoolValue(
"AllowHTML", $NewValue); }
343 {
return $this->UpdateBoolValue(
"UseWysiwygEditor", $NewValue); }
345 {
return $this->UpdateBoolValue(
"UseForOaiSets", $NewValue); }
347 {
return $this->UpdateIntValue(
"NumAjaxResults", $NewValue); }
349 {
return $this->UpdateConstValue(
"ViewingPrivilege", $NewValue); }
351 {
return $this->UpdateConstValue(
"AuthoringPrivilege", $NewValue); }
353 {
return $this->UpdateConstValue(
"EditingPrivilege", $NewValue); }
355 {
return $this->UpdateConstValue(
"ImagePreviewPrivilege", $NewValue); }
357 {
return $this->UpdateConstValue(
"TreeBrowsingPrivilege", $NewValue); }
359 {
return $this->UpdateBoolValue(
"EnableOnOwnerReturn", $NewValue); }
361 {
return $this->UpdateConstValue(
"ViewingUserIsValue", $NewValue,
"MetadataField"); }
363 {
return $this->UpdateConstValue(
"AuthoringUserIsValue", $NewValue,
"MetadataField"); }
365 {
return $this->UpdateConstValue(
"EditingUserIsValue", $NewValue,
"MetadataField"); }
367 {
return $this->UpdateIntValue(
"ViewingUserValue", $NewValue,
"MetadataField"); }
369 {
return $this->UpdateIntValue(
"AuthoringUserValue", $NewValue,
"MetadataField"); }
371 {
return $this->UpdateIntValue(
"EditingUserValue", $NewValue,
"MetadataField"); }
378 $NewValue = serialize((array) $NewValue);
381 $Value = $this->UpdateValue(
"UserPrivilegeRestrictions", $NewValue);
386 $Value = (array) unserialize($Value);
389 # no value set, set it to an empty array
403 $OldValue = $this->UpdateValue(
"PointPrecision",
DB_NOVALUE);
405 if ($NewValue != $OldValue)
407 $Decimals = $this->UpdateValue(
"PointDecimalDigits",
DB_NOVALUE);
408 $TotalDigits = $NewValue + $Decimals;
410 $this->DB->Query(
"ALTER TABLE Resources MODIFY COLUMN "
411 .
"`".$this->DBFields[
"DBFieldName"].
"X` "
412 .
"DECIMAL(".$TotalDigits.
",".$Decimals.
")");
413 $this->DB->Query(
"ALTER TABLE Resources MODIFY COLUMN "
414 .
"`".$this->DBFields[
"DBFieldName"].
"Y` "
415 .
"DECIMAL(".$TotalDigits.
",".$Decimals.
")");
419 return $this->UpdateValue(
"PointPrecision", $NewValue);
427 $OldValue = $this->UpdateValue(
"PointDecimalDigits",
DB_NOVALUE);
429 if ($NewValue != $OldValue)
431 $Precision = $this->UpdateValue(
"PointPrecision",
DB_NOVALUE);
433 $TotalDigits = $NewValue + $Precision;
435 $this->DB->Query(
"ALTER TABLE Resources MODIFY COLUMN "
436 .
"`".$this->DBFields[
"DBFieldName"].
"X` "
437 .
"DECIMAL(".$TotalDigits.
",".$NewValue.
")");
438 $this->DB->Query(
"ALTER TABLE Resources MODIFY COLUMN "
439 .
"`".$this->DBFields[
"DBFieldName"].
"Y` "
440 .
"DECIMAL(".$TotalDigits.
",".$NewValue.
")");
444 return $this->UpdateValue(
"PointDecimalDigits", $NewValue);
453 isset($NewValue[
"X"]) && isset($NewValue[
"Y"]))
455 $NewValue = $NewValue[
"X"].
",".$NewValue[
"Y"];
458 # invalid value given
464 $Value = $this->UpdateValue(
"DefaultValue", $NewValue);
466 if (is_array($Value))
468 $tmp = explode(
",", $Value);
472 return array(
"X" => $tmp[0],
"Y" => $tmp[1]);
476 return array(
"X" => NULL,
"Y" => NULL);
481 # multiple default values to set
482 if (is_array($NewValue))
485 if (count($NewValue) == 0)
490 # multiple defaults are allowed
493 $NewValue = serialize($NewValue);
496 # only one default is allowed so get the first one
499 $NewValue = array_shift($NewValue);
503 $Result = $this->UpdateValue(
"DefaultValue", $NewValue);
505 return empty($Result) || is_numeric($Result) ?
506 $Result : unserialize($Result);
509 return $this->UpdateValue(
"DefaultValue", $NewValue);
519 return $this->UpdateValue(
"UpdateMethod", $NewValue);
522 # get possible values (only meaningful for Trees, Controlled Names, Options,
524 # (index for returned array is IDs for values)
527 # retrieve values based on field type
528 switch ($this->
Type())
531 $QueryString =
"SELECT ClassificationId, ClassificationName"
532 .
" FROM Classifications WHERE FieldId = ".$this->
Id()
533 .
" ORDER BY ClassificationName";
534 if ($MaxNumberOfValues)
536 $QueryString .=
" LIMIT ".intval($MaxNumberOfValues).
" OFFSET "
539 $this->DB->Query($QueryString);
540 $PossibleValues = $this->DB->FetchColumn(
541 "ClassificationName",
"ClassificationId");
546 $QueryString =
"SELECT ControlledNameId, ControlledName"
547 .
" FROM ControlledNames WHERE FieldId = ".$this->
Id()
548 .
" ORDER BY ControlledName";
549 if ($MaxNumberOfValues)
551 $QueryString .=
" LIMIT ".intval($MaxNumberOfValues).
" OFFSET "
554 $this->DB->Query($QueryString);
555 $PossibleValues = $this->DB->FetchColumn(
556 "ControlledName",
"ControlledNameId");
567 $PossibleValues = array();
569 if (count($Restrictions))
571 $PossibleValues = call_user_func_array(
572 array($UserFactory,
"GetUsersWithPrivileges"),
578 $Users = $UserFactory->GetMatchingUsers(
".*.");
580 foreach ($Users as $Id => $Data)
582 $PossibleValues[$Id] = $Data[
"UserName"];
589 # for everything else return an empty array
590 $PossibleValues = array();
594 # return array of possible values to caller
595 return $PossibleValues;
598 # get count of possible values (only meaningful for Trees, Controlled Names,
599 # Options, and Users)
602 # retrieve values based on field type
603 switch ($this->
Type())
606 $Count = $this->DB->Query(
"SELECT count(*) AS ValueCount"
607 .
" FROM Classifications WHERE FieldId = ".$this->
Id(),
613 $Count = $this->DB->Query(
"SELECT count(*) AS ValueCount"
614 .
" FROM ControlledNames WHERE FieldId = ".$this->
Id(),
627 # for everything else return an empty array
632 # return count of possible values to caller
636 # get ID for specified value (only meaningful for Trees / Controlled Names / Options)
637 # (returns NULL if value not found)
640 # retrieve ID based on field type
641 switch ($this->
Type())
644 $Id = $this->DB->Query(
"SELECT ClassificationId FROM Classifications"
645 .
" WHERE ClassificationName = '".addslashes($Value).
"'"
646 .
" AND FieldId = ".$this->
Id(),
652 $Id = $this->DB->Query(
"SELECT ControlledNameId FROM ControlledNames"
653 .
" WHERE ControlledName = '".addslashes($Value).
"'"
654 .
" AND FieldId = ".$this->
Id(),
659 # for everything else return NULL
664 # return ID for value to caller
668 # get value for specified ID (only meaningful for Trees / Controlled Names / Options)
669 # (returns NULL if ID not found)
672 # retrieve ID based on field type
673 switch ($this->
Type())
676 $Value = $this->DB->Query(
"SELECT ClassificationName FROM Classifications"
677 .
" WHERE ClassificationId = '".intval($Id).
"'"
678 .
" AND FieldId = ".$this->
Id(),
679 "ClassificationName");
684 $Value = $this->DB->Query(
"SELECT ControlledName FROM ControlledNames"
685 .
" WHERE ControlledNameId = '".intval($Id).
"'"
686 .
" AND FieldId = ".$this->
Id(),
691 # for everything else return NULL
696 # return ID for value to caller
702 # get/set whether field uses item-level qualifiers
705 # if value provided different from present value
707 && ($NewValue != $this->DBFields[
"HasItemLevelQualifiers"]))
709 # check if qualifier column currently exists
711 $QualColExists = $this->DB->FieldExists(
"Resources", $QualColName);
713 # if new value indicates qualifiers should now be used
714 if ($NewValue == TRUE)
716 # if qualifier column does not exist in DB for this field
717 if ($QualColExists == FALSE)
719 # add qualifier column in DB for this field
720 $this->DB->Query(
"ALTER TABLE Resources ADD COLUMN `"
721 .$QualColName.
"` INT");
726 # if qualifier column exists in DB for this field
727 if ($QualColExists == TRUE)
729 # remove qualifier column from DB for this field
730 $this->DB->Query(
"ALTER TABLE Resources DROP COLUMN `"
736 return $this->UpdateValue(
"HasItemLevelQualifiers", $NewValue);
739 # get list of qualifiers associated with field
742 # start with empty list
745 # for each associated qualifier
746 $this->DB->Query(
"SELECT QualifierId FROM FieldQualifierInts"
747 .
" WHERE MetadataFieldId = ".$this->DBFields[
"FieldId"]);
748 while ($Record = $this->DB->FetchRow())
750 # load qualifier object
751 $Qual =
new Qualifier($Record[
"QualifierId"]);
753 # add qualifier ID and name to list
754 $List[$Qual->Id()] = $Qual->Name();
757 # return list to caller
761 # get list of qualifiers not associated with field
764 # grab list of associated qualifiers
767 # get list of all qualifiers
769 $AllQualifiers = $QFactory->QualifierList();
771 # return list of unassociated qualifiers
772 return array_diff($AllQualifiers, $AssociatedQualifiers);
775 # add qualifier association
778 # if qualifier object passed in
779 if (is_object($QualifierIdOrObject))
781 # grab qualifier ID from object
782 $QualifierIdOrObject = $QualifierIdOrObject->Id();
785 # if not already associated
786 $RecordCount = $this->DB->Query(
787 "SELECT COUNT(*) AS RecordCount FROM FieldQualifierInts"
788 .
" WHERE QualifierId = ".$QualifierIdOrObject
789 .
" AND MetadataFieldId = ".$this->
Id(),
"RecordCount");
790 if ($RecordCount < 1)
792 # associate field with qualifier
793 $this->DB->Query(
"INSERT INTO FieldQualifierInts SET"
794 .
" QualifierId = ".$QualifierIdOrObject.
","
795 .
" MetadataFieldId = ".$this->Id());
799 # delete qualifier association
802 # if qualifier object passed in
803 if (is_object($QualifierIdOrObject))
805 # grab qualifier ID from object
806 $QualifierIdOrObject = $QualifierIdOrObject->Id();
809 # delete intersection record from database
810 $this->DB->Query(
"DELETE FROM FieldQualifierInts WHERE QualifierId = "
811 .$QualifierIdOrObject.
" AND MetadataFieldId = ".
815 # retrieve item factory object for this field
818 switch ($this->
Type())
838 # ---- PRIVATE INTERFACE -------------------------------------------------
842 private $ErrorStatus;
863 # field type DB/PHP enum translations
922 # object constructor (only for use by MetadataSchema object)
924 $Optional = TRUE, $DefaultValue = NULL)
926 # assume everything will be okay
929 # grab our own database handle
933 # if field ID supplied
934 if ($FieldId != NULL)
936 # look up field in database
937 $DB->Query(
"SELECT * FROM MetadataFields WHERE FieldId = ".intval($FieldId));
938 $Record = $DB->FetchRow();
941 # if no field ID supplied or if record not found in database
942 if (($FieldId == NULL) || ($Record == NULL))
944 # error out if valid field type not supplied
951 # if field name supplied
952 $FieldName = trim($FieldName);
953 if (strlen($FieldName) > 0)
955 # error out if field name is duplicate
956 $DuplicateCount = $DB->Query(
"
957 SELECT COUNT(*) AS RecordCount FROM MetadataFields
958 WHERE FieldName = '".addslashes($FieldName).
"'
959 OR Label = '".addslashes($FieldName).
"'",
962 if ($DuplicateCount > 0)
969 # grab current user ID
971 $UserId = $G_User->Get(
"UserId");
973 # lock DB tables and get next temporary field ID
975 $DB->Query(
"LOCK TABLES MetadataFields WRITE");
976 $FieldId = $Schema->GetNextTempItemId();
978 # add field to MDF table in database
980 INSERT INTO MetadataFields
981 (FieldId, FieldName, FieldType, LastModifiedById) VALUES
982 (".intval($FieldId).
",
983 '".addslashes($FieldName).
"',
988 $DB->Query(
"UNLOCK TABLES");
990 # re-read record from database
992 SELECT * FROM MetadataFields
993 WHERE FieldId = ".intval($FieldId));
994 $this->DBFields = $DB->FetchRow();
995 $this->DBFields[
"DBFieldName"] =
996 $this->NormalizeFieldNameForDB($this->DBFields[
"FieldName"]);
1000 $this->
Optional($Optional ? TRUE : FALSE);
1002 # set the default value if specified since NULL is invalid for some
1004 if (!is_null($DefaultValue))
1011 # save values locally
1012 $this->DBFields = $Record;
1013 $this->DBFields[
"DBFieldName"] =
1014 $this->NormalizeFieldNameForDB($Record[
"FieldName"]);
1023 "Description" => NULL,
1024 "Instructions" => NULL,
1029 "AllowMultiple" => FALSE,
1030 "IncludeInKeywordSearch" => FALSE,
1031 "IncludeInAdvancedSearch" => FALSE,
1032 "IncludeInSortOptions" => TRUE,
1033 "IncludeInRecommender" => FALSE,
1034 "ParagraphRows" => 4,
1035 "ParagraphCols" => 50,
1037 "FlagOnLabel" =>
"On",
1038 "FlagOffLabel" =>
"Off",
1039 "DateFormat" => NULL,
1040 "RecommenderWeight" => 1,
1043 "MaxPreviewHeight" => 100,
1044 "MaxPreviewWidth" => 100,
1045 "MaxThumbnailHeight" => 50,
1046 "MaxThumbnailWidth" => 50,
1047 "DefaultAltText" => NULL,
1048 "UsesQualifiers" => FALSE,
1049 "HasItemLevelQualifiers" => FALSE,
1050 "ShowQualifiers" => FALSE,
1051 "DefaultQualifier" => NULL,
1052 "AllowHTML" => FALSE,
1053 "UseWysiwygEditor" => FALSE,
1054 "UseForOaiSets" => FALSE,
1055 "NumAjaxResults" => 50,
1056 "ViewingPrivilege" => NULL,
1057 "AuthoringPrivilege" => PRIV_MYRESOURCEADMIN,
1058 "EditingPrivilege" => PRIV_RESOURCEADMIN,
1059 "ImagePreviewPrivilege" => NULL,
1060 "TreeBrowsingPrivilege" => NULL,
1061 "ViewingUserIsValue" => self::USERISVALUE_UNSET,
1062 "AuthoringUserIsValue" => self::USERISVALUE_UNSET,
1063 "EditingUserIsValue" => self::USERISVALUE_UNSET,
1064 "ViewingUserValue" => NULL,
1065 "AuthoringUserValue" => NULL,
1066 "EditingUserValue" => NULL,
1067 "PointPrecision" => 8,
1068 "PointDecimalDigits" => 5,
1069 "UserPrivilegeRestrictions" => array(),
1070 "UpdateMethod" =>
"NoAutoUpdate",
1071 # 9999 is the
default max value because
default number field length is 4
1072 "MaxValue" => 9999);
1079 "DefaultValue" => NULL,
1080 "SearchWeight" => 1,
1081 "TextFieldSize" => 50,
1082 "MaxLength" => 100),
1084 "DefaultValue" => NULL,
1085 "SearchWeight" => 1,
1086 "TextFieldSize" => 50,
1087 "MaxLength" => 100),
1089 "DefaultValue" => NULL,
1090 "SearchWeight" => 1,
1091 "TextFieldSize" => 4,
1092 "MaxLength" => 100),
1094 "DefaultValue" => NULL,
1095 "SearchWeight" => 1,
1096 "TextFieldSize" => 10,
1097 "MaxLength" => 100),
1099 "DefaultValue" => NULL,
1100 "SearchWeight" => 1,
1101 "TextFieldSize" => 50,
1102 "MaxLength" => 100),
1104 "DefaultValue" => NULL,
1105 "SearchWeight" => 1,
1106 "TextFieldSize" => 50,
1107 "MaxLength" => 100),
1109 "DefaultValue" => NULL,
1110 "SearchWeight" => 1,
1111 "TextFieldSize" => 50,
1112 "MaxLength" => 100),
1114 "DefaultValue" => NULL,
1115 "SearchWeight" => 3,
1116 "TextFieldSize" => 50,
1117 "MaxLength" => 100),
1119 "DefaultValue" => NULL,
1120 "SearchWeight" => 3,
1121 "TextFieldSize" => 50,
1122 "MaxLength" => 100),
1124 "DefaultValue" => NULL,
1125 "SearchWeight" => 1,
1126 "TextFieldSize" => 50,
1127 "MaxLength" => 100),
1129 "DefaultValue" => NULL,
1130 "SearchWeight" => 1,
1131 "TextFieldSize" => 50,
1132 "MaxLength" => 100),
1134 "DefaultValue" => NULL,
1135 "SearchWeight" => 1,
1136 "TextFieldSize" => 50,
1137 "MaxLength" => 100),
1139 "DefaultValue" => NULL,
1140 "SearchWeight" => 1,
1141 "TextFieldSize" => 50,
1142 "MaxLength" => 255),
1144 "DefaultValue" => array(
"X" => NULL,
"Y" => NULL),
1145 "SearchWeight" => 1,
1146 "TextFieldSize" => 10,
1147 "MaxLength" => 100));
1155 # set defaults that are the same for every field
1156 foreach (self::$FixedDefaults as $Key => $Value)
1158 $this->$Key($Value);
1161 # set defaults that depend on the type of the field
1162 foreach (self::$TypeBasedDefaults[$this->
Type()] as $Key => $Value)
1164 $this->$Key($Value);
1167 # tweak the update method if dealing with the date of record creation
1168 if ($this->
Name() ==
"Date Of Record Creation")
1174 # remove field from database (only for use by MetadataSchema object)
1177 # clear other database entries as appropriate for field type
1179 $DBFieldName = $this->DBFields[
"DBFieldName"];
1189 # remove field from resources table
1190 if ($DB->FieldExists(
"Resources", $DBFieldName))
1192 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `".$DBFieldName.
"`");
1197 if ($DB->FieldExists(
"Resources", $DBFieldName.
"X"))
1199 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `".$DBFieldName.
"X`");
1200 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `".$DBFieldName.
"Y`");
1205 # remove field from resources table
1206 if ($DB->FieldExists(
"Resources", $DBFieldName))
1208 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `".$DBFieldName.
"`");
1213 # remove fields from resources table
1214 if ($DB->FieldExists(
"Resources", $DBFieldName.
"Begin"))
1216 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `".$DBFieldName.
"Begin`");
1217 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `".$DBFieldName.
"End`");
1218 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `".$DBFieldName.
"Precision`");
1223 $DB->Query(
"SELECT ClassificationId FROM Classifications "
1224 .
"WHERE FieldId = ".$this->
Id());
1226 while ($ClassificationId = $DB->FetchField(
"ClassificationId"))
1228 # remove any resource / name intersections
1229 $TempDB->Query(
"DELETE FROM ResourceClassInts WHERE "
1230 .
"ClassificationId = ".$ClassificationId);
1232 # remove controlled name
1233 $TempDB->Query(
"DELETE FROM Classifications WHERE "
1234 .
"ClassificationId = ".$ClassificationId);
1240 $DB->Query(
"SELECT ControlledNameId FROM ControlledNames "
1241 .
"WHERE FieldId = ".$this->
Id());
1243 while ($ControlledNameId = $DB->FetchField(
"ControlledNameId"))
1245 # remove any resource / name intersections
1246 $TempDB->Query(
"DELETE FROM ResourceNameInts WHERE "
1247 .
"ControlledNameId = ".$ControlledNameId);
1249 # remove any variant names
1250 $TempDB->Query(
"DELETE FROM VariantNames WHERE "
1251 .
"ControlledNameId = ".$ControlledNameId);
1253 # remove controlled name
1254 $TempDB->Query(
"DELETE FROM ControlledNames WHERE "
1255 .
"ControlledNameId = ".$ControlledNameId);
1260 # for each file associated with this field
1261 $DB->Query(
"SELECT FileId FROM Files WHERE FieldId = '".$this->
Id().
"'");
1262 while ($FileId = $DB->FetchRow())
1265 $File =
new File(intval($FileId));
1271 # remove field from database
1272 $DB->Query(
"DELETE FROM MetadataFields "
1273 .
"WHERE FieldId = '".$this->DBFields[
"FieldId"].
"'");
1275 # remove any qualifier associations
1276 $DB->Query(
"DELETE FROM FieldQualifierInts WHERE MetadataFieldId = '"
1277 .$this->DBFields[
"FieldId"].
"'");
1279 # remove the field from the display and edit order
1285 # remove it from the dispaly and edit oorder
1286 $DisplayOrder->RemoveItem($this->
Id(),
"MetadataField");
1287 $EditOrder->RemoveItem($this->
Id(),
"MetadataField");
1289 # remove field from any metadata field groups in the display order
1290 foreach ($DisplayOrder->GetItemIds() as $Item)
1292 if ($Item[
"Type"] ==
"MetadataFieldGroup")
1295 $Group->RemoveItem($this->
Id(),
"MetadataField");
1299 # remove field from any metadata field groups in the edit order
1300 foreach ($EditOrder->GetItemIds() as $Item)
1302 if ($Item[
"Type"] ==
"MetadataFieldGroup")
1305 $Group->RemoveItem($this->
Id(),
"MetadataField");
1308 }
catch (Exception $Exception) {}
1311 # modify any database fields
1312 private function ModifyField($NewName = NULL, $NewType = NULL)
1314 # grab old DB field name
1315 $OldDBFieldName = $this->DBFields[
"DBFieldName"];
1316 $OldFieldType = NULL;
1318 # if new field name supplied
1319 if ($NewName != NULL)
1321 # cache the old name for options and controllednames below
1322 $OldName = $this->DBFields[
"FieldName"];
1325 $this->UpdateValue(
"FieldName", $NewName);
1327 # determine new DB field name
1328 $NewDBFieldName = $this->NormalizeFieldNameForDB($NewName);
1330 # store new database field name
1331 $this->DBFields[
"DBFieldName"] = $NewDBFieldName;
1335 # set new field name equal to old field name
1336 $NewDBFieldName = $OldDBFieldName;
1339 # if new type supplied
1340 if ($NewType != NULL)
1342 # grab old field type
1345 # store new field type
1349 # if this is not a temporary field
1350 if ($this->
Id() >= 0)
1352 # modify field in DB as appropriate for field type
1360 # alter field declaration in Resources table
1361 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1362 .$OldDBFieldName.
"` `"
1363 .$NewDBFieldName.
"` TEXT "
1364 .($this->DBFields[
"Optional"] ?
"" :
"NOT NULL"));
1369 # alter field declaration in Resources table
1370 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1371 .$OldDBFieldName.
"` `"
1372 .$NewDBFieldName.
"` INT "
1373 .($this->DBFields[
"Optional"] ?
"" :
"NOT NULL"));
1377 $Precision = $this->UpdateValue(
"PointPrecision",
1379 $Digits = $this->UpdateValue(
"PointDecimalDigits",
1381 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN "
1382 .
"`".$OldDBFieldName.
"X` "
1383 .
"`".$NewDBFieldName.
"X`".
1384 " DECIMAL(".$Precision.
",".$Digits.
")");
1385 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN "
1386 .
"`".$OldDBFieldName.
"Y` "
1387 .
"`".$NewDBFieldName.
"Y`".
1388 " DECIMAL(".$Precision.
",".$Digits.
")");
1392 # if DB field name has changed
1393 if ($NewDBFieldName != $OldDBFieldName)
1395 # alter field declaration in Resources table
1396 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1397 .$OldDBFieldName.
"` `"
1398 .$NewDBFieldName.
"` TEXT");
1403 # if DB field name has changed
1404 if ($NewDBFieldName != $OldDBFieldName)
1406 # alter field declaration in Resources table
1407 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1408 .$OldDBFieldName.
"` `"
1409 .$NewDBFieldName.
"` INT");
1414 # alter field declaration in Resources table
1415 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1416 .$OldDBFieldName.
"` `"
1417 .$NewDBFieldName.
"` INT"
1420 # set any unset values to default
1421 $DB->Query(
"UPDATE Resources SET `".$NewDBFieldName
1423 .
" WHERE `".$NewDBFieldName.
"` IS NULL");
1427 # if new type supplied and new type is different from old
1428 if (($NewType != NULL) && ($NewType != $OldFieldType))
1430 # if old type was time stamp
1433 # change time stamp field in resources table to begin date
1434 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1435 .$OldDBFieldName.
"` `"
1436 .$NewDBFieldName.
"Begin` DATE "
1437 .($this->DBFields[
"Optional"] ?
"" :
"NOT NULL"));
1439 # add end date and precision fields
1440 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$NewDBFieldName.
"End"
1442 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$NewDBFieldName.
"Precision`"
1443 .
" INT ".($Optional ?
"" :
"NOT NULL"));
1445 # set precision to reflect time stamp content
1446 $DB->Query(
"UPDATE Resources SET `".$NewDBFieldName.
"Precision` = "
1451 exit(
"<br>ERROR: Attempt to convert metadata field to date from type other than timestamp<br>\n");
1456 # change name of fields
1457 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1458 .$OldDBFieldName.
"Begin` `"
1459 .$NewDBFieldName.
"Begin` DATE "
1460 .($this->DBFields[
"Optional"] ?
"" :
"NOT NULL"));
1461 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1462 .$OldDBFieldName.
"End` `"
1463 .$NewDBFieldName.
"End` DATE "
1464 .($this->DBFields[
"Optional"] ?
"" :
"NOT NULL"));
1465 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1466 .$OldDBFieldName.
"Precision` `"
1467 .$NewDBFieldName.
"Precision` INT "
1468 .($this->DBFields[
"Optional"] ?
"" :
"NOT NULL"));
1473 # if new type supplied and new type is different from old
1474 if (($NewType != NULL) && ($NewType != $OldFieldType))
1476 # if old type was date
1479 # change begin date field in resource table to time stamp
1480 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1481 .$OldDBFieldName.
"Begin` `"
1482 .$NewDBFieldName.
"` DATETIME "
1483 .($this->DBFields[
"Optional"] ?
"" :
"NOT NULL"));
1485 # drop end date and precision fields
1486 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `"
1487 .$OldDBFieldName.
"End`");
1488 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `"
1489 .$OldDBFieldName.
"Precision`");
1493 exit(
"<br>ERROR: Attempt to convert metadata field to time stamp from type other than date<br>\n");
1498 # change name of field
1499 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1500 .$OldDBFieldName.
"` `"
1501 .$NewDBFieldName.
"` DATETIME "
1502 .($this->DBFields[
"Optional"] ?
"" :
"NOT NULL"));
1512 # if qualifier DB field exists
1513 if ($DB->FieldExists(
"Resources", $OldDBFieldName.
"Qualifier"))
1515 # rename qualifier DB field
1516 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1517 .$OldDBFieldName.
"Qualifier` `"
1518 .$NewDBFieldName.
"Qualifier` INT ");
1523 # convenience functions to supply parameters to Database->UpdateValue()
1524 private function UpdateValue($FieldName, $NewValue)
1526 return $this->DB->UpdateValue(
"MetadataFields", $FieldName, $NewValue,
1527 "FieldId = ".intval($this->DBFields[
"FieldId"]),
1530 private function UpdateIntValue($FieldName, $NewValue)
1532 return $this->DB->UpdateIntValue(
"MetadataFields", $FieldName, $NewValue,
1533 "FieldId = ".intval($this->DBFields[
"FieldId"]),
1536 private function UpdateFloatValue($FieldName, $NewValue)
1538 return $this->DB->UpdateFloatValue(
"MetadataFields", $FieldName, $NewValue,
1539 "FieldId = ".intval($this->DBFields[
"FieldId"]),
1542 private function UpdateBoolValue($FieldName, $NewValue)
1544 $NewValue = $this->TranslateStringToConstants($NewValue);
1545 return $this->DB->UpdateIntValue(
"MetadataFields", $FieldName, $NewValue,
1546 "FieldId = ".intval($this->DBFields[
"FieldId"]),
1549 private function UpdateConstValue($FieldName, $NewValue, $ClassName=NULL)
1551 $NewValue = $this->TranslateStringToConstants($NewValue, $ClassName);
1552 return $this->DB->UpdateIntValue(
"MetadataFields", $FieldName, $NewValue,
1553 "FieldId = ".intval($this->DBFields[
"FieldId"]),
1557 # normalize field name for use as database field name
1558 private function NormalizeFieldNameForDB($Name)
1560 return preg_replace(
"/[^a-z0-9]/i",
"", $Name);
1563 # add any needed database fields and/or entries
1564 private function AddDatabaseFields()
1566 # grab values for common use
1568 $FieldName = $this->
Name();
1573 # set up field(s) based on field type
1574 switch ($this->
Type())
1579 # add field to resources table (if not already present)
1580 if (!$DB->FieldExists(
"Resources", $DBFieldName))
1582 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName
1583 .
"` TEXT ".($Optional ?
"" :
"NOT NULL"));
1586 # if default value supplied
1587 if ($DefaultValue != NULL)
1589 # set all existing records to default value
1590 $DB->Query(
"UPDATE Resources SET `"
1591 .$DBFieldName.
"` = '".addslashes($DefaultValue).
"'");
1596 # add field to resources table (if not already present)
1597 if (!$DB->FieldExists(
"Resources", $DBFieldName))
1599 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName
1600 .
"` INT ".($Optional ?
"" :
"NOT NULL"));
1603 # if default value supplied
1604 if ($DefaultValue != NULL)
1606 # set all existing records to default value
1607 $DB->Query(
"UPDATE Resources SET `"
1608 .$DBFieldName.
"` = '".addslashes($DefaultValue).
"'");
1613 if (!$DB->FieldExists(
"Resources", $DBFieldName.
"X"))
1615 $Precision = $this->UpdateValue(
"PointPrecision",
1617 $Digits = $this->UpdateValue(
"PointDecimalDigits",
1620 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `"
1622 " DECIMAL(".$Precision.
",".$Digits.
")");
1623 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `"
1625 " DECIMAL(".$Precision.
",".$Digits.
")");
1630 # if field is not already present in database
1631 if (!$DB->FieldExists(
"Resources", $DBFieldName))
1633 # add field to resources table
1634 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName
1635 .
"` INT DEFAULT ".intval($DefaultValue));
1637 # set all existing records to default value
1638 $DB->Query(
"UPDATE Resources SET `"
1639 .$DBFieldName.
"` = ".intval($DefaultValue));
1644 # add field to resources table (if not already present)
1645 if (!$DB->FieldExists(
"Resources", $DBFieldName))
1647 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName
1648 .
"` INT ".($Optional ?
"" :
"NOT NULL"));
1653 # add fields to resources table (if not already present)
1654 if (!$DB->FieldExists(
"Resources", $DBFieldName))
1656 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `"
1657 .$DBFieldName.
"` TEXT");
1662 # add fields to resources table (if not already present)
1663 if (!$DB->FieldExists(
"Resources", $DBFieldName))
1665 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `"
1666 .$DBFieldName.
"` INT");
1671 # add fields to resources table (if not already present)
1672 if (!$DB->FieldExists(
"Resources", $DBFieldName.
"Begin"))
1674 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName.
"Begin`"
1675 .
" DATE ".($Optional ?
"" :
"NOT NULL"));
1677 if (!$DB->FieldExists(
"Resources", $DBFieldName.
"End"))
1679 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName.
"End`"
1682 if (!$DB->FieldExists(
"Resources", $DBFieldName.
"Precision"))
1684 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName.
"Precision`"
1685 .
" INT ".($Optional ?
"" :
"NOT NULL"));
1690 # add fields to resources table (if not already present)
1691 if (!$DB->FieldExists(
"Resources", $DBFieldName))
1693 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName
1694 .
"` DATETIME ".($Optional ?
"" :
"NOT NULL"));
1704 exit(
"<br>ERROR: Attempt to add database fields for illegal metadata field type<br>\n");
1716 private function TranslateStringToConstants($CString, $ClassName = NULL)
1718 # if not a string return value unchanged to caller
1719 if (!is_string($CString) || ($CString ===
DB_NOVALUE))
1721 $ReturnValue = $CString;
1723 # handle booleans as a special case
1724 elseif (strtoupper(trim($CString)) ==
"TRUE")
1726 $ReturnValue = TRUE;
1728 elseif (strtoupper(trim($CString)) ==
"FALSE")
1730 $ReturnValue = FALSE;
1734 # assume no values will be found
1735 $ReturnValue = NULL;
1737 # split apart any ORed-together values
1738 $Values = explode(
"|", $CString);
1740 # for each value found
1741 foreach ($Values as $Value)
1743 # trim off any extraneous whitespace
1744 $Value = trim($Value);
1746 # add class name prefix to constant name if requested
1747 if ($ClassName) { $Value = $ClassName.
"::".$Value; }
1749 # if value corresponds to a constant
1750 if (defined($Value))
1752 # add constant to return value
1753 $ReturnValue = ($ReturnValue === NULL)
1755 : ($ReturnValue | constant($Value));
1759 # if no corresponding constants were found
1760 if ($ReturnValue === NULL)
1762 # return original value to caller
1763 $ReturnValue = $CString;
1767 # return result to caller
1768 return $ReturnValue;
1771 # ---- DEPRECATED --------------------------------------------------------
1786 return $this->UpdateValue(
"DisplayOrderPosition", $NewValue);
1790 return $this->UpdateValue(
"EditingOrderPosition", $NewValue);
1794 exit(
"invalid order type passed to MetadataField::OrderPosition");