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 }

CWIS logo doxygen
Copyright 2010 Internet Scout