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

Copyright 2010 Internet Scout