Search:

# CWIS Developers Documentation

- Main Page
- Classes
- Files

- File List
- File Members

# Resource.php

Go to the documentation of this file.

    00001 <?PHP
    00002 #
    00003 #   FILE:  Resource.php
    00004 #
    00005 #   Part of the Collection Workflow Integration System (CWIS)
    00006 #   Copyright 2011 Edward Almasy and Internet Scout Project
    00007 #   http://scout.wisc.edu/
    00008 #
    00009
    00013 class Resource {
    00014
    00015     # ---- PUBLIC INTERFACE --------------------------------------------------
    00016
    00017     # object constructor (creates temp resource if no resource ID supplied)
    00018
    00022     function Resource($ResourceId = NULL)
    00023     {
    00024         $this->DB = new SPTDatabase();
    00025         $DB = $this->DB;
    00026         $this->Schema = new MetadataSchema();
    00027
    00028         # if resource ID supplied
    00029         if ($ResourceId !== NULL)
    00030         {
    00031             # save resource ID
    00032             $this->Id = intval($ResourceId);
    00033
    00034             # locate resource in database
    00035             $DB->Query("SELECT * FROM Resources WHERE ResourceId = ".$this->Id);
    00036
    00037             # if unable to locate resource
    00038             $Record = $DB->FetchRow();
    00039             if ($Record == FALSE)
    00040             {
    00041                 # set status to -1 to indicate that creation failed
    00042                 $this->LastStatus = -1;
    00043             }
    00044             else
    00045             {
    00046                 # load in attributes from database
    00047                 $this->DBFields = $Record;
    00048                 $this->CumulativeRating = $Record["CumulativeRating"];
    00049
    00050                 # set status to 1 to indicate that creation succeeded
    00051                 $this->LastStatus = 1;
    00052             }
    00053         }
    00054         else
    00055         {
    00056             # clean out any temp resource records more than three days old
    00057             $RFactory = new ResourceFactory();
    00058             $RFactory->CleanOutStaleTempItems(60 * 24 * 3);
    00059
    00060             # lock DB tables to prevent next ID from being grabbed
    00061             $DB->Query(
    00062                 "LOCK TABLES Resources write, APUsers read, ".
    00063                 "APSessions write, APSessionData write");
    00064
    00065             # find next temp resource ID
    00066             $this->Id = $RFactory->GetNextTempItemId();
    00067
    00068             # write out new resource record with temp resource ID and user ID
    00069             global $User;
    00070             $DB->Query("INSERT INTO Resources (ResourceId, AddedById,"
    00071                     ." LastModifiedById, DateLastModified, DateOfRecordCreation)"
    00072                        ." VALUES (".$this->Id.", "
    00073                                    .$User->Get("UserId").", "
    00074                                    .$User->Get("UserId").", "
    00075                                    ."NOW(), NOW())");
    00076
    00077             # release DB tables
    00078             $DB->Query("UNLOCK TABLES");
    00079
    00080             # load in attributes from database
    00081             $DB->Query("SELECT * FROM Resources WHERE ResourceId = ".$this->Id);
    00082             $this->DBFields = $DB->FetchRow();
    00083             $this->CumulativeRating = $this->DBFields["CumulativeRating"];
    00084
    00085             # set any default values
    00086             $Schema = new MetadataSchema();
    00087             $Fields = $Schema->GetFields(MetadataSchema::MDFTYPE_OPTION
    00088                     |MetadataSchema::MDFTYPE_FLAG
    00089                     |MetadataSchema::MDFTYPE_NUMBER
    00090                     |MetadataSchema::MDFTYPE_POINT);
    00091             foreach ($Fields as $Field)
    00092             {
    00093                 $this->SetByField($Field, $Field->DefaultValue());
    00094             }
    00095
    00096             # Update timestamps as required:
    00097             $TimestampFields = $Schema->GetFields(
    00098                 MetadataSchema::MDFTYPE_TIMESTAMP);
    00099             foreach ($TimestampFields as $Field)
    00100             {
    00101                 if ($Field->UpdateMethod() ==
    00102                     MetadataField::UPDATEMETHOD_ONRECORDCREATE)
    00103                 {
    00104                     $this->SetByField($Field, "now");
    00105                 }
    00106             }
    00107
    00108             # signal resource creation
    00109             $GLOBALS["AF"]->SignalEvent("EVENT_RESOURCE_CREATE", array(
    00110                     "Resource" => $this,
    00111                     ));
    00112
    00113             # set status to 1 to indicate that creation succeeded
    00114             $this->LastStatus = 1;
    00115         }
    00116     }
    00117
    00121     function Delete()
    00122     {
    00123         global $SysConfig;
    00124
    00125         # signal that resource deletion is about to occur
    00126         global $AF;
    00127         $AF->SignalEvent("EVENT_RESOURCE_DELETE", array(
    00128                 "Resource" => $this,
    00129                 ));
    00130
    00131         # grab list of classifications
    00132         $Classifications = $this->Classifications();
    00133
    00134         # delete resource/classification intersections
    00135         $DB = $this->DB;
    00136         $DB->Query("DELETE FROM ResourceClassInts WHERE ResourceId = ".$this->Id());
    00137
    00138         # for each classification type
    00139         foreach ($Classifications as $ClassType => $ClassesOfType)
    00140         {
    00141             # for each classification of that type
    00142             foreach ($ClassesOfType as $ClassId => $ClassName)
    00143             {
    00144                 # recalculate resource count for classification
    00145                 $Class = new Classification($ClassId);
    00146                 $Class->RecalcResourceCount();
    00147             }
    00148         }
    00149
    00150         # delete resource/name intersections
    00151         $DB->Query("DELETE FROM ResourceNameInts WHERE ResourceId = ".$this->Id());
    00152
    00153         # delete any associated images not in use by other resources
    00154         $Fields = $this->Schema->GetFields(MetadataSchema::MDFTYPE_IMAGE);
    00155         foreach ($Fields as $Field)
    00156         {
    00157             $ImageId = $DB->Query("SELECT `".$Field->DBFieldName()
    00158                                   ."` FROM Resources WHERE ResourceId = ".$this->Id(),
    00159                                   $Field->DBFieldName());
    00160             if ($ImageId > 0)
    00161             {
    00162                 $ImageCount = $DB->Query("SELECT COUNT(*) AS ImageCount FROM Resources"
    00163                                          ." WHERE ".$Field->DBFieldName()." = ".$ImageId,
    00164                                          "ImageCount");
    00165                 if ($ImageCount < 2)
    00166                 {
    00167                     $Image = new SPTImage($ImageId);
    00168                     $Image->Delete();
    00169                 }
    00170             }
    00171         }
    00172
    00173         # delete any associated files
    00174         $Factory = new FileFactory(NULL);
    00175         $Files = $Factory->GetFilesForResource($this->Id());
    00176         foreach ($Files as $File)
    00177         {
    00178             $File->Delete();
    00179         }
    00180
    00181         # delete resource record from database
    00182         $DB->Query("DELETE FROM Resources WHERE ResourceId = ".$this->Id());
    00183
    00184         # drop item from search engine and recommender system
    00185         if ($SysConfig->SearchDBEnabled())
    00186         {
    00187             $SearchEngine = new SPTSearchEngine();
    00188             $SearchEngine->DropItem($this->Id());
    00189         }
    00190         if ($SysConfig->RecommenderDBEnabled())
    00191         {
    00192             $Recommender = new SPTRecommender();
    00193             $Recommender->DropItem($this->Id());
    00194         }
    00195
    00196         # delete any resource comments
    00197         $DB->Query("DELETE FROM Messages WHERE ParentId = ".$this->Id);
    00198     }
    00199
    00204     function Status() {  return $this->LastStatus;  }
    00205
    00210     function Id() {  return $this->Id;  }
    00211
    00217     function IsTempResource($NewSetting = NULL)
    00218     {
    00219         # if new temp resource setting supplied
    00220         if (!is_null($NewSetting))
    00221         {
    00222             # if caller requested to switch
    00223             $DB = $this->DB;
    00224             if ((($this->Id() < 0) && ($NewSetting == FALSE))
    00225                     || (($this->Id() >= 0) && ($NewSetting == TRUE)))
    00226             {
    00227                 # lock DB tables to prevent next ID from being grabbed
    00228                 $DB->Query("LOCK TABLES Resources write");
    00229
    00230                 # get next resource ID as appropriate
    00231                 $OldResourceId = $this->Id;
    00232                 $Factory = new ResourceFactory();
    00233                 if ($NewSetting == TRUE)
    00234                 {
    00235                     $this->Id = $Factory->GetNextTempItemId();
    00236                 }
    00237                 else
    00238                 {
    00239                     $this->Id = $Factory->GetNextItemId();
    00240                 }
    00241
    00242                 # change resource ID
    00243                 $DB->Query("UPDATE Resources SET ResourceId = ".
    00244                     $this->Id.  " WHERE ResourceId = ".$OldResourceId);
    00245
    00246                 # release DB tables
    00247                 $DB->Query("UNLOCK TABLES");
    00248
    00249                 # change associations
    00250                 unset($this->ClassificationCache);
    00251                 $DB->Query("UPDATE ResourceClassInts SET ResourceId = ".
    00252                     $this->Id.  " WHERE ResourceId = ".$OldResourceId);
    00253                 unset($this->ControlledNameCache);
    00254                 unset($this->ControlledNameVariantCache);
    00255                 $DB->Query("UPDATE ResourceNameInts SET ResourceId = ".
    00256                     $this->Id.  " WHERE ResourceId = ".$OldResourceId);
    00257                 $DB->Query("UPDATE Files SET ResourceId = ".
    00258                     $this->Id.  " WHERE ResourceId = ".$OldResourceId);
    00259
    00260                 # signal event as appropriate
    00261                 if ($NewSetting === FALSE)
    00262                 {
    00263                     $GLOBALS["AF"]->SignalEvent("EVENT_RESOURCE_ADD", array(
    00264                             "Resource" => $this,
    00265                             ));
    00266                 }
    00267             }
    00268         }
    00269
    00270         # report to caller whether we are a temp resource
    00271         return ($this->Id() < 0) ? TRUE : FALSE;
    00272     }
    00273
    00274
    00275     # --- Generic Attribute Retrieval Methods -------------------------------
    00276
    00291     function Get($FieldNameOrObject, $ReturnObject = FALSE, $IncludeVariants = FALSE)
    00292     {
    00293         # load field object if needed
    00294         $Field = is_object($FieldNameOrObject) ? $FieldNameOrObject
    00295                 : $this->Schema->GetFieldByName($FieldNameOrObject);
    00296
    00297         # return no value found if we don't have a valid field
    00298         if ((get_class($Field) != "MetadataField")
    00299                 || ($Field->Status() != MetadataSchema::MDFSTAT_OK))
    00300                 {  return NULL;  }
    00301
    00302         # grab database field name
    00303         $DBFieldName = $Field->DBFieldName();
    00304
    00305         # format return value based on field type
    00306         switch ($Field->Type())
    00307         {
    00308             case MetadataSchema::MDFTYPE_TEXT:
    00309             case MetadataSchema::MDFTYPE_PARAGRAPH:
    00310             case MetadataSchema::MDFTYPE_NUMBER:
    00311             case MetadataSchema::MDFTYPE_FLAG:
    00312             case MetadataSchema::MDFTYPE_URL:
    00313                 if (isset($this->DBFields[$DBFieldName]))
    00314                 {
    00315                     $ReturnValue = $this->DBFields[$DBFieldName];
    00316                 }
    00317                 else
    00318                 {
    00319                     $ReturnValue = NULL;
    00320                 }
    00321                 break;
    00322
    00323             case MetadataSchema::MDFTYPE_POINT:
    00324                 $ReturnValue = array("X" => $this->DBFields[$DBFieldName."X"],
    00325                                      "Y" => $this->DBFields[$DBFieldName."Y"]);
    00326                 break;
    00327
    00328             case MetadataSchema::MDFTYPE_DATE:
    00329                 $Date = new Date($this->DBFields[$DBFieldName."Begin"],
    00330                                     $this->DBFields[$DBFieldName."End"],
    00331                                     $this->DBFields[$DBFieldName."Precision"]);
    00332                 if ($ReturnObject)
    00333                 {
    00334                     $ReturnValue = $Date;
    00335                 }
    00336                 else
    00337                 {
    00338                     $ReturnValue = $Date->Formatted();
    00339                 }
    00340                 break;
    00341
    00342             case MetadataSchema::MDFTYPE_TIMESTAMP:
    00343                 $ReturnValue = $this->DBFields[$DBFieldName];
    00344                 break;
    00345
    00346             case MetadataSchema::MDFTYPE_TREE:
    00347                 # start with empty array
    00348                 $ReturnValue = array();
    00349
    00350                 # if classification cache has not been loaded
    00351                 if (!isset($this->ClassificationCache))
    00352                 {
    00353                     # load all classifications associated with this resource into cache
    00354                     $this->ClassificationCache = array();
    00355                     $this->DB->Query("SELECT Classifications.ClassificationId,Classifications.FieldId,ClassificationName "
    00356                             ."FROM ResourceClassInts, Classifications  "
    00357                             ."WHERE ResourceClassInts.ResourceId = ".$this->Id." "
    00358                             ."AND ResourceClassInts.ClassificationId = Classifications.ClassificationId ");
    00359                     while ($Record = $this->DB->FetchRow())
    00360                     {
    00361                         $this->ClassificationCache[$Record["ClassificationId"]]["Name"] =
    00362                                 $Record["ClassificationName"];
    00363                         $this->ClassificationCache[$Record["ClassificationId"]]["FieldId"] =
    00364                                 $Record["FieldId"];
    00365                     }
    00366                 }
    00367
    00368                 # for each entry in classification cache
    00369                 foreach ($this->ClassificationCache as $ClassificationId => $ClassificationInfo)
    00370                 {
    00371                     # if classification ID matches field we are looking for
    00372                     if ($ClassificationInfo["FieldId"] == $Field->Id())
    00373                     {
    00374                         # add field to result
    00375                         if ($ReturnObject)
    00376                         {
    00377                             $ReturnValue[$ClassificationId] = new Classification($ClassificationId);
    00378                         }
    00379                         else
    00380                         {
    00381                             $ReturnValue[$ClassificationId] = $ClassificationInfo["Name"];
    00382                         }
    00383                     }
    00384                 }
    00385                 break;
    00386
    00387             case MetadataSchema::MDFTYPE_CONTROLLEDNAME:
    00388             case MetadataSchema::MDFTYPE_OPTION:
    00389                 # start with empty array
    00390                 $ReturnValue = array();
    00391
    00392                 # if controlled name cache has not been loaded
    00393                 if (!isset($this->ControlledNameCache))
    00394                 {
    00395                     # load all controlled names associated with this resource into cache
    00396                     $this->ControlledNameCache = array();
    00397                     $this->DB->Query("SELECT ControlledNames.ControlledNameId,ControlledNames.FieldId,ControlledName "
    00398                             ."FROM ResourceNameInts, ControlledNames  "
    00399                             ."WHERE ResourceNameInts.ResourceId = ".$this->Id." "
    00400                             ."AND ResourceNameInts.ControlledNameId = ControlledNames.ControlledNameId ");
    00401                     while ($Record = $this->DB->FetchRow())
    00402                     {
    00403                         $this->ControlledNameCache[$Record["ControlledNameId"]]["Name"] = $Record["ControlledName"];
    00404                         $this->ControlledNameCache[$Record["ControlledNameId"]]["FieldId"] = $Record["FieldId"];
    00405                     }
    00406                 }
    00407
    00408                 # if variant names requested and variant name cache has not been loaded
    00409                 if ($IncludeVariants && !isset($this->ControlledNameVariantCache))
    00410                 {
    00411                     # load all controlled names associated with this resource into cache
    00412                     $this->ControlledNameVariantCache = array();
    00413                     $this->DB->Query("SELECT ControlledNames.ControlledNameId,ControlledNames.FieldId,ControlledName,VariantName "
    00414                             ."FROM ResourceNameInts, ControlledNames, VariantNames  "
    00415                             ."WHERE ResourceNameInts.ResourceId = ".$this->Id." "
    00416                             ."AND ResourceNameInts.ControlledNameId = ControlledNames.ControlledNameId "
    00417                             ."AND VariantNames.ControlledNameId = ControlledNames.ControlledNameId");
    00418                     while ($Record = $this->DB->FetchRow())
    00419                     {
    00420                         $this->ControlledNameVariantCache[$Record["ControlledNameId"]][] = $Record["VariantName"];
    00421                     }
    00422                 }
    00423
    00424                 # for each entry in controlled name cache
    00425                 foreach ($this->ControlledNameCache as $ControlledNameId => $ControlledNameInfo)
    00426                 {
    00427                     # if controlled name type matches field we are looking for
    00428                     if ($ControlledNameInfo["FieldId"] == $Field->Id())
    00429                     {
    00430                         # if objects requested
    00431                         if ($ReturnObject)
    00432                         {
    00433                             $ReturnValue[$ControlledNameId] =
    00434                                     new ControlledName($ControlledNameId);
    00435                         }
    00436                         else
    00437                         {
    00438                             # if variant names requested
    00439                             if ($IncludeVariants)
    00440                             {
    00441                                 # add field to result
    00442                                 $ReturnValue[] = $ControlledNameInfo["Name"];
    00443
    00444                                 # add any variant names to result
    00445                                 if (isset($this->ControlledNameVariantCache[$ControlledNameId]))
    00446                                 {
    00447                                     $ReturnValue = array_merge($ReturnValue, $this->ControlledNameVariantCache[$ControlledNameId]);
    00448                                 }
    00449                             }
    00450                             else
    00451                             {
    00452                                 # add field with index to result
    00453                                 $ReturnValue[$ControlledNameId] = $ControlledNameInfo["Name"];
    00454                             }
    00455                         }
    00456                     }
    00457                 }
    00458                 break;
    00459
    00460             case MetadataSchema::MDFTYPE_USER:
    00461                 $User = new User($this->DB, (int)$this->DBFields[$DBFieldName]);
    00462                 if ($ReturnObject)
    00463                 {
    00464                     $ReturnValue = $User;
    00465                 }
    00466                 else
    00467                 {
    00468                     $ReturnValue = $User->Get("UserName");
    00469                 }
    00470                 break;
    00471
    00472             case MetadataSchema::MDFTYPE_IMAGE:
    00473                 if ($this->DBFields[$DBFieldName] > 0)
    00474                 {
    00475                     $ImageObject = new SPTImage($this->DBFields[$DBFieldName]);
    00476                     if ($ReturnObject)
    00477                     {
    00478                         $ReturnValue = $ImageObject;
    00479                     }
    00480                     else
    00481                     {
    00482                         $ReturnValue = $ImageObject->AltText();
    00483                     }
    00484                 }
    00485                 else
    00486                 {
    00487                     $ReturnValue = NULL;
    00488                 }
    00489                 break;
    00490
    00491             case MetadataSchema::MDFTYPE_FILE:
    00492                 # retrieve files using factory
    00493                 $Factory = new FileFactory($Field->Id());
    00494                 $ReturnValue = $Factory->GetFilesForResource(
    00495                         $this->Id, $ReturnObject);
    00496                 break;
    00497
    00498             default:
    00499                 # ERROR OUT
    00500                 exit("<br>SPT - ERROR: attempt to retrieve unknown resource field type (".$Field->Type().")<br>\n");
    00501                 break;
    00502         }
    00503
    00504         # return formatted value to caller
    00505         return $ReturnValue;
    00506     }
    00511     function GetByField($FieldNameOrObject,
    00512             $ReturnObject = FALSE, $IncludeVariants = FALSE)
    00513     {  return $this->Get($FieldNameOrObject, $ReturnObject, $IncludeVariants);  }
    00514
    00528     function GetByFieldId($FieldId, $ReturnObject = FALSE, $IncludeVariants = FALSE)
    00529     {
    00530         $Field = $this->Schema->GetField($FieldId);
    00531         return ($Field) ? $this->Get($Field, $ReturnObject, $IncludeVariants) : NULL;
    00532     }
    00533
    00534     # return all resource attributes as an array
    00535     function GetAsArray($IncludeDisabledFields = FALSE, $ReturnObjects = TRUE)
    00536     {
    00537         # retrieve field info
    00538         $Fields = $this->Schema->GetFields();
    00539
    00540         # for each field
    00541         foreach ($Fields as $Field)
    00542         {
    00543             # if field is enabled or caller requested disabled fields
    00544             if ($Field->Enabled() || $IncludeDisabledFields)
    00545             {
    00546                 # retrieve info and add it to the array
    00547                 $FieldStrings[$Field->Name()] = $this->Get($Field, $ReturnObjects);
    00548
    00549                 # if field uses qualifiers
    00550                 if ($Field->UsesQualifiers())
    00551                 {
    00552                     # get qualifier attributes and add to the array
    00553                     $FieldStrings[$Field->Name()." Qualifier"] =
    00554                             $this->GetQualifierByField($Field, $ReturnObjects);
    00555                 }
    00556             }
    00557         }
    00558
    00559         # add in internal values
    00560         $FieldStrings["ResourceId"] = $this->Id();
    00561         $FieldStrings["CumulativeRating"] = $this->CumulativeRating();
    00562
    00563         # return array to caller
    00564         return $FieldStrings;
    00565     }
    00566
    00581     function GetMapped($MappedName, $ReturnObject = FALSE, $IncludeVariants = FALSE)
    00582     {
    00583         return $this->Schema->StdNameToFieldMapping($MappedName)
    00584                 ? $this->GetByFieldId($this->Schema->StdNameToFieldMapping($MappedName),
    00585                         $ReturnObject, $IncludeVariants)
    00586                 : NULL;
    00587     }
    00588
    00595     function GetQualifier($FieldName, $ReturnObject = TRUE)
    00596     {
    00597         $Field = $this->Schema->GetFieldByName($FieldName);
    00598         return $this->GetQualifierByField($Field, $ReturnObject);
    00599     }
    00600
    00607     function GetQualifierByFieldId($FieldId, $ReturnObject = TRUE)
    00608     {
    00609         $Field = $this->Schema->GetField($FieldId);
    00610         return $this->GetQualifierByField($Field, $ReturnObject);
    00611     }
    00612
    00621     function GetQualifierByField($Field, $ReturnObject = TRUE)
    00622     {
    00623         # return NULL if field is invalid
    00624         if ((get_class($Field) != "MetadataField")
    00625                 || ($Field->Status() != MetadataSchema::MDFSTAT_OK))
    00626                 {  return NULL;  }
    00627
    00628         # assume no qualifiers if not otherwise determined
    00629         $ReturnValue = NULL;
    00630
    00631         # if field uses qualifiers
    00632         if ($Field->UsesQualifiers())
    00633         {
    00634             # retrieve qualifiers based on field type
    00635             switch ($Field->Type())
    00636             {
    00637                 case MetadataSchema::MDFTYPE_TREE:
    00638                 case MetadataSchema::MDFTYPE_CONTROLLEDNAME:
    00639                 case MetadataSchema::MDFTYPE_OPTION:
    00640                     # retrieve list of items
    00641                     $Items = $this->Get($Field);
    00642
    00643                     # if field uses item-level qualifiers
    00644                     if ($Field->HasItemLevelQualifiers())
    00645                     {
    00646                         # determine general item name in DB
    00647                         $TableName = ($Field->Type() == MetadataSchema::MDFTYPE_TREE)
    00648                                 ? "Classification" : "ControlledName";
    00649
    00650                         # for each item
    00651                         foreach ($Items as $ItemId => $ItemName)
    00652                         {
    00653                             # look up qualifier for item
    00654                             $QualId = $this->DB->Query(
    00655                                     "SELECT * FROM ".$TableName."s"
    00656                                     ." WHERE ".$TableName."Id = ".$ItemId
    00657                                     , "QualifierId");
    00658
    00659
    00660                             if ($QualId > 0)
    00661                             {
    00662                                 # if object was requested by caller
    00663                                 if ($ReturnObject)
    00664                                 {
    00665                                     # load qualifier and add to return value array
    00666                                     $ReturnValue[$ItemId] = new Qualifier($QualId);
    00667                                 }
    00668                                 else
    00669                                 {
    00670                                     # add qualifier ID to return value array
    00671                                     $ReturnValue[$ItemId] = $QualId;
    00672                                 }
    00673                             }
    00674                             else
    00675                             {
    00676                                 # add NULL to return value array for this item
    00677                                 $ReturnValue[$ItemId] = NULL;
    00678                             }
    00679                         }
    00680                     }
    00681                     else
    00682                     {
    00683                         # for each item
    00684                         foreach ($Items as $ItemId => $ItemName)
    00685                         {
    00686                             # if object was requested by caller
    00687                             if ($ReturnObject)
    00688                             {
    00689                                 # load default qualifier and add to return value array
    00690                                 $ReturnValue[$ItemId] = new Qualifier($Field->DefaultQualifier());
    00691                             }
    00692                             else
    00693                             {
    00694                                 # add default qualifier ID to return value array
    00695                                 $ReturnValue[$ItemId] = $Field->DefaultQualifier();
    00696                             }
    00697                         }
    00698                     }
    00699                     break;
    00700
    00701                 default:
    00702                     # if field uses item-level qualifiers
    00703                     if ($Field->HasItemLevelQualifiers())
    00704                     {
    00705                         # if qualifier available
    00706                         if ($this->DBFields[$Field->DBFieldName()."Qualifier"] > 0)
    00707                         {
    00708                             # if object was requested by caller
    00709                             if ($ReturnObject)
    00710                             {
    00711                                 # return qualifier for field
    00712                                 $ReturnValue = new Qualifier($this->DBFields[$Field->DBFieldName()."Qualifier"]);
    00713                             }
    00714                             else
    00715                             {
    00716                                 # return qualifier ID for field
    00717                                 $ReturnValue = $this->DBFields[$Field->DBFieldName()."Qualifier"];
    00718                             }
    00719                         }
    00720                     }
    00721                     else
    00722                     {
    00723                         # if default qualifier available
    00724                         if ($Field->DefaultQualifier() > 0)
    00725                         {
    00726                             # if object was requested by caller
    00727                             if ($ReturnObject)
    00728                             {
    00729                                 # return default qualifier
    00730                                 $ReturnValue = new Qualifier($Field->DefaultQualifier());
    00731                             }
    00732                             else
    00733                             {
    00734                                 # return default qualifier ID
    00735                                 $ReturnValue = $Field->DefaultQualifier();
    00736                             }
    00737                         }
    00738                     }
    00739                     break;
    00740             }
    00741         }
    00742
    00743         # return qualifier object or ID (or array of same) to caller
    00744         return $ReturnValue;
    00745     }
    00746
    00747
    00748     # --- Generic Attribute Setting Methods ---------------------------------
    00749
    00750     # set value using field name or field object
    00751     function Set($FieldNameOrObject, $NewValue)
    00752     {
    00753         # load field object if needed
    00754         $Field = is_object($FieldNameOrObject) ? $FieldNameOrObject
    00755                 : $this->Schema->GetFieldByName($FieldNameOrObject);
    00756
    00757         # grab commonly-used values for local use
    00758         $DB = $this->DB;
    00759         $ResourceId = $this->Id;
    00760
    00761         # grab database field name
    00762         $DBFieldName = $Field->DBFieldName();
    00763
    00764         # store value in DB based on field type
    00765         switch ($Field->Type())
    00766         {
    00767             case MetadataSchema::MDFTYPE_TEXT:
    00768             case MetadataSchema::MDFTYPE_PARAGRAPH:
    00769             case MetadataSchema::MDFTYPE_URL:
    00770                 # save value directly to DB
    00771                 $DB->Query("UPDATE Resources SET `"
    00772                            .$DBFieldName."` = '".addslashes($NewValue)."' "
    00773                            ."WHERE ResourceId = ".$ResourceId);
    00774
    00775                 # save value locally
    00776                 $this->DBFields[$DBFieldName] = $NewValue;
    00777                 break;
    00778
    00779             case MetadataSchema::MDFTYPE_NUMBER:
    00780                 # save value directly to DB
    00781                 if (is_null($NewValue))
    00782                 {
    00783                     $DB->Query("UPDATE Resources SET `"
    00784                            .$DBFieldName."` = NULL"
    00785                            ." WHERE ResourceId = ".$ResourceId);
    00786                 }
    00787                 else
    00788                 {
    00789                     $DB->Query("UPDATE Resources SET `"
    00790                            .$DBFieldName."` = ".intval($NewValue)
    00791                            ." WHERE ResourceId = ".$ResourceId);
    00792                 }
    00793
    00794                 # save value locally
    00795                 $this->DBFields[$DBFieldName] = $NewValue;
    00796                 break;
    00797
    00798
    00799             case MetadataSchema::MDFTYPE_POINT:
    00800                 if (is_null($NewValue))
    00801                 {
    00802                     $DB->Query("UPDATE Resources SET "
    00803                                ."`".$DBFieldName."X` = NULL, "
    00804                                ."`".$DBFieldName."Y` = NULL "
    00805                                ."WHERE ResourceId = ".$ResourceId);
    00806                     $this->DBFields[$DBFieldName."X"] = NULL;
    00807                     $this->DBFields[$DBFieldName."Y"] = NULL;
    00808                 }
    00809                 else
    00810                 {
    00811                     $DB->Query("UPDATE Resources SET "
    00812                                ."`".$DBFieldName."X` = ".(strlen($NewValue["X"])
    00813                                             ? "'".$NewValue["X"]."'" : "NULL").", "
    00814                                ."`".$DBFieldName."Y` = ".(strlen($NewValue["Y"])
    00815                                             ? "'".$NewValue["Y"]."'" : "NULL")
    00816                                ." WHERE ResourceId = ".$ResourceId);
    00817
    00818                     $Digits = $Field->PointDecimalDigits();
    00819
    00820                     $this->DBFields[$DBFieldName."X"] =
    00821                         strlen($NewValue["X"]) ? round($NewValue["X"], $Digits) : NULL;
    00822                     $this->DBFields[$DBFieldName."Y"] =
    00823                         strlen($NewValue["Y"]) ? round($NewValue["Y"], $Digits) : NULL;
    00824                 }
    00825                 break;
    00826
    00827             case MetadataSchema::MDFTYPE_FLAG:
    00828                 # save value directly to DB
    00829                 if (is_null($NewValue))
    00830                 {
    00831                     $DB->Query("UPDATE Resources SET `"
    00832                            .$DBFieldName."` = NULL"
    00833                            ." WHERE ResourceId = ".$ResourceId);
    00834                 }
    00835                 else
    00836                 {
    00837                     $DB->Query("UPDATE Resources SET `"
    00838                            .$DBFieldName."` = ".$NewValue
    00839                            ." WHERE ResourceId = ".$ResourceId);
    00840                 }
    00841
    00842                 # save value locally
    00843                 $OldValue = $this->DBFields[$DBFieldName];
    00844                 $this->DBFields[$DBFieldName] = $NewValue;
    00845
    00846                 # recalculate counts for any associated classifications if necessary
    00847                 if (($DBFieldName == "ReleaseFlag") && ($NewValue != $OldValue))
    00848                 {
    00849                     $DB->Query("SELECT ClassificationId FROM ResourceClassInts WHERE ResourceId = ".$ResourceId);
    00850                     while ($ClassId = $DB->FetchField("ClassificationId"))
    00851                     {
    00852                         $Class = new Classification($ClassId);
    00853                         $Class->RecalcResourceCount();
    00854                     }
    00855                 }
    00856                 break;
    00857
    00858             case MetadataSchema::MDFTYPE_USER:
    00859                 # if value passed in was object
    00860                 if (is_object($NewValue))
    00861                 {
    00862                     # retrieve user ID from object
    00863                     $UserId = $NewValue->Get("UserId");
    00864                 }
    00865                 # else if value passed in was user name
    00866                 elseif (is_string($NewValue))
    00867                 {
    00868                     # create user object and retrieve user ID from there
    00869                     $User = new User($this->DB, $NewValue);
    00870                     $UserId = $User->Get("UserId");
    00871                 }
    00872                 else
    00873                 {
    00874                     # assume value is user ID and use value directly
    00875                     $UserId = $NewValue;
    00876                 }
    00877
    00878                 # save value directly to DB
    00879                 $DB->Query("UPDATE Resources SET `"
    00880                            .$DBFieldName."` = '".$UserId."' "
    00881                            ."WHERE ResourceId = ".$ResourceId);
    00882
    00883                 # save value locally
    00884                 $this->DBFields[$DBFieldName] = $UserId;
    00885                 break;
    00886
    00887             case MetadataSchema::MDFTYPE_DATE:
    00888                 # if we were given a date object
    00889                 if (is_object($NewValue))
    00890                 {
    00891                     # use supplied date object
    00892                     $Date = $NewValue;
    00893                 }
    00894                 else
    00895                 {
    00896                     # create date object
    00897                     $Date = new Date($NewValue);
    00898                 }
    00899
    00900                 # extract values from date object and store in DB
    00901                 $BeginDate = "'".$Date->BeginDate()."'";
    00902                 if (strlen($BeginDate) < 3) {  $BeginDate = "NULL";  }
    00903                 $EndDate = "'".$Date->EndDate()."'";
    00904                 if (strlen($EndDate) < 3) {  $EndDate = "NULL";  }
    00905                 $DB->Query("UPDATE Resources SET "
    00906                            .$DBFieldName."Begin = ".$BeginDate.", "
    00907                            .$DBFieldName."End = ".$EndDate.", "
    00908                            .$DBFieldName."Precision = '".$Date->Precision()."' "
    00909                            ."WHERE ResourceId = ".$ResourceId);
    00910
    00911                 # save values locally
    00912                 $this->DBFields[$DBFieldName."Begin"] = $Date->BeginDate();
    00913                 $this->DBFields[$DBFieldName."End"] = $Date->EndDate();
    00914                 $this->DBFields[$DBFieldName."Precision"] = $Date->Precision();
    00915                 break;
    00916
    00917             case MetadataSchema::MDFTYPE_TIMESTAMP:
    00918                 if (is_null($NewValue))
    00919                 {
    00920                     $DateValue = $NewValue;
    00921
    00922                     # save value directly to DB
    00923                     $DB->Query("
    00924                         UPDATE Resources SET
    00925                         `".$DBFieldName."` = NULL
    00926                         WHERE ResourceId = ".$ResourceId);
    00927                 }
    00928
    00929                 else
    00930                 {
    00931                     # assume value is date and use directly
    00932                     $DateValue = date("Y-m-d H:i:s", strtotime($NewValue));
    00933
    00934                     # save value directly to DB
    00935                     $DB->Query("
    00936                         UPDATE Resources SET
    00937                         `".$DBFieldName."` = '".addslashes($DateValue)."'
    00938                         WHERE ResourceId = ".$ResourceId);
    00939                 }
    00940
    00941                 # save value locally
    00942                 $this->DBFields[$DBFieldName] = $DateValue;
    00943                 break;
    00944
    00945             case MetadataSchema::MDFTYPE_TREE:
    00946                 # if incoming value is array
    00947                 if (is_array($NewValue))
    00948                 {
    00949                     # for each element of array
    00950                     foreach ($NewValue as
    00951                         $ClassificationId => $ClassificationName)
    00952                     {
    00953                         $Class = new Classification($ClassificationId);
    00954                         if ($Class->Status() == Classification::CLASSSTAT_OK)
    00955                         {
    00956                             # associate with resource if not already associated
    00957                             $this->AddAssociation("ResourceClassInts",
    00958                                                   "ClassificationId",
    00959                                                   $ClassificationId);
    00960                             $Class->RecalcResourceCount();
    00961                         }
    00962                     }
    00963                 }
    00964                 else
    00965                 {
    00966                     # associate with resource if not already associated
    00967                     if (is_object($NewValue))
    00968                     {
    00969                         $Class = $NewValue;
    00970                         $NewValue = $Class->Id();
    00971                     }
    00972                     else
    00973                     {
    00974                         $Class = new Classification($NewValue);
    00975                     }
    00976                     $this->AddAssociation("ResourceClassInts",
    00977                                           "ClassificationId",
    00978                                           $NewValue);
    00979                     $Class->RecalcResourceCount();
    00980                 }
    00981
    00982                 # clear our classification cache
    00983                 unset($this->ClassificationCache);
    00984                 break;
    00985
    00986             case MetadataSchema::MDFTYPE_CONTROLLEDNAME:
    00987             case MetadataSchema::MDFTYPE_OPTION:
    00988                 # Clear other values if this field expects unique options
    00989                 if ($Field->AllowMultiple() === FALSE)
    00990                 {
    00991                     $this->RemoveAllAssociations("ResourceNameInts",
    00992                                                  "ControlledNameId",
    00993                                                  $Field );
    00994                 }
    00995
    00996                 # if incoming value is array
    00997                 if (is_array($NewValue) && ($Field->AllowMultiple() !== FALSE) )
    00998                 {
    00999                     # for each element of array
    01000                     foreach ($NewValue as $ControlledNameId => $ControlledName)
    01001                     {
    01002                         # associate with resource if not already associated
    01003                         $this->AddAssociation("ResourceNameInts",
    01004                                               "ControlledNameId",
    01005                                               $ControlledNameId);
    01006                     }
    01007                 }
    01008                 else
    01009                 {
    01010                     # If we're fed an array for a unique option,
    01011                     # just use the last element of the array
    01012                     if (is_array($NewValue))
    01013                     {
    01014                         $NewValue = array_pop($NewValue);
    01015                     }
    01016
    01017                     # associate with resource if not already associated
    01018                     if (is_object($NewValue)) {  $NewValue = $NewValue->Id();  }
    01019                     $this->AddAssociation("ResourceNameInts",
    01020                                           "ControlledNameId",
    01021                                           $NewValue);
    01022                 }
    01023
    01024                 # clear our controlled name cache
    01025                 unset($this->ControlledNameCache);
    01026                 unset($this->ControlledNameVariantCache);
    01027                 break;
    01028
    01029             case MetadataSchema::MDFTYPE_IMAGE:
    01030                 # if we were given an image object
    01031                 if (is_object($NewValue))
    01032                 {
    01033                     # grab ID from object
    01034                     $ImageId = $NewValue->Id();
    01035                 }
    01036                 else
    01037                 {
    01038                     # assume incoming value is ID
    01039                     $ImageId = $NewValue;
    01040                 }
    01041
    01042                 # store new image object ID in database
    01043                 $DB->Query("UPDATE Resources SET `"
    01044                            .$DBFieldName."` = '".$ImageId."'"
    01045                            ." WHERE ResourceId = ".$ResourceId);
    01046
    01047                 # save value locally
    01048                 $this->DBFields[$DBFieldName] = $ImageId;
    01049                 break;
    01050
    01051             case MetadataSchema::MDFTYPE_FILE:
    01052                 # convert incoming value to array if necessary
    01053                 if (!is_array($NewValue)) {  $NewValue = array($NewValue);  }
    01054
    01055                 # for each incoming file
    01056                 $Factory = new FileFactory($Field->Id());
    01057                 foreach ($NewValue as $File)
    01058                 {
    01059                     # make copy of file
    01060                     $NewFile = $Factory->Copy($File);
    01061
    01062                     # associate copy with this resource and field
    01063                     $NewFile->ResourceId($this->Id);
    01064                     $NewFile->FieldId($Field->Id());
    01065                 }
    01066                 break;
    01067
    01068             default:
    01069                 # ERROR OUT
    01070                 exit("<br>SPT - ERROR: attempt to set unknown resource field type<br>\n");
    01071                 break;
    01072         }
    01073     }
    01074     # (for backward compatibility)
    01075     function SetByField($Field, $NewValue) {  return $this->Set($Field, $NewValue);  }
    01076
    01077     # set value by field ID
    01078     function SetByFieldId($FieldId, $NewValue)
    01079     {
    01080         $Field = $this->Schema->GetField($FieldId);
    01081         return $this->Set($Field, $NewValue);
    01082     }
    01083
    01084     # set qualifier by field name
    01085     function SetQualifier($FieldName, $NewValue)
    01086     {
    01087         $Field = $this->Schema->GetFieldByName($FieldName);
    01088         return $this->SetQualifierByField($Field, $NewValue);
    01089     }
    01090
    01091     # set qualifier by field ID
    01092     function SetQualifierByFieldId($FieldId, $NewValue)
    01093     {
    01094         $Field = $this->Schema->GetField($FieldId);
    01095         return $this->SetQualifierByField($Field, $NewValue);
    01096     }
    01097
    01098     # set qualifier using field object
    01099     function SetQualifierByField($Field, $NewValue)
    01100     {
    01101         # if field uses qualifiers and uses item-level qualifiers
    01102         if ($Field->UsesQualifiers() && $Field->HasItemLevelQualifiers())
    01103         {
    01104             # if qualifier object passed in
    01105             if (is_object($NewValue))
    01106             {
    01107                 # grab qualifier ID from object
    01108                 $QualifierId = $NewValue->Id();
    01109             }
    01110             else
    01111             {
    01112                 # assume value passed in is qualifier ID
    01113                 $QualifierId = $NewValue;
    01114             }
    01115
    01116             # update qualifier value in database
    01117             $DBFieldName = $Field->DBFieldName();
    01118             $this->DB->Query("UPDATE Resources SET "
    01119                      .$DBFieldName."Qualifier = '".$QualifierId."' "
    01120                      ."WHERE ResourceId = ".$this->Id);
    01121
    01122             # update local qualifier value
    01123             $this->DBFields[$DBFieldName."Qualifier"] = $QualifierId;
    01124         }
    01125     }
    01126
    01127     # clear value by field name
    01128     function Clear($FieldName, $ValueToClear = NULL)
    01129     {
    01130         $Field = $this->Schema->GetFieldByName($FieldName);
    01131         return $this->ClearByField($Field, $ValueToClear);
    01132     }
    01133
    01134     # clear value by field ID
    01135     function ClearByFieldId($FieldId, $ValueToClear = NULL)
    01136     {
    01137         $Field = $this->Schema->GetField($FieldId);
    01138         return $this->ClearByField($Field, $ValueToClear);
    01139     }
    01140
    01141     # clear value using field object
    01142     function ClearByField($Field, $ValueToClear = NULL)
    01143     {
    01144         # grab commonly-used values for local use
    01145         $DB = $this->DB;
    01146         $ResourceId = $this->Id;
    01147
    01148         # grab database field name
    01149         $DBFieldName = $Field->DBFieldName();
    01150
    01151         # store value in DB based on field type
    01152         switch ($Field->Type())
    01153         {
    01154             case MetadataSchema::MDFTYPE_TEXT:
    01155             case MetadataSchema::MDFTYPE_PARAGRAPH:
    01156             case MetadataSchema::MDFTYPE_NUMBER:
    01157             case MetadataSchema::MDFTYPE_FLAG:
    01158             case MetadataSchema::MDFTYPE_USER:
    01159             case MetadataSchema::MDFTYPE_TIMESTAMP:
    01160             case MetadataSchema::MDFTYPE_URL:
    01161                 # clear value in DB
    01162                 $DB->Query("UPDATE Resources SET `"
    01163                            .$DBFieldName."` = '' "
    01164                            ."WHERE ResourceId = ".$ResourceId);
    01165
    01166                 # clear value locally
    01167                 $this->DBFields[$DBFieldName] = NULL;
    01168                 break;
    01169
    01170             case MetadataSchema::MDFTYPE_POINT:
    01171                 # Clear DB Values
    01172                 $DB->Query("UPDATE Resources SET "
    01173                            ."`".$DBFieldName."X` = NULL ,"
    01174                            ."`".$DBFieldName."Y` = NULL "
    01175                            ."WHERE ResourceId = ".$ResourceId);
    01176
    01177                 # Clear local values
    01178                 $this->DBFields[$DBFieldName."X"] = NULL;
    01179                 $this->DBFields[$DBFieldName."Y"] = NULL;
    01180                 break;
    01181
    01182             case MetadataSchema::MDFTYPE_DATE:
    01183                 # clear date object values in DB
    01184                 $DB->Query("UPDATE Resources SET "
    01185                            .$DBFieldName."Begin = '', "
    01186                            .$DBFieldName."End = '', "
    01187                            .$DBFieldName."Precision = '' "
    01188                            ."WHERE ResourceId = ".$ResourceId);
    01189
    01190                 # clear value locally
    01191                 $this->DBFields[$DBFieldName."Begin"] = NULL;
    01192                 $this->DBFields[$DBFieldName."End"] = NULL;
    01193                 $this->DBFields[$DBFieldName."Precision"] = NULL;
    01194                 break;
    01195
    01196             case MetadataSchema::MDFTYPE_TREE:
    01197                 # if value to clear supplied
    01198                 if ($ValueToClear !== NULL)
    01199                 {
    01200                     # if supplied value is array
    01201                     if (is_array($ValueToClear))
    01202                     {
    01203                         # for each element of array
    01204                         foreach ($ValueToClear as $ClassificationId => $Dummy)
    01205                         {
    01206                             # remove association with resource (if any)
    01207                             $this->RemoveAssociation("ResourceClassInts",
    01208                                                   "ClassificationId",
    01209                                                   $ClassificationId);
    01210                             $Class = new Classification($ClassificationId);
    01211                             $Class->RecalcResourceCount();
    01212                         }
    01213                     }
    01214                     else
    01215                     {
    01216                         # remove association with resource (if any)
    01217                         $this->RemoveAssociation("ResourceClassInts",
    01218                                               "ClassificationId",
    01219                                               $ValueToClear);
    01220                         $Class = new Classification($ValueToClear);
    01221                         $Class->RecalcResourceCount();
    01222                     }
    01223                 }
    01224                 else
    01225                 {
    01226                     # remove all associations for resource and field
    01227                     $this->RemoveAllAssociations("ResourceClassInts", "ClassificationId", $Field);
    01228
    01229                     # recompute resource count
    01230                     $Values = $this->Get($Field);
    01231                     foreach ($Values as $ClassificationId => $Dummy)
    01232                     {
    01233                         $Class = new Classification($ClassificationId);
    01234                         $Class->RecalcResourceCount();
    01235                     }
    01236                 }
    01237
    01238                 # clear our classification cache
    01239                 unset($this->ClassificationCache);
    01240                 break;
    01241
    01242             case MetadataSchema::MDFTYPE_CONTROLLEDNAME:
    01243             case MetadataSchema::MDFTYPE_OPTION:
    01244                 # if value to clear supplied
    01245                 if ($ValueToClear !== NULL)
    01246                 {
    01247                     # if incoming value is array
    01248                     if (is_array($ValueToClear))
    01249                     {
    01250                         # for each element of array
    01251                         foreach ($ValueToClear as $ControlledNameId =>
    01252                             $ControlledName)
    01253                         {
    01254                             # remove association with resource (if any)
    01255                             $this->RemoveAssociation("ResourceNameInts",
    01256                                                   "ControlledNameId",
    01257                                                   $ControlledNameId);
    01258                         }
    01259                     }
    01260                     else
    01261                     {
    01262                         # remove association with resource (if any)
    01263                         $this->RemoveAssociation("ResourceNameInts",
    01264                                               "ControlledNameId",
    01265                                               $ValueToClear);
    01266                     }
    01267                 }
    01268                 else
    01269                 {
    01270                     # remove all associations for resource and field
    01271                     $this->RemoveAllAssociations("ResourceNameInts", "ControlledNameId", $Field);
    01272                 }
    01273
    01274                 # clear our controlled name cache
    01275                 unset($this->ControlledNameCache);
    01276                 unset($this->ControlledNameVariantCache);
    01277                 break;
    01278
    01279             case MetadataSchema::MDFTYPE_IMAGE:
    01280                 # delete image if no other resources are using it
    01281                 $ImageId = $DB->Query("SELECT `".$DBFieldName
    01282                                       ."` FROM Resources WHERE ResourceId = ".$ResourceId,
    01283                                       $DBFieldName);
    01284                 if ($ImageId > 0)
    01285                 {
    01286                     $ImageCount = $DB->Query("SELECT COUNT(*) AS ImageCount FROM Resources"
    01287                                              ." WHERE `".$DBFieldName."` = ".$ImageId,
    01288                                              "ImageCount");
    01289                     if ($ImageCount < 2)
    01290                     {
    01291                         $Image = new SPTImage($ImageId);
    01292                         $Image->Delete();
    01293                     }
    01294                 }
    01295
    01296                 # clear stored ID
    01297                 $DB->Query("UPDATE Resources SET `"
    01298                            .$DBFieldName."` = '' "
    01299                            ."WHERE ResourceId = ".$ResourceId);
    01300
    01301                 # clear value locally
    01302                 $this->DBFields[$DBFieldName] = NULL;
    01303                 break;
    01304
    01305             case MetadataSchema::MDFTYPE_FILE:
    01306                 # get array of Files associated with this resource
    01307                 $Files = $this->Get($Field, TRUE);
    01308
    01309                 # for each File
    01310                 foreach ($Files as $File)
    01311                 {
    01312                     # delete file
    01313                     $File->Delete();
    01314                 }
    01315                 break;
    01316
    01317             default:
    01318                 # ERROR OUT
    01319                 exit("<br>SPT - ERROR: attempt to clear unknown resource field type<br>\n");
    01320                 break;
    01321         }
    01322     }
    01323
    01324
    01325     # --- Field-Specific or Type-Specific Attribute Retrieval Methods -------
    01326
    01327     # return 2D array of classifications associated with resource
    01328     # (first index is classification (field) name, second index is classification ID)
    01329     function Classifications()
    01330     {
    01331         $DB = $this->DB;
    01332
    01333         # start with empty array
    01334         $Names = array();
    01335
    01336         # for each controlled name
    01337         $DB->Query("SELECT ClassificationName, MetadataFields.FieldName, "
    01338                 ."ResourceClassInts.ClassificationId FROM ResourceClassInts, "
    01339                 ."Classifications, MetadataFields "
    01340                 ."WHERE ResourceClassInts.ResourceId = ".$this->Id." "
    01341                 ."AND ResourceClassInts.ClassificationId = Classifications.ClassificationId "
    01342                 ."AND Classifications.FieldId = MetadataFields.FieldId ");
    01343         while ($Record = $DB->FetchRow())
    01344         {
    01345             # add name to array
    01346             $Names[$Record["FieldName"]][$Record["ClassificationId"]] =
    01347                     $Record["ClassificationName"];
    01348         }
    01349
    01350         # return array to caller
    01351         return $Names;
    01352     }
    01353
    01354
    01355     # --- Ratings Methods ---------------------------------------------------
    01356
    01357     # return cumulative rating  (range is usually 0-100)
    01358     function CumulativeRating() {  return $this->CumulativeRating;  }
    01359
    01360     # return cumulative rating scaled to 1/10th  (range is usually 0-10)
    01361     function ScaledCumulativeRating()
    01362     {
    01363         if ($this->CumulativeRating == NULL)
    01364         {
    01365             return NULL;
    01366         }
    01367         else
    01368         {
    01369             return intval(($this->CumulativeRating + 5) / 10);
    01370         }
    01371     }
    01372
    01373     # return current number of ratings for resource
    01374     function NumberOfRatings()
    01375     {
    01376         # if number of ratings not already set
    01377         if (!isset($this->NumberOfRatings))
    01378         {
    01379             # obtain number of ratings
    01380             $this->NumberOfRatings =
    01381                     $this->DB->Query("SELECT Count(*) AS NumberOfRatings "
    01382                             ."FROM ResourceRatings "
    01383                             ."WHERE ResourceId = ".$this->Id,
    01384                     "NumberOfRatings"
    01385                     );
    01386
    01387             # recalculate cumulative rating if it looks erroneous
    01388             if (($this->NumberOfRatings > 0) && !$this->CumulativeRating())
    01389             {
    01390                 $this->UpdateCumulativeRating();
    01391             }
    01392         }
    01393
    01394         # return number of ratings to caller
    01395         return $this->NumberOfRatings;
    01396     }
    01397
    01398     # update individual rating for resource
    01399     function Rating($NewRating = NULL, $UserId = NULL)
    01400     {
    01401         $DB = $this->DB;
    01402
    01403         # if user ID not supplied
    01404         if ($UserId == NULL)
    01405         {
    01406             # if user is logged in
    01407             global $User;
    01408             if ($User->IsLoggedIn())
    01409             {
    01410                 # use ID of current user
    01411                 $UserId = $User->Get("UserId");
    01412             }
    01413             else
    01414             {
    01415                 # return NULL to caller
    01416                 return NULL;
    01417             }
    01418         }
    01419
    01420         # sanitize $NewRating
    01421         if (!is_null($NewRating))
    01422         {
    01423             $NewRating = intval($NewRating);
    01424         }
    01425
    01426         # if there is a rating for resource and user
    01427         $DB->Query("SELECT Rating FROM ResourceRatings "
    01428                 ."WHERE UserId = ${UserId} AND ResourceId = ".$this->Id);
    01429         if ($Record = $DB->FetchRow())
    01430         {
    01431             # if new rating was supplied
    01432             if ($NewRating != NULL)
    01433             {
    01434                 # update existing rating
    01435                 $DB->Query("UPDATE ResourceRatings "
    01436                         ."SET Rating = ${NewRating}, DateRated = NOW() "
    01437                         ."WHERE UserId = ${UserId} AND ResourceId = ".$this->Id);
    01438
    01439                 # update cumulative rating value
    01440                 $this->UpdateCumulativeRating();
    01441
    01442                 # return value is new rating
    01443                 $Rating = $NewRating;
    01444             }
    01445             else
    01446             {
    01447                 # get rating value to return to caller
    01448                 $Rating = $Record["Rating"];
    01449             }
    01450         }
    01451         else
    01452         {
    01453             # if new rating was supplied
    01454             if ($NewRating != NULL)
    01455             {
    01456                 # add new rating
    01457                 $DB->Query("INSERT INTO ResourceRatings "
    01458                         ."(ResourceId, UserId, DateRated, Rating) "
    01459                         ."VALUES ("
    01460                                 .$this->Id.", "
    01461                                 ."${UserId}, "
    01462                                 ."NOW(), "
    01463                                 ."${NewRating})");
    01464
    01465                 # update cumulative rating value
    01466                 $this->UpdateCumulativeRating();
    01467
    01468                 # return value is new rating
    01469                 $Rating = $NewRating;
    01470             }
    01471             else
    01472             {
    01473                 # return value is NULL
    01474                 $Rating = NULL;
    01475             }
    01476         }
    01477
    01478         # return rating value to caller
    01479         return $Rating;
    01480     }
    01481
    01482
    01483     # --- Resource Comment Methods ------------------------------------------
    01484
    01485     # return comments as array of Message objects
    01486     function Comments()
    01487     {
    01488         # read in comments if not already loaded
    01489         if (!isset($this->Comments))
    01490         {
    01491             $this->DB->Query("SELECT MessageId FROM Messages "
    01492                     ."WHERE ParentId = ".$this->Id
    01493                     ." AND ParentType = 2 "
    01494                     ."ORDER BY DatePosted DESC");
    01495             while ($MessageId = $this->DB->FetchField("MessageId"))
    01496             {
    01497                 $this->Comments[] = new Message($MessageId);
    01498             }
    01499         }
    01500
    01501         # return array of comments to caller
    01502         return $this->Comments;
    01503     }
    01504
    01505     # return current number of comments
    01506     function NumberOfComments()
    01507     {
    01508         # obtain number of comments if not already set
    01509         if (!isset($this->NumberOfComments))
    01510         {
    01511             $this->NumberOfComments =
    01512                     $this->DB->Query("SELECT Count(*) AS NumberOfComments "
    01513                             ."FROM Messages "
    01514                             ."WHERE ParentId = ".$this->Id
    01515                             ." AND ParentType = 2",
    01516                     "NumberOfComments"
    01517                     );
    01518         }
    01519
    01520         # return number of comments to caller
    01521         return $this->NumberOfComments;
    01522     }
    01523
    01524
    01525     # --- Permission Methods -------------------------------------------------
    01526
    01527     # return whether user can edit this resource
    01528     function UserCanEdit($User)
    01529     {
    01530         return ($User->HasPriv(PRIV_RESOURCEADMIN)
    01531             || $User->HasPriv(PRIV_RELEASEADMIN)
    01532             || ($User->HasPriv(PRIV_MYRESOURCEADMIN)
    01533                     && ($User->Id() == $this->DBFields["AddedById"]))
    01534         );
    01535     }
    01536
    01537     # report whether user can view or edit specified field
    01538     function UserCanViewField($User, $FieldOrFieldName)
    01539     {
    01540         # get field (if not supplied)
    01541         if (is_object($FieldOrFieldName)
    01542                 && ($FieldOrFieldName instanceof MetadataField))
    01543         {
    01544             $Field = $FieldOrFieldName;
    01545         }
    01546         elseif (strlen(trim($FieldOrFieldName)))
    01547         {
    01548             $Schema = new MetadataSchema();
    01549             if ($Schema->FieldExists($FieldOrFieldName))
    01550             {
    01551                 $Field = $Schema->GetFieldByName($FieldOrFieldName);
    01552             }
    01553         }
    01554         if (!isset($Field))
    01555         {
    01556             return FALSE;
    01557         }
    01558
    01559         # return enabled and viewable state from field
    01560         return $Field->Enabled()
    01561                 && ($Field->ViewingPrivilege() == 0
    01562                     || $User->HasPriv($Field->ViewingPrivilege())
    01563                     || $this->UserCanEditField($User, $Field));
    01564     }
    01565
    01566     function UserCanEditField($User, $FieldOrFieldName)
    01567     {
    01568         # get field (if not supplied)
    01569         if (is_object($FieldOrFieldName)
    01570                 && ($FieldOrFieldName instanceof MetadataField))
    01571         {
    01572             $Field = $FieldOrFieldName;
    01573         }
    01574         elseif (strlen(trim($FieldOrFieldName)))
    01575         {
    01576             $Schema = new MetadataSchema();
    01577             if ($Schema->FieldExists($FieldOrFieldName))
    01578             {
    01579                 $Field = $Schema->GetFieldByName($FieldOrFieldName);
    01580             }
    01581         }
    01582         if (!isset($Field))
    01583         {
    01584             return FALSE;
    01585         }
    01586
    01587         # start out assuming field cannot be edited
    01588         $IsEditable = FALSE;
    01589
    01590         # if user has editing privileges for field
    01591         #       or user added resource and has authoring privileges for field
    01592         if ($User->HasPriv($Field->EditingPrivilege())
    01593                 || (($User->Name() == $this->Get("Added By Id"))
    01594                         && (($Field->AuthoringPrivilege() == 0)
    01595                             || $User->HasPriv($Field->AuthoringPrivilege()))))
    01596         {
    01597             # if field name does not appear on "no edit" list
    01598             $UneditableFields = array(
    01599                     "Cumulative Rating",
    01600                     "Date Of Record Creation",
    01601                     "Date Of Record Release",
    01602                     "Date Last Modified",
    01603                     "Added By Id",
    01604                     "Last Modified By Id",
    01605                     );
    01606             if (!in_array($Field->Name(), $UneditableFields))
    01607             {
    01608                 # user can edit field
    01609                 $IsEditable = TRUE;
    01610             }
    01611         }
    01612
    01613         # return result to caller
    01614         return $IsEditable;
    01615     }
    01616
    01617     # ---- PRIVATE INTERFACE -------------------------------------------------
    01618
    01619     private $DB;
    01620     private $Schema;
    01621     private $DBFields;
    01622     private $Id;
    01623     private $NumberOfRatings;
    01624     private $CumulativeRating;
    01625     private $NumberOfComments;
    01626     private $Comments;
    01627     private $LastStatus;
    01628     private $ControlledNameCache;
    01629     private $ControlledNameVariantCache;
    01630     private $ClassificationCache;
    01631
    01632     # recalculate and save cumulative rating value for resource
    01633     private function UpdateCumulativeRating()
    01634     {
    01635         # grab totals from DB
    01636         $this->DB->Query("SELECT COUNT(Rating) AS Count, "
    01637                 ."SUM(Rating) AS Total FROM ResourceRatings "
    01638                 ."WHERE ResourceId = ".$this->Id);
    01639         $Record = $this->DB->FetchRow();
    01640
    01641         # calculate new cumulative rating
    01642         $this->CumulativeRating = round($Record["Total"] / $Record["Count"]);
    01643
    01644         # save new cumulative rating in DB
    01645         $this->DB->Query("UPDATE Resources "
    01646                 ."SET CumulativeRating = ".$this->CumulativeRating." "
    01647                 ."WHERE ResourceId = ".$this->Id);
    01648     }
    01649
    01650     # add intersection if not already present
    01651     private function AddAssociation($TableName, $TargetFieldName, $TargetValue)
    01652     {
    01653         # if target not already associated with resource
    01654         if ($this->DB->Query("SELECT COUNT(*) AS RecordCount FROM ".$TableName
    01655                    ." WHERE ResourceId = ".$this->Id
    01656                    ." AND ".$TargetFieldName." = '".$TargetValue."'",
    01657                    "RecordCount") == 0)
    01658         {
    01659             # associate target with resource
    01660             $this->DB->Query("INSERT INTO ".$TableName." SET"
    01661                        ." ResourceId = ".$this->Id
    01662                        .", ".$TargetFieldName." = '".$TargetValue."'");
    01663         }
    01664     }
    01665
    01666     # remove intersections (if any)
    01667     private function RemoveAssociation($TableName, $TargetFieldName, $TargetValue)
    01668     {
    01669         # remove any intersections with target ID from DB
    01670         $this->DB->Query("DELETE FROM ".$TableName
    01671                          ." WHERE ResourceId = ".$this->Id
    01672                          ." AND ".$TargetFieldName." = '".$TargetValue."'");
    01673     }
    01674
    01675     # remove all intersections for resource and field (if any)
    01676     private function RemoveAllAssociations($TableName, $TargetFieldName, $Field)
    01677     {
    01678         # retrieve list of entries for this field and resource
    01679         $Entries = $this->Get($Field);
    01680
    01681         # for each entry
    01682         foreach ($Entries as $EntryId => $EntryName)
    01683         {
    01684             # remove intersection
    01685             $this->RemoveAssociation($TableName, $TargetFieldName, $EntryId);
    01686         }
    01687     }
    01688 }

Copyright 2010 Internet Scout