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 {
01518 $Field = $FieldOrFieldName;
01519 }
01520 else
01521 {
01522 $Schema = new MetadataSchema();
01523 $Field = $Schema->GetFieldByName($FieldOrFieldName);
01524 }
01525
01526 if ($Field->Status() != MetadataSchema::MDFSTAT_OK)
01527 {
01528 return FALSE;
01529 }
01530
01531 # return enabled and viewable state from field
01532 return $Field->Enabled()
01533 && ($Field->ViewingPrivilege() == 0
01534 || $User->HasPriv($Field->ViewingPrivilege())
01535 || $this->UserCanEditField($User, $Field));
01536 }
01537
01538 function UserCanEditField($User, $FieldOrFieldName)
01539 {
01540 # get field (if not supplied)
01541 if (is_object($FieldOrFieldName))
01542 {
01543 $Field = $FieldOrFieldName;
01544 }
01545 else
01546 {
01547 $Schema = new MetadataSchema();
01548 $Field = $Schema->GetFieldByName($FieldOrFieldName);
01549 }
01550
01551 if ($Field->Status() != MetadataSchema::MDFSTAT_OK)
01552 {
01553 return FALSE;
01554 }
01555
01556 # start out assuming field cannot be edited
01557 $IsEditable = FALSE;
01558
01559 # if user has editing privileges for field
01560 # or user added resource and has authoring privileges for field
01561 if ($User->HasPriv($Field->EditingPrivilege())
01562 || (($User->Name() == $this->Get("Added By Id"))
01563 && (($Field->AuthoringPrivilege() == 0)
01564 || $User->HasPriv($Field->AuthoringPrivilege()))))
01565 {
01566 # if field name does not appear on "no edit" list
01567 $UneditableFields = array(
01568 "Cumulative Rating",
01569 "Date Of Record Creation",
01570 "Date Of Record Release",
01571 "Date Last Modified",
01572 "Added By Id",
01573 "Last Modified By Id",
01574 );
01575 if (!in_array($Field->Name(), $UneditableFields))
01576 {
01577 # user can edit field
01578 $IsEditable = TRUE;
01579 }
01580 }
01581
01582 # return result to caller
01583 return $IsEditable;
01584 }
01585
01586 # ---- PRIVATE INTERFACE -------------------------------------------------
01587
01588 private $DB;
01589 private $Schema;
01590 private $DBFields;
01591 private $Id;
01592 private $NumberOfRatings;
01593 private $CumulativeRating;
01594 private $NumberOfComments;
01595 private $Comments;
01596 private $LastStatus;
01597 private $ControlledNameCache;
01598 private $ControlledNameVariantCache;
01599 private $ClassificationCache;
01600
01601 # recalculate and save cumulative rating value for resource
01602 private function UpdateCumulativeRating()
01603 {
01604 # grab totals from DB
01605 $this->DB->Query("SELECT COUNT(Rating) AS Count, "
01606 ."SUM(Rating) AS Total FROM ResourceRatings "
01607 ."WHERE ResourceId = ".$this->Id);
01608 $Record = $this->DB->FetchRow();
01609
01610 # calculate new cumulative rating
01611 $this->CumulativeRating = round($Record["Total"] / $Record["Count"]);
01612
01613 # save new cumulative rating in DB
01614 $this->DB->Query("UPDATE Resources "
01615 ."SET CumulativeRating = ".$this->CumulativeRating." "
01616 ."WHERE ResourceId = ".$this->Id);
01617 }
01618
01619 # add intersection if not already present
01620 private function AddAssociation($TableName, $TargetFieldName, $TargetValue)
01621 {
01622 # if target not already associated with resource
01623 if ($this->DB->Query("SELECT COUNT(*) AS RecordCount FROM ".$TableName
01624 ." WHERE ResourceId = ".$this->Id
01625 ." AND ".$TargetFieldName." = '".$TargetValue."'",
01626 "RecordCount") == 0)
01627 {
01628 # associate target with resource
01629 $this->DB->Query("INSERT INTO ".$TableName." SET"
01630 ." ResourceId = ".$this->Id
01631 .", ".$TargetFieldName." = '".$TargetValue."'");
01632 }
01633 }
01634
01635 # remove intersections (if any)
01636 private function RemoveAssociation($TableName, $TargetFieldName, $TargetValue)
01637 {
01638 # remove any intersections with target ID from DB
01639 $this->DB->Query("DELETE FROM ".$TableName
01640 ." WHERE ResourceId = ".$this->Id
01641 ." AND ".$TargetFieldName." = '".$TargetValue."'");
01642 }
01643
01644 # remove all intersections for resource and field (if any)
01645 private function RemoveAllAssociations($TableName, $TargetFieldName, $Field)
01646 {
01647 # retrieve list of entries for this field and resource
01648 $Entries = $this->Get($Field);
01649
01650 # for each entry
01651 foreach ($Entries as $EntryId => $EntryName)
01652 {
01653 # remove intersection
01654 $this->RemoveAssociation($TableName, $TargetFieldName, $EntryId);
01655 }
01656 }
01657 }
01658
01659
01660 ?>