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