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