Search:

CWIS Developers Documentation

  • Main Page
  • Classes
  • Files
  • File List
  • File Members

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 

CWIS logo doxygen
Copyright 2010 Internet Scout