3 # FILE: MetadataField.php 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/ 15 # ---- PUBLIC INTERFACE -------------------------------------------------- 17 # update methods for timestamp fields 24 # values for the *UserIsValue fields 36 return $this->ErrorStatus;
47 # if new value supplied 48 $FTFieldName = $this->DBFields[
"FieldType"];
50 && ($NewValue != self::$FieldTypePHPEnums[$FTFieldName]))
52 # update database fields and store new type 53 $this->ModifyField(NULL, $NewValue);
56 # return type to caller 57 return self::$FieldTypePHPEnums[$FTFieldName];
66 return $this->DBFields[
"FieldType"];
76 switch ($this->
Type())
94 return $this->DBFields[
"SchemaId"];
115 # if new name specified 117 && trim($NewName) != $this->DBFields[
"FieldName"])
119 $NewName = trim($NewName);
120 $NormalizedName = $this->NormalizeFieldNameForDB(strtolower($NewName));
122 # if field name is invalid 123 if (!preg_match(
"/^[[:alnum:] \(\)]+$/", $NewName))
125 # set error status to indicate illegal name 129 # if the new name is a reserved word 130 else if ($NormalizedName ==
"resourceid" || $NormalizedName ==
"schemaid")
132 # set error status to indicate illegal name 136 # the name is okay but might be a duplicate 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"]),
146 # if field name is duplicate 147 if ($DuplicateCount > 0)
149 # set error status to indicate duplicate name 154 # modify database declaration to reflect new field name 156 $this->ModifyField($NewName);
161 # return value to caller 162 return $this->DBFields[
"FieldName"];
172 $ValidValueExp =
'/^[[:alnum:] ]*$/';
173 $Value = $this->DBFields[
"Label"];
175 # if a new label was specified 176 if ($NewLabel !==
DB_NOVALUE && trim($NewLabel) != $Value)
178 $NewLabel = trim($NewLabel);
180 # if field label is valid 181 if (preg_match($ValidValueExp, $NewLabel))
183 $this->UpdateValue(
"Label", $NewLabel);
186 # the field label is invalid 203 # determine type list based on our type 204 switch ($this->
Type())
211 $AllowedTypes = array(
222 $AllowedTypes = array(
229 $AllowedTypes = array(
236 $AllowedTypes = array(
248 $AllowedTypes = array();
252 # return type list to caller 253 return $AllowedTypes;
266 $ItemTableName =
"MetadataFields";
267 $ItemIdFieldName =
"FieldId";
268 $ItemFactoryObjectName =
"MetadataSchema";
269 $ItemAssociationTables = array(
270 "FieldQualifierInts",
272 $ItemAssociationFieldName =
"MetadataFieldId";
274 # if new temp item setting supplied 275 if (!is_null($NewSetting))
277 # if caller requested to switch 278 if (($this->
Id() < 0 && $NewSetting == FALSE)
279 || ($this->
Id() >= 0 && $NewSetting == TRUE))
281 # if field name is invalid 282 if (strlen($this->NormalizeFieldNameForDB($this->
Name())) < 1)
284 # set error status to indicate illegal name 289 # lock DB tables to prevent next ID from being grabbed 292 LOCK TABLES ".$ItemTableName.
" WRITE, 293 APSessions WRITE, APSessionData WRITE, 294 MetadataSchemas WRITE");
296 # nuke stale field cache 297 self::$FieldCache = NULL;
299 # get next temp item ID 300 $OldItemId = $this->
Id();
301 $Factory =
new $ItemFactoryObjectName();
302 if ($NewSetting == TRUE)
304 $NewId = $Factory->GetNextTempItemId();
308 $NewId = $Factory->GetNextItemId();
312 $DB->Query(
"UPDATE ".$ItemTableName.
" SET ".$ItemIdFieldName.
" = ".
313 $NewId.
" WHERE ".$ItemIdFieldName.
" = ".$OldItemId);
316 $DB->Query(
"UNLOCK TABLES");
318 # change associations 319 foreach ($ItemAssociationTables as $TableName)
321 $DB->Query(
"UPDATE ".$TableName.
" ".
322 "SET ".$ItemAssociationFieldName.
" = ".$NewId.
" ".
323 "WHERE ".$ItemAssociationFieldName.
" = ".$OldItemId);
326 # if changing item from temp to non-temp 327 if ($NewSetting == FALSE)
329 # add any needed database fields and/or entries 330 $this->AddDatabaseFields();
332 # Signal that a new (real) field was added: 336 array(
"FieldId" => $NewId ) );
338 # set field order values for new field 339 $Schema->GetDisplayOrder()->AppendItem($NewId,
"MetadataField");
340 $Schema->GetEditOrder()->AppendItem($NewId,
"MetadataField");
343 # update metadata field id 344 $this->DBFields[
"FieldId"] = $NewId;
350 # report to caller whether we are a temp item 351 return ($this->
Id() < 0) ? TRUE : FALSE;
361 # if new privileges supplied 362 if ($NewValue !== NULL)
364 # store new privileges in database 365 $this->UpdateValue(
"AuthoringPrivileges", $NewValue->Data());
369 # return current value to caller 370 return $this->AuthoringPrivileges;
380 # if new privileges supplied 381 if ($NewValue !== NULL)
383 # store new privileges in database 384 $this->UpdateValue(
"EditingPrivileges", $NewValue->Data());
388 # return current value to caller 389 return $this->EditingPrivileges;
399 # if new privileges supplied 400 if ($NewValue !== NULL)
402 # store new privileges in database 403 $this->UpdateValue(
"ViewingPrivileges", $NewValue->Data());
407 # return current value to caller 408 return $this->ViewingPrivileges;
418 # if new privileges supplied 419 if ($NewValue !== NULL)
421 # store new privileges in database 422 $this->UpdateValue(
"PreviewingPrivileges", $NewValue->Data());
426 # return current value to caller 427 return $this->PreviewingPrivileges;
446 return $this->DBFields[
"DBFieldName"];
456 return $this->UpdateValue(
"Description", $NewValue);
466 return $this->UpdateValue(
"Instructions", $NewValue);
476 return $this->UpdateValue(
"Owner", $NewValue);
487 return $this->UpdateBoolValue(
"Enabled", $NewValue);
498 return $this->UpdateBoolValue(
"Optional", $NewValue);
509 return $this->UpdateBoolValue(
"Editable", $NewValue);
520 return $this->UpdateBoolValue(
"AllowMultiple", $NewValue);
531 return $this->UpdateBoolValue(
"IncludeInKeywordSearch", $NewValue);
542 return $this->UpdateBoolValue(
"IncludeInAdvancedSearch", $NewValue);
553 return $this->UpdateBoolValue(
"IncludeInFacetedSearch", $NewValue);
567 # if a new value was passed, verify that it's a legal value 572 "Invalid NewValue for SearchGroupLogic(). " 573 .
"Must be a SearchEngine::LOGIC_* constant.");
577 return $this->UpdateIntValue(
"SearchGroupLogic", $NewValue);
588 return $this->UpdateBoolValue(
"IncludeInSortOptions", $NewValue);
599 return $this->UpdateBoolValue(
"IncludeInRecommender", $NewValue);
609 return $this->UpdateBoolValue(
"CopyOnResourceDuplication", $NewValue);
619 return $this->UpdateIntValue(
"TextFieldSize", $NewValue);
629 return $this->UpdateIntValue(
"MaxLength", $NewValue);
639 return $this->UpdateIntValue(
"ParagraphRows", $NewValue);
649 return $this->UpdateIntValue(
"ParagraphCols", $NewValue);
659 return $this->UpdateFloatValue(
"MinValue", $NewValue);
669 return $this->UpdateFloatValue(
"MaxValue", $NewValue);
679 return $this->UpdateValue(
"FlagOnLabel", $NewValue);
689 return $this->UpdateValue(
"FlagOffLabel", $NewValue);
699 return $this->UpdateValue(
"DateFormat", $NewValue);
710 return $this->UpdateIntValue(
"SearchWeight", $NewValue);
721 return $this->UpdateIntValue(
"RecommenderWeight", $NewValue);
731 return $this->UpdateIntValue(
"MaxHeight", $NewValue);
741 return $this->UpdateIntValue(
"MaxWidth", $NewValue);
751 return $this->UpdateIntValue(
"MaxPreviewHeight", $NewValue);
761 return $this->UpdateIntValue(
"MaxPreviewWidth", $NewValue);
771 return $this->UpdateIntValue(
"MaxThumbnailHeight", $NewValue);
781 return $this->UpdateIntValue(
"MaxThumbnailWidth", $NewValue);
791 return $this->UpdateValue(
"DefaultAltText", $NewValue);
801 return $this->UpdateBoolValue(
"UsesQualifiers", $NewValue);
811 return $this->UpdateBoolValue(
"ShowQualifiers", $NewValue);
821 return $this->UpdateValue(
"DefaultQualifier", $NewValue);
831 return $this->UpdateBoolValue(
"AllowHTML", $NewValue);
841 return $this->UpdateBoolValue(
"UseWysiwygEditor", $NewValue);
851 return $this->UpdateBoolValue(
"UseForOaiSets", $NewValue);
862 return $this->UpdateBoolValue(
"DisplayAsListForAdvancedSearch", $NewValue);
873 return $this->UpdateIntValue(
"MaxDepthForAdvancedSearch", $NewValue);
883 return $this->UpdateIntValue(
"OptionListThreshold", $NewValue);
893 return $this->UpdateIntValue(
"AjaxThreshold", $NewValue);
904 return $this->UpdateIntValue(
"NumAjaxResults", $NewValue);
916 return $this->UpdateBoolValue(
"RequiredBySPT", $NewValue);
929 $OldValue = $this->UpdateValue(
"PointPrecision",
DB_NOVALUE);
931 if ($NewValue != $OldValue)
933 $Decimals = $this->UpdateValue(
"PointDecimalDigits",
DB_NOVALUE);
934 $TotalDigits = $NewValue + $Decimals;
936 $this->DB->Query(
"ALTER TABLE Resources MODIFY COLUMN " 937 .
"`".$this->DBFields[
"DBFieldName"].
"X` " 938 .
"DECIMAL(".$TotalDigits.
",".$Decimals.
")");
939 $this->DB->Query(
"ALTER TABLE Resources MODIFY COLUMN " 940 .
"`".$this->DBFields[
"DBFieldName"].
"Y` " 941 .
"DECIMAL(".$TotalDigits.
",".$Decimals.
")");
945 return $this->UpdateValue(
"PointPrecision", $NewValue);
958 $OldValue = $this->UpdateValue(
"PointDecimalDigits",
DB_NOVALUE);
960 if ($NewValue != $OldValue)
962 $Precision = $this->UpdateValue(
"PointPrecision",
DB_NOVALUE);
964 $TotalDigits = $NewValue + $Precision;
966 $this->DB->Query(
"ALTER TABLE Resources MODIFY COLUMN " 967 .
"`".$this->DBFields[
"DBFieldName"].
"X` " 968 .
"DECIMAL(".$TotalDigits.
",".$NewValue.
")");
969 $this->DB->Query(
"ALTER TABLE Resources MODIFY COLUMN " 970 .
"`".$this->DBFields[
"DBFieldName"].
"Y` " 971 .
"DECIMAL(".$TotalDigits.
",".$NewValue.
")");
975 return $this->UpdateValue(
"PointDecimalDigits", $NewValue);
989 isset($NewValue[
"X"]) && isset($NewValue[
"Y"]))
991 $NewValue = $NewValue[
"X"].
",".$NewValue[
"Y"];
994 # invalid value given 1000 $Value = $this->UpdateValue(
"DefaultValue", $NewValue);
1002 if (is_array($Value))
1004 $tmp = explode(
",", $Value);
1008 return array(
"X" => $tmp[0],
"Y" => $tmp[1]);
1012 return array(
"X" => NULL,
"Y" => NULL);
1017 # multiple default values to set 1018 if (is_array($NewValue))
1021 if (count($NewValue) == 0)
1026 # multiple defaults are allowed 1029 $NewValue = serialize($NewValue);
1032 # only one default is allowed so get the first one 1035 $NewValue = array_shift($NewValue);
1039 $Result = $this->UpdateValue(
"DefaultValue", $NewValue);
1041 return empty($Result) || is_numeric($Result) ?
1042 $Result : unserialize($Result);
1045 return $this->UpdateValue(
"DefaultValue", $NewValue);
1055 return $this->UpdateValue(
"UpdateMethod", $NewValue);
1067 # retrieve values based on field type 1068 switch ($this->
Type())
1071 $QueryString =
"SELECT ClassificationId, ClassificationName" 1072 .
" FROM Classifications WHERE FieldId = ".$this->
Id()
1073 .
" ORDER BY ClassificationName";
1074 if ($MaxNumberOfValues)
1076 $QueryString .=
" LIMIT ".intval($MaxNumberOfValues).
" OFFSET " 1079 $this->DB->Query($QueryString);
1080 $PossibleValues = $this->DB->FetchColumn(
1081 "ClassificationName",
"ClassificationId");
1086 $QueryString =
"SELECT ControlledNameId, ControlledName" 1087 .
" FROM ControlledNames WHERE FieldId = ".$this->
Id()
1088 .
" ORDER BY ControlledName";
1089 if ($MaxNumberOfValues)
1091 $QueryString .=
" LIMIT ".intval($MaxNumberOfValues).
" OFFSET " 1094 $this->DB->Query($QueryString);
1095 $PossibleValues = $this->DB->FetchColumn(
1096 "ControlledName",
"ControlledNameId");
1107 $PossibleValues = array();
1109 if (count($Restrictions))
1111 $PossibleValues = call_user_func_array(
1112 array($UserFactory,
"GetUsersWithPrivileges"),
1118 $Users = $UserFactory->GetMatchingUsers(
".*.");
1120 foreach ($Users as $Id => $Data)
1122 $PossibleValues[$Id] = $Data[
"UserName"];
1129 # for everything else return an empty array 1130 $PossibleValues = array();
1134 # return array of possible values to caller 1135 return $PossibleValues;
1145 # retrieve values based on field type 1146 switch ($this->
Type())
1149 $Count = $this->DB->Query(
"SELECT count(*) AS ValueCount" 1150 .
" FROM Classifications WHERE FieldId = ".$this->
Id(),
1156 $Count = $this->DB->Query(
"SELECT count(*) AS ValueCount" 1157 .
" FROM ControlledNames WHERE FieldId = ".$this->
Id(),
1170 # for everything else return an empty array 1175 # return count of possible values to caller 1186 # retrieve ID based on field type 1187 switch ($this->
Type())
1190 $Id = $this->DB->Query(
"SELECT ClassificationId FROM Classifications" 1191 .
" WHERE ClassificationName = '".addslashes($Value).
"'" 1192 .
" AND FieldId = ".$this->
Id(),
1193 "ClassificationId");
1198 $Id = $this->DB->Query(
"SELECT ControlledNameId FROM ControlledNames" 1199 .
" WHERE ControlledName = '".addslashes($Value).
"'" 1200 .
" AND FieldId = ".$this->
Id(),
1201 "ControlledNameId");
1205 # for everything else return NULL 1210 # return ID for value to caller 1221 # retrieve ID based on field type 1222 switch ($this->
Type())
1225 $Value = $this->DB->Query(
"SELECT ClassificationName FROM Classifications" 1226 .
" WHERE ClassificationId = '".intval($Id).
"'" 1227 .
" AND FieldId = ".$this->
Id(),
1228 "ClassificationName");
1233 $Value = $this->DB->Query(
"SELECT ControlledName FROM ControlledNames" 1234 .
" WHERE ControlledNameId = '".intval($Id).
"'" 1235 .
" AND FieldId = ".$this->
Id(),
1240 # for everything else return NULL 1245 # return ID for value to caller 1261 # retrieve ID if object passed in 1262 if (is_object($Value) && method_exists($Value,
"Id"))
1264 $Value = $Value->Id();
1267 # check value based on field type 1268 $DBFieldName = $this->DBFields[
"DBFieldName"];
1269 switch ($this->
Type())
1280 $UseCount = $this->DB->Query(
"SELECT COUNT(*) AS UseCount" 1282 .
" WHERE `".$DBFieldName.
"` = '".addslashes($Value).
"'" 1283 .
" AND SchemaId = ".intval($this->DBFields[
"SchemaId"]),
1288 $UseCount = $this->DB->Query(
"SELECT COUNT(*) AS UseCount" 1289 .
" FROM ResourceClassInts" 1290 .
" WHERE ClassificationId = ".intval($Value),
1296 $UseCount = $this->DB->Query(
"SELECT COUNT(*) AS UseCount" 1297 .
" FROM ResourceNameInts" 1298 .
" WHERE ControlledNameId = ".intval($Value),
1303 $UseCount = $this->DB->Query(
"SELECT COUNT(*) AS UseCount" 1305 .
" WHERE `".$DBFieldName.
"X` = '".$Value[
"X"].
"'" 1306 .
" AND `".$DBFieldName.
"Y` = '".$Value[
"Y"].
"'" 1307 .
" AND SchemaId = ".intval($this->DBFields[
"SchemaId"]),
1312 throw new Exception(__CLASS__.
"::".__METHOD__.
"() called for" 1313 .
" unsupported field type (".$this->Type().
").");
1317 # report use count to caller 1329 # if value provided different from present value 1331 && ($NewValue != $this->DBFields[
"HasItemLevelQualifiers"]))
1333 # check if qualifier column currently exists 1335 $QualColExists = $this->DB->FieldExists(
"Resources", $QualColName);
1337 # if new value indicates qualifiers should now be used 1338 if ($NewValue == TRUE)
1340 # if qualifier column does not exist in DB for this field 1341 if ($QualColExists == FALSE)
1343 # add qualifier column in DB for this field 1344 $this->DB->Query(
"ALTER TABLE Resources ADD COLUMN `" 1345 .$QualColName.
"` INT");
1350 # if qualifier column exists in DB for this field 1351 if ($QualColExists == TRUE)
1353 # remove qualifier column from DB for this field 1354 $this->DB->Query(
"ALTER TABLE Resources DROP COLUMN `" 1360 return $this->UpdateValue(
"HasItemLevelQualifiers", $NewValue);
1369 # start with empty list 1372 # for each associated qualifier 1373 $this->DB->Query(
"SELECT QualifierId FROM FieldQualifierInts" 1374 .
" WHERE MetadataFieldId = ".$this->DBFields[
"FieldId"]);
1375 while ($Record = $this->DB->FetchRow())
1377 # load qualifier object 1378 $Qual =
new Qualifier($Record[
"QualifierId"]);
1380 # add qualifier ID and name to list 1381 $List[$Qual->Id()] = $Qual->Name();
1384 # return list to caller 1394 # grab list of associated qualifiers 1397 # get list of all qualifiers 1399 $AllQualifiers = $QFactory->GetItemNames();
1401 # return list of unassociated qualifiers 1402 return array_diff($AllQualifiers, $AssociatedQualifiers);
1412 # if qualifier object passed in 1413 if (is_object($Qualifier))
1415 # grab qualifier ID from object 1416 $Qualifier = $Qualifier->Id();
1418 # else if string passed in does not look like ID 1419 elseif (!is_numeric($Qualifier))
1421 # assume string passed in is name and use it to retrieve ID 1423 $Qualifier = $QFact->GetItemIdByName($Qualifier);
1424 if ($Qualifier === FALSE)
1426 throw new InvalidArgumentException(
"Unknown qualifier name (\"" 1427 .$Qualifier.
"\").");
1431 # if not already associated 1432 $RecordCount = $this->DB->Query(
1433 "SELECT COUNT(*) AS RecordCount FROM FieldQualifierInts" 1434 .
" WHERE QualifierId = ".$Qualifier
1435 .
" AND MetadataFieldId = ".$this->
Id(),
"RecordCount");
1436 if ($RecordCount < 1)
1438 # associate field with qualifier 1439 $this->DB->Query(
"INSERT INTO FieldQualifierInts SET" 1440 .
" QualifierId = ".$Qualifier.
"," 1441 .
" MetadataFieldId = ".$this->Id());
1453 # if qualifier object passed in 1454 if (is_object($QualifierIdOrObject))
1456 # grab qualifier ID from object 1457 $QualifierIdOrObject = $QualifierIdOrObject->Id();
1460 # delete intersection record from database 1461 $this->DB->Query(
"DELETE FROM FieldQualifierInts WHERE QualifierId = " 1462 .$QualifierIdOrObject.
" AND MetadataFieldId = ".
1472 switch ($this->
Type())
1501 $CacheKey =
"View".$User->Id() .
"-".
1502 ($AllowHooksToModify ?
"1" :
"0");
1504 # see if we have a cached permission for this field and user 1505 if (!isset($this->PermissionCache[$CacheKey]))
1509 # the field should not be viewed if it is disabled 1510 $this->PermissionCache[$CacheKey] = FALSE;
1517 # otherwise, evaluate the perms 1519 $Schema->ViewingPrivileges()->MeetsRequirements($User) &&
1523 if ($AllowHooksToModify)
1525 $SignalResult = $GLOBALS[
"AF"]->SignalEvent(
1526 "EVENT_FIELD_VIEW_PERMISSION_CHECK", array(
1530 "CanView" => $CheckResult));
1531 $CheckResult = $SignalResult[
"CanView"];
1534 $this->PermissionCache[$CacheKey] = $CheckResult;
1538 return $this->PermissionCache[$CacheKey];
1549 # if a new value was provided, convert it to a string 1554 $Ids = implode(
",", $Ids);
1558 # update/retrieve the value 1559 $Value = $this->UpdateValue(
1560 "ReferenceableSchemaIds", $Ids);
1562 # and convert stored string to an array 1563 return explode(
",", $Value);
1566 # ---- PRIVATE INTERFACE ------------------------------------------------- 1571 private $ErrorStatus;
1572 private $AuthoringPrivileges;
1573 private $EditingPrivileges;
1574 private $ViewingPrivileges;
1575 private $PreviewingPrivileges;
1576 private $PermissionCache;
1599 # field type DB/PHP enum translations 1653 self::UPDATEMETHOD_NOAUTOUPDATE =>
"Do not update automatically",
1654 self::UPDATEMETHOD_ONRECORDCREATE =>
"Update on record creation",
1655 self::UPDATEMETHOD_BUTTON =>
"Provide an update button",
1656 self::UPDATEMETHOD_ONRECORDEDIT =>
"Update when record is edited",
1657 self::UPDATEMETHOD_ONRECORDCHANGE =>
"Update when record is changed" 1673 public static function Create($SchemaId, $FieldType, $FieldName,
1674 $Optional = NULL, $DefaultValue = NULL)
1676 # error out if field type is bad 1677 if (empty(self::$FieldTypeDBEnums[$FieldType]))
1679 throw new InvalidArgumentException(
"Bad field type (".$FieldType.
").");
1682 # error out if field name is duplicate 1684 $FieldName = trim($FieldName);
1685 $DuplicateCount = $DB->Query(
1686 "SELECT COUNT(*) AS RecordCount FROM MetadataFields" 1687 .
" WHERE FieldName = '".addslashes($FieldName).
"'" 1688 .
" AND SchemaId = ".intval($SchemaId),
1690 if ($DuplicateCount > 0)
1692 throw new InvalidArgumentException(
"Duplicate field name (".$FieldName.
").");
1695 # grab current user ID 1696 $UserId = $GLOBALS[
"G_User"]->Get(
"UserId");
1698 # normalize schema ID 1700 $SchemaId = $Schema->Id();
1702 # use schema privileges as starting privilege values 1703 $AuthorPrivs = $Schema->AuthoringPrivileges();
1704 $EditPrivs = $Schema->EditingPrivileges();
1705 $ViewPrivs = $Schema->ViewingPrivileges();
1706 $PreviewPrivs = $Schema->ViewingPrivileges();
1708 # lock DB tables and get next temporary field ID 1709 $DB->Query(
"LOCK TABLES MetadataFields WRITE");
1710 $FieldId = $Schema->GetNextTempItemId();
1712 # add field to MDF table in database 1713 $DB->Query(
"INSERT INTO MetadataFields" 1714 .
" (FieldId, SchemaId, FieldName, FieldType, LastModifiedById," 1715 .
" Optional, AuthoringPrivileges, EditingPrivileges," 1716 .
" ViewingPrivileges, PreviewingPrivileges)" 1718 .intval($FieldId).
", " 1719 .intval($SchemaId).
"," 1720 .
" '".addslashes($FieldName).
"'," 1721 .
" '".self::$FieldTypeDBEnums[$FieldType].
"', " 1722 .intval($UserId).
", " 1723 .($Optional ?
"1" :
"0").
"," 1724 .
"'".$DB->EscapeString($AuthorPrivs->Data()).
"'," 1725 .
"'".$DB->EscapeString($EditPrivs->Data()).
"'," 1726 .
"'".$DB->EscapeString($ViewPrivs->Data()).
"'," 1727 .
"'".$DB->EscapeString($PreviewPrivs->Data()).
"')");
1730 $DB->Query(
"UNLOCK TABLES");
1732 # nuke potentially stale cache information 1733 self::$FieldCache = NULL;
1738 # set field defaults 1739 $Field->SetDefaults();
1741 # set the default value if specified 1742 if ($DefaultValue !== NULL)
1744 $Field->DefaultValue($DefaultValue);
1747 # return newly-constructed field to caller 1759 # assume everything will be okay 1762 # check if we have cached field info 1764 if (self::$FieldCache === NULL)
1766 # if not, retrieve field info from database 1767 $this->DB->Query(
"SELECT * FROM MetadataFields");
1768 while ($Row = $this->DB->FetchRow())
1770 self::$FieldCache[$Row[
"FieldId"]] = $Row;
1774 # error if requested field did not exist 1775 if (!array_key_exists($FieldId, self::$FieldCache) )
1777 throw new InvalidArgumentException(
"Invalid metadata field ID (" 1779 .StdLib::GetMyCaller().
".");
1781 $Row = self::$FieldCache[$FieldId];
1782 $this->DBFields = $Row;
1783 $this->
Id = $FieldId;
1785 # if privileges have not yet been initialized 1786 if (!strlen($this->DBFields[
"AuthoringPrivileges"]))
1788 # set default values for privileges from metadata schema 1797 # set privileges from stored values 1799 $Row[
"AuthoringPrivileges"]);
1801 $Row[
"EditingPrivileges"]);
1803 $Row[
"ViewingPrivileges"]);
1805 $Row[
"PreviewingPrivileges"]);
1808 # set database column name 1809 $this->DBFields[
"DBFieldName"] =
1810 $this->NormalizeFieldNameForDB($this->DBFields[
"FieldName"]);
1819 "Description" => NULL,
1820 "Instructions" => NULL,
1824 "CopyOnResourceDuplication" => TRUE,
1825 "AllowMultiple" => FALSE,
1826 "IncludeInKeywordSearch" => FALSE,
1827 "IncludeInAdvancedSearch" => FALSE,
1828 "IncludeInFacetedSearch" => FALSE,
1830 "IncludeInSortOptions" => TRUE,
1831 "IncludeInRecommender" => FALSE,
1832 "ParagraphRows" => 4,
1833 "ParagraphCols" => 50,
1835 "FlagOnLabel" =>
"On",
1836 "FlagOffLabel" =>
"Off",
1837 "DateFormat" => NULL,
1838 "RecommenderWeight" => 1,
1841 "MaxPreviewHeight" => 100,
1842 "MaxPreviewWidth" => 100,
1843 "MaxThumbnailHeight" => 50,
1844 "MaxThumbnailWidth" => 50,
1845 "DefaultAltText" => NULL,
1846 "UsesQualifiers" => FALSE,
1847 "HasItemLevelQualifiers" => FALSE,
1848 "ShowQualifiers" => FALSE,
1849 "DefaultQualifier" => NULL,
1850 "AllowHTML" => FALSE,
1851 "UseWysiwygEditor" => FALSE,
1852 "UseForOaiSets" => FALSE,
1853 "DisplayAsListForAdvancedSearch" => FALSE,
1854 "MaxDepthForAdvancedSearch" => 1,
1855 "OptionListThreshold" => 25,
1856 "AjaxThreshold" => 50,
1857 "NumAjaxResults" => 50,
1858 "PointPrecision" => 8,
1859 "PointDecimalDigits" => 5,
1860 "UserPrivilegeRestrictions" => array(),
1861 "UpdateMethod" =>
"NoAutoUpdate",
1862 # 9999 is the
default max value because
default number field length is 4
1863 "MaxValue" => 9999);
1871 "DefaultValue" => NULL,
1872 "SearchWeight" => 1,
1873 "TextFieldSize" => 50,
1874 "MaxLength" => 100),
1876 "DefaultValue" => NULL,
1877 "SearchWeight" => 1,
1878 "TextFieldSize" => 50,
1879 "MaxLength" => 100),
1881 "DefaultValue" => NULL,
1882 "SearchWeight" => 1,
1883 "TextFieldSize" => 4,
1884 "MaxLength" => 100),
1886 "DefaultValue" => NULL,
1887 "SearchWeight" => 1,
1888 "TextFieldSize" => 10,
1889 "MaxLength" => 100),
1891 "DefaultValue" => NULL,
1892 "SearchWeight" => 1,
1893 "TextFieldSize" => 50,
1894 "MaxLength" => 100),
1896 "DefaultValue" => NULL,
1897 "SearchWeight" => 1,
1898 "TextFieldSize" => 50,
1899 "MaxLength" => 100),
1901 "DefaultValue" => NULL,
1902 "SearchWeight" => 1,
1903 "AllowMultiple" => TRUE,
1904 "TextFieldSize" => 50,
1905 "MaxLength" => 100),
1907 "DefaultValue" => NULL,
1908 "SearchWeight" => 3,
1909 "AllowMultiple" => TRUE,
1910 "TextFieldSize" => 50,
1911 "MaxLength" => 100),
1913 "DefaultValue" => NULL,
1914 "SearchWeight" => 3,
1915 "TextFieldSize" => 50,
1916 "MaxLength" => 100),
1918 "DefaultValue" => NULL,
1919 "SearchWeight" => 1,
1920 "TextFieldSize" => 50,
1921 "MaxLength" => 100),
1923 "DefaultValue" => NULL,
1924 "CopyOnResourceDuplication" => FALSE,
1925 "SearchWeight" => 1,
1926 "TextFieldSize" => 50,
1927 "MaxLength" => 100),
1929 "DefaultValue" => NULL,
1930 "CopyOnResourceDuplication" => FALSE,
1931 "AllowMultiple" => TRUE,
1932 "SearchWeight" => 1,
1933 "TextFieldSize" => 50,
1934 "MaxLength" => 100),
1936 "DefaultValue" => NULL,
1937 "SearchWeight" => 1,
1938 "TextFieldSize" => 50,
1939 "MaxLength" => 255),
1941 "DefaultValue" => array(
"X" => NULL,
"Y" => NULL),
1942 "SearchWeight" => 1,
1943 "TextFieldSize" => 10,
1944 "MaxLength" => 100),
1946 "DefaultValue" => NULL,
1947 "SearchWeight" => 1,
1948 "TextFieldSize" => 50,
1950 "ReferenceableSchemaIds" => array(
1958 # set defaults that are the same for every field 1959 foreach (self::$FixedDefaults as $Key => $Value)
1961 $this->$Key($Value);
1964 # set defaults that depend on the type of the field 1965 foreach (self::$TypeBasedDefaults[$this->
Type()] as $Key => $Value)
1967 $this->$Key($Value);
1970 # tweak the update method if dealing with the date of record creation 1971 if ($this->
Name() ==
"Date Of Record Creation")
1985 "Attempt to update drop Metadata Field at %FILE%:%LINE%." 1986 .
" (Fields may only be dropped by MetadataSchema.)");
1988 # clear other database entries as appropriate for field type 1990 $DBFieldName = $this->DBFields[
"DBFieldName"];
1992 switch (self::$FieldTypePHPEnums[$this->DBFields[
"FieldType"]])
2002 # remove field from resources table 2003 if ($DB->FieldExists(
"Resources", $DBFieldName))
2005 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `".$DBFieldName.
"`");
2010 if ($DB->FieldExists(
"Resources", $DBFieldName.
"X"))
2012 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `".$DBFieldName.
"X`");
2013 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `".$DBFieldName.
"Y`");
2018 # remove fields from resources table 2019 if ($DB->FieldExists(
"Resources", $DBFieldName.
"Begin"))
2021 $DB->Query(
"ALTER TABLE Resources " 2022 .
"DROP COLUMN `".$DBFieldName.
"Begin`");
2023 $DB->Query(
"ALTER TABLE Resources " 2024 .
"DROP COLUMN `".$DBFieldName.
"End`");
2025 $DB->Query(
"ALTER TABLE Resources " 2026 .
"DROP COLUMN `".$DBFieldName.
"Precision`");
2031 $DB->Query(
"SELECT ClassificationId FROM Classifications " 2032 .
"WHERE FieldId = ".$this->
Id());
2034 while ($ClassificationId = $DB->FetchField(
"ClassificationId"))
2036 # remove any resource / name intersections 2037 $TempDB->Query(
"DELETE FROM ResourceClassInts WHERE " 2038 .
"ClassificationId = ".$ClassificationId);
2040 # remove controlled name 2041 $TempDB->Query(
"DELETE FROM Classifications WHERE " 2042 .
"ClassificationId = ".$ClassificationId);
2048 $DB->Query(
"SELECT ControlledNameId FROM ControlledNames " 2049 .
"WHERE FieldId = ".$this->
Id());
2051 while ($ControlledNameId = $DB->FetchField(
"ControlledNameId"))
2053 # remove any resource / name intersections 2054 $TempDB->Query(
"DELETE FROM ResourceNameInts WHERE " 2055 .
"ControlledNameId = ".$ControlledNameId);
2057 # remove any variant names 2058 $TempDB->Query(
"DELETE FROM VariantNames WHERE " 2059 .
"ControlledNameId = ".$ControlledNameId);
2061 # remove controlled name 2062 $TempDB->Query(
"DELETE FROM ControlledNames WHERE " 2063 .
"ControlledNameId = ".$ControlledNameId);
2068 # for each file associated with this field 2069 $DB->Query(
"SELECT FileId FROM Files WHERE FieldId = '".$this->
Id().
"'");
2070 while ($FileId = $DB->FetchRow())
2073 $File =
new File(intval($FileId));
2079 # remove any resource references for the field 2081 DELETE FROM ReferenceInts 2082 WHERE FieldId = '".addslashes($this->
Id()).
"'");
2086 # remove field from database 2087 $DB->Query(
"DELETE FROM MetadataFields " 2088 .
"WHERE FieldId = '".$this->DBFields[
"FieldId"].
"'");
2090 # remove any qualifier associations 2091 $DB->Query(
"DELETE FROM FieldQualifierInts WHERE MetadataFieldId = '" 2092 .$this->DBFields[
"FieldId"].
"'");
2094 # get the order objects the field is part of 2097 # remove it if it's a direct descendant 2098 $Order->RemoveItem($this->
Id(),
"MetadataField");
2100 # also make sure to remove it if it's part of a group 2101 foreach ($Order->GetItemIds() as $Item)
2103 if ($Item[
"Type"] ==
"MetadataFieldGroup")
2106 $Group->RemoveItem($this->
Id(),
"MetadataField");
2111 # nuke stale field cache 2112 self::$FieldCache = NULL;
2122 private function ModifyField($NewName = NULL, $NewType = NULL)
2124 # grab old DB field name 2125 $OldDBFieldName = $this->DBFields[
"DBFieldName"];
2126 $OldFieldType = NULL;
2128 # if new field name supplied 2129 if ($NewName != NULL)
2131 # cache the old name for options and controllednames below 2132 $OldName = $this->DBFields[
"FieldName"];
2135 $this->UpdateValue(
"FieldName", $NewName);
2137 # determine new DB field name 2138 $NewDBFieldName = $this->NormalizeFieldNameForDB($NewName);
2140 # store new database field name 2141 $this->DBFields[
"DBFieldName"] = $NewDBFieldName;
2145 # set new field name equal to old field name 2146 $NewDBFieldName = $OldDBFieldName;
2149 # if new type supplied 2150 if ($NewType != NULL)
2152 # grab old field type 2153 $OldFieldType = self::$FieldTypePHPEnums[$this->DBFields[
"FieldType"]];
2155 # store new field type 2156 $this->UpdateValue(
"FieldType", self::$FieldTypeDBEnums[$NewType]);
2159 # if this is not a temporary field 2160 if ($this->
Id() >= 0)
2162 # modify field in DB as appropriate for field type 2164 $FieldType = self::$FieldTypePHPEnums[$this->DBFields[
"FieldType"]];
2170 # alter field declaration in Resources table 2171 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `" 2172 .$OldDBFieldName.
"` `" 2173 .$NewDBFieldName.
"` TEXT DEFAULT NULL");
2177 # alter field declaration in Resources table 2178 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `" 2179 .$OldDBFieldName.
"` `" 2180 .$NewDBFieldName.
"` INT DEFAULT NULL");
2185 $Precision = $this->UpdateValue(
"PointPrecision",
2187 $Digits = $this->UpdateValue(
"PointDecimalDigits",
2189 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN " 2190 .
"`".$OldDBFieldName.
"X` " 2191 .
"`".$NewDBFieldName.
"X`".
2192 " DECIMAL(".$Precision.
",".$Digits.
")");
2193 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN " 2194 .
"`".$OldDBFieldName.
"Y` " 2195 .
"`".$NewDBFieldName.
"Y`".
2196 " DECIMAL(".$Precision.
",".$Digits.
")");
2200 # alter field declaration in Resources table 2201 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `" 2202 .$OldDBFieldName.
"` `" 2203 .$NewDBFieldName.
"` INT" 2206 # set any unset values to default 2207 $DB->Query(
"UPDATE Resources SET `".$NewDBFieldName
2209 .
" WHERE `".$NewDBFieldName.
"` IS NULL");
2213 # if new type supplied and new type is different from old 2214 if (($NewType != NULL) && ($NewType != $OldFieldType))
2216 # if old type was time stamp 2219 # change time stamp field in resources table to begin date 2220 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `" 2221 .$OldDBFieldName.
"` `" 2222 .$NewDBFieldName.
"Begin` DATE " 2225 # add end date and precision fields 2226 $DB->Query(
"ALTER TABLE Resources " 2227 .
"ADD COLUMN `".$NewDBFieldName.
"End` DATE");
2228 $DB->Query(
"ALTER TABLE Resources " 2229 .
"ADD COLUMN `".$NewDBFieldName.
"Precision`" 2230 .
"INT DEFAULT NULL");
2233 # set precision to reflect time stamp content 2234 $DB->Query(
"UPDATE Resources " 2235 .
"SET `".$NewDBFieldName.
"Precision` = " 2241 exit(
"<br>ERROR: Attempt to convert metadata field " 2242 .
"to date from type other than timestamp<br>\n");
2247 # change name of fields 2248 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `" 2249 .$OldDBFieldName.
"Begin` `" 2250 .$NewDBFieldName.
"Begin` DATE " 2252 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `" 2253 .$OldDBFieldName.
"End` `" 2254 .$NewDBFieldName.
"End` DATE " 2256 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `" 2257 .$OldDBFieldName.
"Precision` `" 2258 .$NewDBFieldName.
"Precision` INT " 2264 # if new type supplied and new type is different from old 2265 if (($NewType != NULL) && ($NewType != $OldFieldType))
2267 # if old type was date 2270 # change begin date field in resource table to time stamp 2271 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `" 2272 .$OldDBFieldName.
"Begin` `" 2273 .$NewDBFieldName.
"` DATETIME " 2276 # drop end date and precision fields 2277 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `" 2278 .$OldDBFieldName.
"End`");
2279 $DB->Query(
"ALTER TABLE Resources DROP COLUMN `" 2280 .$OldDBFieldName.
"Precision`");
2284 exit(
"<br>ERROR: Attempt to convert metadata field to " 2285 .
"time stamp from type other than date<br>\n");
2290 # change name of field 2291 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `" 2292 .$OldDBFieldName.
"` `" 2293 .$NewDBFieldName.
"` DATETIME " 2307 # if qualifier DB field exists 2308 if ($DB->FieldExists(
"Resources", $OldDBFieldName.
"Qualifier"))
2310 # rename qualifier DB field 2311 $DB->Query(
"ALTER TABLE Resources CHANGE COLUMN `" 2312 .$OldDBFieldName.
"Qualifier` `" 2313 .$NewDBFieldName.
"Qualifier` INT ");
2324 private function UpdateValue($FieldName, $NewValue)
2326 # nuke stale field cache 2327 self::$FieldCache = NULL;
2329 return $this->DB->UpdateValue(
"MetadataFields", $FieldName, $NewValue,
2330 "FieldId = ".intval($this->DBFields[
"FieldId"]),
2340 private function UpdateIntValue($FieldName, $NewValue)
2342 # nuke stale field cache 2343 self::$FieldCache = NULL;
2345 return $this->DB->UpdateIntValue(
"MetadataFields", $FieldName, $NewValue,
2346 "FieldId = ".intval($this->DBFields[
"FieldId"]),
2356 private function UpdateFloatValue($FieldName, $NewValue)
2358 # nuke stale field cache 2359 self::$FieldCache = NULL;
2361 return $this->DB->UpdateFloatValue(
"MetadataFields", $FieldName, $NewValue,
2362 "FieldId = ".intval($this->DBFields[
"FieldId"]),
2372 private function UpdateBoolValue($FieldName, $NewValue)
2374 # nuke stale field cache 2375 self::$FieldCache = NULL;
2377 $NewValue = $this->TranslateStringToConstants($NewValue);
2378 return $this->DB->UpdateIntValue(
"MetadataFields", $FieldName, $NewValue,
2379 "FieldId = ".intval($this->DBFields[
"FieldId"]),
2390 private function UpdateConstValue($FieldName, $NewValue, $ClassName=NULL)
2392 # nuke stale field cache 2393 self::$FieldCache = NULL;
2395 $NewValue = $this->TranslateStringToConstants($NewValue, $ClassName);
2396 return $this->DB->UpdateIntValue(
"MetadataFields", $FieldName, $NewValue,
2397 "FieldId = ".intval($this->DBFields[
"FieldId"]),
2406 private function NormalizeFieldNameForDB($Name)
2408 return preg_replace(
"/[^a-z0-9]/i",
"", $Name)
2416 private function AddDatabaseFields()
2418 # grab values for common use 2422 # set up field(s) based on field type 2423 switch ($this->
Type())
2428 # add field to resources table (if not already present) 2429 if (!$DB->FieldExists(
"Resources", $DBFieldName))
2431 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName
2432 .
"` TEXT DEFAULT NULL");
2438 # add field to resources table (if not already present) 2439 if (!$DB->FieldExists(
"Resources", $DBFieldName))
2441 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName
2442 .
"` INT DEFAULT NULL");
2447 if (!$DB->FieldExists(
"Resources", $DBFieldName.
"X"))
2449 $Precision = $this->UpdateValue(
"PointPrecision",
2451 $Digits = $this->UpdateValue(
"PointDecimalDigits",
2454 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `" 2456 " DECIMAL(".$Precision.
",".$Digits.
") DEFAULT NULL");
2457 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `" 2459 " DECIMAL(".$Precision.
",".$Digits.
") DEFAULT NULL");
2464 # if field is not already present in database 2465 if (!$DB->FieldExists(
"Resources", $DBFieldName))
2467 # add field to resources table 2468 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName
2469 .
"` INT DEFAULT NULL");
2474 # add fields to resources table (if not already present) 2475 if (!$DB->FieldExists(
"Resources", $DBFieldName.
"Begin"))
2477 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName.
"Begin`" 2478 .
" DATE DEFAULT NULL");
2480 if (!$DB->FieldExists(
"Resources", $DBFieldName.
"End"))
2482 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName.
"End`" 2483 .
" DATE DEFAULT NULL");
2485 if (!$DB->FieldExists(
"Resources", $DBFieldName.
"Precision"))
2487 $DB->Query(
"ALTER TABLE Resources " 2488 .
"ADD COLUMN `".$DBFieldName.
"Precision`" 2489 .
" INT DEFAULT NULL");
2494 # add fields to resources table (if not already present) 2495 if (!$DB->FieldExists(
"Resources", $DBFieldName))
2497 $DB->Query(
"ALTER TABLE Resources ADD COLUMN `".$DBFieldName
2498 .
"` DATETIME DEFAULT NULL");
2512 exit(
"<br>ERROR: Attempt to add database fields " 2513 .
"for illegal metadata field type<br>\n");
2525 private function TranslateStringToConstants($CString, $ClassName = NULL)
2527 # if not a string return value unchanged to caller 2528 if (!is_string($CString) || ($CString ===
DB_NOVALUE))
2530 $ReturnValue = $CString;
2532 # handle booleans as a special case 2533 elseif (strtoupper(trim($CString)) ==
"TRUE")
2535 $ReturnValue = TRUE;
2537 elseif (strtoupper(trim($CString)) ==
"FALSE")
2539 $ReturnValue = FALSE;
2543 # assume no values will be found 2544 $ReturnValue = NULL;
2546 # split apart any ORed-together values 2547 $Values = explode(
"|", $CString);
2549 # for each value found 2550 foreach ($Values as $Value)
2552 # trim off any extraneous whitespace 2553 $Value = trim($Value);
2555 # add class name prefix to constant name if requested 2556 if ($ClassName) { $Value = $ClassName.
"::".$Value; }
2558 # if value corresponds to a constant 2559 if (defined($Value))
2561 # add constant to return value 2562 $ReturnValue = ($ReturnValue === NULL)
2564 : ($ReturnValue | constant($Value));
2568 # if no corresponding constants were found 2569 if ($ReturnValue === NULL)
2571 # return original value to caller 2572 $ReturnValue = $CString;
2576 # return result to caller 2577 return $ReturnValue;
2583 private static $FieldCache = NULL;
2586 # ---- DEPRECATED METHODS ------------------------------------------------ 2588 # These are maintained only for backward compatibility with older 2589 # code. Newer code should not use them. 2611 $NewValue = serialize((array) $NewValue);
2614 $Value = $this->UpdateValue(
"UserPrivilegeRestrictions", $NewValue);
2619 $Value = (array) unserialize($Value);
2622 # no value set, set it to an empty array 2633 return $this->UpdateConstValue(
2634 "AuthoringUserIsValue", $NewValue,
"MetadataField");
2639 return $this->UpdateConstValue(
"EditingUserIsValue", $NewValue,
"MetadataField");
2644 return $this->UpdateIntValue(
"ViewingUserValue", $NewValue,
"MetadataField");
2649 return $this->UpdateIntValue(
"AuthoringUserValue", $NewValue,
"MetadataField");
2654 return $this->UpdateIntValue(
"EditingUserValue", $NewValue,
"MetadataField");
2659 return $this->UpdateConstValue(
"ViewingUserIsValue", $NewValue,
"MetadataField");
2664 return $this->UpdateBoolValue(
"EnableOnOwnerReturn", $NewValue);
2675 throw new Exception(
"Deprecated ".__METHOD__.
"() called -- ".
2676 __METHOD__.
"s() should be used instead.");
2688 throw new Exception(
"Deprecated ".__METHOD__.
"() called -- ".
2689 __METHOD__.
"s() should be used instead.");
2701 throw new Exception(
"Deprecated ".__METHOD__.
"() called -- ".
2702 __METHOD__.
"s() should be used instead.");
2714 throw new Exception(
"Deprecated ".__METHOD__.
"() called -- ".
2715 "ViewingPrivileges() should be used instead.");
2727 throw new Exception(
"Deprecated ".__METHOD__.
"() called -- ".
2728 "this should probably be using ViewingPrivileges() instead.");
static CheckMyCaller($DesiredCaller, $ExceptionMsg=NULL)
Check the caller of the current function.
SQL database abstraction object with smart query caching.
Set of privileges used to access resource information or other parts of the system.
Factory class for Qualifier.
CWIS-specific user factory class.
Factory for manipulating ControlledName objects.
Factory for producing and manipulating Classification objects.
Class representing a stored (usually uploaded) file.