Search:

# CWIS Developers Documentation

- Main Page
- Classes
- Files

- Search for |

- File List
- File Members

# MetadataSchema.php

Go to the documentation of this file.

    00001 <?PHP
    00002
    00003 #
    00004 #   FILE:  MetadataSchema.php
    00005 #
    00006 #   Copyright 2002-2010 Edward Almasy and Internet Scout
    00007 #   http://scout.wisc.edu
    00008 #
    00009
    00010 class MetadataSchema extends ItemFactory {
    00011
    00012     # ---- PUBLIC INTERFACE --------------------------------------------------
    00013
    00014     # types of field ordering
    00015     const MDFORDER_DISPLAY =  1;
    00016     const MDFORDER_EDITING =  2;
    00017     const MDFORDER_ALPHABETICAL =  3;
    00018
    00019     # metadata field types
    00020 # (must parallel MetadataFields.FieldType declaration in install/CreateTables.sql
    00021 #        and MetadataField::$FieldTypeDBEnums declaration below)
    00022     const MDFTYPE_TEXT =            1;
    00023     const MDFTYPE_PARAGRAPH =       2;
    00024     const MDFTYPE_NUMBER =          4;
    00025     const MDFTYPE_DATE =            8;
    00026     const MDFTYPE_TIMESTAMP =       16;
    00027     const MDFTYPE_FLAG =            32;
    00028     const MDFTYPE_TREE =            64;
    00029     const MDFTYPE_CONTROLLEDNAME =  128;
    00030     const MDFTYPE_OPTION =          256;
    00031     const MDFTYPE_USER =            512;
    00032     const MDFTYPE_IMAGE =           1024;
    00033     const MDFTYPE_FILE =            2048;
    00034     const MDFTYPE_URL =             4096;
    00035     const MDFTYPE_POINT =           8192;
    00036
    00037     # error status codes
    00038     const MDFSTAT_OK =                 1;
    00039     const MDFSTAT_DUPLICATENAME =      2;
    00040     const MDFSTAT_DUPLICATEDBCOLUMN =  4;
    00041     const MDFSTAT_ILLEGALNAME =        8;
    00042     const MDFSTAT_FIELDDOESNOTEXIST =  16;
    00043
    00044     # object constructor
    00045     function MetadataSchema()
    00046     {
    00047         # set up item factory base class
    00048         $this->ItemFactory(
    00049                 "MetadataField", "MetadataFields", "FieldId", "FieldName");
    00050
    00051         # start with field info caching enabled
    00052         $this->CachingOn = TRUE;
    00053     }
    00054
    00055     # turn internal caching of field info on or off
    00056     function CacheData($NewValue)
    00057     {
    00058         $this->CachingOn = $NewValue;
    00059     }
    00060
    00061     # add new metadata field
    00062     function AddField($FieldName, $FieldType, $Optional = TRUE, $DefaultValue = NULL)
    00063     {
    00064         # create new field
    00065         $Field = new MetadataField(NULL, $FieldName, $FieldType, $Optional, $DefaultValue);
    00066
    00067         # save error code if create failed and return NULL
    00068         if ($Field->Status() != MetadataSchema::MDFSTAT_OK)
    00069         {
    00070             $this->ErrorStatus = $Field->Status();
    00071             $Field = NULL;
    00072         }
    00073
    00074         # return new field to caller
    00075         return $Field;
    00076     }
    00077
    00078     # delete metadata field
    00079     function DropField($FieldId)
    00080     {
    00081         $Field = new MetadataField($FieldId);
    00082         $Field->Drop();
    00083     }
    00084
    00085     # retrieve field by ID
    00086     function GetField($FieldId)
    00087     {
    00088         static $Fields;
    00089
    00090         # if caching is off or field is already loaded
    00091         if (($this->CachingOn != TRUE) || !isset($Fields[$FieldId]))
    00092         {
    00093             # retrieve field
    00094             $Fields[$FieldId] = new MetadataField($FieldId);
    00095         }
    00096
    00097         # return field to caller
    00098         return $Fields[$FieldId];
    00099     }
    00100
    00107     function GetFieldByName($FieldName, $IgnoreCase = FALSE)
    00108     {
    00109         $FieldId = $this->GetFieldIdByName($FieldName, $IgnoreCase);
    00110         return ($FieldId === NULL) ? NULL : $this->GetField($FieldId);
    00111     }
    00112
    00120     function GetFieldIdByName($FieldName, $IgnoreCase = FALSE)
    00121     {
    00122         static $FieldIdsByName;
    00123
    00124         # if caching is off or field ID is already loaded
    00125         if (($this->CachingOn != TRUE) || !isset($FieldIdsByName[$FieldName]))
    00126         {
    00127             # retrieve field ID from DB
    00128             $Condition = $IgnoreCase
    00129                     ? "WHERE LOWER(FieldName) = '".addslashes(strtolower($FieldName))."'"
    00130                     : "WHERE FieldName = '".addslashes($FieldName)."'";
    00131             $FieldIdsByName[$FieldName] = $this->DB->Query(
    00132                     "SELECT FieldId FROM MetadataFields ".$Condition, "FieldId");
    00133         }
    00134
    00135         return $FieldIdsByName[$FieldName];
    00136     }
    00137
    00138     # check whether field with specified name exists
    00139     function FieldExists($FieldName) {  return $this->NameIsInUse($FieldName);  }
    00140
    00141     # retrieve array of fields
    00142     function GetFields($FieldTypes = NULL, $OrderType = NULL,
    00143             $IncludeDisabledFields = FALSE, $IncludeTempFields = FALSE)
    00144     {
    00145         # create empty array to pass back
    00146         $Fields = array();
    00147
    00148         # for each field type in database
    00149         if ($IncludeTempFields && $IncludeDisabledFields)
    00150         {
    00151             $this->DB->Query("SELECT FieldId, FieldType FROM MetadataFields");
    00152         }
    00153         else
    00154         {
    00155             if ($IncludeTempFields)
    00156             {
    00157                 $this->DB->Query("SELECT FieldId, FieldType FROM MetadataFields WHERE Enabled != 0");
    00158             }
    00159             elseif ($IncludeDisabledFields)
    00160             {
    00161                 $this->DB->Query("SELECT FieldId, FieldType FROM MetadataFields WHERE FieldId >= 0");
    00162             }
    00163             else
    00164             {
    00165                 $this->DB->Query("SELECT FieldId, FieldType FROM MetadataFields WHERE FieldId >= 0 AND Enabled != 0");
    00166             }
    00167         }
    00168         while ($Record = $this->DB->FetchRow())
    00169         {
    00170             # if no specific type requested or if field is of requested type
    00171             if (($FieldTypes == NULL)
    00172                 || (MetadataField::$FieldTypePHPEnums[$Record["FieldType"]] & $FieldTypes))
    00173             {
    00174                 # create field object and add to array to be passed back
    00175                 $Fields[$Record["FieldId"]] = new MetadataField($Record["FieldId"]);
    00176             }
    00177         }
    00178
    00179         # if field sorting requested
    00180         if ($OrderType !== NULL)
    00181         {
    00182             # sort field array by requested order type
    00183             $this->FieldCompareType = $OrderType;
    00184             $this->FieldOrderError = FALSE;
    00185             uasort($Fields, array($this, "CompareFieldOrder"));
    00186
    00187             # if field order error detected
    00188             if ($this->FieldOrderError)
    00189             {
    00190                 # repair (reset) field order
    00191                 $OrderIndex = 1;
    00192                 foreach ($Fields as $Field)
    00193                 {
    00194                     $Field->OrderPosition($OrderType, $OrderIndex);
    00195                     $OrderIndex++;
    00196                 }
    00197             }
    00198         }
    00199
    00200         # return array of field objects to caller
    00201         return $Fields;
    00202     }
    00203
    00204     # callback function for sorting fields
    00205     function CompareFieldOrder($FieldA, $FieldB)
    00206     {
    00207         if ($this->FieldCompareType == MetadataSchema::MDFORDER_ALPHABETICAL)
    00208         {
    00209             return ($FieldA->Name() < $FieldB->Name()) ? -1 : 1;
    00210         }
    00211         else
    00212         {
    00213             if ($FieldA->OrderPosition($this->FieldCompareType)
    00214                     == $FieldB->OrderPosition($this->FieldCompareType))
    00215             {
    00216                 $this->FieldOrderError = TRUE;
    00217                 return 0;
    00218             }
    00219             else
    00220             {
    00221                 return ($FieldA->OrderPosition($this->FieldCompareType)
    00222                         < $FieldB->OrderPosition($this->FieldCompareType)) ? -1 : 1;
    00223             }
    00224         }
    00225     }
    00226
    00227     function GetFieldNames($FieldTypes = NULL, $OrderType = NULL,
    00228                             $IncludeDisabledFields = FALSE, $IncludeTempFields = FALSE)
    00229     {
    00230         global $DB;
    00231
    00232         $FieldNames=array();
    00233         $Fields = $this->GetFields($FieldTypes, $OrderType, $IncludeDisabledFields, $IncludeTempFields);
    00234
    00235         foreach($Fields as $Field)
    00236         {
    00237             $DB->Query("SELECT FieldName FROM MetadataFields WHERE FieldId=".$Field->Id());
    00238             $FieldNames[ $Field->Id() ] = $DB->FetchField("FieldName");
    00239         }
    00240
    00241         return $FieldNames;
    00242     }
    00243
    00253     function GetFieldsAsOptionList(
    00254             $OptionListName, $FieldTypes = NULL, $SelectedFieldId = NULL)
    00255     {
    00256         # retrieve requested fields
    00257         $FieldNames = $this->GetFieldNames($FieldTypes);
    00258
    00259         # begin HTML option list
    00260         $Html = "<select name=\"".$OptionListName."\">\n";
    00261         $Html .= "<option value=\"-1\">--</option>\n";
    00262
    00263         # for each metadata field
    00264         foreach ($FieldNames as $Id => $Name)
    00265         {
    00266             # add entry for field to option list
    00267             $Html .= "<option value=\"".$Id."\"";
    00268             if ($Id == $SelectedFieldId) {  $Html .= " selected";  }
    00269             $Html .= ">".htmlspecialchars($Name)."</option>\n";
    00270         }
    00271
    00272         # end HTML option list
    00273         $Html .= "</select>\n";
    00274
    00275         # return constructed HTML to caller
    00276         return $Html;
    00277     }
    00278
    00279     # retrieve array of field types (enumerated type => field name)
    00280     function GetFieldTypes()
    00281     {
    00282         return MetadataField::$FieldTypeDBEnums;
    00283     }
    00284
    00285     # retrieve array of field types that user can create (enumerated type => field name)
    00286     function GetAllowedFieldTypes()
    00287     {
    00288         return MetadataField::$FieldTypeDBAllowedEnums;
    00289     }
    00290
    00291     # remove all metadata field associations for a given qualifier
    00292     function RemoveQualifierAssociations($QualifierIdOrObject)
    00293     {
    00294         # sanitize qualifier ID or grab it from object
    00295         $QualifierIdOrObject = is_object($QualifierIdOrObject)
    00296                 ? $QualifierIdOrObject->Id() : intval($QualifierIdOrObject);
    00297
    00298         # delete intersection records from database
    00299         $this->DB->Query("DELETE FROM FieldQualifierInts WHERE QualifierId = "
    00300                          .$QualifierIdOrObject);
    00301     }
    00302
    00303     # return whether qualifier is in use by metadata field
    00304     function QualifierIsInUse($QualifierIdOrObject)
    00305     {
    00306         # sanitize qualifier ID or grab it from object
    00307         $QualifierIdOrObject = is_object($QualifierIdOrObject)
    00308                 ? $QualifierIdOrObject->Id() : intval($QualifierIdOrObject);
    00309
    00310         # determine whether any fields use qualifier as default
    00311         $DefaultCount = $this->DB->Query("SELECT COUNT(*) AS RecordCount FROM MetadataFields"
    00312                                          ." WHERE DefaultQualifier = ".$QualifierIdOrObject,
    00313                                          "RecordCount");
    00314
    00315         # determine whether any fields are associated with qualifier
    00316         $AssociationCount = $this->DB->Query("SELECT COUNT(*) AS RecordCount FROM FieldQualifierInts"
    00317                                          ." WHERE QualifierId = ".$QualifierIdOrObject,
    00318                                          "RecordCount");
    00319
    00320         # report whether qualifier is in use based on defaults and associations
    00321         return (($DefaultCount + $AssociationCount) > 0) ? TRUE : FALSE;
    00322     }
    00323
    00324     # move fields up or down in field order
    00325     function MoveUpInOrder($FieldIdOrObj, $OrderType)
    00326     {
    00327         $this->MoveFieldInOrder($FieldIdOrObj, $OrderType, FALSE);
    00328     }
    00329     function MoveDownInOrder($FieldIdOrObj, $OrderType)
    00330     {
    00331         $this->MoveFieldInOrder($FieldIdOrObj, $OrderType, TRUE);
    00332     }
    00333
    00334     # return highest field ID currently in use
    00335     function GetHighestFieldId() {  return $this->GetHighestItemId();  }
    00336
    00344     static function StdNameToFieldMapping($MappedName, $FieldId = NULL)
    00345     {
    00346         if ($FieldId !== NULL)
    00347         {
    00348             self::$FieldMappings[$MappedName] = $FieldId;
    00349         }
    00350         return isset(self::$FieldMappings[$MappedName])
    00351                 ? self::$FieldMappings[$MappedName] : NULL;
    00352     }
    00353
    00360     static function FieldToStdNameMapping($FieldId)
    00361     {
    00362         foreach (self::$FieldMappings as $MappedName => $MappedFieldId)
    00363         {
    00364             if ($MappedFieldId == $FieldId)
    00365             {
    00366                 return $MappedName;
    00367             }
    00368         }
    00369         return NULL;
    00370     }
    00371
    00379     function GetFieldByMappedName($MappedName)
    00380     {
    00381         return ($this->StdNameToFieldMapping($MappedName) == NULL) ? NULL
    00382                 : $this->GetField($this->StdNameToFieldMapping($MappedName));
    00383     }
    00384
    00385
    00386     # ---- PRIVATE INTERFACE -------------------------------------------------
    00387
    00388     private $FieldCompareType;
    00389     private $FieldOrderError;
    00390     private $CachingOn;
    00391     private static $FieldMappings;
    00392
    00393     private function MoveFieldInOrder($FieldIdOrObj, $OrderType, $MoveFieldDown)
    00394     {
    00395         # grab field ID
    00396         $FieldId = is_object($FieldIdOrObj) ? $Field->Id() : $FieldIdOrObj;
    00397
    00398         # retrieve array of fields
    00399         $Fields = $this->GetFields(NULL, $OrderType);
    00400
    00401         # reverse array of fields if we are moving field down
    00402         if ($MoveFieldDown)
    00403         {
    00404             $Fields = array_reverse($Fields);
    00405         }
    00406
    00407         # for each field in order
    00408         $PreviousField = NULL;
    00409         foreach ($Fields as $Field)
    00410         {
    00411             # if field is the field to be moved
    00412             if ($Field->Id() == $FieldId)
    00413             {
    00414                 # if we have a previous field
    00415                 if ($PreviousField !== NULL)
    00416                 {
    00417                     # swap field with previous field according to order type
    00418                     $TempVal = $Field->OrderPosition($OrderType);
    00419                     $Field->OrderPosition($OrderType, $PreviousField->OrderPosition($OrderType));
    00420                     $PreviousField->OrderPosition($OrderType, $TempVal);
    00421                 }
    00422             }
    00423
    00424             # save field for next iteration
    00425             $PreviousField = $Field;
    00426         }
    00427     }
    00428 }
    00429
    00430 ?>