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