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