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
712 # retrieve ID if object passed in
713 if (is_object($Value) && method_exists($Value,
"Id"))
715 $Value = $Value->Id();
718 # check value based on field type
719 $DBFieldName = $this->DBFields[
"DBFieldName"];
720 switch ($this->
Type())
731 $UseCount = $this->DB->Query(
"SELECT COUNT(*) AS UseCount"
733 .
" WHERE `".$DBFieldName.
"` = '".addslashes($Value).
"'",
738 $UseCount = $this->DB->Query(
"SELECT COUNT(*) AS UseCount"
739 .
" FROM ResourceClassInts"
740 .
" WHERE ClassificationId = ".intval($Value),
746 $UseCount = $this->DB->Query(
"SELECT COUNT(*) AS UseCount"
747 .
" FROM ResourceNameInts"
748 .
" WHERE ControlledNameId = ".intval($Value),
753 $UseCount = $this->DB->Query(
"SELECT COUNT(*) AS UseCount"
755 .
" WHERE `".$DBFieldName.
"X` = '".$Value[
"X"].
"'"
756 .
" AND `".$DBFieldName.
"Y` = '".$Value[
"Y"].
"'",
761 throw new Exception(__CLASS__.
"::".__METHOD__.
"() called for"
762 .
" unsupported field type (".$this->Type().
").");
766 # report use count to caller
770 # get/set whether field uses item-level qualifiers
773 # if value provided different from present value
775 && ($NewValue != $this->DBFields[
"HasItemLevelQualifiers"]))
777 # check if qualifier column currently exists
779 $QualColExists = $this->DB->FieldExists(
"Resources", $QualColName);
781 # if new value indicates qualifiers should now be used
782 if ($NewValue == TRUE)
784 # if qualifier column does not exist in DB for this field
785 if ($QualColExists == FALSE)
787 # add qualifier column in DB for this field
788 $this->DB->Query(
"ALTER TABLE Resources ADD COLUMN `"
789 .$QualColName.
"` INT");
794 # if qualifier column exists in DB for this field
795 if ($QualColExists == TRUE)
797 # remove qualifier column from DB for this field
798 $this->DB->Query(
"ALTER TABLE Resources DROP COLUMN `"
804 return $this->UpdateValue(
"HasItemLevelQualifiers", $NewValue);
807 # get list of qualifiers associated with field
810 # start with empty list
813 # for each associated qualifier
814 $this->DB->Query(
"SELECT QualifierId FROM FieldQualifierInts"
815 .
" WHERE MetadataFieldId = ".$this->DBFields[
"FieldId"]);
816 while ($Record = $this->DB->FetchRow())
818 # load qualifier object
819 $Qual =
new Qualifier($Record[
"QualifierId"]);
821 # add qualifier ID and name to list
822 $List[$Qual->Id()] = $Qual->Name();
825 # return list to caller
829 # get list of qualifiers not associated with field
832 # grab list of associated qualifiers
835 # get list of all qualifiers
837 $AllQualifiers = $QFactory->QualifierList();
839 # return list of unassociated qualifiers
840 return array_diff($AllQualifiers, $AssociatedQualifiers);
843 # add qualifier association
846 # if qualifier object passed in
847 if (is_object($QualifierIdOrObject))
849 # grab qualifier ID from object
850 $QualifierIdOrObject = $QualifierIdOrObject->Id();
853 # if not already associated
854 $RecordCount = $this->DB->Query(
855 "SELECT COUNT(*) AS RecordCount FROM FieldQualifierInts"
856 .
" WHERE QualifierId = ".$QualifierIdOrObject
857 .
" AND MetadataFieldId = ".$this->
Id(),
"RecordCount");
858 if ($RecordCount < 1)
860 # associate field with qualifier
861 $this->DB->Query(
"INSERT INTO FieldQualifierInts SET"
862 .
" QualifierId = ".$QualifierIdOrObject.
","
863 .
" MetadataFieldId = ".$this->Id());
867 # delete qualifier association
870 # if qualifier object passed in
871 if (is_object($QualifierIdOrObject))
873 # grab qualifier ID from object
874 $QualifierIdOrObject = $QualifierIdOrObject->Id();
877 # delete intersection record from database
878 $this->DB->Query(
"DELETE FROM FieldQualifierInts WHERE QualifierId = "
879 .$QualifierIdOrObject.
" AND MetadataFieldId = ".
883 # retrieve item factory object for this field
886 switch ($this->
Type())
906 # ---- PRIVATE INTERFACE -------------------------------------------------
910 private $ErrorStatus;
931 # field type DB/PHP enum translations
990 # object constructor (only for use by MetadataSchema object)
992 $Optional = TRUE, $DefaultValue = NULL)
994 # assume everything will be okay
997 # grab our own database handle
1001 # if field ID supplied
1002 if ($FieldId != NULL)
1004 # look up field in database
1005 $DB->Query(
"SELECT * FROM MetadataFields WHERE FieldId = ".intval($FieldId));
1006 $Record = $DB->FetchRow();
1009 # if no field ID supplied or if record not found in database
1010 if (($FieldId == NULL) || ($Record == NULL))
1012 # error out if valid field type not supplied
1019 # if field name supplied
1020 $FieldName = trim($FieldName);
1021 if (strlen($FieldName) > 0)
1023 # error out if field name is duplicate
1024 $DuplicateCount = $DB->Query(
"
1025 SELECT COUNT(*) AS RecordCount FROM MetadataFields
1026 WHERE FieldName = '".addslashes($FieldName).
"'
1027 OR Label = '".addslashes($FieldName).
"'",
1030 if ($DuplicateCount > 0)
1037 # grab current user ID
1039 $UserId = $G_User->Get(
"UserId");
1041 # lock DB tables and get next temporary field ID
1043 $DB->Query(
"LOCK TABLES MetadataFields WRITE");
1044 $FieldId = $Schema->GetNextTempItemId();
1046 # add field to MDF table in database
1048 INSERT INTO MetadataFields
1049 (FieldId, FieldName, FieldType, LastModifiedById) VALUES
1050 (".intval($FieldId).
",
1051 '".addslashes($FieldName).
"',
1056 $DB->Query(
"UNLOCK TABLES");
1058 # re-read record from database
1060 SELECT * FROM MetadataFields
1061 WHERE FieldId = ".intval($FieldId));
1062 $this->DBFields = $DB->FetchRow();
1063 $this->DBFields[
"DBFieldName"] =
1064 $this->NormalizeFieldNameForDB($this->DBFields[
"FieldName"]);
1066 # set field defaults
1068 $this->
Optional($Optional ? TRUE : FALSE);
1070 # set the default value if specified since NULL is invalid for some
1072 if (!is_null($DefaultValue))
1079 # save values locally
1080 $this->DBFields = $Record;
1081 $this->DBFields[
"DBFieldName"] =
1082 $this->NormalizeFieldNameForDB($Record[
"FieldName"]);
1091 "Description" => NULL,
1092 "Instructions" => NULL,
1097 "AllowMultiple" => FALSE,
1098 "IncludeInKeywordSearch" => FALSE,
1099 "IncludeInAdvancedSearch" => FALSE,
1100 "IncludeInSortOptions" => TRUE,
1101 "IncludeInRecommender" => FALSE,
1102 "ParagraphRows" => 4,
1103 "ParagraphCols" => 50,
1105 "FlagOnLabel" =>
"On",
1106 "FlagOffLabel" =>
"Off",
1107 "DateFormat" => NULL,
1108 "RecommenderWeight" => 1,
1111 "MaxPreviewHeight" => 100,
1112 "MaxPreviewWidth" => 100,
1113 "MaxThumbnailHeight" => 50,
1114 "MaxThumbnailWidth" => 50,
1115 "DefaultAltText" => NULL,
1116 "UsesQualifiers" => FALSE,
1117 "HasItemLevelQualifiers" => FALSE,
1118 "ShowQualifiers" => FALSE,
1119 "DefaultQualifier" => NULL,
1120 "AllowHTML" => FALSE,
1121 "UseWysiwygEditor" => FALSE,
1122 "UseForOaiSets" => FALSE,
1123 "NumAjaxResults" => 50,
1124 "ViewingPrivilege" => NULL,
1125 "AuthoringPrivilege" => PRIV_MYRESOURCEADMIN,
1126 "EditingPrivilege" => PRIV_RESOURCEADMIN,
1127 "ImagePreviewPrivilege" => NULL,
1128 "TreeBrowsingPrivilege" => NULL,
1129 "ViewingUserIsValue" => self::USERISVALUE_UNSET,
1130 "AuthoringUserIsValue" => self::USERISVALUE_UNSET,
1131 "EditingUserIsValue" => self::USERISVALUE_UNSET,
1132 "ViewingUserValue" => NULL,
1133 "AuthoringUserValue" => NULL,
1134 "EditingUserValue" => NULL,
1135 "PointPrecision" => 8,
1136 "PointDecimalDigits" => 5,
1137 "UserPrivilegeRestrictions" => array(),
1138 "UpdateMethod" =>
"NoAutoUpdate",
1139 # 9999 is the
default max value because
default number field length is 4
1140 "MaxValue" => 9999);
1147 "DefaultValue" => NULL,
1148 "SearchWeight" => 1,
1149 "TextFieldSize" => 50,
1150 "MaxLength" => 100),
1152 "DefaultValue" => NULL,
1153 "SearchWeight" => 1,
1154 "TextFieldSize" => 50,
1155 "MaxLength" => 100),
1157 "DefaultValue" => NULL,
1158 "SearchWeight" => 1,
1159 "TextFieldSize" => 4,
1160 "MaxLength" => 100),
1162 "DefaultValue" => NULL,
1163 "SearchWeight" => 1,
1164 "TextFieldSize" => 10,
1165 "MaxLength" => 100),
1167 "DefaultValue" => NULL,
1168 "SearchWeight" => 1,
1169 "TextFieldSize" => 50,
1170 "MaxLength" => 100),
1172 "DefaultValue" => NULL,
1173 "SearchWeight" => 1,
1174 "TextFieldSize" => 50,
1175 "MaxLength" => 100),
1177 "DefaultValue" => NULL,
1178 "SearchWeight" => 1,
1179 "TextFieldSize" => 50,
1180 "MaxLength" => 100),
1182 "DefaultValue" => NULL,
1183 "SearchWeight" => 3,
1184 "TextFieldSize" => 50,
1185 "MaxLength" => 100),
1187 "DefaultValue" => NULL,
1188 "SearchWeight" => 3,
1189 "TextFieldSize" => 50,
1190 "MaxLength" => 100),
1192 "DefaultValue" => NULL,
1193 "SearchWeight" => 1,
1194 "TextFieldSize" => 50,
1195 "MaxLength" => 100),
1197 "DefaultValue" => NULL,
1198 "SearchWeight" => 1,
1199 "TextFieldSize" => 50,
1200 "MaxLength" => 100),
1202 "DefaultValue" => NULL,
1203 "SearchWeight" => 1,
1204 "TextFieldSize" => 50,
1205 "MaxLength" => 100),
1207 "DefaultValue" => NULL,
1208 "SearchWeight" => 1,
1209 "TextFieldSize" => 50,
1210 "MaxLength" => 255),
1212 "DefaultValue" => array(
"X" => NULL,
"Y" => NULL),
1213 "SearchWeight" => 1,
1214 "TextFieldSize" => 10,
1215 "MaxLength" => 100));
1223 # set defaults that are the same for every field
1224 foreach (self::$FixedDefaults as $Key => $Value)
1226 $this->$Key($Value);
1229 # set defaults that depend on the type of the field
1230 foreach (self::$TypeBasedDefaults[$this->
Type()] as $Key => $Value)
1232 $this->$Key($Value);
1235 # tweak the update method if dealing with the date of record creation
1236 if ($this->
Name() ==
"Date Of Record Creation")
1242 # remove field from database (only for use by MetadataSchema object)
1245 # clear other database entries as appropriate for field type
1247 $DBFieldName = $this->DBFields[
"DBFieldName"];
1258 # remove field from resources table
1259 if ($DB->FieldExists(
"Resources", $DBFieldName))
1261 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `".$DBFieldName.
"`");
1266 if ($DB->FieldExists(
"Resources", $DBFieldName.
"X"))
1268 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `".$DBFieldName.
"X`");
1269 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `".$DBFieldName.
"Y`");
1274 # remove fields from resources table
1275 if ($DB->FieldExists(
"Resources", $DBFieldName.
"Begin"))
1277 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `".$DBFieldName.
"Begin`");
1278 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `".$DBFieldName.
"End`");
1279 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `".$DBFieldName.
"Precision`");
1284 $DB->Query(
"SELECT ClassificationId FROM Classifications "
1285 .
"WHERE FieldId = ".$this->
Id());
1287 while ($ClassificationId = $DB->FetchField(
"ClassificationId"))
1289 # remove any resource / name intersections
1290 $TempDB->Query(
"DELETE FROM ResourceClassInts WHERE "
1291 .
"ClassificationId = ".$ClassificationId);
1293 # remove controlled name
1294 $TempDB->Query(
"DELETE FROM Classifications WHERE "
1295 .
"ClassificationId = ".$ClassificationId);
1301 $DB->Query(
"SELECT ControlledNameId FROM ControlledNames "
1302 .
"WHERE FieldId = ".$this->
Id());
1304 while ($ControlledNameId = $DB->FetchField(
"ControlledNameId"))
1306 # remove any resource / name intersections
1307 $TempDB->Query(
"DELETE FROM ResourceNameInts WHERE "
1308 .
"ControlledNameId = ".$ControlledNameId);
1310 # remove any variant names
1311 $TempDB->Query(
"DELETE FROM VariantNames WHERE "
1312 .
"ControlledNameId = ".$ControlledNameId);
1314 # remove controlled name
1315 $TempDB->Query(
"DELETE FROM ControlledNames WHERE "
1316 .
"ControlledNameId = ".$ControlledNameId);
1321 # for each file associated with this field
1322 $DB->Query(
"SELECT FileId FROM Files WHERE FieldId = '".$this->
Id().
"'");
1323 while ($FileId = $DB->FetchRow())
1326 $File =
new File(intval($FileId));
1332 # remove field from database
1333 $DB->Query(
"DELETE FROM MetadataFields "
1334 .
"WHERE FieldId = '".$this->DBFields[
"FieldId"].
"'");
1336 # remove any qualifier associations
1337 $DB->Query(
"DELETE FROM FieldQualifierInts WHERE MetadataFieldId = '"
1338 .$this->DBFields[
"FieldId"].
"'");
1340 # remove the field from the display and edit order
1346 # remove it from the dispaly and edit oorder
1347 $DisplayOrder->RemoveItem($this->
Id(),
"MetadataField");
1348 $EditOrder->RemoveItem($this->
Id(),
"MetadataField");
1350 # remove field from any metadata field groups in the display order
1351 foreach ($DisplayOrder->GetItemIds() as $Item)
1353 if ($Item[
"Type"] ==
"MetadataFieldGroup")
1356 $Group->RemoveItem($this->
Id(),
"MetadataField");
1360 # remove field from any metadata field groups in the edit order
1361 foreach ($EditOrder->GetItemIds() as $Item)
1363 if ($Item[
"Type"] ==
"MetadataFieldGroup")
1366 $Group->RemoveItem($this->
Id(),
"MetadataField");
1369 }
catch (Exception $Exception) {}
1372 # modify any database fields
1373 private function ModifyField($NewName = NULL, $NewType = NULL)
1375 # grab old DB field name
1376 $OldDBFieldName = $this->DBFields[
"DBFieldName"];
1377 $OldFieldType = NULL;
1379 # if new field name supplied
1380 if ($NewName != NULL)
1382 # cache the old name for options and controllednames below
1383 $OldName = $this->DBFields[
"FieldName"];
1386 $this->UpdateValue(
"FieldName", $NewName);
1388 # determine new DB field name
1389 $NewDBFieldName = $this->NormalizeFieldNameForDB($NewName);
1391 # store new database field name
1392 $this->DBFields[
"DBFieldName"] = $NewDBFieldName;
1396 # set new field name equal to old field name
1397 $NewDBFieldName = $OldDBFieldName;
1400 # if new type supplied
1401 if ($NewType != NULL)
1403 # grab old field type
1406 # store new field type
1410 # if this is not a temporary field
1411 if ($this->
Id() >= 0)
1413 # modify field in DB as appropriate for field type
1421 # alter field declaration in Resources table
1422 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1423 .$OldDBFieldName.
"` `"
1424 .$NewDBFieldName.
"` TEXT "
1425 .($this->DBFields[
"Optional"] ?
"" :
"NOT NULL"));
1430 # alter field declaration in Resources table
1431 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1432 .$OldDBFieldName.
"` `"
1433 .$NewDBFieldName.
"` INT "
1434 .($this->DBFields[
"Optional"] ?
"" :
"NOT NULL"));
1438 $Precision = $this->UpdateValue(
"PointPrecision",
1440 $Digits = $this->UpdateValue(
"PointDecimalDigits",
1442 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN "
1443 .
"`".$OldDBFieldName.
"X` "
1444 .
"`".$NewDBFieldName.
"X`".
1445 " DECIMAL(".$Precision.
",".$Digits.
")");
1446 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN "
1447 .
"`".$OldDBFieldName.
"Y` "
1448 .
"`".$NewDBFieldName.
"Y`".
1449 " DECIMAL(".$Precision.
",".$Digits.
")");
1453 # if DB field name has changed
1454 if ($NewDBFieldName != $OldDBFieldName)
1456 # alter field declaration in Resources table
1457 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1458 .$OldDBFieldName.
"` `"
1459 .$NewDBFieldName.
"` TEXT");
1464 # if DB field name has changed
1465 if ($NewDBFieldName != $OldDBFieldName)
1467 # alter field declaration in Resources table
1468 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1469 .$OldDBFieldName.
"` `"
1470 .$NewDBFieldName.
"` INT");
1475 # alter field declaration in Resources table
1476 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1477 .$OldDBFieldName.
"` `"
1478 .$NewDBFieldName.
"` INT"
1481 # set any unset values to default
1482 $DB->Query(
"UPDATE Resources SET `".$NewDBFieldName
1484 .
" WHERE `".$NewDBFieldName.
"` IS NULL");
1488 # if new type supplied and new type is different from old
1489 if (($NewType != NULL) && ($NewType != $OldFieldType))
1491 # if old type was time stamp
1494 # change time stamp field in resources table to begin date
1495 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1496 .$OldDBFieldName.
"` `"
1497 .$NewDBFieldName.
"Begin` DATE "
1498 .($this->DBFields[
"Optional"] ?
"" :
"NOT NULL"));
1500 # add end date and precision fields
1501 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$NewDBFieldName.
"End"
1503 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$NewDBFieldName.
"Precision`"
1504 .
" INT ".($Optional ?
"" :
"NOT NULL"));
1506 # set precision to reflect time stamp content
1507 $DB->Query(
"UPDATE Resources SET `".$NewDBFieldName.
"Precision` = "
1512 exit(
"<br>ERROR: Attempt to convert metadata field to date from type other than timestamp<br>\n");
1517 # change name of fields
1518 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1519 .$OldDBFieldName.
"Begin` `"
1520 .$NewDBFieldName.
"Begin` DATE "
1521 .($this->DBFields[
"Optional"] ?
"" :
"NOT NULL"));
1522 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1523 .$OldDBFieldName.
"End` `"
1524 .$NewDBFieldName.
"End` DATE "
1525 .($this->DBFields[
"Optional"] ?
"" :
"NOT NULL"));
1526 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1527 .$OldDBFieldName.
"Precision` `"
1528 .$NewDBFieldName.
"Precision` INT "
1529 .($this->DBFields[
"Optional"] ?
"" :
"NOT NULL"));
1534 # if new type supplied and new type is different from old
1535 if (($NewType != NULL) && ($NewType != $OldFieldType))
1537 # if old type was date
1540 # change begin date field in resource table to time stamp
1541 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1542 .$OldDBFieldName.
"Begin` `"
1543 .$NewDBFieldName.
"` DATETIME "
1544 .($this->DBFields[
"Optional"] ?
"" :
"NOT NULL"));
1546 # drop end date and precision fields
1547 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `"
1548 .$OldDBFieldName.
"End`");
1549 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `"
1550 .$OldDBFieldName.
"Precision`");
1554 exit(
"<br>ERROR: Attempt to convert metadata field to time stamp from type other than date<br>\n");
1559 # change name of field
1560 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1561 .$OldDBFieldName.
"` `"
1562 .$NewDBFieldName.
"` DATETIME "
1563 .($this->DBFields[
"Optional"] ?
"" :
"NOT NULL"));
1573 # if qualifier DB field exists
1574 if ($DB->FieldExists(
"Resources", $OldDBFieldName.
"Qualifier"))
1576 # rename qualifier DB field
1577 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `"
1578 .$OldDBFieldName.
"Qualifier` `"
1579 .$NewDBFieldName.
"Qualifier` INT ");
1584 # convenience functions to supply parameters to Database->UpdateValue()
1585 private function UpdateValue($FieldName, $NewValue)
1587 return $this->DB->UpdateValue(
"MetadataFields", $FieldName, $NewValue,
1588 "FieldId = ".intval($this->DBFields[
"FieldId"]),
1591 private function UpdateIntValue($FieldName, $NewValue)
1593 return $this->DB->UpdateIntValue(
"MetadataFields", $FieldName, $NewValue,
1594 "FieldId = ".intval($this->DBFields[
"FieldId"]),
1597 private function UpdateFloatValue($FieldName, $NewValue)
1599 return $this->DB->UpdateFloatValue(
"MetadataFields", $FieldName, $NewValue,
1600 "FieldId = ".intval($this->DBFields[
"FieldId"]),
1603 private function UpdateBoolValue($FieldName, $NewValue)
1605 $NewValue = $this->TranslateStringToConstants($NewValue);
1606 return $this->DB->UpdateIntValue(
"MetadataFields", $FieldName, $NewValue,
1607 "FieldId = ".intval($this->DBFields[
"FieldId"]),
1610 private function UpdateConstValue($FieldName, $NewValue, $ClassName=NULL)
1612 $NewValue = $this->TranslateStringToConstants($NewValue, $ClassName);
1613 return $this->DB->UpdateIntValue(
"MetadataFields", $FieldName, $NewValue,
1614 "FieldId = ".intval($this->DBFields[
"FieldId"]),
1618 # normalize field name for use as database field name
1619 private function NormalizeFieldNameForDB($Name)
1621 return preg_replace(
"/[^a-z0-9]/i",
"", $Name);
1624 # add any needed database fields and/or entries
1625 private function AddDatabaseFields()
1627 # grab values for common use
1629 $FieldName = $this->
Name();
1634 # set up field(s) based on field type
1635 switch ($this->
Type())
1640 # add field to resources table (if not already present)
1641 if (!$DB->FieldExists(
"Resources", $DBFieldName))
1643 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName
1644 .
"` TEXT ".($Optional ?
"" :
"NOT NULL"));
1647 # if default value supplied
1648 if ($DefaultValue != NULL)
1650 # set all existing records to default value
1651 $DB->Query(
"UPDATE Resources SET `"
1652 .$DBFieldName.
"` = '".addslashes($DefaultValue).
"'");
1657 # add field to resources table (if not already present)
1658 if (!$DB->FieldExists(
"Resources", $DBFieldName))
1660 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName
1661 .
"` INT ".($Optional ?
"" :
"NOT NULL"));
1664 # if default value supplied
1665 if ($DefaultValue != NULL)
1667 # set all existing records to default value
1668 $DB->Query(
"UPDATE Resources SET `"
1669 .$DBFieldName.
"` = '".addslashes($DefaultValue).
"'");
1674 if (!$DB->FieldExists(
"Resources", $DBFieldName.
"X"))
1676 $Precision = $this->UpdateValue(
"PointPrecision",
1678 $Digits = $this->UpdateValue(
"PointDecimalDigits",
1681 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `"
1683 " DECIMAL(".$Precision.
",".$Digits.
")");
1684 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `"
1686 " DECIMAL(".$Precision.
",".$Digits.
")");
1691 # if field is not already present in database
1692 if (!$DB->FieldExists(
"Resources", $DBFieldName))
1694 # add field to resources table
1695 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName
1696 .
"` INT DEFAULT ".intval($DefaultValue));
1698 # set all existing records to default value
1699 $DB->Query(
"UPDATE Resources SET `"
1700 .$DBFieldName.
"` = ".intval($DefaultValue));
1705 # add field to resources table (if not already present)
1706 if (!$DB->FieldExists(
"Resources", $DBFieldName))
1708 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName
1709 .
"` INT ".($Optional ?
"" :
"NOT NULL"));
1714 # add fields to resources table (if not already present)
1715 if (!$DB->FieldExists(
"Resources", $DBFieldName))
1717 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `"
1718 .$DBFieldName.
"` TEXT");
1723 # add fields to resources table (if not already present)
1724 if (!$DB->FieldExists(
"Resources", $DBFieldName))
1726 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `"
1727 .$DBFieldName.
"` INT");
1732 # add fields to resources table (if not already present)
1733 if (!$DB->FieldExists(
"Resources", $DBFieldName.
"Begin"))
1735 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName.
"Begin`"
1736 .
" DATE ".($Optional ?
"" :
"NOT NULL"));
1738 if (!$DB->FieldExists(
"Resources", $DBFieldName.
"End"))
1740 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName.
"End`"
1743 if (!$DB->FieldExists(
"Resources", $DBFieldName.
"Precision"))
1745 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName.
"Precision`"
1746 .
" INT ".($Optional ?
"" :
"NOT NULL"));
1751 # add fields to resources table (if not already present)
1752 if (!$DB->FieldExists(
"Resources", $DBFieldName))
1754 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName
1755 .
"` DATETIME ".($Optional ?
"" :
"NOT NULL"));
1765 exit(
"<br>ERROR: Attempt to add database fields for illegal metadata field type<br>\n");
1777 private function TranslateStringToConstants($CString, $ClassName = NULL)
1779 # if not a string return value unchanged to caller
1780 if (!is_string($CString) || ($CString ===
DB_NOVALUE))
1782 $ReturnValue = $CString;
1784 # handle booleans as a special case
1785 elseif (strtoupper(trim($CString)) ==
"TRUE")
1787 $ReturnValue = TRUE;
1789 elseif (strtoupper(trim($CString)) ==
"FALSE")
1791 $ReturnValue = FALSE;
1795 # assume no values will be found
1796 $ReturnValue = NULL;
1798 # split apart any ORed-together values
1799 $Values = explode(
"|", $CString);
1801 # for each value found
1802 foreach ($Values as $Value)
1804 # trim off any extraneous whitespace
1805 $Value = trim($Value);
1807 # add class name prefix to constant name if requested
1808 if ($ClassName) { $Value = $ClassName.
"::".$Value; }
1810 # if value corresponds to a constant
1811 if (defined($Value))
1813 # add constant to return value
1814 $ReturnValue = ($ReturnValue === NULL)
1816 : ($ReturnValue | constant($Value));
1820 # if no corresponding constants were found
1821 if ($ReturnValue === NULL)
1823 # return original value to caller
1824 $ReturnValue = $CString;
1828 # return result to caller
1829 return $ReturnValue;