MetadataField.php
Go to the documentation of this file.
00001 <?PHP 00002 # 00003 # FILE: MetadataField.php 00004 # 00005 # Part of the Collection Workflow Integration System (CWIS) 00006 # Copyright 2011 Edward Almasy and Internet Scout 00007 # http://scout.wisc.edu 00008 # 00009 00010 class MetadataField { 00011 00012 # ---- PUBLIC INTERFACE -------------------------------------------------- 00013 00014 # Update methods for timestamp fields 00015 const UPDATEMETHOD_NOAUTOUPDATE = "NoAutoUpdate"; 00016 const UPDATEMETHOD_ONRECORDCREATE = "OnRecordCreate"; 00017 const UPDATEMETHOD_BUTTON = "Button"; 00018 const UPDATEMETHOD_ONRECORDEDIT = "OnRecordEdit"; 00019 const UPDATEMETHOD_ONRECORDCHANGE = "OnRecordChange"; 00020 00021 # get current error status of object 00022 function Status() { return $this->ErrorStatus; } 00023 00024 # get/set type of field as enumerated value 00025 function Type($NewValue = DB_NOVALUE) 00026 { 00027 # if new value supplied 00028 if (($NewValue != DB_NOVALUE) 00029 && ($NewValue != MetadataField::$FieldTypePHPEnums[ 00030 $this->DBFields["FieldType"]])) 00031 { 00032 # update database fields and store new type 00033 $this->ModifyField(NULL, $NewValue); 00034 } 00035 00036 # return type to caller 00037 return MetadataField::$FieldTypePHPEnums[$this->DBFields["FieldType"]]; 00038 } 00039 00040 # get type of field as type name (string) 00041 function TypeAsName() 00042 { 00043 return $this->DBFields["FieldType"]; 00044 } 00045 00046 # get displayable name for the field 00047 # first tries to get label but uses field name if label isn't set 00048 function GetDisplayName() 00049 { 00050 return strlen($this->Label()) ? $this->Label() : $this->Name(); 00051 } 00052 00053 # get/set name of field 00054 # once the name is set to a valid value, it cannot be changed 00055 function Name($NewName = DB_NOVALUE) 00056 { 00057 # if new name specified 00058 if ($NewName != DB_NOVALUE 00059 && trim($NewName) != $this->DBFields["FieldName"]) 00060 { 00061 # if field name is invalid 00062 $NewName = trim($NewName); 00063 if (!preg_match("/^[[:alnum:] \(\)]+$/", $NewName)) 00064 { 00065 # set error status to indicate illegal name 00066 $this->ErrorStatus = MetadataSchema::MDFSTAT_ILLEGALNAME; 00067 } 00068 else 00069 { 00070 # check for duplicate name 00071 $DuplicateCount = $this->DB->Query(" 00072 SELECT COUNT(*) AS RecordCount FROM MetadataFields 00073 WHERE FieldName = '".addslashes($NewName)."' 00074 OR Label = '".addslashes($NewName)."'", 00075 "RecordCount"); 00076 00077 # if field name is duplicate 00078 if ($DuplicateCount > 0) 00079 { 00080 # set error status to indicate duplicate name 00081 $this->ErrorStatus = MetadataSchema::MDFSTAT_DUPLICATENAME; 00082 } 00083 else 00084 { 00085 # modify database declaration to reflect new field name 00086 $this->ErrorStatus = MetadataSchema::MDFSTAT_OK; 00087 $this->ModifyField($NewName); 00088 } 00089 } 00090 } 00091 00092 # return value to caller 00093 return $this->DBFields["FieldName"]; 00094 } 00095 00096 # get/set label of field 00097 public function Label($NewLabel = DB_NOVALUE) 00098 { 00099 $ValidValueExp = '/^[[:alnum:] ]*$/'; 00100 $Value = $this->DBFields["Label"]; 00101 00102 # if a new label was specified 00103 if ($NewLabel !== DB_NOVALUE && trim($NewLabel) != $Value) 00104 { 00105 $NewLabel = trim($NewLabel); 00106 00107 # if field label is invalid 00108 if (!preg_match($ValidValueExp, $NewLabel)) 00109 { 00110 $this->ErrorStatus = MetadataSchema::MDFSTAT_ILLEGALLABEL; 00111 } 00112 00113 else 00114 { 00115 if (strlen($NewLabel) > 0) 00116 { 00117 # check for duplicate name 00118 $DuplicateCount = $this->DB->Query(" 00119 SELECT COUNT(*) AS RecordCount FROM MetadataFields 00120 WHERE Label = '".addslashes($NewLabel)."' 00121 OR FieldName = '".addslashes($NewLabel)."'", 00122 "RecordCount"); 00123 00124 # if field name is duplicate 00125 if ($DuplicateCount > 0) 00126 { 00127 $this->ErrorStatus = MetadataSchema::MDFSTAT_DUPLICATELABEL; 00128 } 00129 00130 else 00131 { 00132 $this->ErrorStatus = MetadataSchema::MDFSTAT_OK; 00133 $this->UpdateValue("Label", $NewLabel); 00134 $Value = $NewLabel; 00135 } 00136 } 00137 00138 else 00139 { 00140 $this->ErrorStatus = MetadataSchema::MDFSTAT_OK; 00141 $this->UpdateValue("Label", $NewLabel); 00142 $Value = $NewLabel; 00143 } 00144 } 00145 } 00146 00147 return $Value; 00148 } 00149 00150 # get associative array (enumeration => string) containing field types we can convert to 00151 function GetAllowedConversionTypes() 00152 { 00153 # determine type list based on our type 00154 switch ($this->Type()) 00155 { 00156 case MetadataSchema::MDFTYPE_TEXT: 00157 case MetadataSchema::MDFTYPE_PARAGRAPH: 00158 case MetadataSchema::MDFTYPE_NUMBER: 00159 case MetadataSchema::MDFTYPE_FLAG: 00160 case MetadataSchema::MDFTYPE_URL: 00161 $AllowedTypes = array( 00162 MetadataSchema::MDFTYPE_TEXT => "Text", 00163 MetadataSchema::MDFTYPE_PARAGRAPH => "Paragraph", 00164 MetadataSchema::MDFTYPE_NUMBER => "Number", 00165 MetadataSchema::MDFTYPE_FLAG => "Flag", 00166 MetadataSchema::MDFTYPE_URL => "Url" 00167 ); 00168 break; 00169 00170 case MetadataSchema::MDFTYPE_CONTROLLEDNAME: 00171 case MetadataSchema::MDFTYPE_OPTION: 00172 $AllowedTypes = array( 00173 MetadataSchema::MDFTYPE_CONTROLLEDNAME => "ControlledName", 00174 MetadataSchema::MDFTYPE_OPTION => "Option", 00175 ); 00176 break; 00177 00178 case MetadataSchema::MDFTYPE_DATE: 00179 $AllowedTypes = array( 00180 MetadataSchema::MDFTYPE_TEXT => "Text", 00181 MetadataSchema::MDFTYPE_DATE => "Date", 00182 ); 00183 break; 00184 00185 case MetadataSchema::MDFTYPE_IMAGE: 00186 $AllowedTypes = array( 00187 MetadataSchema::MDFTYPE_TEXT => "Text", 00188 MetadataSchema::MDFTYPE_IMAGE => "Still Image", 00189 ); 00190 break; 00191 00192 case MetadataSchema::MDFTYPE_TIMESTAMP: 00193 case MetadataSchema::MDFTYPE_TREE: 00194 case MetadataSchema::MDFTYPE_USER: 00195 case MetadataSchema::MDFTYPE_FILE: 00196 default: 00197 $AllowedTypes = array(); 00198 break; 00199 } 00200 00201 # return type list to caller 00202 return $AllowedTypes; 00203 } 00204 00205 # get/set whether item is temporary instance 00206 function IsTempItem($NewSetting = NULL) 00207 { 00208 $ItemTableName = "MetadataFields"; 00209 $ItemIdFieldName = "FieldId"; 00210 $ItemFactoryObjectName = "MetadataSchema"; 00211 $ItemAssociationTables = array( 00212 "FieldQualifierInts", 00213 ); 00214 $ItemAssociationFieldName = "MetadataFieldId"; 00215 00216 # if new temp item setting supplied 00217 if (!is_null($NewSetting)) 00218 { 00219 # if caller requested to switch 00220 if (($this->Id() < 0 && $NewSetting == FALSE) 00221 || ($this->Id() >= 0 && $NewSetting == TRUE)) 00222 { 00223 # if field name is invalid 00224 if (strlen($this->NormalizeFieldNameForDB($this->Name())) < 1) 00225 { 00226 # set error status to indicate illegal name 00227 $this->ErrorStatus = MetadataSchema::MDFSTAT_ILLEGALNAME; 00228 } 00229 else 00230 { 00231 # lock DB tables to prevent next ID from being grabbed 00232 $DB = $this->DB; 00233 $DB->Query("LOCK TABLES ".$ItemTableName." WRITE,". 00234 "APSessions WRITE, APSessionData WRITE"); 00235 00236 # get next temp item ID 00237 $OldItemId = $this->Id(); 00238 $Factory = new $ItemFactoryObjectName(); 00239 if ($NewSetting == TRUE) 00240 { 00241 $NewId = $Factory->GetNextTempItemId(); 00242 } 00243 else 00244 { 00245 $NewId = $Factory->GetNextItemId(); 00246 } 00247 00248 # change item ID 00249 $DB->Query("UPDATE ".$ItemTableName." SET ".$ItemIdFieldName." = ". 00250 $NewId. " WHERE ".$ItemIdFieldName." = ".$OldItemId); 00251 00252 # release DB tables 00253 $DB->Query("UNLOCK TABLES"); 00254 00255 # change associations 00256 foreach ($ItemAssociationTables as $TableName) 00257 { 00258 $DB->Query("UPDATE ".$TableName." SET ".$ItemAssociationFieldName." = ". 00259 $NewId. " WHERE ".$ItemAssociationFieldName." = ".$OldItemId); 00260 } 00261 00262 # if changing item from temp to non-temp 00263 if ($NewSetting == FALSE) 00264 { 00265 # add any needed database fields and/or entries 00266 $this->AddDatabaseFields(); 00267 } 00268 00269 # update metadata field id 00270 $this->DBFields["FieldId"] = $NewId; 00271 } 00272 } 00273 } 00274 00275 # report to caller whether we are a temp item 00276 return ($this->Id() < 0) ? TRUE : FALSE; 00277 } 00278 00279 # get field attributes 00280 function Id() { return $this->DBFields["FieldId"]; } 00281 function DBFieldName() { return $this->DBFields["DBFieldName"]; } 00282 00283 # get/set field attributes 00284 function Description($NewValue = DB_NOVALUE) 00285 { return $this->UpdateValue("Description", $NewValue); } 00286 function Owner($NewValue = DB_NOVALUE) 00287 { return $this->UpdateValue("Owner", $NewValue); } 00288 function RequiredBySPT($NewValue = DB_NOVALUE) 00289 { return $this->UpdateBoolValue("RequiredBySPT", $NewValue); } 00290 function Enabled($NewValue = DB_NOVALUE) 00291 { return $this->UpdateBoolValue("Enabled", $NewValue); } 00292 function Optional($NewValue = DB_NOVALUE) 00293 { return $this->UpdateBoolValue("Optional", $NewValue); } 00294 function Editable($NewValue = DB_NOVALUE) 00295 { return $this->UpdateBoolValue("Editable", $NewValue); } 00296 function Viewable($NewValue = DB_NOVALUE) 00297 { return $this->UpdateBoolValue("Viewable", $NewValue); } 00298 function AllowMultiple($NewValue = DB_NOVALUE) 00299 { return $this->UpdateBoolValue("AllowMultiple", $NewValue); } 00300 function IncludeInKeywordSearch($NewValue = DB_NOVALUE) 00301 { return $this->UpdateBoolValue("IncludeInKeywordSearch", $NewValue); } 00302 function IncludeInAdvancedSearch($NewValue = DB_NOVALUE) 00303 { return $this->UpdateBoolValue("IncludeInAdvancedSearch", $NewValue); } 00304 function IncludeInSortOptions($NewValue = DB_NOVALUE) 00305 { return $this->UpdateBoolValue("IncludeInSortOptions", $NewValue); } 00306 function IncludeInRecommenderSystem($NewValue = DB_NOVALUE) 00307 { return $this->UpdateBoolValue("IncludeInRecommenderSystem", $NewValue); } 00308 function TextFieldSize($NewValue = DB_NOVALUE) 00309 { return $this->UpdateIntValue("TextFieldSize", $NewValue); } 00310 function MaxLength($NewValue = DB_NOVALUE) 00311 { return $this->UpdateIntValue("MaxLength", $NewValue); } 00312 function ParagraphRows($NewValue = DB_NOVALUE) 00313 { return $this->UpdateIntValue("ParagraphRows", $NewValue); } 00314 function ParagraphCols($NewValue = DB_NOVALUE) 00315 { return $this->UpdateIntValue("ParagraphCols", $NewValue); } 00316 function MinValue($NewValue = DB_NOVALUE) 00317 { return $this->UpdateFloatValue("MinValue", $NewValue); } 00318 function MaxValue($NewValue = DB_NOVALUE) 00319 { return $this->UpdateFloatValue("MaxValue", $NewValue); } 00320 function FlagOnLabel($NewValue = DB_NOVALUE) 00321 { return $this->UpdateValue("FlagOnLabel", $NewValue); } 00322 function FlagOffLabel($NewValue = DB_NOVALUE) 00323 { return $this->UpdateValue("FlagOffLabel", $NewValue); } 00324 function DateFormat($NewValue = DB_NOVALUE) 00325 { return $this->UpdateValue("DateFormat", $NewValue); } 00326 function SearchWeight($NewValue = DB_NOVALUE) 00327 { return $this->UpdateIntValue("SearchWeight", $NewValue); } 00328 function RecommenderWeight($NewValue = DB_NOVALUE) 00329 { return $this->UpdateIntValue("RecommenderWeight", $NewValue); } 00330 function MaxHeight($NewValue = DB_NOVALUE) 00331 { return $this->UpdateIntValue("MaxHeight", $NewValue); } 00332 function MaxWidth($NewValue = DB_NOVALUE) 00333 { return $this->UpdateIntValue("MaxWidth", $NewValue); } 00334 function MaxPreviewHeight($NewValue = DB_NOVALUE) 00335 { return $this->UpdateIntValue("MaxPreviewHeight", $NewValue); } 00336 function MaxPreviewWidth($NewValue = DB_NOVALUE) 00337 { return $this->UpdateIntValue("MaxPreviewWidth", $NewValue); } 00338 function MaxThumbnailHeight($NewValue = DB_NOVALUE) 00339 { return $this->UpdateIntValue("MaxThumbnailHeight", $NewValue); } 00340 function MaxThumbnailWidth($NewValue = DB_NOVALUE) 00341 { return $this->UpdateIntValue("MaxThumbnailWidth", $NewValue); } 00342 function DefaultAltText($NewValue = DB_NOVALUE) 00343 { return $this->UpdateValue("DefaultAltText", $NewValue); } 00344 function UsesQualifiers($NewValue = DB_NOVALUE) 00345 { return $this->UpdateBoolValue("UsesQualifiers", $NewValue); } 00346 function ShowQualifiers($NewValue = DB_NOVALUE) 00347 { return $this->UpdateBoolValue("ShowQualifiers", $NewValue); } 00348 function DefaultQualifier($NewValue = DB_NOVALUE) 00349 { return $this->UpdateValue("DefaultQualifier", $NewValue); } 00350 function AllowHTML($NewValue = DB_NOVALUE) 00351 { return $this->UpdateBoolValue("AllowHTML", $NewValue); } 00352 function UseForOaiSets($NewValue = DB_NOVALUE) 00353 { return $this->UpdateBoolValue("UseForOaiSets", $NewValue); } 00354 function ViewingPrivilege($NewValue = DB_NOVALUE) 00355 { return $this->UpdateConstValue("ViewingPrivilege", $NewValue); } 00356 function AuthoringPrivilege($NewValue = DB_NOVALUE) 00357 { return $this->UpdateConstValue("AuthoringPrivilege", $NewValue); } 00358 function EditingPrivilege($NewValue = DB_NOVALUE) 00359 { return $this->UpdateConstValue("EditingPrivilege", $NewValue); } 00360 function ImagePreviewPrivilege($NewValue = DB_NOVALUE) 00361 { return $this->UpdateConstValue("ImagePreviewPrivilege", $NewValue); } 00362 function TreeBrowsingPrivilege($NewValue = DB_NOVALUE) 00363 { return $this->UpdateConstValue("TreeBrowsingPrivilege", $NewValue); } 00364 function EnableOnOwnerReturn($NewValue = DB_NOVALUE) 00365 { return $this->UpdateBoolValue("EnableOnOwnerReturn", $NewValue); } 00366 00367 function PointPrecision($NewValue = DB_NOVALUE) 00368 { 00369 if ($NewValue !== DB_NOVALUE && $this->Id() >= 0) 00370 { 00371 $OldValue = $this->UpdateValue("PointPrecision", DB_NOVALUE); 00372 00373 if ($NewValue != $OldValue) 00374 { 00375 $Decimals = $this->UpdateValue("PointDecimalDigits", DB_NOVALUE); 00376 00377 $TotalDigits = $NewValue + $Decimals; 00378 00379 00380 $this->DB->Query("ALTER TABLE Resources MODIFY COLUMN " 00381 ."`".$this->DBFields["DBFieldName"]."X` " 00382 ."DECIMAL(".$TotalDigits.",".$Decimals.")"); 00383 $this->DB->Query("ALTER TABLE Resources MODIFY COLUMN " 00384 ."`".$this->DBFields["DBFieldName"]."Y` " 00385 ."DECIMAL(".$TotalDigits.",".$Decimals.")"); 00386 } 00387 } 00388 00389 return $this->UpdateValue("PointPrecision", $NewValue); 00390 } 00391 00392 function PointDecimalDigits($NewValue = DB_NOVALUE) 00393 { 00394 if ($NewValue !== DB_NOVALUE && $this->Id() >= 0) 00395 { 00396 $OldValue = $this->UpdateValue("PointDecimalDigits", DB_NOVALUE); 00397 00398 if ($NewValue != $OldValue) 00399 { 00400 $Precision = $this->UpdateValue("PointPrecision", DB_NOVALUE); 00401 00402 $TotalDigits = $NewValue + $Precision; 00403 00404 $this->DB->Query("ALTER TABLE Resources MODIFY COLUMN " 00405 ."`".$this->DBFields["DBFieldName"]."X` " 00406 ."DECIMAL(".$TotalDigits.",".$NewValue.")"); 00407 $this->DB->Query("ALTER TABLE Resources MODIFY COLUMN " 00408 ."`".$this->DBFields["DBFieldName"]."Y` " 00409 ."DECIMAL(".$TotalDigits.",".$NewValue.")"); 00410 } 00411 } 00412 00413 return $this->UpdateValue("PointDecimalDigits", $NewValue); 00414 } 00415 00416 function DefaultValue($NewValue = DB_NOVALUE) 00417 { 00418 if ($this->Type() == MetadataSchema::MDFTYPE_POINT) 00419 { 00420 if ($NewValue !== DB_NOVALUE && 00421 isset($NewValue["X"]) && isset($NewValue["Y"])) 00422 { 00423 $NewValue = $NewValue["X"].",".$NewValue["Y"]; 00424 } 00425 00426 $tmp = explode(",", $this->UpdateValue("DefaultValue", $NewValue)); 00427 00428 if (count($tmp)==2) 00429 { 00430 $rc = array("X" => $tmp[0], "Y" => $tmp[1]); 00431 } 00432 else 00433 { 00434 $rc = array("X" => NULL, "Y" => NULL); 00435 } 00436 } 00437 else 00438 { 00439 $rc = $this->UpdateValue("DefaultValue", $NewValue); 00440 } 00441 return $rc; 00442 } 00443 00449 function UpdateMethod($NewValue = DB_NOVALUE) 00450 { 00451 return $this->UpdateValue("UpdateMethod", $NewValue); 00452 } 00453 00454 # get possible values (only meaningful for Trees, Controlled Names, Options, Flags) 00455 # (index for returned array is IDs for values) 00456 function GetPossibleValues($MaxNumberOfValues = NULL, $Offset=0) 00457 { 00458 # retrieve values based on field type 00459 switch ($this->Type()) 00460 { 00461 case MetadataSchema::MDFTYPE_TREE: 00462 $QueryString = "SELECT ClassificationId, ClassificationName" 00463 ." FROM Classifications WHERE FieldId = ".$this->Id() 00464 ." ORDER BY ClassificationName"; 00465 if ($MaxNumberOfValues) 00466 { 00467 $QueryString .= " LIMIT ".intval($MaxNumberOfValues)." OFFSET " 00468 .intval($Offset); 00469 } 00470 $this->DB->Query($QueryString); 00471 $PossibleValues = $this->DB->FetchColumn( 00472 "ClassificationName", "ClassificationId"); 00473 break; 00474 00475 case MetadataSchema::MDFTYPE_CONTROLLEDNAME: 00476 case MetadataSchema::MDFTYPE_OPTION: 00477 $QueryString = "SELECT ControlledNameId, ControlledName" 00478 ." FROM ControlledNames WHERE FieldId = ".$this->Id() 00479 ." ORDER BY ControlledName"; 00480 if ($MaxNumberOfValues) 00481 { 00482 $QueryString .= " LIMIT ".intval($MaxNumberOfValues)." OFFSET " 00483 .intval($Offset); 00484 } 00485 $this->DB->Query($QueryString); 00486 $PossibleValues = $this->DB->FetchColumn( 00487 "ControlledName", "ControlledNameId"); 00488 break; 00489 00490 case MetadataSchema::MDFTYPE_FLAG: 00491 $PossibleValues[0] = $this->FlagOffLabel(); 00492 $PossibleValues[1] = $this->FlagOnLabel(); 00493 break; 00494 00495 default: 00496 # for everything else return an empty array 00497 $PossibleValues = array(); 00498 break; 00499 } 00500 00501 # return array of possible values to caller 00502 return $PossibleValues; 00503 } 00504 00505 # get count of possible values (only meaningful for Trees, Controlled Names, Options) 00506 function GetCountOfPossibleValues() 00507 { 00508 # retrieve values based on field type 00509 switch ($this->Type()) 00510 { 00511 case MetadataSchema::MDFTYPE_TREE: 00512 $Count = $this->DB->Query("SELECT count(*) AS ValueCount" 00513 ." FROM Classifications WHERE FieldId = ".$this->Id(), 00514 "ValueCount"); 00515 break; 00516 00517 case MetadataSchema::MDFTYPE_CONTROLLEDNAME: 00518 case MetadataSchema::MDFTYPE_OPTION: 00519 $Count = $this->DB->Query("SELECT count(*) AS ValueCount" 00520 ." FROM ControlledNames WHERE FieldId = ".$this->Id(), 00521 "ValueCount"); 00522 break; 00523 00524 case MetadataSchema::MDFTYPE_FLAG: 00525 $Count = 2; 00526 break; 00527 00528 default: 00529 # for everything else return an empty array 00530 $Count = 0; 00531 break; 00532 } 00533 00534 # return count of possible values to caller 00535 return $Count; 00536 } 00537 00538 # get ID for specified value (only meaningful for Trees / Controlled Names / Options) 00539 # (returns NULL if value not found) 00540 function GetIdForValue($Value) 00541 { 00542 # retrieve ID based on field type 00543 switch ($this->Type()) 00544 { 00545 case MetadataSchema::MDFTYPE_TREE: 00546 $Id = $this->DB->Query("SELECT ClassificationId FROM Classifications" 00547 ." WHERE ClassificationName = '".addslashes($Value)."'" 00548 ." AND FieldId = ".$this->Id(), 00549 "ClassificationId"); 00550 break; 00551 00552 case MetadataSchema::MDFTYPE_CONTROLLEDNAME: 00553 case MetadataSchema::MDFTYPE_OPTION: 00554 $Id = $this->DB->Query("SELECT ControlledNameId FROM ControlledNames" 00555 ." WHERE ControlledName = '".addslashes($Value)."'" 00556 ." AND FieldId = ".$this->Id(), 00557 "ControlledNameId"); 00558 break; 00559 00560 default: 00561 # for everything else return NULL 00562 $Id = NULL; 00563 break; 00564 } 00565 00566 # return ID for value to caller 00567 return $Id; 00568 } 00569 00570 # get value for specified ID (only meaningful for Trees / Controlled Names / Options) 00571 # (returns NULL if ID not found) 00572 function GetValueForId($Id) 00573 { 00574 # retrieve ID based on field type 00575 switch ($this->Type()) 00576 { 00577 case MetadataSchema::MDFTYPE_TREE: 00578 $Value = $this->DB->Query("SELECT ClassificationName FROM Classifications" 00579 ." WHERE ClassificationId = '".intval($Id)."'" 00580 ." AND FieldId = ".$this->Id(), 00581 "ClassificationName"); 00582 break; 00583 00584 case MetadataSchema::MDFTYPE_CONTROLLEDNAME: 00585 case MetadataSchema::MDFTYPE_OPTION: 00586 $Value = $this->DB->Query("SELECT ControlledName FROM ControlledNames" 00587 ." WHERE ControlledNameId = '".intval($Id)."'" 00588 ." AND FieldId = ".$this->Id(), 00589 "ControlledName"); 00590 break; 00591 00592 default: 00593 # for everything else return NULL 00594 $Value = NULL; 00595 break; 00596 } 00597 00598 # return ID for value to caller 00599 return $Value; 00600 } 00601 00602 00603 00604 # get/set whether field uses item-level qualifiers 00605 function HasItemLevelQualifiers($NewValue = DB_NOVALUE) 00606 { 00607 # if value provided different from present value 00608 if (($NewValue != DB_NOVALUE) 00609 && ($NewValue != $this->DBFields["HasItemLevelQualifiers"])) 00610 { 00611 # check if qualifier column currently exists 00612 $QualColName = $this->DBFieldName()."Qualifier"; 00613 $QualColExists = $this->DB->FieldExists("Resources", $QualColName); 00614 00615 # if new value indicates qualifiers should now be used 00616 if ($NewValue == TRUE) 00617 { 00618 # if qualifier column does not exist in DB for this field 00619 if ($QualColExists == FALSE) 00620 { 00621 # add qualifier column in DB for this field 00622 $this->DB->Query("ALTER TABLE Resources ADD COLUMN `" 00623 .$QualColName."` INT"); 00624 } 00625 } 00626 else 00627 { 00628 # if qualifier column exists in DB for this field 00629 if ($QualColExists == TRUE) 00630 { 00631 # remove qualifier column from DB for this field 00632 $this->DB->Query("ALTER TABLE Resources DROP COLUMN `" 00633 .$QualColName."`"); 00634 } 00635 } 00636 } 00637 00638 return $this->UpdateValue("HasItemLevelQualifiers", $NewValue); 00639 } 00640 00641 # get list of qualifiers associated with field 00642 function AssociatedQualifierList() 00643 { 00644 # start with empty list 00645 $List = array(); 00646 00647 # for each associated qualifier 00648 $this->DB->Query("SELECT QualifierId FROM FieldQualifierInts" 00649 ." WHERE MetadataFieldId = ".$this->DBFields["FieldId"]); 00650 while ($Record = $this->DB->FetchRow()) 00651 { 00652 # load qualifier object 00653 $Qual = new Qualifier($Record["QualifierId"]); 00654 00655 # add qualifier ID and name to list 00656 $List[$Qual->Id()] = $Qual->Name(); 00657 } 00658 00659 # return list to caller 00660 return $List; 00661 } 00662 00663 # get list of qualifiers not associated with field 00664 function UnassociatedQualifierList() 00665 { 00666 # grab list of associated qualifiers 00667 $AssociatedQualifiers = $this->AssociatedQualifierList(); 00668 00669 # get list of all qualifiers 00670 $QFactory = new QualifierFactory(); 00671 $AllQualifiers = $QFactory->QualifierList(); 00672 00673 # return list of unassociated qualifiers 00674 return array_diff($AllQualifiers, $AssociatedQualifiers); 00675 } 00676 00677 # add qualifier association 00678 function AssociateWithQualifier($QualifierIdOrObject) 00679 { 00680 # if qualifier object passed in 00681 if (is_object($QualifierIdOrObject)) 00682 { 00683 # grab qualifier ID from object 00684 $QualifierIdOrObject = $QualifierIdOrObject->Id(); 00685 } 00686 00687 # if not already associated 00688 $RecordCount = $this->DB->Query( 00689 "SELECT COUNT(*) AS RecordCount FROM FieldQualifierInts" 00690 ." WHERE QualifierId = ".$QualifierIdOrObject 00691 ." AND MetadataFieldId = ".$this->Id(), "RecordCount"); 00692 if ($RecordCount < 1) 00693 { 00694 # associate field with qualifier 00695 $this->DB->Query("INSERT INTO FieldQualifierInts SET" 00696 ." QualifierId = ".$QualifierIdOrObject."," 00697 ." MetadataFieldId = ".$this->Id()); 00698 } 00699 } 00700 00701 # delete qualifier association 00702 function UnassociateWithQualifier($QualifierIdOrObject) 00703 { 00704 # if qualifier object passed in 00705 if (is_object($QualifierIdOrObject)) 00706 { 00707 # grab qualifier ID from object 00708 $QualifierIdOrObject = $QualifierIdOrObject->Id(); 00709 } 00710 00711 # delete intersection record from database 00712 $this->DB->Query("DELETE FROM FieldQualifierInts WHERE QualifierId = " 00713 .$QualifierIdOrObject." AND MetadataFieldId = ". 00714 $this->Id()); 00715 } 00716 00717 # retrieve item factory object for this field 00718 function GetFactory() 00719 { 00720 switch ($this->Type()) 00721 { 00722 case MetadataSchema::MDFTYPE_TREE: 00723 $Factory = new ClassificationFactory($this->Id()); 00724 break; 00725 00726 case MetadataSchema::MDFTYPE_CONTROLLEDNAME: 00727 case MetadataSchema::MDFTYPE_OPTION: 00728 $Factory = new ControlledNameFactory($this->Id()); 00729 break; 00730 00731 default: 00732 $Factory = NULL; 00733 break; 00734 } 00735 00736 return $Factory; 00737 } 00738 00739 00740 # ---- PRIVATE INTERFACE ------------------------------------------------- 00741 00742 private $DB; 00743 private $DBFields; 00744 private $ErrorStatus; 00745 00746 # field type DB/PHP enum translations 00747 public static $FieldTypeDBEnums = array( 00748 MetadataSchema::MDFTYPE_TEXT => "Text", 00749 MetadataSchema::MDFTYPE_PARAGRAPH => "Paragraph", 00750 MetadataSchema::MDFTYPE_NUMBER => "Number", 00751 MetadataSchema::MDFTYPE_DATE => "Date", 00752 MetadataSchema::MDFTYPE_TIMESTAMP => "TimeStamp", 00753 MetadataSchema::MDFTYPE_FLAG => "Flag", 00754 MetadataSchema::MDFTYPE_TREE => "Tree", 00755 MetadataSchema::MDFTYPE_CONTROLLEDNAME => "ControlledName", 00756 MetadataSchema::MDFTYPE_OPTION => "Option", 00757 MetadataSchema::MDFTYPE_USER => "User", 00758 MetadataSchema::MDFTYPE_IMAGE => "Still Image", 00759 MetadataSchema::MDFTYPE_FILE => "File", 00760 MetadataSchema::MDFTYPE_URL => "Url", 00761 MetadataSchema::MDFTYPE_POINT => "Point" 00762 ); 00763 public static $FieldTypeDBAllowedEnums = array( 00764 MetadataSchema::MDFTYPE_TEXT => "Text", 00765 MetadataSchema::MDFTYPE_PARAGRAPH => "Paragraph", 00766 MetadataSchema::MDFTYPE_NUMBER => "Number", 00767 MetadataSchema::MDFTYPE_DATE => "Date", 00768 MetadataSchema::MDFTYPE_TIMESTAMP => "TimeStamp", 00769 MetadataSchema::MDFTYPE_FLAG => "Flag", 00770 MetadataSchema::MDFTYPE_TREE => "Tree", 00771 MetadataSchema::MDFTYPE_CONTROLLEDNAME => "ControlledName", 00772 MetadataSchema::MDFTYPE_OPTION => "Option", 00773 MetadataSchema::MDFTYPE_USER => "User", 00774 MetadataSchema::MDFTYPE_IMAGE => "Still Image", 00775 MetadataSchema::MDFTYPE_FILE => "File", 00776 MetadataSchema::MDFTYPE_URL => "Url", 00777 MetadataSchema::MDFTYPE_POINT => "Point" 00778 ); 00779 public static $FieldTypePHPEnums = array( 00780 "Text" => MetadataSchema::MDFTYPE_TEXT, 00781 "Paragraph" => MetadataSchema::MDFTYPE_PARAGRAPH, 00782 "Number" => MetadataSchema::MDFTYPE_NUMBER, 00783 "Date" => MetadataSchema::MDFTYPE_DATE, 00784 "TimeStamp" => MetadataSchema::MDFTYPE_TIMESTAMP, 00785 "Flag" => MetadataSchema::MDFTYPE_FLAG, 00786 "Tree" => MetadataSchema::MDFTYPE_TREE, 00787 "ControlledName" => MetadataSchema::MDFTYPE_CONTROLLEDNAME, 00788 "Option" => MetadataSchema::MDFTYPE_OPTION, 00789 "User" => MetadataSchema::MDFTYPE_USER, 00790 "Still Image" => MetadataSchema::MDFTYPE_IMAGE, 00791 "File" => MetadataSchema::MDFTYPE_FILE, 00792 "Url" => MetadataSchema::MDFTYPE_URL, 00793 "Point" => MetadataSchema::MDFTYPE_POINT 00794 ); 00795 00796 public static $UpdateTypes = array( 00797 MetadataField::UPDATEMETHOD_NOAUTOUPDATE => "Do not update automatically", 00798 MetadataField::UPDATEMETHOD_ONRECORDCREATE => "Update on record creation", 00799 MetadataField::UPDATEMETHOD_BUTTON => "Provide an update button", 00800 MetadataField::UPDATEMETHOD_ONRECORDEDIT => "Update when record is edited", 00801 MetadataField::UPDATEMETHOD_ONRECORDCHANGE => "Update when record is changed" 00802 ); 00803 00804 00805 # object constructor (only for use by MetadataSchema object) 00806 function MetadataField($FieldId, $FieldName = NULL, $FieldType = NULL, 00807 $Optional = TRUE, $DefaultValue = NULL) 00808 { 00809 # assume everything will be okay 00810 $this->ErrorStatus = MetadataSchema::MDFSTAT_OK; 00811 00812 # grab our own database handle 00813 $this->DB = new Database(); 00814 $DB = $this->DB; 00815 00816 # if field ID supplied 00817 if ($FieldId != NULL) 00818 { 00819 # look up field in database 00820 $DB->Query("SELECT * FROM MetadataFields WHERE FieldId = ".intval($FieldId)); 00821 $Record = $DB->FetchRow(); 00822 } 00823 00824 # if no field ID supplied or if record not found in database 00825 if (($FieldId == NULL) || ($Record == NULL)) 00826 { 00827 # error out if valid field type not supplied 00828 if (empty(MetadataField::$FieldTypeDBEnums[$FieldType])) 00829 { 00830 $this->ErrorStatus = MetadataSchema::MDFSTAT_FIELDDOESNOTEXIST; 00831 return; 00832 } 00833 00834 # if field name supplied 00835 $FieldName = trim($FieldName); 00836 if (strlen($FieldName) > 0) 00837 { 00838 # error out if field name is duplicate 00839 $DuplicateCount = $DB->Query(" 00840 SELECT COUNT(*) AS RecordCount FROM MetadataFields 00841 WHERE FieldName = '".addslashes($FieldName)."' 00842 OR Label = '".addslashes($FieldName)."'", 00843 "RecordCount"); 00844 00845 if ($DuplicateCount > 0) 00846 { 00847 $this->ErrorStatus = MetadataSchema::MDFSTAT_DUPLICATENAME; 00848 return; 00849 } 00850 } 00851 00852 # grab current user ID 00853 global $G_User; 00854 $UserId = $G_User->Get("UserId"); 00855 00856 # lock DB tables and get next temporary field ID 00857 $Schema = new MetadataSchema(); 00858 $DB->Query("LOCK TABLES MetadataFields WRITE"); 00859 $FieldId = $Schema->GetNextTempItemId(); 00860 00861 # add field to MDF table in database 00862 $DB->Query("INSERT INTO MetadataFields " 00863 ."(FieldId, FieldName, FieldType, Optional," 00864 ." DefaultValue, LastModifiedById) VALUES " 00865 ."(".intval($FieldId).", " 00866 ."'".addslashes($FieldName)."', " 00867 ."'".MetadataField::$FieldTypeDBEnums[$FieldType]."', " 00868 .($Optional ? 1 : 0).", " 00869 ."'".addslashes($DefaultValue)."'," 00870 ."'".$UserId."')"); 00871 00872 # release DB tables 00873 $DB->Query("UNLOCK TABLES"); 00874 00875 # re-read record from database 00876 $DB->Query("SELECT * FROM MetadataFields WHERE FieldId = " 00877 .intval($FieldId)); 00878 $this->DBFields = $DB->FetchRow(); 00879 $this->DBFields["DBFieldName"] = 00880 $this->NormalizeFieldNameForDB($this->DBFields["FieldName"]); 00881 00882 # set field order values for new field 00883 $FieldCount = $DB->Query("SELECT COUNT(*) AS FieldCount" 00884 ." FROM MetadataFields", "FieldCount"); 00885 $this->OrderPosition(MetadataSchema::MDFORDER_DISPLAY, ($FieldCount + 1)); 00886 $this->OrderPosition(MetadataSchema::MDFORDER_EDITING, ($FieldCount + 1)); 00887 00888 # set other field defaults 00889 $this->SearchWeight(($FieldType & (MetadataSchema::MDFTYPE_OPTION 00890 |MetadataSchema::MDFTYPE_CONTROLLEDNAME)) ? 3 : 1); 00891 } 00892 else 00893 { 00894 # save values locally 00895 $this->DBFields = $Record; 00896 $this->DBFields["DBFieldName"] = 00897 $this->NormalizeFieldNameForDB($Record["FieldName"]); 00898 } 00899 } 00900 00901 # remove field from database (only for use by MetadataSchema object) 00902 function Drop() 00903 { 00904 # clear other database entries as appropriate for field type 00905 $DB = $this->DB; 00906 $DBFieldName = $this->DBFields["DBFieldName"]; 00907 switch (MetadataField::$FieldTypePHPEnums[$this->DBFields["FieldType"]]) 00908 { 00909 case MetadataSchema::MDFTYPE_TEXT: 00910 case MetadataSchema::MDFTYPE_PARAGRAPH: 00911 case MetadataSchema::MDFTYPE_NUMBER: 00912 case MetadataSchema::MDFTYPE_USER: 00913 case MetadataSchema::MDFTYPE_IMAGE: 00914 case MetadataSchema::MDFTYPE_TIMESTAMP: 00915 case MetadataSchema::MDFTYPE_URL: 00916 # remove field from resources table 00917 if ($DB->FieldExists("Resources", $DBFieldName)) 00918 { 00919 $DB->Query("ALTER TABLE Resources DROP COLUMN `".$DBFieldName."`"); 00920 } 00921 break; 00922 00923 case MetadataSchema::MDFTYPE_POINT: 00924 if ($DB->FieldExists("Resources", $DBFieldName."X")) 00925 { 00926 $DB->Query("ALTER TABLE Resources DROP COLUMN `".$DBFieldName."X`"); 00927 $DB->Query("ALTER TABLE Resources DROP COLUMN `".$DBFieldName."Y`"); 00928 } 00929 break; 00930 00931 case MetadataSchema::MDFTYPE_FLAG: 00932 # remove field from resources table 00933 if ($DB->FieldExists("Resources", $DBFieldName)) 00934 { 00935 $DB->Query("ALTER TABLE Resources DROP COLUMN `".$DBFieldName."`"); 00936 } 00937 break; 00938 00939 case MetadataSchema::MDFTYPE_DATE: 00940 # remove fields from resources table 00941 if ($DB->FieldExists("Resources", $DBFieldName."Begin")) 00942 { 00943 $DB->Query("ALTER TABLE Resources DROP COLUMN `".$DBFieldName."Begin`"); 00944 $DB->Query("ALTER TABLE Resources DROP COLUMN `".$DBFieldName."End`"); 00945 $DB->Query("ALTER TABLE Resources DROP COLUMN `".$DBFieldName."Precision`"); 00946 } 00947 break; 00948 00949 case MetadataSchema::MDFTYPE_TREE: 00950 $DB->Query("SELECT ClassificationId FROM Classifications " 00951 ."WHERE FieldId = ".$this->Id()); 00952 $TempDB = new SPTDatabase(); 00953 while ($ClassificationId = $DB->FetchField("ClassificationId")) 00954 { 00955 # remove any resource / name intersections 00956 $TempDB->Query("DELETE FROM ResourceClassInts WHERE " 00957 ."ClassificationId = ".$ClassificationId); 00958 00959 # remove controlled name 00960 $TempDB->Query("DELETE FROM Classifications WHERE " 00961 ."ClassificationId = ".$ClassificationId); 00962 } 00963 break; 00964 00965 case MetadataSchema::MDFTYPE_CONTROLLEDNAME: 00966 case MetadataSchema::MDFTYPE_OPTION: 00967 $DB->Query("SELECT ControlledNameId FROM ControlledNames " 00968 ."WHERE FieldId = ".$this->Id()); 00969 $TempDB = new SPTDatabase(); 00970 while ($ControlledNameId = $DB->FetchField("ControlledNameId")) 00971 { 00972 # remove any resource / name intersections 00973 $TempDB->Query("DELETE FROM ResourceNameInts WHERE " 00974 ."ControlledNameId = ".$ControlledNameId); 00975 00976 # remove any variant names 00977 $TempDB->Query("DELETE FROM VariantNames WHERE " 00978 ."ControlledNameId = ".$ControlledNameId); 00979 00980 # remove controlled name 00981 $TempDB->Query("DELETE FROM ControlledNames WHERE " 00982 ."ControlledNameId = ".$ControlledNameId); 00983 } 00984 break; 00985 00986 case MetadataSchema::MDFTYPE_FILE: 00987 # for each file associated with this field 00988 $DB->Query("SELECT FileId FROM Files WHERE FieldId = '".$this->Id()."'"); 00989 while ($FileId = $DB->FetchRow()) 00990 { 00991 # delete file 00992 $File = new File(intval($FileId)); 00993 $File->Delete(); 00994 } 00995 break; 00996 } 00997 00998 # remove field from database 00999 $DB->Query("DELETE FROM MetadataFields " 01000 ."WHERE FieldId = '".$this->DBFields["FieldId"]."'"); 01001 01002 # remove any qualifier associations 01003 $DB->Query("DELETE FROM FieldQualifierInts WHERE MetadataFieldId = '" 01004 .$this->DBFields["FieldId"]."'"); 01005 } 01006 01007 # get/set field order positions (intended only for use by MetadataSchema object) 01008 function OrderPosition($OrderType, $NewValue = DB_NOVALUE) 01009 { 01010 switch ($OrderType) 01011 { 01012 case MetadataSchema::MDFORDER_DISPLAY: 01013 return $this->UpdateValue("DisplayOrderPosition", $NewValue); 01014 break; 01015 01016 case MetadataSchema::MDFORDER_EDITING: 01017 return $this->UpdateValue("EditingOrderPosition", $NewValue); 01018 break; 01019 01020 default: 01021 exit("invalid order type passed to MetadataField::OrderPosition"); 01022 break; 01023 } 01024 } 01025 01026 # modify any database fields 01027 private function ModifyField($NewName = NULL, $NewType = NULL) 01028 { 01029 # grab old DB field name 01030 $OldDBFieldName = $this->DBFields["DBFieldName"]; 01031 $OldFieldType = NULL; 01032 01033 # if new field name supplied 01034 if ($NewName != NULL) 01035 { 01036 # cache the old name for options and controllednames below 01037 $OldName = $this->DBFields["FieldName"]; 01038 01039 # store new name 01040 $this->UpdateValue("FieldName", $NewName); 01041 01042 # determine new DB field name 01043 $NewDBFieldName = $this->NormalizeFieldNameForDB($NewName); 01044 01045 # store new database field name 01046 $this->DBFields["DBFieldName"] = $NewDBFieldName; 01047 } 01048 else 01049 { 01050 # set new field name equal to old field name 01051 $NewDBFieldName = $OldDBFieldName; 01052 } 01053 01054 # if new type supplied 01055 if ($NewType != NULL) 01056 { 01057 # grab old field type 01058 $OldFieldType = MetadataField::$FieldTypePHPEnums[$this->DBFields["FieldType"]]; 01059 01060 # store new field type 01061 $this->UpdateValue("FieldType", MetadataField::$FieldTypeDBEnums[$NewType]); 01062 } 01063 01064 # if this is not a temporary field 01065 if ($this->Id() >= 0) 01066 { 01067 # modify field in DB as appropriate for field type 01068 $DB = $this->DB; 01069 $FieldType = MetadataField::$FieldTypePHPEnums[$this->DBFields["FieldType"]]; 01070 switch ($FieldType) 01071 { 01072 case MetadataSchema::MDFTYPE_TEXT: 01073 case MetadataSchema::MDFTYPE_PARAGRAPH: 01074 case MetadataSchema::MDFTYPE_URL: 01075 # alter field declaration in Resources table 01076 $DB->Query("ALTER TABLE Resources CHANGE COLUMN `" 01077 .$OldDBFieldName."` `" 01078 .$NewDBFieldName."` TEXT " 01079 .($this->DBFields["Optional"] ? "" : "NOT NULL")); 01080 break; 01081 01082 case MetadataSchema::MDFTYPE_NUMBER: 01083 case MetadataSchema::MDFTYPE_USER: 01084 # alter field declaration in Resources table 01085 $DB->Query("ALTER TABLE Resources CHANGE COLUMN `" 01086 .$OldDBFieldName."` `" 01087 .$NewDBFieldName."` INT " 01088 .($this->DBFields["Optional"] ? "" : "NOT NULL")); 01089 break; 01090 01091 case MetadataSchema::MDFTYPE_POINT: 01092 $Precision = $this->UpdateValue("PointPrecision", 01093 DB_NOVALUE); 01094 $Digits = $this->UpdateValue("PointDecimalDigits", 01095 DB_NOVALUE); 01096 $DB->Query("ALTER TABLE Resources CHANGE COLUMN " 01097 ."`".$OldDBFieldName."X` " 01098 ."`".$NewDBFieldName."X`". 01099 " DECIMAL(".$Precision.",".$Digits.")"); 01100 $DB->Query("ALTER TABLE Resources CHANGE COLUMN " 01101 ."`".$OldDBFieldName."Y` " 01102 ."`".$NewDBFieldName."Y`". 01103 " DECIMAL(".$Precision.",".$Digits.")"); 01104 break; 01105 01106 case MetadataSchema::MDFTYPE_FILE: 01107 # if DB field name has changed 01108 if ($NewDBFieldName != $OldDBFieldName) 01109 { 01110 # alter field declaration in Resources table 01111 $DB->Query("ALTER TABLE Resources CHANGE COLUMN `" 01112 .$OldDBFieldName."` `" 01113 .$NewDBFieldName."` TEXT"); 01114 } 01115 break; 01116 01117 case MetadataSchema::MDFTYPE_IMAGE: 01118 # if DB field name has changed 01119 if ($NewDBFieldName != $OldDBFieldName) 01120 { 01121 # alter field declaration in Resources table 01122 $DB->Query("ALTER TABLE Resources CHANGE COLUMN `" 01123 .$OldDBFieldName."` `" 01124 .$NewDBFieldName."` INT"); 01125 } 01126 break; 01127 01128 case MetadataSchema::MDFTYPE_FLAG: 01129 # alter field declaration in Resources table 01130 $DB->Query("ALTER TABLE Resources CHANGE COLUMN `" 01131 .$OldDBFieldName."` `" 01132 .$NewDBFieldName."` INT" 01133 ." DEFAULT ".intval($this->DefaultValue())); 01134 01135 # set any unset values to default 01136 $DB->Query("UPDATE Resources SET `".$NewDBFieldName 01137 ."` = ".intval($this->DefaultValue()) 01138 ." WHERE `".$NewDBFieldName."` IS NULL"); 01139 break; 01140 01141 case MetadataSchema::MDFTYPE_DATE: 01142 # if new type supplied and new type is different from old 01143 if (($NewType != NULL) && ($NewType != $OldFieldType)) 01144 { 01145 # if old type was time stamp 01146 if ($OldFieldType == MetadataSchema::MDFTYPE_TIMESTAMP) 01147 { 01148 # change time stamp field in resources table to begin date 01149 $DB->Query("ALTER TABLE Resources CHANGE COLUMN `" 01150 .$OldDBFieldName."` `" 01151 .$NewDBFieldName."Begin` DATE " 01152 .($this->DBFields["Optional"] ? "" : "NOT NULL")); 01153 01154 # add end date and precision fields 01155 $DB->Query("ALTER TABLE Resources ADD COLUMN `".$NewDBFieldName."End" 01156 ."` DATE"); 01157 $DB->Query("ALTER TABLE Resources ADD COLUMN `".$NewDBFieldName."Precision`" 01158 ." INT ".($Optional ? "" : "NOT NULL")); 01159 01160 # set precision to reflect time stamp content 01161 $DB->Query("UPDATE Resources SET `".$NewDBFieldName."Precision` = " 01162 .(DATEPRE_BEGINYEAR|DATEPRE_BEGINMONTH|DATEPRE_BEGINDAY)); 01163 } 01164 else 01165 { 01166 exit("<br>ERROR: Attempt to convert metadata field to date from type other than timestamp<br>\n"); 01167 } 01168 } 01169 else 01170 { 01171 # change name of fields 01172 $DB->Query("ALTER TABLE Resources CHANGE COLUMN `" 01173 .$OldDBFieldName."Begin` `" 01174 .$NewDBFieldName."Begin` DATE " 01175 .($this->DBFields["Optional"] ? "" : "NOT NULL")); 01176 $DB->Query("ALTER TABLE Resources CHANGE COLUMN `" 01177 .$OldDBFieldName."End` `" 01178 .$NewDBFieldName."End` DATE " 01179 .($this->DBFields["Optional"] ? "" : "NOT NULL")); 01180 $DB->Query("ALTER TABLE Resources CHANGE COLUMN `" 01181 .$OldDBFieldName."Precision` `" 01182 .$NewDBFieldName."Precision` INT " 01183 .($this->DBFields["Optional"] ? "" : "NOT NULL")); 01184 } 01185 break; 01186 01187 case MetadataSchema::MDFTYPE_TIMESTAMP: 01188 # if new type supplied and new type is different from old 01189 if (($NewType != NULL) && ($NewType != $OldFieldType)) 01190 { 01191 # if old type was date 01192 if ($OldFieldType == MetadataSchema::MDFTYPE_DATE) 01193 { 01194 # change begin date field in resource table to time stamp 01195 $DB->Query("ALTER TABLE Resources CHANGE COLUMN `" 01196 .$OldDBFieldName."Begin` `" 01197 .$NewDBFieldName."` DATETIME " 01198 .($this->DBFields["Optional"] ? "" : "NOT NULL")); 01199 01200 # drop end date and precision fields 01201 $DB->Query("ALTER TABLE Resources DROP COLUMN `" 01202 .$OldDBFieldName."End`"); 01203 $DB->Query("ALTER TABLE Resources DROP COLUMN `" 01204 .$OldDBFieldName."Precision`"); 01205 } 01206 else 01207 { 01208 exit("<br>ERROR: Attempt to convert metadata field to time stamp from type other than date<br>\n"); 01209 } 01210 } 01211 else 01212 { 01213 # change name of field 01214 $DB->Query("ALTER TABLE Resources CHANGE COLUMN `" 01215 .$OldDBFieldName."` `" 01216 .$NewDBFieldName."` DATETIME " 01217 .($this->DBFields["Optional"] ? "" : "NOT NULL")); 01218 } 01219 break; 01220 01221 case MetadataSchema::MDFTYPE_TREE: 01222 case MetadataSchema::MDFTYPE_CONTROLLEDNAME: 01223 case MetadataSchema::MDFTYPE_OPTION: 01224 break; 01225 } 01226 01227 # if qualifier DB field exists 01228 if ($DB->FieldExists("Resources", $OldDBFieldName."Qualifier")) 01229 { 01230 # rename qualifier DB field 01231 $DB->Query("ALTER TABLE Resources CHANGE COLUMN `" 01232 .$OldDBFieldName."Qualifier` `" 01233 .$NewDBFieldName."Qualifier` INT "); 01234 } 01235 } 01236 } 01237 01238 # convenience functions to supply parameters to Database->UpdateValue() 01239 private function UpdateValue($FieldName, $NewValue) 01240 { 01241 return $this->DB->UpdateValue("MetadataFields", $FieldName, $NewValue, 01242 "FieldId = ".intval($this->DBFields["FieldId"]), 01243 $this->DBFields); 01244 } 01245 private function UpdateIntValue($FieldName, $NewValue) 01246 { 01247 return $this->DB->UpdateIntValue("MetadataFields", $FieldName, $NewValue, 01248 "FieldId = ".intval($this->DBFields["FieldId"]), 01249 $this->DBFields); 01250 } 01251 private function UpdateFloatValue($FieldName, $NewValue) 01252 { 01253 return $this->DB->UpdateFloatValue("MetadataFields", $FieldName, $NewValue, 01254 "FieldId = ".intval($this->DBFields["FieldId"]), 01255 $this->DBFields); 01256 } 01257 private function UpdateBoolValue($FieldName, $NewValue) 01258 { 01259 $NewValue = $this->TranslateStringToConstants($NewValue); 01260 return $this->DB->UpdateIntValue("MetadataFields", $FieldName, $NewValue, 01261 "FieldId = ".intval($this->DBFields["FieldId"]), 01262 $this->DBFields); 01263 } 01264 private function UpdateConstValue($FieldName, $NewValue) 01265 { 01266 $NewValue = $this->TranslateStringToConstants($NewValue); 01267 return $this->DB->UpdateIntValue("MetadataFields", $FieldName, $NewValue, 01268 "FieldId = ".intval($this->DBFields["FieldId"]), 01269 $this->DBFields); 01270 } 01271 01272 # normalize field name for use as database field name 01273 private function NormalizeFieldNameForDB($Name) 01274 { 01275 return preg_replace("/[^a-z0-9]/i", "", $Name); 01276 } 01277 01278 # add any needed database fields and/or entries 01279 private function AddDatabaseFields() 01280 { 01281 # grab values for common use 01282 $DB = $this->DB; 01283 $FieldName = $this->Name(); 01284 $DBFieldName = $this->DBFieldName(); 01285 $Optional = $this->Optional(); 01286 $DefaultValue = $this->DefaultValue(); 01287 01288 # set up field(s) based on field type 01289 switch ($this->Type()) 01290 { 01291 case MetadataSchema::MDFTYPE_TEXT: 01292 case MetadataSchema::MDFTYPE_PARAGRAPH: 01293 case MetadataSchema::MDFTYPE_URL: 01294 # add field to resources table (if not already present) 01295 if (!$DB->FieldExists("Resources", $DBFieldName)) 01296 { 01297 $DB->Query("ALTER TABLE Resources ADD COLUMN `".$DBFieldName 01298 ."` TEXT ".($Optional ? "" : "NOT NULL")); 01299 } 01300 01301 # if default value supplied 01302 if ($DefaultValue != NULL) 01303 { 01304 # set all existing records to default value 01305 $DB->Query("UPDATE Resources SET `" 01306 .$DBFieldName."` = '".addslashes($DefaultValue)."'"); 01307 } 01308 break; 01309 01310 case MetadataSchema::MDFTYPE_NUMBER: 01311 # add field to resources table (if not already present) 01312 if (!$DB->FieldExists("Resources", $DBFieldName)) 01313 { 01314 $DB->Query("ALTER TABLE Resources ADD COLUMN `".$DBFieldName 01315 ."` INT ".($Optional ? "" : "NOT NULL")); 01316 } 01317 01318 # if default value supplied 01319 if ($DefaultValue != NULL) 01320 { 01321 # set all existing records to default value 01322 $DB->Query("UPDATE Resources SET `" 01323 .$DBFieldName."` = '".addslashes($DefaultValue)."'"); 01324 } 01325 break; 01326 01327 case MetadataSchema::MDFTYPE_POINT: 01328 if (!$DB->FieldExists("Resources", $DBFieldName."X")) 01329 { 01330 $Precision = $this->UpdateValue("PointPrecision", 01331 DB_NOVALUE); 01332 $Digits = $this->UpdateValue("PointDecimalDigits", 01333 DB_NOVALUE); 01334 01335 $DB->Query("ALTER TABLE Resources ADD COLUMN `" 01336 .$DBFieldName."X`". 01337 " DECIMAL(".$Precision.",".$Digits.")"); 01338 $DB->Query("ALTER TABLE Resources ADD COLUMN `" 01339 .$DBFieldName."Y`". 01340 " DECIMAL(".$Precision.",".$Digits.")"); 01341 } 01342 01343 break; 01344 case MetadataSchema::MDFTYPE_FLAG: 01345 # if field is not already present in database 01346 if (!$DB->FieldExists("Resources", $DBFieldName)) 01347 { 01348 # add field to resources table 01349 $DB->Query("ALTER TABLE Resources ADD COLUMN `".$DBFieldName 01350 ."` INT DEFAULT ".intval($DefaultValue)); 01351 01352 # set all existing records to default value 01353 $DB->Query("UPDATE Resources SET `" 01354 .$DBFieldName."` = ".intval($DefaultValue)); 01355 } 01356 break; 01357 01358 case MetadataSchema::MDFTYPE_USER: 01359 # add field to resources table (if not already present) 01360 if (!$DB->FieldExists("Resources", $DBFieldName)) 01361 { 01362 $DB->Query("ALTER TABLE Resources ADD COLUMN `".$DBFieldName 01363 ."` INT ".($Optional ? "" : "NOT NULL")); 01364 } 01365 break; 01366 01367 case MetadataSchema::MDFTYPE_FILE: 01368 # add fields to resources table (if not already present) 01369 if (!$DB->FieldExists("Resources", $DBFieldName)) 01370 { 01371 $DB->Query("ALTER TABLE Resources ADD COLUMN `" 01372 .$DBFieldName."` TEXT"); 01373 } 01374 break; 01375 01376 case MetadataSchema::MDFTYPE_IMAGE: 01377 # add fields to resources table (if not already present) 01378 if (!$DB->FieldExists("Resources", $DBFieldName)) 01379 { 01380 $DB->Query("ALTER TABLE Resources ADD COLUMN `" 01381 .$DBFieldName."` INT"); 01382 } 01383 break; 01384 01385 case MetadataSchema::MDFTYPE_DATE: 01386 # add fields to resources table (if not already present) 01387 if (!$DB->FieldExists("Resources", $DBFieldName."Begin")) 01388 { 01389 $DB->Query("ALTER TABLE Resources ADD COLUMN `".$DBFieldName."Begin`" 01390 ." DATE ".($Optional ? "" : "NOT NULL")); 01391 } 01392 if (!$DB->FieldExists("Resources", $DBFieldName."End")) 01393 { 01394 $DB->Query("ALTER TABLE Resources ADD COLUMN `".$DBFieldName."End`" 01395 ." DATE"); 01396 } 01397 if (!$DB->FieldExists("Resources", $DBFieldName."Precision")) 01398 { 01399 $DB->Query("ALTER TABLE Resources ADD COLUMN `".$DBFieldName."Precision`" 01400 ." INT ".($Optional ? "" : "NOT NULL")); 01401 } 01402 break; 01403 01404 case MetadataSchema::MDFTYPE_TIMESTAMP: 01405 # add fields to resources table (if not already present) 01406 if (!$DB->FieldExists("Resources", $DBFieldName)) 01407 { 01408 $DB->Query("ALTER TABLE Resources ADD COLUMN `".$DBFieldName 01409 ."` DATETIME ".($Optional ? "" : "NOT NULL")); 01410 } 01411 break; 01412 01413 case MetadataSchema::MDFTYPE_TREE: 01414 case MetadataSchema::MDFTYPE_CONTROLLEDNAME: 01415 case MetadataSchema::MDFTYPE_OPTION: 01416 break; 01417 01418 default: 01419 exit("<br>ERROR: Attempt to add database fields for illegal metadata field type<br>\n"); 01420 break; 01421 } 01422 } 01423 01431 private function TranslateStringToConstants($CString, $ClassName = NULL) 01432 { 01433 # if not a string return value unchanged to caller 01434 if (!is_string($CString) || ($CString === DB_NOVALUE)) 01435 { 01436 $ReturnValue = $CString; 01437 } 01438 # handle booleans as a special case 01439 elseif (strtoupper(trim($CString)) == "TRUE") 01440 { 01441 $ReturnValue = TRUE; 01442 } 01443 elseif (strtoupper(trim($CString)) == "FALSE") 01444 { 01445 $ReturnValue = FALSE; 01446 } 01447 else 01448 { 01449 # assume no values will be found 01450 $ReturnValue = NULL; 01451 01452 # split apart any ORed-together values 01453 $Values = explode("|", $CString); 01454 01455 # for each value found 01456 foreach ($Values as $Value) 01457 { 01458 # trim off any extraneous whitespace 01459 $Value = trim($Value); 01460 01461 # add class name prefix to constant name if requested 01462 if ($ClassName) { $Value = $ClassName."::".$Value; } 01463 01464 # if value corresponds to a constant 01465 if (defined($Value)) 01466 { 01467 # add constant to return value 01468 $ReturnValue = ($ReturnValue === NULL) 01469 ? constant($Value) 01470 : ($ReturnValue | constant($Value)); 01471 } 01472 } 01473 01474 # if no corresponding constants were found 01475 if ($ReturnValue === NULL) 01476 { 01477 # return original value to caller 01478 $ReturnValue = $CString; 01479 } 01480 } 01481 01482 # return result to caller 01483 return $ReturnValue; 01484 } 01485 } 01486