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