5 # Part of the Collection Workflow Integration System (CWIS) 6 # Copyright 2011-2016 Edward Almasy and Internet Scout Research Group 7 # http://scout.wisc.edu/cwis/ 16 # ---- PUBLIC INTERFACE -------------------------------------------------- 26 # call parent contstructor to load info from DB 27 parent::__construct($ResourceId);
29 # load local attributes from database value cache 32 # load our local metadata schema 33 $this->
SchemaId = $this->ValueCache[
"SchemaId"];
34 if (!isset(self::$Schemas[$this->
SchemaId]))
36 self::$Schemas[$this->SchemaId] =
47 public static function Create($SchemaId)
49 # clean out any temp resource records more than three days old 51 $RFactory->CleanOutStaleTempItems(60 * 24 * 3);
53 # lock DB tables to prevent next ID from being grabbed 55 $DB->Query(
"LOCK TABLES Resources WRITE");
57 # find next temp resource ID 58 $Id = $RFactory->GetNextTempItemId();
60 # write out new resource record with temp resource ID 61 # Set DateLastModified = NOW() to avoid being pruned as a 62 # stale temp resource. 64 "INSERT INTO Resources 65 SET `ResourceId` = '".intval(
$Id).
"', 66 `SchemaId` = '".intval($SchemaId).
"', 67 `DateLastModified` = NOW() " );
70 $DB->Query(
"UNLOCK TABLES");
72 # create new Resource object 75 # set some additional fields for default resources 78 $Resource->Set(
"Added By Id", $GLOBALS[
"G_User"]->
Id());
79 $Resource->Set(
"Last Modified By Id", $GLOBALS[
"G_User"]->
Id());
80 $Resource->Set(
"Date Of Record Creation", date(
"Y-m-d H:i:s"));
81 $Resource->Set(
"Date Last Modified", date(
"Y-m-d H:i:s"));
84 # for each field that can have a default value 91 foreach ($Fields as $Field)
93 # if there is a default value available 94 $DefaultValue = $Field->DefaultValue();
95 if ($DefaultValue !== NULL)
97 # if the default value is an array 98 if (is_array($DefaultValue))
100 # if there are values in the array 101 if (!empty($DefaultValue))
103 # flip values for Set() if necessary 106 $DefaultValue = array_flip($DefaultValue);
110 $Resource->Set($Field, $DefaultValue);
116 $Resource->Set($Field, $DefaultValue);
121 $Resource->UpdateAutoupdateFields(
125 # signal resource creation 126 $GLOBALS[
"AF"]->SignalEvent(
"EVENT_RESOURCE_CREATE", array(
127 "Resource" => $Resource,
130 # return new Resource object to caller 142 # signal that resource deletion is about to occur 144 $AF->SignalEvent(
"EVENT_RESOURCE_DELETE", array(
148 # grab list of classifications 151 # delete resource/classification intersections 153 $DB->Query(
"DELETE FROM ResourceClassInts WHERE ResourceId = ".$this->
Id());
155 # for each classification type 156 foreach ($Classifications as $ClassType => $ClassesOfType)
158 # for each classification of that type 159 foreach ($ClassesOfType as $ClassId => $ClassName)
161 # recalculate resource count for classification 163 $Class->RecalcResourceCount();
167 # delete resource references 169 DELETE FROM ReferenceInts 170 WHERE SrcResourceId = '".addslashes($this->
Id()).
"' 171 OR DstResourceId = '".addslashes($this->
Id()).
"'");
173 # delete resource/name intersections 174 $DB->Query(
"DELETE FROM ResourceNameInts WHERE ResourceId = ".$this->
Id());
176 # delete resource/user intersections 177 $DB->Query(
"DELETE FROM ResourceUserInts WHERE ResourceId = ".$this->
Id());
179 # get the list of all images associated with this resource 180 $DB->Query(
"SELECT ImageId FROM ResourceImageInts" 181 .
" WHERE ResourceId = ".intval($this->
Id()));
182 $ImageIds =
$DB->FetchColumn(
"ImageId");
184 # disassociate this resource from all images 185 $DB->Query(
"DELETE FROM ResourceImageInts" 186 .
" WHERE ResourceId = ".intval($this->
Id()));
188 # delete any images that no longer belong to any resources 189 foreach ($ImageIds as $ImageId)
191 $DB->Query(
"SELECT ResourceId FROM ResourceImageInts" 192 .
" WHERE ImageId = ".intval($ImageId) );
193 if (
$DB->NumRowsSelected() == 0)
200 # delete any associated files 202 $Files = $Factory->GetFilesForResource($this->
Id());
203 foreach ($Files as $File)
208 # delete resource record from database 209 $DB->Query(
"DELETE FROM Resources WHERE ResourceId = ".$this->
Id());
211 # drop item from search engine and recommender system 212 if ($SysConfig->SearchDBEnabled())
215 $SearchEngine->DropItem($this->
Id());
217 if ($SysConfig->RecommenderDBEnabled())
220 $Recommender->DropItem($this->
Id());
223 # get the folders containing the resource 225 $Folders = $FolderFactory->GetFoldersContainingItem(
229 # drop the resource from each folder it belongs to 230 foreach ($Folders as $Folder)
232 # mixed item type folder 233 if ($Folder->ContainsItem($this->Id,
"Resource"))
235 $Folder->RemoveItem($this->
Id,
"Resource");
238 # single item type folder 241 $Folder->RemoveItem($this->
Id);
245 # delete any resource comments 246 $DB->Query(
"DELETE FROM Messages WHERE ParentId = ".$this->
Id);
257 # update all the timestamp fields as required 258 $TimestampFields = $this->
Schema()->GetFields(
260 foreach ($TimestampFields as $Field)
262 if ($Field->UpdateMethod() == $UpdateType)
264 $this->
Set($Field,
"now");
268 # if a user was provided, update the user fields as well 271 $UserFields = $this->
Schema()->GetFields(
273 foreach ($UserFields as $Field)
275 if ($Field->UpdateMethod() == $UpdateType)
277 $this->
Set($Field, $User);
298 return $this->SchemaId;
307 return self::$Schemas[$this->SchemaId];
318 # if new temp resource setting supplied 319 if (!is_null($NewSetting))
321 # if caller requested to switch 323 if ((($this->
Id() < 0) && ($NewSetting == FALSE))
324 || (($this->
Id() >= 0) && ($NewSetting == TRUE)))
326 # lock DB tables to prevent next ID from being grabbed 327 $DB->Query(
"LOCK TABLES Resources write");
329 # get next resource ID as appropriate 332 if ($NewSetting == TRUE)
334 $this->
Id = $Factory->GetNextTempItemId();
338 $this->
Id = $Factory->GetNextItemId();
342 $DB->Query(
"UPDATE Resources SET ResourceId = ".
343 $this->
Id.
" WHERE ResourceId = ".$OldResourceId);
346 $DB->Query(
"UNLOCK TABLES");
348 # change associations 349 unset($this->ClassificationCache);
350 $DB->Query(
"UPDATE ResourceClassInts SET ResourceId = ".
351 $this->
Id.
" WHERE ResourceId = ".$OldResourceId);
352 unset($this->ControlledNameCache);
353 unset($this->ControlledNameVariantCache);
354 $DB->Query(
"UPDATE ResourceNameInts SET ResourceId = ".
355 $this->
Id.
" WHERE ResourceId = ".$OldResourceId);
356 $DB->Query(
"UPDATE Files SET ResourceId = ".
357 $this->
Id.
" WHERE ResourceId = ".$OldResourceId);
358 $DB->Query(
"UPDATE ReferenceInts SET SrcResourceId = ".
359 $this->
Id.
" WHERE SrcResourceId = ".$OldResourceId);
360 $DB->Query(
"UPDATE ResourceImageInts SET ResourceId = ".
361 $this->
Id.
" WHERE ResourceId = ".$OldResourceId);
362 $DB->Query(
"UPDATE ResourceUserInts SET ResourceId = ".
363 $this->
Id.
" WHERE ResourceId = ".$OldResourceId);
365 # signal event as appropriate 366 if ($NewSetting === FALSE)
368 $GLOBALS[
"AF"]->SignalEvent(
"EVENT_RESOURCE_ADD", array(
375 # report to caller whether we are a temp resource 376 return ($this->
Id() < 0) ? TRUE : FALSE;
380 # --- Generic Attribute Retrieval Methods ------------------------------- 388 # put our Id into the ViewPage from our schema 391 $this->
Schema()->ViewPage());
393 # return clean url, if one is available 394 return $GLOBALS[
"AF"]->GetCleanUrlForPath($Url);
410 public function Get($Field, $ReturnObject = FALSE, $IncludeVariants = FALSE)
412 # load field object if not already supplied 413 $Field = is_object($Field) ? $Field
414 : (is_numeric($Field) ? $this->
Schema()->GetField($Field)
415 : $this->
Schema()->GetFieldByName($Field));
417 # return no value found if we don't have a valid field 420 if ($Field->SchemaId() != $this->
SchemaId())
422 throw new Exception(
"Attempt to get a value for a field" 423 .
" from a different schema." 424 .
" (Field: ".$Field->Name().
" [".$Field->Id()
425 .
"], Field Schema: ".$Field->SchemaId()
426 .
", Resource Schema: ".$this->
SchemaId()
430 # grab database field name 431 $DBFieldName = $Field->DBFieldName();
433 # format return value based on field type 434 switch ($Field->Type())
439 $ReturnValue = isset($this->ValueCache[$DBFieldName])
440 ? (string)$this->ValueCache[$DBFieldName] : NULL;
444 $ReturnValue = isset($this->ValueCache[$DBFieldName])
445 ? (int)$this->ValueCache[$DBFieldName] : NULL;
449 $ReturnValue = isset($this->ValueCache[$DBFieldName])
450 ? (bool)$this->ValueCache[$DBFieldName] : NULL;
454 $ReturnValue = array(
"X" => (
float)$this->ValueCache[$DBFieldName.
"X"],
455 "Y" => (
float)$this->ValueCache[$DBFieldName.
"Y"]);
459 $Date =
new Date($this->ValueCache[$DBFieldName.
"Begin"],
460 $this->ValueCache[$DBFieldName.
"End"],
461 $this->ValueCache[$DBFieldName.
"Precision"]);
464 $ReturnValue = $Date;
468 $ReturnValue = $Date->Formatted();
473 $ReturnValue = $this->ValueCache[$DBFieldName];
477 # start with empty array 478 $ReturnValue = array();
480 # if classification cache has not been loaded 481 if (!isset($this->ClassificationCache))
483 # load all classifications associated with this resource into cache 484 $this->ClassificationCache = array();
486 "SELECT Classifications.ClassificationId," 487 .
" Classifications.FieldId,ClassificationName" 488 .
" FROM ResourceClassInts, Classifications" 489 .
" WHERE ResourceClassInts.ResourceId = ".$this->
Id 490 .
" AND ResourceClassInts.ClassificationId" 491 .
" = Classifications.ClassificationId");
492 while ($Record = $this->DB->FetchRow())
494 $ClassId = $Record[
"ClassificationId"];
495 $this->ClassificationCache[$ClassId][
"Name"]
496 = $Record[
"ClassificationName"];
497 $this->ClassificationCache[$ClassId][
"FieldId"]
498 = $Record[
"FieldId"];
501 # for each entry in classification cache 502 foreach ($this->ClassificationCache as
503 $ClassificationId => $ClassificationInfo)
505 # if classification ID matches field we are looking for 506 if ($ClassificationInfo[
"FieldId"] == $Field->Id())
508 # add field to result 511 $ReturnValue[$ClassificationId] =
516 $ReturnValue[$ClassificationId] = $ClassificationInfo[
"Name"];
524 # start with empty array 525 $ReturnValue = array();
527 # if controlled name cache has not been loaded 528 if (!isset($this->ControlledNameCache))
530 # load all controlled names associated with this resource into cache 531 $this->ControlledNameCache = array();
533 "SELECT ControlledNames.ControlledNameId," 534 .
" ControlledNames.FieldId,ControlledName" 535 .
" FROM ResourceNameInts, ControlledNames" 536 .
" WHERE ResourceNameInts.ResourceId = ".$this->
Id 537 .
" AND ResourceNameInts.ControlledNameId" 538 .
" = ControlledNames.ControlledNameId" 539 .
" ORDER BY ControlledNames.ControlledName ASC");
540 while ($Record = $this->DB->FetchRow())
542 $CNameId = $Record[
"ControlledNameId"];
543 $this->ControlledNameCache[$CNameId][
"Name"]
544 = $Record[
"ControlledName"];
545 $this->ControlledNameCache[$CNameId][
"FieldId"]
546 = $Record[
"FieldId"];
550 # if variant names requested and variant name cache has not been loaded 551 if ($IncludeVariants && !isset($this->ControlledNameVariantCache))
553 # load all controlled names associated with this resource into cache 554 $this->ControlledNameVariantCache = array();
555 $this->DB->Query(
"SELECT ControlledNames.ControlledNameId," 556 .
" ControlledNames.FieldId," 557 .
" ControlledName, VariantName" 558 .
" FROM ResourceNameInts, ControlledNames, VariantNames" 559 .
" WHERE ResourceNameInts.ResourceId = ".$this->
Id 560 .
" AND ResourceNameInts.ControlledNameId" 561 .
" = ControlledNames.ControlledNameId" 562 .
" AND VariantNames.ControlledNameId" 563 .
" = ControlledNames.ControlledNameId");
564 while ($Record = $this->DB->FetchRow())
566 $this->ControlledNameVariantCache[$Record[
"ControlledNameId"]][]
567 = $Record[
"VariantName"];
571 # for each entry in controlled name cache 572 foreach ($this->ControlledNameCache as
573 $CNameId => $ControlledNameInfo)
575 # if controlled name type matches field we are looking for 576 if ($ControlledNameInfo[
"FieldId"] == $Field->Id())
578 # if objects requested 581 $ReturnValue[$CNameId] =
586 # if variant names requested 587 if ($IncludeVariants)
589 # add field to result 590 $ReturnValue[] = $ControlledNameInfo[
"Name"];
592 # add any variant names to result 593 if (isset($this->ControlledNameVariantCache[$CNameId]))
595 $ReturnValue = array_merge(
597 $this->ControlledNameVariantCache[$CNameId]);
602 # add field with index to result 603 $ReturnValue[$CNameId] =
604 $ControlledNameInfo[
"Name"];
612 # start out assuming no associated users 613 $ReturnValue = array();
615 # query the database to get the associated userids 617 "SELECT UserId FROM ResourceUserInts WHERE ".
618 "ResourceId=".intval($this->
Id).
619 " AND FieldId=".intval($Field->Id()));
620 $UserIds = $this->DB->FetchColumn(
"UserId");
622 # convert each userid to either a name or a CWUser object 623 foreach ($UserIds as $UserId)
625 $User =
new CWUser(intval($UserId));
628 $ReturnValue[$UserId] = $User;
632 $ReturnValue[$UserId] = $User->Get(
"UserName");
638 # start out assuming no images will be found 639 $ReturnValue = array();
641 # find all images associated with this resource 642 $this->DB->Query(
"SELECT ImageId FROM ResourceImageInts" 643 .
" WHERE ResourceId = ".intval($this->
Id())
644 .
" AND FieldId = ".intval($Field->Id()));
646 # if images were found 647 if ($this->DB->NumRowsSelected())
649 # if we are to return an object 650 $ImageIds = $this->DB->FetchColumn(
"ImageId");
653 # load array of Image objects for return value 654 foreach ($ImageIds as $ImageId)
656 $ReturnValue[$ImageId] =
new SPTImage($ImageId);
661 # load array of Image ids for return value 662 $ReturnValue = $ImageIds;
668 # retrieve files using factory 671 $this->
Id, $ReturnObject);
675 # query for resource references 677 SELECT * FROM ReferenceInts 678 WHERE FieldId = '".addslashes($Field->Id()).
"' 679 AND SrcResourceId = '".addslashes($this->
Id()).
"'");
681 $ReturnValue = array();
683 # return each reference as a Resource object 686 $FoundErrors = FALSE;
688 while (FALSE !== ($Record = $this->DB->FetchRow()))
690 $ReferenceId = $Record[
"DstResourceId"];
691 $Reference =
new Resource($ReferenceId);
692 $ReturnValue[$ReferenceId] = $Reference;
696 # return each reference as a resource ID 699 while (FALSE !== ($Record = $this->DB->FetchRow()))
701 $ReferenceId = $Record[
"DstResourceId"];
702 $ReturnValue[$ReferenceId] = $ReferenceId;
709 exit(
"<br>SPT - ERROR: attempt to retrieve " 710 .
"unknown resource field type (".$Field->Type().
")<br>\n");
714 # return formatted value to caller 738 $FieldNameOrObject, $ReturnObject = TRUE, $IncludeVariants = FALSE)
740 # normalize metadata field for use by any hooked code 741 $Field = is_object($FieldNameOrObject) ? $FieldNameOrObject
742 : $this->
Schema()->GetFieldByName($FieldNameOrObject);
745 $Value = $this->
Get($Field, $ReturnObject, $IncludeVariants);
747 # signal event to allowed hooked code to modify value 748 $SignalResult = $GLOBALS[
"AF"]->SignalEvent(
749 "EVENT_FIELD_DISPLAY_FILTER", array(
754 # return possibly modified value to caller 755 return $SignalResult[
"Value"];
774 $ReturnObject = FALSE, $IncludeVariants = FALSE)
776 return $this->
Get($FieldNameOrObject, $ReturnObject, $IncludeVariants);
794 $FieldId, $ReturnObject = FALSE, $IncludeVariants = FALSE)
796 return $this->
Get($FieldId, $ReturnObject, $IncludeVariants);
811 public function GetAsArray($IncludeDisabledFields = FALSE, $ReturnObjects = TRUE)
813 # retrieve field info 814 $Fields = $this->
Schema()->GetFields();
817 foreach ($Fields as $Field)
819 # if field is enabled or caller requested disabled fields 820 if ($Field->Enabled() || $IncludeDisabledFields)
822 # retrieve info and add it to the array 823 $FieldStrings[$Field->Name()] = $this->
Get($Field, $ReturnObjects);
825 # if field uses qualifiers 826 if ($Field->UsesQualifiers())
828 # get qualifier attributes and add to the array 829 $FieldStrings[$Field->Name().
" Qualifier"] =
835 # add in internal values 836 $FieldStrings[
"ResourceId"] = $this->
Id();
839 # return array to caller 840 return $FieldStrings;
858 $MappedName, $ReturnObject = FALSE, $IncludeVariants = FALSE)
860 $Schema = $this->
Schema();
861 $FieldId = $Schema->StdNameToFieldMapping($MappedName);
863 ? $this->
Get($FieldId, $ReturnObject, $IncludeVariants)
877 $Field = $this->
Schema()->GetFieldByName($FieldName);
891 $Field = $this->
Schema()->GetField($FieldId);
905 # return NULL if field is invalid 908 # assume no qualifiers if not otherwise determined 911 # if field uses qualifiers 912 if ($Field->UsesQualifiers())
914 # retrieve qualifiers based on field type 915 switch ($Field->Type())
920 # retrieve list of items 923 # if field uses item-level qualifiers 924 if ($Field->HasItemLevelQualifiers())
926 # determine general item name in DB 928 ?
"Classification" :
"ControlledName";
931 foreach (
$Items as $ItemId => $ItemName)
933 # look up qualifier for item 934 $QualId = $this->DB->Query(
935 "SELECT * FROM ".$TableName.
"s" 936 .
" WHERE ".$TableName.
"Id = ".$ItemId,
942 # if object was requested by caller 945 # load qualifier and add to return value array 946 $ReturnValue[$ItemId] =
new Qualifier($QualId);
950 # add qualifier ID to return value array 951 $ReturnValue[$ItemId] = $QualId;
956 # add NULL to return value array for this item 957 $ReturnValue[$ItemId] = NULL;
964 foreach (
$Items as $ItemId => $ItemName)
966 # if object was requested by caller 969 # load default qualifier and add to return value array 971 $Field->DefaultQualifier());
975 # add default qualifier ID to return value array 976 $ReturnValue[$ItemId] = $Field->DefaultQualifier();
983 # if field uses item-level qualifiers 984 if ($Field->HasItemLevelQualifiers())
986 # if qualifier available 987 if ($this->ValueCache[$Field->DBFieldName().
"Qualifier"] > 0)
989 # if object was requested by caller 990 $QFieldName = $Field->DBFieldName().
"Qualifier";
993 # return qualifier for field 995 $this->ValueCache[$QFieldName]);
999 # return qualifier ID for field 1000 $ReturnValue = $this->ValueCache[$QFieldName];
1006 # if default qualifier available 1007 if ($Field->DefaultQualifier() > 0)
1009 # if object was requested by caller 1012 # return default qualifier 1013 $ReturnValue =
new Qualifier($Field->DefaultQualifier());
1017 # return default qualifier ID 1018 $ReturnValue = $Field->DefaultQualifier();
1026 # return qualifier object or ID (or array of same) to caller 1027 return $ReturnValue;
1037 public function FieldIsSet($FieldNameOrObject, $IgnorePadding=FALSE)
1039 # load field object if needed 1040 $Field = is_object($FieldNameOrObject) ? $FieldNameOrObject
1041 : $this->
Schema()->GetFieldByName($FieldNameOrObject);
1043 # return no value found if we don't have a valid field 1047 $Value = $this->
Get($Field);
1049 # checks depend on the field type 1050 switch ($Field->Type())
1056 return isset($Value)
1058 && (!$IgnorePadding || ($IgnorePadding && strlen(trim($Value))));
1061 return isset($Value)
1065 return isset($Value[
"X"])
1066 && isset($Value[
"Y"])
1067 && strlen(trim($Value[
"X"]))
1068 && strlen(trim($Value[
"Y"]));
1071 return isset($Value)
1072 && strlen(trim($Value))
1073 && $Value !=
"0000-00-00";
1076 return isset($Value)
1077 && strlen(trim($Value))
1078 && $Value !=
"0000-00-00 00:00:00";
1086 return count($Value) > 0;
1090 return isset($Value)
1092 && $Factory->UserNameExists($Value);
1111 # get our target field and extract its values 1112 $Field = is_object($FieldNameOrObject) ? $FieldNameOrObject
1113 : $this->
Schema()->GetField($FieldNameOrObject);
1114 $Images = $this->
Get($Field, TRUE);
1116 # iterate over our images getting URLs for each 1118 foreach ($Images as $Image)
1120 $Result[$Image->Id()] = $Image->GetImageUrlForResource(
1121 $this->
Id(), $Field->Id(), $Index, $ImageSize);
1128 # --- Generic Attribute Setting Methods --------------------------------- 1142 public function Set($Field, $NewValue, $Reset=FALSE)
1144 # load field object if not already supplied 1145 $Field = is_object($Field) ? $Field
1146 : (is_numeric($Field) ? $this->
Schema()->GetField($Field)
1147 : $this->
Schema()->GetFieldByName($Field));
1149 # return if we don't have a valid field 1152 if ($Field->SchemaId() != $this->
SchemaId())
1154 throw new Exception(
"Attempt to set a value for a field " 1155 .
"from a different schema.");
1158 # grab commonly-used values for local use 1162 # grab database field name 1163 $DBFieldName = $Field->DBFieldName();
1165 # Flag to deterimine if we've actually changed anything. 1166 $UpdateModTime = FALSE;
1168 # store value in DB based on field type 1169 switch ($Field->Type())
1174 if ($this->ValueCache[$DBFieldName] != $NewValue)
1176 # save value directly to DB 1177 $DB->Query(
"UPDATE Resources SET `" 1178 .$DBFieldName.
"` = '".addslashes($NewValue).
"' " 1179 .
"WHERE ResourceId = ".$ResourceId);
1181 # save value locally 1182 $this->ValueCache[$DBFieldName] = $NewValue;
1183 $UpdateModTime=TRUE;
1188 if ( $this->ValueCache[$DBFieldName] != $NewValue )
1190 # save value directly to DB 1191 if (is_null($NewValue))
1193 $DB->Query(
"UPDATE Resources SET `" 1194 .$DBFieldName.
"` = NULL" 1195 .
" WHERE ResourceId = ".$ResourceId);
1199 $DB->Query(
"UPDATE Resources SET `" 1200 .$DBFieldName.
"` = ".intval($NewValue)
1201 .
" WHERE ResourceId = ".$ResourceId);
1204 # save value locally 1205 $this->ValueCache[$DBFieldName] = $NewValue;
1206 $UpdateModTime = TRUE;
1212 if ($this->ValueCache[$DBFieldName.
"X"] != $NewValue[
"X"] ||
1213 $this->ValueCache[$DBFieldName.
"Y"] != $NewValue[
"Y"] )
1215 if (is_null($NewValue))
1217 $DB->Query(
"UPDATE Resources SET " 1218 .
"`".$DBFieldName.
"X` = NULL, " 1219 .
"`".$DBFieldName.
"Y` = NULL " 1220 .
"WHERE ResourceId = ".$ResourceId);
1221 $this->ValueCache[$DBFieldName.
"X"] = NULL;
1222 $this->ValueCache[$DBFieldName.
"Y"] = NULL;
1226 $DB->Query(
"UPDATE Resources SET " 1227 .
"`".$DBFieldName.
"X` = " .(strlen($NewValue[
"X"])
1228 ?
"'".$NewValue[
"X"].
"'" :
"NULL").
", " 1229 .
"`".$DBFieldName.
"Y` = ".(strlen($NewValue[
"Y"])
1230 ?
"'".$NewValue[
"Y"].
"'" :
"NULL")
1231 .
" WHERE ResourceId = ".$ResourceId);
1233 $Digits = $Field->PointDecimalDigits();
1235 $this->ValueCache[$DBFieldName.
"X"] =
1236 strlen($NewValue[
"X"]) ?
1237 round($NewValue[
"X"], $Digits) : NULL;
1238 $this->ValueCache[$DBFieldName.
"Y"] =
1239 strlen($NewValue[
"Y"]) ?
1240 round($NewValue[
"Y"], $Digits) : NULL;
1242 $UpdateModTime = TRUE;
1247 if ($this->ValueCache[$DBFieldName] != $NewValue)
1249 # save value directly to DB 1250 if (is_null($NewValue))
1252 $DB->Query(
"UPDATE Resources SET `" 1253 .$DBFieldName.
"` = NULL" 1254 .
" WHERE ResourceId = ".$ResourceId);
1258 $NewValue = $NewValue ?
"1" :
"0";
1259 $DB->Query(
"UPDATE Resources SET `" 1260 .$DBFieldName.
"` = ".$NewValue
1261 .
" WHERE ResourceId = ".$ResourceId);
1264 $this->ValueCache[$DBFieldName] = $NewValue;
1266 # recalculate counts for any associated classifications if necessary 1267 if ($DBFieldName ==
"ReleaseFlag")
1269 $DB->Query(
"SELECT ClassificationId FROM ResourceClassInts" 1270 .
" WHERE ResourceId = ".$ResourceId);
1271 while ($ClassId =
$DB->FetchField(
"ClassificationId"))
1274 $Class->RecalcResourceCount();
1277 $UpdateModTime = TRUE;
1282 $OldValue = $this->
Get($Field);
1283 # value comes back as array (UserId => UserName), just get the Ids 1284 $OldValue = array_keys($OldValue);
1286 # input to Set() for these fields is one of 1287 # 1. an int specifying a UserId 1288 if (is_numeric($NewValue))
1290 $NewValue = array($NewValue);
1292 # 2. a CWUser object 1293 elseif ($NewValue instanceof
CWUser)
1295 $NewValue = array($NewValue->Id());
1297 # 3. an array keyed by UserId (don't care about the values) 1298 elseif (is_array($NewValue))
1300 $NewValue = array_keys($NewValue);
1304 throw new Exception(
"Unknown format for NewValue in a User field");
1307 # if this is a unique field, only accept the first of the options given 1308 if ($Field->AllowMultiple() == FALSE && count($NewValue) > 1)
1310 $NewValue = array_slice($NewValue, 0, 1, TRUE);
1313 # sort new and old values so we can directly compare 1317 # if the value has changed 1318 if ($OldValue != $NewValue)
1320 if ($Reset || $Field->AllowMultiple() == FALSE )
1322 $ToRemove = array_diff($OldValue, $NewValue);
1323 $this->RemoveAssociation(
1324 "ResourceUserInts",
"UserId", $ToRemove, $Field);
1327 # associate with resource if not already associated 1328 $this->AddAssociation(
"ResourceUserInts",
1332 $UpdateModTime=TRUE;
1337 # if we were given a date object 1338 if (is_object($NewValue))
1340 # use supplied date object 1345 # create date object 1346 $Date =
new Date($NewValue);
1349 $OldDate =
new Date(
1350 $this->ValueCache[$DBFieldName.
"Begin"],
1351 $this->ValueCache[$DBFieldName.
"End"]);
1353 if ($OldDate->BeginDate() != $Date->BeginDate() ||
1354 $OldDate->EndDate() != $Date->EndDate() ||
1355 $OldDate->Precision() != $Date->Precision() )
1357 # extract values from date object and store in DB 1358 $BeginDate =
"'".$Date->BeginDate().
"'";
1359 if (strlen($BeginDate) < 3) { $BeginDate =
"NULL"; }
1360 $EndDate =
"'".$Date->EndDate().
"'";
1361 if (strlen($EndDate) < 3) { $EndDate =
"NULL"; }
1363 $DB->Query(
"UPDATE Resources SET " 1364 .$DBFieldName.
"Begin = ".$BeginDate.
", " 1365 .$DBFieldName.
"End = ".$EndDate.
", " 1366 .$DBFieldName.
"Precision = '".$Date->Precision().
"' " 1367 .
"WHERE ResourceId = ".$ResourceId);
1369 # save values locally 1370 $this->ValueCache[$DBFieldName.
"Begin"] = $Date->BeginDate();
1371 $this->ValueCache[$DBFieldName.
"End"] = $Date->EndDate();
1372 $this->ValueCache[$DBFieldName.
"Precision"] = $Date->Precision();
1373 $UpdateModTime=TRUE;
1378 if (is_null($NewValue) || !strlen(trim($NewValue)))
1380 $DateValue = $NewValue;
1382 if (!is_null($this->ValueCache[$DBFieldName]))
1384 # save value directly to DB 1385 $DB->Query(
"UPDATE Resources SET " 1386 .
"`".$DBFieldName.
"` = NULL " 1387 .
"WHERE ResourceId = ".$ResourceId);
1388 $UpdateModTime = TRUE;
1393 # assume value is date and use directly 1394 $TimestampValue = strtotime($NewValue);
1396 # use the new value if the date is valid 1397 if ($TimestampValue !== FALSE && $TimestampValue >= 0)
1399 $DateValue = date(
"Y-m-d H:i:s", $TimestampValue);
1401 if ($this->ValueCache[$DBFieldName] != $DateValue)
1403 # save value directly to DB 1404 $DB->Query(
"UPDATE Resources SET " 1405 .
"`".$DBFieldName.
"` = '".addslashes($DateValue).
"' " 1406 .
"WHERE ResourceId = ".$ResourceId);
1407 $UpdateModTime=TRUE;
1411 # continue using the old value if invalid 1414 $DateValue = $this->
Get($Field);
1418 # save value locally 1419 $this->ValueCache[$DBFieldName] = $DateValue;
1423 $OldValue = $this->
Get($Field);
1425 # if incoming value is array 1426 if (is_array($NewValue))
1428 if ($OldValue != $NewValue)
1432 # remove values that were in the old value 1433 # but not the new one 1434 $ToRemove = array_diff(array_keys($OldValue),
1435 array_keys($NewValue));
1436 foreach ($ToRemove as $ClassificationId)
1438 $this->RemoveAssociation(
"ResourceClassInts",
1442 $Class->RecalcResourceCount();
1446 # for each element of array 1447 foreach ($NewValue as
1448 $ClassificationId => $ClassificationName)
1451 if ($Class->FieldId() == $Field->Id())
1453 # associate with resource if not already associated 1454 if ($this->AddAssociation(
"ResourceClassInts",
1455 "ClassificationId", $ClassificationId))
1457 $Class->UpdateLastAssigned();
1458 $Class->RecalcResourceCount();
1463 throw new Exception(
1464 "Attempting to store classification from " 1465 .
"Field ".$Class->FieldId().
" into Field " 1471 $UpdateModTime=TRUE;
1476 # associate with resource if not already associated 1477 if (is_object($NewValue))
1480 $NewValue = $Class->Id();
1487 if (!array_key_exists($Class->Id(), $OldValue))
1490 $this->AddAssociation(
"ResourceClassInts",
1493 $Class->UpdateLastAssigned();
1494 $Class->RecalcResourceCount();
1495 $UpdateModTime=TRUE;
1499 # clear our classification cache 1502 unset($this->ClassificationCache);
1508 $OldValue = $this->
Get($Field);
1510 # input to Set() for these fields is one of 1511 # 1. an int specifying a ControlledNameId 1512 # 2. a ControlledName object 1513 # 3. an array with keys giving Ids and values giving ControlledNames 1515 # normalize 1 and 2 into 3 for simplicity of processing 1516 if (is_object($NewValue) || !is_array($NewValue) )
1518 if (!is_object($NewValue))
1523 $TmpValue = array();
1524 $TmpValue[$NewValue->Id()] = $NewValue->Name();
1526 $NewValue = $TmpValue;
1529 # if this is a unique field, only accept the first of the options given 1530 # NB: all ControlledNames implicitly AllowMultiple 1532 $Field->AllowMultiple() == FALSE && count($NewValue) > 1)
1534 $NewValue = array_slice($NewValue, 0, 1, TRUE);
1537 # if the value has changed 1538 if ($OldValue != $NewValue)
1541 && $Field->AllowMultiple() == FALSE ) )
1543 $ToRemove = array_diff(array_keys($OldValue),
1544 array_keys($NewValue));
1545 foreach ($ToRemove as $CNId)
1547 $this->RemoveAssociation(
"ResourceNameInts",
1553 # for each element of array 1554 foreach ($NewValue as $ControlledNameId => $ControlledName)
1556 # associate with resource if not already associated 1557 if ($this->AddAssociation(
"ResourceNameInts",
1564 $this->RemoveAssociation(
"ResourceNameInts",
1565 "ControlledNameId", $ControlledNameId);
1566 throw new InvalidArgumentException(
1567 "Attempt to set controlled name with" 1568 .
" invalid ID (".$ControlledNameId.
").");
1570 $CN->UpdateLastAssigned();
1573 $UpdateModTime = TRUE;
1578 # clear our controlled name cache 1579 unset($this->ControlledNameCache);
1580 unset($this->ControlledNameVariantCache);
1582 # clear visible count cache for any affected resources 1583 $ValueIds = array_keys($OldValue) + array_keys($NewValue);
1585 "DELETE FROM VisibleResourceCounts WHERE " 1586 .
"SchemaId=".intval($this->
SchemaId).
" AND " 1587 .
"ValueId IN (".implode(
",", $ValueIds).
")");
1593 # associate value(s) with resource 1594 $this->AddAssociation(
1595 "ResourceImageInts",
"ImageId", $NewValue, $Field);
1596 # clear cached image mappings 1601 # convert incoming value to array if necessary 1602 if (!is_array($NewValue)) { $NewValue = array($NewValue); }
1604 # for each incoming file 1606 foreach ($NewValue as $File)
1609 $NewFile = $Factory->
Copy($File);
1611 # associate copy with this resource and field 1612 $NewFile->ResourceId($this->
Id);
1613 $NewFile->FieldId($Field->Id());
1615 # Since we make a fresh copy of the File whenever Set is called, 1616 # we'll always update the modification time for this field. 1617 $UpdateModTime = TRUE;
1621 # convert incoming value to array to simplify the workflow 1622 if (is_scalar($NewValue) || $NewValue instanceof
Resource)
1624 $NewValue = array($NewValue);
1627 # delete existing resource references 1630 # add each reference 1631 foreach ($NewValue as $ReferenceOrId)
1633 # initially issume it's a reference ID and not an object... 1634 $ReferenceId = $ReferenceOrId;
1636 # ... but get the reference ID if it's an object 1637 if ($ReferenceOrId instanceof
Resource)
1639 $ReferenceId = $ReferenceOrId->Id();
1642 # skip blank reference IDs 1643 if (strlen(trim($ReferenceId)) < 1)
1648 # skip reference IDs that don't look right 1649 if (!is_numeric($ReferenceId))
1654 # skip references to the current resource 1655 if ($ReferenceId == $this->
Id())
1660 # add the reference to the references table 1662 INSERT INTO ReferenceInts ( 1667 ".addslashes($Field->Id()).
", 1668 ".addslashes($this->
Id()).
", 1669 ".addslashes($ReferenceId).
")");
1675 exit(
"<br>SPT - ERROR: attempt to set unknown resource field type<br>\n");
1681 # update modification timestamps 1683 $UserId = $G_User->IsLoggedIn() ? $G_User->Get(
"UserId") : -1;
1684 $DB->Query(
"DELETE FROM ResourceFieldTimestamps " 1685 .
"WHERE ResourceId=".$this->
Id.
" AND " 1686 .
"FieldId=".$Field->Id() );
1687 $DB->Query(
"INSERT INTO ResourceFieldTimestamps " 1688 .
"(ResourceId,FieldId,ModifiedBy,Timestamp) VALUES (" 1689 .$this->
Id.
",".$Field->Id().
"," 1690 .$UserId.
",NOW())");
1692 # on resource modification, clear the UserPermsCache entry 1693 # so that stale permissions checks are not cached 1694 $DB->Query(
"DELETE FROM UserPermsCache WHERE ResourceId=".$this->
Id);
1707 $this->
Set($Field, $NewValue);
1719 $this->
Set($FieldId, $NewValue);
1729 $Field = $this->
Schema()->GetFieldByName($FieldName);
1740 $Field = $this->
Schema()->GetField($FieldId);
1751 # if field uses qualifiers and uses item-level qualifiers 1752 if ($Field->UsesQualifiers() && $Field->HasItemLevelQualifiers())
1754 # if qualifier object passed in 1755 if (is_object($NewValue))
1757 # grab qualifier ID from object 1758 $QualifierId = $NewValue->Id();
1762 # assume value passed in is qualifier ID 1763 $QualifierId = $NewValue;
1766 # update qualifier value in database 1767 $DBFieldName = $Field->DBFieldName();
1768 $this->DB->Query(
"UPDATE Resources SET " 1769 .$DBFieldName.
"Qualifier = '".$QualifierId.
"' " 1770 .
"WHERE ResourceId = ".$this->Id);
1772 # update local qualifier value 1773 $this->ValueCache[$DBFieldName.
"Qualifier"] = $QualifierId;
1785 $Field = $this->
Schema()->GetField($FieldId);
1786 $this->
Clear($Field, $ValueToClear);
1795 public function Clear($Field, $ValueToClear = NULL)
1797 # convert field name to object if necessary 1798 if (!is_object($Field))
1800 $Field = $this->
Schema()->GetFieldByName($Field);
1803 # grab commonly-used values for local use 1807 # grab database field name 1808 $DBFieldName = $Field->DBFieldName();
1810 $UpdateModTime=FALSE;
1812 # store value in DB based on field type 1813 switch ($Field->Type())
1821 if (strlen($this->ValueCache[$DBFieldName])>0)
1824 $DB->Query(
"UPDATE Resources SET `" 1825 .$DBFieldName.
"` = NULL " 1826 .
"WHERE ResourceId = ".$ResourceId);
1828 # clear value locally 1829 $this->ValueCache[$DBFieldName] = NULL;
1830 $UpdateModTime=TRUE;
1835 if (!is_null($this->ValueCache[$DBFieldName.
"X"]) ||
1836 !is_null($this->ValueCache[$DBFieldName.
"Y"]) )
1839 $DB->Query(
"UPDATE Resources SET " 1840 .
"`".$DBFieldName.
"X` = NULL ," 1841 .
"`".$DBFieldName.
"Y` = NULL " 1842 .
"WHERE ResourceId = ".$ResourceId);
1844 # Clear local values 1845 $this->ValueCache[$DBFieldName.
"X"] = NULL;
1846 $this->ValueCache[$DBFieldName.
"Y"] = NULL;
1847 $UpdateModTime=TRUE;
1852 if (!is_null($this->ValueCache[$DBFieldName.
"Begin"]) ||
1853 !is_null($this->ValueCache[$DBFieldName.
"End"]) ||
1854 !is_null($this->ValueCache[$DBFieldName.
"Precision"]))
1856 # clear date object values in DB 1857 $DB->Query(
"UPDATE Resources SET " 1858 .$DBFieldName.
"Begin = '', " 1859 .$DBFieldName.
"End = '', " 1860 .$DBFieldName.
"Precision = '' " 1861 .
"WHERE ResourceId = ".$ResourceId);
1863 # clear value locally 1864 $this->ValueCache[$DBFieldName.
"Begin"] = NULL;
1865 $this->ValueCache[$DBFieldName.
"End"] = NULL;
1866 $this->ValueCache[$DBFieldName.
"Precision"] = NULL;
1867 $UpdateModTime=TRUE;
1872 $OldValue = $this->
Get($Field);
1874 # if value to clear supplied 1875 if ($ValueToClear !== NULL)
1877 # if supplied value is array 1878 if (is_array($ValueToClear))
1880 # for each element of array 1881 foreach ($ValueToClear as $ClassificationId => $Dummy)
1883 if (array_key_exists($ClassificationId, $OldValue))
1885 # remove association with resource (if any) 1886 $this->RemoveAssociation(
"ResourceClassInts",
1890 $Class->RecalcResourceCount();
1891 $UpdateModTime=TRUE;
1897 if (array_key_exists($ValueToClear, $OldValue))
1899 # remove association with resource (if any) 1900 $this->RemoveAssociation(
"ResourceClassInts",
1904 $Class->RecalcResourceCount();
1905 $UpdateModTime=TRUE;
1911 if (count($OldValue)>0)
1913 # remove all associations for resource and field 1914 $this->RemoveAllAssociations(
1915 "ResourceClassInts",
"ClassificationId", $Field);
1917 # recompute resource count 1918 $Values = $this->
Get($Field);
1919 foreach ($Values as $ClassificationId => $Dummy)
1922 $Class->RecalcResourceCount();
1924 $UpdateModTime=TRUE;
1928 # clear our classification cache 1931 unset($this->ClassificationCache);
1937 $OldValue = $this->
Get($Field);
1938 # if value to clear supplied 1939 if ($ValueToClear !== NULL)
1941 # if incoming value is array 1942 if (is_array($ValueToClear))
1944 # for each element of array 1945 foreach ($ValueToClear as $ControlledNameId =>
1948 if (array_key_exists($ControlledNameId, $OldValue))
1950 # remove association with resource (if any) 1951 $this->RemoveAssociation(
"ResourceNameInts",
1954 $UpdateModTime=TRUE;
1960 if (array_key_exists($ValueToClear, $OldValue))
1962 # remove association with resource (if any) 1963 $this->RemoveAssociation(
"ResourceNameInts",
1966 $UpdateModTime=TRUE;
1972 if (count($OldValue)>0)
1974 # remove all associations for resource and field 1975 $this->RemoveAllAssociations(
1976 "ResourceNameInts",
"ControlledNameId", $Field);
1977 $UpdateModTime=TRUE;
1983 # clear our controlled name cache 1984 unset($this->ControlledNameCache);
1985 unset($this->ControlledNameVariantCache);
1990 $OldValue = $this->
Get($Field);
1992 # if value to clear supplied 1993 if ($ValueToClear !== NULL)
1995 # if incoming value is array 1996 if (is_array($ValueToClear))
1998 # for each element of array 1999 foreach ($ValueToClear as $UserId => $User)
2001 if (array_key_exists($UserId, $OldValue))
2003 # remove association with resource (if any) 2004 $this->RemoveAssociation(
"ResourceUserInts",
2008 $UpdateModTime=TRUE;
2014 if (array_key_exists($ValueToClear, $OldValue))
2016 # remove association with resource (if any) 2017 $this->RemoveAssociation(
"ResourceUserInts",
2021 $UpdateModTime=TRUE;
2027 if (count($OldValue)>0)
2029 # remove all associations for resource and field 2030 $this->RemoveAllAssociations(
2031 "ResourceUserInts",
"UserId", $Field);
2032 $UpdateModTime=TRUE;
2039 # if value to clear supplied 2040 if ($ValueToClear !== NULL)
2042 # convert value to array if necessary 2043 $Files = $ValueToClear;
2044 if (!is_array($Files)) { $Files = array($Files); }
2046 # convert values to objects if necessary 2047 foreach ($Files as $Index => $File)
2049 if (!is_object($File))
2051 $Files[$Index] =
new File($File);
2057 # use all files associated with resource 2058 $Files = $this->
Get($Field, TRUE);
2062 foreach ($Files as $File) { $File->Delete(); }
2066 # if value to clear supplied 2067 if ($ValueToClear !== NULL)
2069 # convert value to array if necessary 2070 $Images = $ValueToClear;
2071 if (!is_array($Images)) { $Images = array($Images); }
2073 # convert values to objects if necessary 2074 foreach ($Images as $Index => $Image)
2076 if (!is_object($Image))
2078 $Images[$Index] =
new SPTImage($Image);
2084 # use all images associated with resource 2085 $Images = $this->
Get($Field, TRUE);
2088 # delete images if we are the last resource referencing 2089 # a particular image. 2090 foreach ($Images as $Image)
2092 $Cnt = $this->DB->Query(
2093 "SELECT COUNT(*) AS Cnt FROM ResourceImageInts WHERE ".
2094 "ImageId=".$Image->Id(),
"Cnt");
2101 # clear cached image mappings 2104 # remove connections to images 2105 $UpdateModTime = $this->RemoveAssociation(
2106 "ResourceImageInts",
"ImageId", $Images, $Field);
2110 # remove references from the references table 2112 DELETE FROM ReferenceInts 2113 WHERE FieldId = '".addslashes($Field->Id()).
"' 2114 AND SrcResourceId = '".addslashes($this->
Id()).
"'");
2119 exit(
"<br>SPT - ERROR: attempt to clear " 2120 .
"unknown resource field type<br>\n");
2126 # update modification timestamps 2128 $UserId = $G_User->IsLoggedIn() ? $G_User->Get(
"UserId") : -1;
2129 $DB->Query(
"DELETE FROM ResourceFieldTimestamps " 2130 .
"WHERE ResourceId=".$this->
Id.
" AND " 2131 .
"FieldId=".$Field->Id() );
2132 $DB->Query(
"INSERT INTO ResourceFieldTimestamps " 2133 .
"(ResourceId,FieldId,ModifiedBy,Timestamp) VALUES (" 2134 .$this->
Id.
",".$Field->Id().
"," 2135 .$UserId.
",NOW())");
2149 $this->
Clear($Field, $ValueToClear);
2152 # --- Field-Specific or Type-Specific Attribute Retrieval Methods ------- 2163 # start with empty array 2166 # for each controlled name 2167 $DB->Query(
"SELECT ClassificationName, MetadataFields.FieldName, " 2168 .
"ResourceClassInts.ClassificationId FROM ResourceClassInts, " 2169 .
"Classifications, MetadataFields " 2170 .
"WHERE ResourceClassInts.ResourceId = ".$this->
Id.
" " 2171 .
"AND ResourceClassInts.ClassificationId = " 2172 .
"Classifications.ClassificationId " 2173 .
"AND Classifications.FieldId = MetadataFields.FieldId ");
2174 while ($Record =
$DB->FetchRow())
2177 $Names[$Record[
"FieldName"]][$Record[
"ClassificationId"]] =
2178 $Record[
"ClassificationName"];
2181 # return array to caller 2186 # --- Ratings Methods --------------------------------------------------- 2194 return $this->CumulativeRating;
2219 # if number of ratings not already set 2222 # obtain number of ratings 2224 $this->DB->Query(
"SELECT Count(*) AS NumberOfRatings " 2225 .
"FROM ResourceRatings " 2226 .
"WHERE ResourceId = ".$this->
Id,
2230 # recalculate cumulative rating if it looks erroneous 2233 $this->UpdateCumulativeRating();
2237 # return number of ratings to caller 2238 return $this->NumberOfRatings;
2248 public function Rating($NewRating = NULL, $UserId = NULL)
2252 # if user ID not supplied 2253 if ($UserId == NULL)
2255 # if user is logged in 2257 if ($User->IsLoggedIn())
2259 # use ID of current user 2260 $UserId = $User->Get(
"UserId");
2264 # return NULL to caller 2269 # sanitize $NewRating 2270 if (!is_null($NewRating))
2272 $NewRating = intval($NewRating);
2275 # if there is a rating for resource and user 2276 $DB->Query(
"SELECT Rating FROM ResourceRatings " 2277 .
"WHERE UserId = ${UserId} AND ResourceId = ".$this->
Id);
2278 if ($Record =
$DB->FetchRow())
2280 # if new rating was supplied 2281 if ($NewRating != NULL)
2283 # update existing rating 2284 $DB->Query(
"UPDATE ResourceRatings " 2285 .
"SET Rating = ${NewRating}, DateRated = NOW() " 2286 .
"WHERE UserId = ${UserId} AND ResourceId = ".$this->
Id);
2288 # update cumulative rating value 2289 $this->UpdateCumulativeRating();
2291 # return value is new rating 2292 $Rating = $NewRating;
2296 # get rating value to return to caller 2297 $Rating = $Record[
"Rating"];
2302 # if new rating was supplied 2303 if ($NewRating != NULL)
2306 $DB->Query(
"INSERT INTO ResourceRatings " 2307 .
"(ResourceId, UserId, DateRated, Rating) " 2314 # update cumulative rating value 2315 $this->UpdateCumulativeRating();
2317 # return value is new rating 2318 $Rating = $NewRating;
2322 # return value is NULL 2327 # return rating value to caller 2332 # --- Resource Comment Methods ------------------------------------------ 2340 # read in comments if not already loaded 2343 $this->DB->Query(
"SELECT MessageId FROM Messages " 2344 .
"WHERE ParentId = ".$this->
Id 2345 .
" AND ParentType = 2 " 2346 .
"ORDER BY DatePosted DESC");
2347 while ($MessageId = $this->DB->FetchField(
"MessageId"))
2353 # return array of comments to caller 2354 return $this->Comments;
2363 # obtain number of comments if not already set 2367 $this->DB->Query(
"SELECT Count(*) AS NumberOfComments " 2369 .
"WHERE ParentId = ".$this->
Id 2370 .
" AND ParentType = 2",
2375 # return number of comments to caller 2376 return $this->NumberOfComments;
2380 # --- Permission Methods ------------------------------------------------- 2393 return $this->CheckSchemaPermissions($User,
"View", $AllowHooksToModify);
2404 return $this->CheckSchemaPermissions($User,
"Edit");
2415 return $this->CheckSchemaPermissions($User,
"Author");
2426 $CheckFn =
"UserCan".(($this->Id()<0) ?
"Author" :
"Edit");
2427 return $this->$CheckFn($User);
2438 return $this->CheckFieldPermissions( $User, $FieldOrFieldName,
"View" );
2449 return $this->CheckFieldPermissions( $User, $FieldOrFieldName,
"Edit" );
2460 return $this->CheckFieldPermissions( $User, $FieldOrFieldName,
"Author" );
2472 $CheckFn =
"UserCan".(($this->Id()<0) ?
"Author" :
"Edit").
"Field";
2474 return $this->$CheckFn($User, $FieldOrFieldName);
2477 # --- Utility Methods ---------------------------------------------------- 2487 $SearchEngine->QueueUpdateForItem($this);
2490 $Recommender->QueueUpdateForItem($this);
2501 # if schema IDs are not loaded 2502 if (!isset(self::$SchemaIdCache))
2506 $DB->Query(
"SELECT ResourceId, SchemaId FROM Resources");
2507 self::$SchemaIdCache =
$DB->FetchColumn(
"SchemaId",
"ResourceId");
2510 # if multiple resources specified 2511 if (is_array($ResourceId))
2513 # find schema IDs for specified resources 2514 $SchemaIds = array_intersect_key(self::$SchemaIdCache,
2515 array_flip($ResourceId));
2517 # check that specified resource IDs were all valid 2518 if (count($SchemaIds) < count($ResourceId))
2520 $BadIds = array_diff($ResourceId, array_keys($SchemaIds));
2521 throw new InvalidArgumentException(
"Unknown resource IDs (" 2522 .implode(
", ", $BadIds).
").");
2525 # return schema IDs to caller 2530 # check that specified resource was valid 2531 if (!isset(self::$SchemaIdCache[$ResourceId]))
2533 throw new InvalidArgumentException(
"Unknown resource ID (" 2537 # return schema IDs for specified resource 2538 return self::$SchemaIdCache[$ResourceId];
2543 # ---- PRIVATE INTERFACE ------------------------------------------------- 2545 private $ClassificationCache;
2547 private $ControlledNameCache;
2548 private $ControlledNameVariantCache;
2549 private $CumulativeRating;
2550 private $NumberOfComments;
2551 private $NumberOfRatings;
2552 private $PermissionCache;
2555 static private $Schemas;
2556 static private $SchemaIdCache;
2568 private function CheckSchemaPermissions($User, $CheckType, $AllowHooksToModify=TRUE)
2570 # construct a key to use for our permissions cache 2571 $CacheKey =
"UserCan".$CheckType.$User->Id();
2573 # if we don't have a cached value for this perm, compute one 2574 if (!isset($this->PermissionCache[$CacheKey]))
2576 # get privileges for schema 2577 $PermsFn = $CheckType.
"ingPrivileges";
2578 $SchemaPrivs = $this->
Schema()->$PermsFn();
2580 # check passes if user privileges are greater than resource set 2581 $CheckResult = $SchemaPrivs->MeetsRequirements($User, $this);
2583 # save the result of this check in our cache 2584 $this->PermissionCache[$CacheKey] = $CheckResult;
2587 $Value = $this->PermissionCache[$CacheKey];
2589 if ($AllowHooksToModify)
2591 $SignalResult = $GLOBALS[
"AF"]->SignalEvent(
2592 "EVENT_RESOURCE_".strtoupper($CheckType).
"_PERMISSION_CHECK",
2594 "Resource" => $this,
2596 "Can".$CheckType => $Value,
2597 "Schema" => $this->
Schema(), ));
2599 $Value = $SignalResult[
"Can".$CheckType];
2613 private function CheckFieldPermissions($User, $Field, $CheckType)
2615 # get field object (if not supplied) 2620 $Field = $this->
Schema()->GetField($Field);
2622 catch (InvalidArgumentException $Exception)
2624 # (user cannot view/author/edit if field was invalid) 2629 # construct a key to use for our permissions cache 2630 $CacheKey =
"UserCan".$CheckType.
"Field".$Field->Id().
"-".$User->Id();
2632 # if we don't have a cahced value, compute one 2633 if (!isset($this->PermissionCache[$CacheKey]))
2635 # if field is enabled and editable, do permission check 2636 if ($Field->Enabled() &&
2637 ($CheckType ==
"View" || $Field->Editable()))
2639 # be sure schema privs allow View/Edit/Author for this resource 2640 $SchemaCheckFn =
"UserCan".$CheckType;
2641 if ($this->$SchemaCheckFn($User))
2643 # get appropriate privilege set for field 2644 $PermsFn = $CheckType.
"ingPrivileges";
2645 $FieldPrivs = $Field->$PermsFn();
2647 # user can View/Edit/Author if privileges are greater than field set 2648 $CheckResult = $FieldPrivs->MeetsRequirements($User, $this);
2652 $CheckResult = FALSE;
2657 $CheckResult = FALSE;
2660 # allow plugins to modify result of permission check 2661 $SignalResult = $GLOBALS[
"AF"]->SignalEvent(
2662 "EVENT_FIELD_".strtoupper($CheckType).
"_PERMISSION_CHECK", array(
2664 "Resource" => $this,
2666 "Can".$CheckType => $CheckResult));
2667 $CheckResult = $SignalResult[
"Can".$CheckType];
2669 # save the result of this check in our cache 2670 $this->PermissionCache[$CacheKey] = $CheckResult;
2673 # return cached permission value 2674 return $this->PermissionCache[$CacheKey];
2680 private function UpdateCumulativeRating()
2682 # grab totals from DB 2683 $this->DB->Query(
"SELECT COUNT(Rating) AS Count, " 2684 .
"SUM(Rating) AS Total FROM ResourceRatings " 2685 .
"WHERE ResourceId = ".$this->
Id);
2686 $Record = $this->DB->FetchRow();
2688 # calculate new cumulative rating 2691 # save new cumulative rating in DB 2692 $this->DB->Query(
"UPDATE Resources " 2694 .
"WHERE ResourceId = ".$this->Id);
2708 private function AddAssociation($TableName, $FieldName, $Value, $Field = NULL)
2710 # We should ignore duplicate key errors when doing inserts: 2711 $this->DB->SetQueryErrorsToIgnore( array(
2712 "/INSERT INTO ".$TableName.
"/" =>
2713 "/Duplicate entry '-?[0-9]+-[0-9]+(-[0-9]+)?' for key/"));
2715 # start out assuming no association will be added 2716 $AssociationAdded = FALSE;
2718 # convert new value to array if necessary 2719 $Values = is_array($Value) ? $Value : array($Value);
2721 # for each new value 2722 foreach ($Values as $Value)
2724 # retrieve ID from value if necessary 2725 if (is_object($Value)) { $Value = $Value->Id(); }
2727 # Try to insert a new entry for this association. 2728 $this->DB->Query(
"INSERT INTO ".$TableName.
" SET" 2729 .
" ResourceId = ".intval($this->
Id)
2730 .
", ".$FieldName.
" = ".intval($Value)
2731 .($Field ?
", FieldId = ".intval($Field->Id()) :
""));
2733 # If the insert ran without a duplicate key error, 2734 # then we added an assocation: 2735 if ($this->DB->IgnoredError() === FALSE)
2737 $AssociationAdded = TRUE;
2741 # Clear ignored errors: 2742 $this->DB->SetQueryErrorsToIgnore( NULL );
2744 # report to caller whether association was added 2745 return $AssociationAdded;
2759 private function RemoveAssociation($TableName, $FieldName, $Value, $Field = NULL)
2761 # start out assuming no association will be removed 2762 $AssociationRemoved = FALSE;
2764 # convert value to array if necessary 2765 $Values = is_array($Value) ? $Value : array($Value);
2768 foreach ($Values as $Value)
2770 # retrieve ID from value if necessary 2771 if (is_object($Value)) { $Value = $Value->Id(); }
2773 # remove any intersections with target ID from DB 2774 $this->DB->Query(
"DELETE FROM ".$TableName
2775 .
" WHERE ResourceId = ".intval($this->
Id)
2776 .($Field ?
" AND FieldId = ".intval($Field->Id()) :
"")
2777 .
" AND ".$FieldName.
" = ".intval($Value));
2778 if ($this->DB->NumRowsAffected()) { $AssociationRemoved = TRUE; }
2781 # report to caller whether association was added 2782 return $AssociationRemoved;
2791 private function RemoveAllAssociations($TableName, $TargetFieldName, $Field)
2793 # retrieve list of entries for this field and resource 2794 $Entries = $this->
Get($Field);
2796 # divide them into chunks of not more than 100 2797 foreach (array_chunk($Entries, 100, TRUE) as $Chunk)
2799 # remove assocations from this chunk 2800 $this->DB->Query(
"DELETE FROM ".$TableName
2801 .
" WHERE ResourceId = ".intval($this->
Id)
2802 .
" AND ".$TargetFieldName.
" IN " 2803 .
"(".implode(
",", array_keys($Chunk)).
")");
2815 if (!isset(self::$ItemIdColumnNames[$ClassName]))
2817 self::$ItemIdColumnNames[$ClassName] =
"ResourceId";
2818 self::$ItemNameColumnNames[$ClassName] = NULL;
2819 self::$ItemTableNames[$ClassName] =
"Resources";
GetByField($FieldNameOrObject, $ReturnObject=FALSE, $IncludeVariants=FALSE)
Old method for retrieving values, deprecated in favor of Get().
UserCanView(User $User, $AllowHooksToModify=TRUE)
Determine if the given user can view the resource, e.g., on the full record page. ...
GetFilesForResource($ResourceOrResourceId, $ReturnObjects=TRUE)
Retrieve all files (names or objects) for specified resource.
GetImageUrls($FieldNameOrObject, $ImageSize=SPTImage::SIZE_FULL)
Get URLs for images, returning CleanURLs when possible and direct paths to image files otherwise...
SetQualifier($FieldName, $NewValue)
Set qualifier using field name.
Abstraction for forum messages and resource comments.
SQL database abstraction object with smart query caching.
UserCanModifyField($User, $FieldOrFieldName)
Check whether user is allowed to modify (Edit for perm resources, Author for temp) specified metadata...
QueueSearchAndRecommenderUpdate()
Update search and recommender system DBs.
GetAsArray($IncludeDisabledFields=FALSE, $ReturnObjects=TRUE)
Retrieve all resource values as an array.
Id()
Retrieve numerical resource ID.
UserCanEditField($User, $FieldOrFieldName)
Check whether user is allowed to edit specified metadata field.
SetQualifierByField($Field, $NewValue)
Set qualifier using field object.
GetViewPageUrl()
Retrieve view page URL for this resource.
Rating($NewRating=NULL, $UserId=NULL)
Get/set rating by a specific user for resource.
NumberOfComments()
Get current number of comments for resource.
NumberOfRatings()
Get current number of ratings for resource.
GetQualifier($FieldName, $ReturnObject=TRUE)
Retrieve qualifier by field name.
Factory object for Folder class, used to retrieve and manage Folders and groups of Folders...
Copy($FileToCopy)
Create copy of File and return to caller.
Schema()
Get MetadataSchema for resource.
Metadata type representing non-hierarchical controlled vocabulary values.
UserCanEdit($User)
Determine if the given user can edit the resource.
GetForDisplay($FieldNameOrObject, $ReturnObject=TRUE, $IncludeVariants=FALSE)
Retrieve value using field name or field object, signaling EVENT_FIELD_DISPLAY_FILTER to allow other ...
Comments()
Get comments for resource.
UpdateAutoupdateFields($UpdateType, $User=NULL)
Update the auto-updated fields as necessary.
CWIS-specific user factory class.
Get($Field, $ReturnObject=FALSE, $IncludeVariants=FALSE)
Retrieve value using field name or field object.
static GetSchemaForResource($ResourceId)
Get schema ID for specified resource(s).
Factory for manipulating File objects.
Common base class for persistent items store in database.
GetQualifierByFieldId($FieldId, $ReturnObject=TRUE)
Retrieve qualifier by field ID.
Encapsulates a full-size, preview, and thumbnail image.
UserCanAuthorField($User, $FieldOrFieldName)
Check whether user is allowed to author specified metadata field.
Clear($Field, $ValueToClear=NULL)
Clear field value.
UserCanModify($User)
Check if the user is allowed to modify (Edit for perm resources, Author for temp) a specified resourc...
UserCanAuthor($User)
Determine if the given user can edit the resource.
GetByFieldId($FieldId, $ReturnObject=FALSE, $IncludeVariants=FALSE)
Retrieve value using field ID.
IsTempResource($NewSetting=NULL)
Get/set whether resource is a temporary record.
SetByField($Field, $NewValue)
Method replaced by Resource::Set(), preserved for backward compatibility.
const STATUS_OK
Successful execution.
__construct($ResourceId)
Object constructor for loading an existing resource.
GetMapped($MappedName, $ReturnObject=FALSE, $IncludeVariants=FALSE)
Retrieve value using standard (mapped) field name.
static SetDatabaseAccessValues($ClassName)
Set the database access values (table name, ID column name, name column name) for specified class...
Represents a "resource" in CWIS.
GetQualifierByField($Field, $ReturnObject=TRUE)
Retrieve qualifier by Field object.
ClearByFieldId($FieldId, $ValueToClear=NULL)
Clear field value specified by field ID.
SetQualifierByFieldId($FieldId, $NewValue)
Set qualifier using field ID.
static ClearImageSymlinksForResource($ResourceId, $FieldId)
Remove symlinks used for to cache image mappings.
SchemaId()
Retrieve ID of schema for resource.
ScaledCumulativeRating()
Return cumulative rating scaled to 1/10th.
Set($Field, $NewValue, $Reset=FALSE)
Set value using field name or field object.
static Create($SchemaId)
Create a new resource.
UserCanViewField($User, $FieldOrFieldName)
Check whether user is allowed to view specified metadata field.
Metadata type representing hierarchical ("Tree") controlled vocabulary values.
SetByFieldId($FieldId, $NewValue)
Set field value using field ID.
Classifications()
Get 2D array of classifications associated with resource.
ClearByField($Field, $ValueToClear=NULL)
Clear field value.
Class representing a stored (usually uploaded) file.
Factory for Resource objects.
CWIS-specific user class.
CumulativeRating()
Get cumulative rating (range is usually 0-100)
FieldIsSet($FieldNameOrObject, $IgnorePadding=FALSE)
Determine if the value for a field is set.
Delete()
Remove resource (and accompanying associations) from database and delete any associated files...