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

Copyright 2010 Internet Scout