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 # 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 ?>