5 # Part of the Collection Workflow Integration System (CWIS)
6 # Copyright 2011 Edward Almasy and Internet Scout Project
7 # http://scout.wisc.edu/
15 # ---- PUBLIC INTERFACE --------------------------------------------------
28 # if resource ID supplied
29 if ($ResourceId !== NULL)
32 $this->
Id = intval($ResourceId);
34 # locate resource in database
35 $DB->Query(
"SELECT * FROM Resources WHERE ResourceId = ".$this->
Id);
37 # if unable to locate resource
38 $Record = $DB->FetchRow();
41 # set status to -1 to indicate that creation failed
42 $this->LastStatus = -1;
46 # load in attributes from database
47 $this->DBFields = $Record;
50 # set status to 1 to indicate that creation succeeded
51 $this->LastStatus = 1;
56 # clean out any temp resource records more than three days old
58 $RFactory->CleanOutStaleTempItems(60 * 24 * 3);
60 # lock DB tables to prevent next ID from being grabbed
62 "LOCK TABLES Resources write, APUsers read, ".
63 "APSessions write, APSessionData write");
65 # find next temp resource ID
66 $this->
Id = $RFactory->GetNextTempItemId();
68 # write out new resource record with temp resource ID and user ID
70 $DB->Query(
"INSERT INTO Resources (ResourceId, AddedById,"
71 .
" LastModifiedById, DateLastModified, DateOfRecordCreation)"
72 .
" VALUES (".$this->
Id.
", "
73 .$User->Get(
"UserId").
", "
74 .$User->Get(
"UserId").
", "
78 $DB->Query(
"UNLOCK TABLES");
80 # load in attributes from database
81 $DB->Query(
"SELECT * FROM Resources WHERE ResourceId = ".$this->
Id);
82 $this->DBFields = $DB->FetchRow();
85 # set any default values
92 foreach ($Fields as $Field)
94 $DefaultValue = $Field->DefaultValue();
96 # flip option default values to get into the form that
97 # Resource::Set() expects
99 && is_array($DefaultValue))
101 $DefaultValue = array_flip($DefaultValue);
107 # Update timestamps as required:
108 $TimestampFields = $Schema->GetFields(
110 foreach ($TimestampFields as $Field)
112 if ($Field->UpdateMethod() ==
119 # signal resource creation
120 $GLOBALS[
"AF"]->SignalEvent(
"EVENT_RESOURCE_CREATE", array(
124 # set status to 1 to indicate that creation succeeded
125 $this->LastStatus = 1;
137 # signal that resource deletion is about to occur
139 $AF->SignalEvent(
"EVENT_RESOURCE_DELETE", array(
143 # grab list of classifications
146 # delete resource/classification intersections
148 $DB->Query(
"DELETE FROM ResourceClassInts WHERE ResourceId = ".$this->
Id());
150 # for each classification type
151 foreach ($Classifications as $ClassType => $ClassesOfType)
153 # for each classification of that type
154 foreach ($ClassesOfType as $ClassId => $ClassName)
156 # recalculate resource count for classification
158 $Class->RecalcResourceCount();
162 # delete resource/name intersections
163 $DB->Query(
"DELETE FROM ResourceNameInts WHERE ResourceId = ".$this->
Id());
165 # delete any associated images not in use by other resources
167 foreach ($Fields as $Field)
169 $ImageId = $DB->Query(
"SELECT `".$Field->DBFieldName()
170 .
"` FROM Resources WHERE ResourceId = ".$this->
Id(),
171 $Field->DBFieldName());
174 $ImageCount = $DB->Query(
"SELECT COUNT(*) AS ImageCount FROM Resources"
175 .
" WHERE ".$Field->DBFieldName().
" = ".$ImageId,
185 # delete any associated files
187 $Files = $Factory->GetFilesForResource($this->
Id());
188 foreach ($Files as $File)
193 # delete resource record from database
194 $DB->Query(
"DELETE FROM Resources WHERE ResourceId = ".$this->
Id());
196 # drop item from search engine and recommender system
197 if ($SysConfig->SearchDBEnabled())
200 $SearchEngine->DropItem($this->
Id());
202 if ($SysConfig->RecommenderDBEnabled())
205 $Recommender->DropItem($this->
Id());
208 # get the folders containing the resource
210 $Folders = $FolderFactory->GetFoldersContainingItem(
214 # drop the resource from each folder it belongs to
215 foreach ($Folders as $Folder)
217 # mixed item type folder
218 if ($Folder->ContainsItem($this->Id,
"Resource"))
220 $Folder->RemoveItem($this->
Id,
"Resource");
223 # single item type folder
226 $Folder->RemoveItem($this->
Id);
230 # delete any resource comments
231 $DB->Query(
"DELETE FROM Messages WHERE ParentId = ".$this->
Id);
238 function Status() {
return $this->LastStatus; }
244 function Id() {
return $this->Id; }
253 # if new temp resource setting supplied
254 if (!is_null($NewSetting))
256 # if caller requested to switch
258 if ((($this->
Id() < 0) && ($NewSetting == FALSE))
259 || (($this->
Id() >= 0) && ($NewSetting == TRUE)))
261 # lock DB tables to prevent next ID from being grabbed
262 $DB->Query(
"LOCK TABLES Resources write");
264 # get next resource ID as appropriate
265 $OldResourceId = $this->Id;
267 if ($NewSetting == TRUE)
269 $this->
Id = $Factory->GetNextTempItemId();
273 $this->
Id = $Factory->GetNextItemId();
277 $DB->Query(
"UPDATE Resources SET ResourceId = ".
278 $this->
Id.
" WHERE ResourceId = ".$OldResourceId);
281 $DB->Query(
"UNLOCK TABLES");
283 # change associations
284 unset($this->ClassificationCache);
285 $DB->Query(
"UPDATE ResourceClassInts SET ResourceId = ".
286 $this->
Id.
" WHERE ResourceId = ".$OldResourceId);
287 unset($this->ControlledNameCache);
288 unset($this->ControlledNameVariantCache);
289 $DB->Query(
"UPDATE ResourceNameInts SET ResourceId = ".
290 $this->
Id.
" WHERE ResourceId = ".$OldResourceId);
291 $DB->Query(
"UPDATE Files SET ResourceId = ".
292 $this->
Id.
" WHERE ResourceId = ".$OldResourceId);
294 # signal event as appropriate
295 if ($NewSetting === FALSE)
297 $GLOBALS[
"AF"]->SignalEvent(
"EVENT_RESOURCE_ADD", array(
304 # report to caller whether we are a temp resource
305 return ($this->
Id() < 0) ? TRUE : FALSE;
309 # --- Generic Attribute Retrieval Methods -------------------------------
325 function Get($FieldNameOrObject, $ReturnObject = FALSE, $IncludeVariants = FALSE)
327 # load field object if needed
328 $Field = is_object($FieldNameOrObject) ? $FieldNameOrObject
329 : $this->Schema->GetFieldByName($FieldNameOrObject);
331 # return no value found if we don't have a valid field
332 if ((get_class($Field) !=
"MetadataField")
336 # grab database field name
337 $DBFieldName = $Field->DBFieldName();
339 # format return value based on field type
340 switch ($Field->Type())
347 if (isset($this->DBFields[$DBFieldName]))
349 $ReturnValue = $this->DBFields[$DBFieldName];
358 $ReturnValue = array(
"X" => $this->DBFields[$DBFieldName.
"X"],
359 "Y" => $this->DBFields[$DBFieldName.
"Y"]);
363 $Date =
new Date($this->DBFields[$DBFieldName.
"Begin"],
364 $this->DBFields[$DBFieldName.
"End"],
365 $this->DBFields[$DBFieldName.
"Precision"]);
368 $ReturnValue = $Date;
372 $ReturnValue = $Date->Formatted();
377 $ReturnValue = $this->DBFields[$DBFieldName];
381 # start with empty array
382 $ReturnValue = array();
384 # if classification cache has not been loaded
385 if (!isset($this->ClassificationCache))
387 # load all classifications associated with this resource into cache
388 $this->ClassificationCache = array();
389 $this->DB->Query(
"SELECT Classifications.ClassificationId,Classifications.FieldId,ClassificationName "
390 .
"FROM ResourceClassInts, Classifications "
391 .
"WHERE ResourceClassInts.ResourceId = ".$this->
Id.
" "
392 .
"AND ResourceClassInts.ClassificationId = Classifications.ClassificationId ");
393 while ($Record = $this->DB->FetchRow())
395 $this->ClassificationCache[$Record[
"ClassificationId"]][
"Name"] =
396 $Record[
"ClassificationName"];
397 $this->ClassificationCache[$Record[
"ClassificationId"]][
"FieldId"] =
402 # for each entry in classification cache
403 foreach ($this->ClassificationCache as $ClassificationId => $ClassificationInfo)
405 # if classification ID matches field we are looking for
406 if ($ClassificationInfo[
"FieldId"] == $Field->Id())
408 # add field to result
411 $ReturnValue[$ClassificationId] =
new Classification($ClassificationId);
415 $ReturnValue[$ClassificationId] = $ClassificationInfo[
"Name"];
423 # start with empty array
424 $ReturnValue = array();
426 # if controlled name cache has not been loaded
427 if (!isset($this->ControlledNameCache))
429 # load all controlled names associated with this resource into cache
430 $this->ControlledNameCache = array();
431 $this->DB->Query(
"SELECT ControlledNames.ControlledNameId,ControlledNames.FieldId,ControlledName "
432 .
"FROM ResourceNameInts, ControlledNames "
433 .
"WHERE ResourceNameInts.ResourceId = ".$this->
Id.
" "
434 .
"AND ResourceNameInts.ControlledNameId = ControlledNames.ControlledNameId ");
435 while ($Record = $this->DB->FetchRow())
437 $this->ControlledNameCache[$Record[
"ControlledNameId"]][
"Name"] = $Record[
"ControlledName"];
438 $this->ControlledNameCache[$Record[
"ControlledNameId"]][
"FieldId"] = $Record[
"FieldId"];
442 # if variant names requested and variant name cache has not been loaded
443 if ($IncludeVariants && !isset($this->ControlledNameVariantCache))
445 # load all controlled names associated with this resource into cache
446 $this->ControlledNameVariantCache = array();
447 $this->DB->Query(
"SELECT ControlledNames.ControlledNameId,ControlledNames.FieldId,ControlledName,VariantName "
448 .
"FROM ResourceNameInts, ControlledNames, VariantNames "
449 .
"WHERE ResourceNameInts.ResourceId = ".$this->
Id.
" "
450 .
"AND ResourceNameInts.ControlledNameId = ControlledNames.ControlledNameId "
451 .
"AND VariantNames.ControlledNameId = ControlledNames.ControlledNameId");
452 while ($Record = $this->DB->FetchRow())
454 $this->ControlledNameVariantCache[$Record[
"ControlledNameId"]][] = $Record[
"VariantName"];
458 # for each entry in controlled name cache
459 foreach ($this->ControlledNameCache as $ControlledNameId => $ControlledNameInfo)
461 # if controlled name type matches field we are looking for
462 if ($ControlledNameInfo[
"FieldId"] == $Field->Id())
464 # if objects requested
467 $ReturnValue[$ControlledNameId] =
472 # if variant names requested
473 if ($IncludeVariants)
475 # add field to result
476 $ReturnValue[] = $ControlledNameInfo[
"Name"];
478 # add any variant names to result
479 if (isset($this->ControlledNameVariantCache[$ControlledNameId]))
481 $ReturnValue = array_merge($ReturnValue, $this->ControlledNameVariantCache[$ControlledNameId]);
486 # add field with index to result
487 $ReturnValue[$ControlledNameId] = $ControlledNameInfo[
"Name"];
495 $User =
new User($this->DB, (
int)$this->DBFields[$DBFieldName]);
498 $ReturnValue = $User;
502 $ReturnValue = $User->Get(
"UserName");
507 if ($this->DBFields[$DBFieldName] > 0)
509 $ImageObject =
new SPTImage($this->DBFields[$DBFieldName]);
512 $ReturnValue = $ImageObject;
516 $ReturnValue = $ImageObject->AltText();
526 # retrieve files using factory
529 $this->
Id, $ReturnObject);
534 exit(
"<br>SPT - ERROR: attempt to retrieve unknown resource field type (".$Field->Type().
")<br>\n");
538 # return formatted value to caller
546 $ReturnObject = FALSE, $IncludeVariants = FALSE)
547 {
return $this->
Get($FieldNameOrObject, $ReturnObject, $IncludeVariants); }
562 function GetByFieldId($FieldId, $ReturnObject = FALSE, $IncludeVariants = FALSE)
564 $Field = $this->Schema->GetField($FieldId);
565 return ($Field) ? $this->
Get($Field, $ReturnObject, $IncludeVariants) : NULL;
580 function GetAsArray($IncludeDisabledFields = FALSE, $ReturnObjects = TRUE)
582 # retrieve field info
583 $Fields = $this->Schema->GetFields();
586 foreach ($Fields as $Field)
588 # if field is enabled or caller requested disabled fields
589 if ($Field->Enabled() || $IncludeDisabledFields)
591 # retrieve info and add it to the array
592 $FieldStrings[$Field->Name()] = $this->
Get($Field, $ReturnObjects);
594 # if field uses qualifiers
595 if ($Field->UsesQualifiers())
597 # get qualifier attributes and add to the array
598 $FieldStrings[$Field->Name().
" Qualifier"] =
604 # add in internal values
605 $FieldStrings[
"ResourceId"] = $this->
Id();
608 # return array to caller
609 return $FieldStrings;
626 function GetMapped($MappedName, $ReturnObject = FALSE, $IncludeVariants = FALSE)
628 return $this->Schema->StdNameToFieldMapping($MappedName)
629 ? $this->
GetByFieldId($this->Schema->StdNameToFieldMapping($MappedName),
630 $ReturnObject, $IncludeVariants)
644 $Field = $this->Schema->GetFieldByName($FieldName);
658 $Field = $this->Schema->GetField($FieldId);
672 # return NULL if field is invalid
673 if ((get_class($Field) !=
"MetadataField")
677 # assume no qualifiers if not otherwise determined
680 # if field uses qualifiers
681 if ($Field->UsesQualifiers())
683 # retrieve qualifiers based on field type
684 switch ($Field->Type())
689 # retrieve list of items
692 # if field uses item-level qualifiers
693 if ($Field->HasItemLevelQualifiers())
695 # determine general item name in DB
697 ?
"Classification" :
"ControlledName";
700 foreach (
$Items as $ItemId => $ItemName)
702 # look up qualifier for item
703 $QualId = $this->DB->Query(
704 "SELECT * FROM ".$TableName.
"s"
705 .
" WHERE ".$TableName.
"Id = ".$ItemId
711 # if object was requested by caller
714 # load qualifier and add to return value array
715 $ReturnValue[$ItemId] =
new Qualifier($QualId);
719 # add qualifier ID to return value array
720 $ReturnValue[$ItemId] = $QualId;
725 # add NULL to return value array for this item
726 $ReturnValue[$ItemId] = NULL;
733 foreach (
$Items as $ItemId => $ItemName)
735 # if object was requested by caller
738 # load default qualifier and add to return value array
739 $ReturnValue[$ItemId] =
new Qualifier($Field->DefaultQualifier());
743 # add default qualifier ID to return value array
744 $ReturnValue[$ItemId] = $Field->DefaultQualifier();
751 # if field uses item-level qualifiers
752 if ($Field->HasItemLevelQualifiers())
754 # if qualifier available
755 if ($this->DBFields[$Field->DBFieldName().
"Qualifier"] > 0)
757 # if object was requested by caller
760 # return qualifier for field
761 $ReturnValue =
new Qualifier($this->DBFields[$Field->DBFieldName().
"Qualifier"]);
765 # return qualifier ID for field
766 $ReturnValue = $this->DBFields[$Field->DBFieldName().
"Qualifier"];
772 # if default qualifier available
773 if ($Field->DefaultQualifier() > 0)
775 # if object was requested by caller
778 # return default qualifier
779 $ReturnValue =
new Qualifier($Field->DefaultQualifier());
783 # return default qualifier ID
784 $ReturnValue = $Field->DefaultQualifier();
792 # return qualifier object or ID (or array of same) to caller
797 # --- Generic Attribute Setting Methods ---------------------------------
799 # set value using field name or field object
800 function Set($FieldNameOrObject, $NewValue)
802 # load field object if needed
803 $Field = is_object($FieldNameOrObject) ? $FieldNameOrObject
804 : $this->Schema->GetFieldByName($FieldNameOrObject);
806 # grab commonly-used values for local use
808 $ResourceId = $this->Id;
810 # grab database field name
811 $DBFieldName = $Field->DBFieldName();
813 # Flag to deterimine if we've actually changed anything.
814 $UpdateModTime = FALSE;
816 # store value in DB based on field type
817 switch ($Field->Type())
822 if ($this->DBFields[$DBFieldName] != $NewValue)
824 # save value directly to DB
825 $DB->Query(
"UPDATE Resources SET `"
826 .$DBFieldName.
"` = '".addslashes($NewValue).
"' "
827 .
"WHERE ResourceId = ".$ResourceId);
830 $this->DBFields[$DBFieldName] = $NewValue;
836 if ( $this->DBFields[$DBFieldName] != $NewValue )
838 # save value directly to DB
839 if (is_null($NewValue))
841 $DB->Query(
"UPDATE Resources SET `"
842 .$DBFieldName.
"` = NULL"
843 .
" WHERE ResourceId = ".$ResourceId);
847 $DB->Query(
"UPDATE Resources SET `"
848 .$DBFieldName.
"` = ".intval($NewValue)
849 .
" WHERE ResourceId = ".$ResourceId);
853 $this->DBFields[$DBFieldName] = $NewValue;
854 $UpdateModTime = TRUE;
860 if ($this->DBFields[$DBFieldName.
"X"] != $NewValue[
"X"] ||
861 $this->DBFields[$DBFieldName.
"Y"] != $NewValue[
"Y"] )
863 if (is_null($NewValue))
865 $DB->Query(
"UPDATE Resources SET "
866 .
"`".$DBFieldName.
"X` = NULL, "
867 .
"`".$DBFieldName.
"Y` = NULL "
868 .
"WHERE ResourceId = ".$ResourceId);
869 $this->DBFields[$DBFieldName.
"X"] = NULL;
870 $this->DBFields[$DBFieldName.
"Y"] = NULL;
874 $DB->Query(
"UPDATE Resources SET "
875 .
"`".$DBFieldName.
"X` = ".(strlen($NewValue[
"X"])
876 ?
"'".$NewValue[
"X"].
"'" :
"NULL").
", "
877 .
"`".$DBFieldName.
"Y` = ".(strlen($NewValue[
"Y"])
878 ?
"'".$NewValue[
"Y"].
"'" :
"NULL")
879 .
" WHERE ResourceId = ".$ResourceId);
881 $Digits = $Field->PointDecimalDigits();
883 $this->DBFields[$DBFieldName.
"X"] =
884 strlen($NewValue[
"X"]) ? round($NewValue[
"X"], $Digits) : NULL;
885 $this->DBFields[$DBFieldName.
"Y"] =
886 strlen($NewValue[
"Y"]) ? round($NewValue[
"Y"], $Digits) : NULL;
888 $UpdateModTime = TRUE;
893 if ($this->DBFields[$DBFieldName] != $NewValue)
895 # save value directly to DB
896 if (is_null($NewValue))
898 $DB->Query(
"UPDATE Resources SET `"
899 .$DBFieldName.
"` = NULL"
900 .
" WHERE ResourceId = ".$ResourceId);
904 $DB->Query(
"UPDATE Resources SET `"
905 .$DBFieldName.
"` = ".$NewValue
906 .
" WHERE ResourceId = ".$ResourceId);
909 $this->DBFields[$DBFieldName] = $NewValue;
911 # recalculate counts for any associated classifications if necessary
912 if ($DBFieldName ==
"ReleaseFlag")
914 $DB->Query(
"SELECT ClassificationId FROM ResourceClassInts"
915 .
" WHERE ResourceId = ".$ResourceId);
916 while ($ClassId = $DB->FetchField(
"ClassificationId"))
919 $Class->RecalcResourceCount();
922 $UpdateModTime = TRUE;
927 # if value passed in was object
928 if (is_object($NewValue))
930 # retrieve user ID from object
931 $UserId = $NewValue->Get(
"UserId");
933 # else if value passed in was user name
934 elseif (is_string($NewValue))
936 # create user object and retrieve user ID from there
937 $User =
new User($this->DB, $NewValue);
938 $UserId = $User->Get(
"UserId");
942 # assume value is user ID and use value directly
946 if ($this->DBFields[$DBFieldName] != $UserId)
948 # save value directly to DB
949 $DB->Query(
"UPDATE Resources SET `"
950 .$DBFieldName.
"` = '".$UserId.
"' "
951 .
"WHERE ResourceId = ".$ResourceId);
954 $this->DBFields[$DBFieldName] = $UserId;
955 $UpdateModTime = TRUE;
960 # if we were given a date object
961 if (is_object($NewValue))
963 # use supplied date object
969 $Date =
new Date($NewValue);
973 $this->DBFields[$DBFieldName.
"Begin"],
974 $this->DBFields[$DBFieldName.
"End"]);
976 if ($OldDate->BeginDate() != $Date->BeginDate() ||
977 $OldDate->EndDate() != $Date->EndDate() ||
978 $OldDate->Precision() != $Date->Precision() )
980 # extract values from date object and store in DB
981 $BeginDate =
"'".$Date->BeginDate().
"'";
982 if (strlen($BeginDate) < 3) { $BeginDate =
"NULL"; }
983 $EndDate =
"'".$Date->EndDate().
"'";
984 if (strlen($EndDate) < 3) { $EndDate =
"NULL"; }
986 $DB->Query(
"UPDATE Resources SET "
987 .$DBFieldName.
"Begin = ".$BeginDate.
", "
988 .$DBFieldName.
"End = ".$EndDate.
", "
989 .$DBFieldName.
"Precision = '".$Date->Precision().
"' "
990 .
"WHERE ResourceId = ".$ResourceId);
992 # save values locally
993 $this->DBFields[$DBFieldName.
"Begin"] = $Date->BeginDate();
994 $this->DBFields[$DBFieldName.
"End"] = $Date->EndDate();
995 $this->DBFields[$DBFieldName.
"Precision"] = $Date->Precision();
1001 if (is_null($NewValue))
1003 $DateValue = $NewValue;
1005 if (!is_null($this->DBFields[$DBFieldName]))
1007 # save value directly to DB
1008 $DB->Query(
"UPDATE Resources SET "
1009 .
"`".$DBFieldName.
"` = NULL "
1010 .
"WHERE ResourceId = ".$ResourceId);
1011 $UpdateModTime = TRUE;
1016 # assume value is date and use directly
1017 $DateValue = date(
"Y-m-d H:i:s", strtotime($NewValue));
1019 if ($this->DBFields[$DBFieldName] != $DateValue)
1021 # save value directly to DB
1022 $DB->Query(
"UPDATE Resources SET "
1023 .
"`".$DBFieldName.
"` = '".addslashes($DateValue).
"' "
1024 .
"WHERE ResourceId = ".$ResourceId);
1025 $UpdateModTime=TRUE;
1029 # save value locally
1030 $this->DBFields[$DBFieldName] = $DateValue;
1034 $OldValue = $this->
Get($Field);
1036 # if incoming value is array
1037 if (is_array($NewValue))
1039 if ($OldValue != $NewValue)
1041 # for each element of array
1042 foreach ($NewValue as
1043 $ClassificationId => $ClassificationName)
1048 # associate with resource if not already associated
1049 $this->AddAssociation(
"ResourceClassInts",
1052 $Class->RecalcResourceCount();
1055 $UpdateModTime=TRUE;
1060 # associate with resource if not already associated
1061 if (is_object($NewValue))
1064 $NewValue = $Class->Id();
1071 if (!array_key_exists($Class->Id(), $OldValue))
1074 $this->AddAssociation(
"ResourceClassInts",
1077 $Class->RecalcResourceCount();
1078 $UpdateModTime=TRUE;
1082 # clear our classification cache
1085 unset($this->ClassificationCache);
1091 $OldValue = $this->
Get($Field);
1093 # Clear other values if this field expects unique options
1094 if ($Field->AllowMultiple() === FALSE)
1096 # If we're fed an array for a unique option,
1097 # just use the last element of the array
1098 if (is_array($NewValue)){
1099 $NewValue = array_pop($NewValue);
1102 if (!array_key_exists($NewValue, $OldValue))
1105 $this->RemoveAllAssociations(
"ResourceNameInts",
1108 $UpdateModTime=TRUE;
1112 # if incoming value is array
1113 if (is_array($NewValue) && ($Field->AllowMultiple() !== FALSE) )
1115 if ($OldValue != $NewValue)
1117 # for each element of array
1118 foreach ($NewValue as $ControlledNameId => $ControlledName)
1120 # associate with resource if not already associated
1121 $this->AddAssociation(
"ResourceNameInts",
1125 $UpdateModTime=TRUE;
1130 # associate with resource if not already associated
1131 if (is_object($NewValue)) { $NewValue = $NewValue->Id(); }
1132 if (!array_key_exists($NewValue, $OldValue))
1134 $this->AddAssociation(
"ResourceNameInts",
1137 $UpdateModTime=TRUE;
1143 # clear our controlled name cache
1144 unset($this->ControlledNameCache);
1145 unset($this->ControlledNameVariantCache);
1151 # if we were given an image object
1152 if (is_object($NewValue))
1154 # grab ID from object
1155 $ImageId = $NewValue->Id();
1159 # assume incoming value is ID
1160 $ImageId = $NewValue;
1163 if ($this->DBFields[$DBFieldName] != $ImageId)
1165 # store new image object ID in database
1166 $DB->Query(
"UPDATE Resources SET `"
1167 .$DBFieldName.
"` = '".$ImageId.
"'"
1168 .
" WHERE ResourceId = ".$ResourceId);
1169 $UpdateModTime = TRUE;
1170 # save value locally
1171 $this->DBFields[$DBFieldName] = $ImageId;
1176 # convert incoming value to array if necessary
1177 if (!is_array($NewValue)) { $NewValue = array($NewValue); }
1179 # for each incoming file
1181 foreach ($NewValue as $File)
1184 $NewFile = $Factory->
Copy($File);
1186 # associate copy with this resource and field
1187 $NewFile->ResourceId($this->
Id);
1188 $NewFile->FieldId($Field->Id());
1190 # Since we make a fresh copy of the File whenever Set is called,
1191 # we'll always update the modification time for this field.
1192 $UpdateModTime = TRUE;
1197 exit(
"<br>SPT - ERROR: attempt to set unknown resource field type<br>\n");
1203 # update modification timestamps
1205 $UserId = $G_User->IsLoggedIn() ? $G_User->Get(
"UserId") : -1;
1206 $DB->Query(
"DELETE FROM ResourceFieldTimestamps "
1207 .
"WHERE ResourceId=".$this->
Id.
" AND "
1208 .
"FieldId=".$Field->Id() );
1209 $DB->Query(
"INSERT INTO ResourceFieldTimestamps "
1210 .
"(ResourceId,FieldId,ModifiedBy,Timestamp) VALUES ("
1211 .$this->
Id.
",".$Field->Id().
","
1212 .$UserId.
",NOW())");
1215 # (for backward compatibility)
1216 function SetByField($Field, $NewValue) {
return $this->
Set($Field, $NewValue); }
1218 # set value by field ID
1221 $Field = $this->Schema->GetField($FieldId);
1222 return $this->
Set($Field, $NewValue);
1225 # set qualifier by field name
1228 $Field = $this->Schema->GetFieldByName($FieldName);
1232 # set qualifier by field ID
1235 $Field = $this->Schema->GetField($FieldId);
1239 # set qualifier using field object
1242 # if field uses qualifiers and uses item-level qualifiers
1243 if ($Field->UsesQualifiers() && $Field->HasItemLevelQualifiers())
1245 # if qualifier object passed in
1246 if (is_object($NewValue))
1248 # grab qualifier ID from object
1249 $QualifierId = $NewValue->Id();
1253 # assume value passed in is qualifier ID
1254 $QualifierId = $NewValue;
1257 # update qualifier value in database
1258 $DBFieldName = $Field->DBFieldName();
1259 $this->DB->Query(
"UPDATE Resources SET "
1260 .$DBFieldName.
"Qualifier = '".$QualifierId.
"' "
1261 .
"WHERE ResourceId = ".$this->Id);
1263 # update local qualifier value
1264 $this->DBFields[$DBFieldName.
"Qualifier"] = $QualifierId;
1268 # clear value by field name
1269 function Clear($FieldName, $ValueToClear = NULL)
1271 $Field = $this->Schema->GetFieldByName($FieldName);
1275 # clear value by field ID
1278 $Field = $this->Schema->GetField($FieldId);
1282 # clear value using field object
1285 # grab commonly-used values for local use
1287 $ResourceId = $this->Id;
1289 # grab database field name
1290 $DBFieldName = $Field->DBFieldName();
1292 $UpdateModTime=FALSE;
1294 # store value in DB based on field type
1295 switch ($Field->Type())
1304 if (strlen($this->DBFields[$DBFieldName])>0)
1307 $DB->Query(
"UPDATE Resources SET `"
1308 .$DBFieldName.
"` = '' "
1309 .
"WHERE ResourceId = ".$ResourceId);
1311 # clear value locally
1312 $this->DBFields[$DBFieldName] = NULL;
1313 $UpdateModTime=TRUE;
1318 if (!is_null($this->DBFields[$DBFieldName.
"X"]) ||
1319 !is_null($this->DBFields[$DBFieldName.
"Y"]) )
1322 $DB->Query(
"UPDATE Resources SET "
1323 .
"`".$DBFieldName.
"X` = NULL ,"
1324 .
"`".$DBFieldName.
"Y` = NULL "
1325 .
"WHERE ResourceId = ".$ResourceId);
1327 # Clear local values
1328 $this->DBFields[$DBFieldName.
"X"] = NULL;
1329 $this->DBFields[$DBFieldName.
"Y"] = NULL;
1330 $UpdateModTime=TRUE;
1335 if (!is_null($this->DBFields[$DBFieldName.
"Begin"]) ||
1336 !is_null($this->DBFields[$DBFieldName.
"End"]) ||
1337 !is_null($this->DBFields[$DBFieldName.
"Precision"]))
1339 # clear date object values in DB
1340 $DB->Query(
"UPDATE Resources SET "
1341 .$DBFieldName.
"Begin = '', "
1342 .$DBFieldName.
"End = '', "
1343 .$DBFieldName.
"Precision = '' "
1344 .
"WHERE ResourceId = ".$ResourceId);
1346 # clear value locally
1347 $this->DBFields[$DBFieldName.
"Begin"] = NULL;
1348 $this->DBFields[$DBFieldName.
"End"] = NULL;
1349 $this->DBFields[$DBFieldName.
"Precision"] = NULL;
1350 $UpdateModTime=TRUE;
1355 $OldValue = $this->
Get($Field);
1357 # if value to clear supplied
1358 if ($ValueToClear !== NULL)
1360 # if supplied value is array
1361 if (is_array($ValueToClear))
1363 # for each element of array
1364 foreach ($ValueToClear as $ClassificationId => $Dummy)
1366 if (array_key_exists($ClassificationId, $OldValue))
1368 # remove association with resource (if any)
1369 $this->RemoveAssociation(
"ResourceClassInts",
1373 $Class->RecalcResourceCount();
1374 $UpdateModTime=TRUE;
1380 if (array_key_exists($ValueToClear, $OldValue))
1382 # remove association with resource (if any)
1383 $this->RemoveAssociation(
"ResourceClassInts",
1387 $Class->RecalcResourceCount();
1388 $UpdateModTime=TRUE;
1394 if (count($OldValue)>0)
1396 # remove all associations for resource and field
1397 $this->RemoveAllAssociations(
"ResourceClassInts",
"ClassificationId", $Field);
1399 # recompute resource count
1400 $Values = $this->
Get($Field);
1401 foreach ($Values as $ClassificationId => $Dummy)
1404 $Class->RecalcResourceCount();
1406 $UpdateModTime=TRUE;
1410 # clear our classification cache
1413 unset($this->ClassificationCache);
1419 $OldValue = $this->
Get($Field);
1420 # if value to clear supplied
1421 if ($ValueToClear !== NULL)
1423 # if incoming value is array
1424 if (is_array($ValueToClear))
1426 # for each element of array
1427 foreach ($ValueToClear as $ControlledNameId =>
1430 if (array_key_exists($ControlledNameId, $OldValue))
1432 # remove association with resource (if any)
1433 $this->RemoveAssociation(
"ResourceNameInts",
1436 $UpdateModTime=TRUE;
1442 if (array_key_exists($ValueToClear, $OldValue))
1444 # remove association with resource (if any)
1445 $this->RemoveAssociation(
"ResourceNameInts",
1448 $UpdateModTime=TRUE;
1454 if (count($OldValue)>0)
1456 # remove all associations for resource and field
1457 $this->RemoveAllAssociations(
"ResourceNameInts",
"ControlledNameId", $Field);
1458 $UpdateModTime=TRUE;
1464 # clear our controlled name cache
1465 unset($this->ControlledNameCache);
1466 unset($this->ControlledNameVariantCache);
1471 # delete image if no other resources are using it
1472 $ImageId = $DB->Query(
"SELECT `".$DBFieldName
1473 .
"` FROM Resources WHERE ResourceId = ".$ResourceId,
1477 $ImageCount = $DB->Query(
"SELECT COUNT(*) AS ImageCount FROM Resources"
1478 .
" WHERE `".$DBFieldName.
"` = ".$ImageId,
1480 if ($ImageCount < 2)
1485 $UpdateModTime=TRUE;
1489 $DB->Query(
"UPDATE Resources SET `"
1490 .$DBFieldName.
"` = '' "
1491 .
"WHERE ResourceId = ".$ResourceId);
1493 # clear value locally
1494 $this->DBFields[$DBFieldName] = NULL;
1498 # get array of Files associated with this resource
1499 $Files = $this->
Get($Field, TRUE);
1501 if (count($Files)>0){
1503 foreach ($Files as $File)
1508 $UpdateModTime=TRUE;
1514 exit(
"<br>SPT - ERROR: attempt to clear unknown resource field type<br>\n");
1520 # update modification timestamps
1522 $UserId = $G_User->IsLoggedIn() ? $G_User->Get(
"UserId") : -1;
1523 $DB->Query(
"DELETE FROM ResourceFieldTimestamps "
1524 .
"WHERE ResourceId=".$this->
Id.
" AND "
1525 .
"FieldId=".$Field->Id() );
1526 $DB->Query(
"INSERT INTO ResourceFieldTimestamps "
1527 .
"(ResourceId,FieldId,ModifiedBy,Timestamp) VALUES ("
1528 .$this->
Id.
",".$Field->Id().
","
1529 .$UserId.
",NOW())");
1534 # --- Field-Specific or Type-Specific Attribute Retrieval Methods -------
1536 # return 2D array of classifications associated with resource
1537 # (first index is classification (field) name, second index is classification ID)
1542 # start with empty array
1545 # for each controlled name
1546 $DB->Query(
"SELECT ClassificationName, MetadataFields.FieldName, "
1547 .
"ResourceClassInts.ClassificationId FROM ResourceClassInts, "
1548 .
"Classifications, MetadataFields "
1549 .
"WHERE ResourceClassInts.ResourceId = ".$this->
Id.
" "
1550 .
"AND ResourceClassInts.ClassificationId = Classifications.ClassificationId "
1551 .
"AND Classifications.FieldId = MetadataFields.FieldId ");
1552 while ($Record = $DB->FetchRow())
1555 $Names[$Record[
"FieldName"]][$Record[
"ClassificationId"]] =
1556 $Record[
"ClassificationName"];
1559 # return array to caller
1564 # --- Ratings Methods ---------------------------------------------------
1566 # return cumulative rating (range is usually 0-100)
1569 # return cumulative rating scaled to 1/10th (range is usually 0-10)
1582 # return current number of ratings for resource
1585 # if number of ratings not already set
1588 # obtain number of ratings
1590 $this->DB->Query(
"SELECT Count(*) AS NumberOfRatings "
1591 .
"FROM ResourceRatings "
1592 .
"WHERE ResourceId = ".$this->
Id,
1596 # recalculate cumulative rating if it looks erroneous
1599 $this->UpdateCumulativeRating();
1603 # return number of ratings to caller
1604 return $this->NumberOfRatings;
1607 # update individual rating for resource
1608 function Rating($NewRating = NULL, $UserId = NULL)
1612 # if user ID not supplied
1613 if ($UserId == NULL)
1615 # if user is logged in
1617 if ($User->IsLoggedIn())
1619 # use ID of current user
1620 $UserId = $User->Get(
"UserId");
1624 # return NULL to caller
1629 # sanitize $NewRating
1630 if (!is_null($NewRating))
1632 $NewRating = intval($NewRating);
1635 # if there is a rating for resource and user
1636 $DB->Query(
"SELECT Rating FROM ResourceRatings "
1637 .
"WHERE UserId = ${UserId} AND ResourceId = ".$this->
Id);
1638 if ($Record = $DB->FetchRow())
1640 # if new rating was supplied
1641 if ($NewRating != NULL)
1643 # update existing rating
1644 $DB->Query(
"UPDATE ResourceRatings "
1645 .
"SET Rating = ${NewRating}, DateRated = NOW() "
1646 .
"WHERE UserId = ${UserId} AND ResourceId = ".$this->
Id);
1648 # update cumulative rating value
1649 $this->UpdateCumulativeRating();
1651 # return value is new rating
1652 $Rating = $NewRating;
1656 # get rating value to return to caller
1657 $Rating = $Record[
"Rating"];
1662 # if new rating was supplied
1663 if ($NewRating != NULL)
1666 $DB->Query(
"INSERT INTO ResourceRatings "
1667 .
"(ResourceId, UserId, DateRated, Rating) "
1674 # update cumulative rating value
1675 $this->UpdateCumulativeRating();
1677 # return value is new rating
1678 $Rating = $NewRating;
1682 # return value is NULL
1687 # return rating value to caller
1692 # --- Resource Comment Methods ------------------------------------------
1694 # return comments as array of Message objects
1697 # read in comments if not already loaded
1700 $this->DB->Query(
"SELECT MessageId FROM Messages "
1701 .
"WHERE ParentId = ".$this->
Id
1702 .
" AND ParentType = 2 "
1703 .
"ORDER BY DatePosted DESC");
1704 while ($MessageId = $this->DB->FetchField(
"MessageId"))
1710 # return array of comments to caller
1711 return $this->Comments;
1714 # return current number of comments
1717 # obtain number of comments if not already set
1721 $this->DB->Query(
"SELECT Count(*) AS NumberOfComments "
1723 .
"WHERE ParentId = ".$this->
Id
1724 .
" AND ParentType = 2",
1729 # return number of comments to caller
1730 return $this->NumberOfComments;
1734 # --- Permission Methods -------------------------------------------------
1747 # cannot view a resource that is not valid
1748 if ($this->
Status() !== 1)
1753 # check authorization if the resource has not been released
1754 else if (!$this->
Get(
"Release Flag"))
1756 $IsCreator = $User->
Name() == $this->
Get(
"Added By Id");
1758 # if the user is not a personal resource admin or is not the creator
1759 # then an additional admin check is necessary
1760 if (!$User->
HasPriv(PRIV_MYRESOURCEADMIN) || !$IsCreator)
1762 # if the user is not a resource admin or release admin
1763 if (!$User->
HasPriv(PRIV_RESOURCEADMIN, PRIV_RELEASEADMIN))
1770 # allow plugins to modify result of the permission check
1771 $SignalResult = $GLOBALS[
"AF"]->SignalEvent(
1772 "EVENT_RESOURCE_VIEW_PERMISSION_CHECK",
1773 array(
"Resource" => $this,
"User" => $User,
"CanView" => $CanView));
1774 $CanView = $SignalResult[
"CanView"];
1779 # return whether user can edit this resource
1782 # determine whether user can edit resource
1783 if ($User->HasPriv(PRIV_RESOURCEADMIN)
1784 || $User->HasPriv(PRIV_RELEASEADMIN)
1785 || ($User->HasPriv(PRIV_MYRESOURCEADMIN)
1786 && ($User->Id() == $this->DBFields[
"AddedById"])))
1794 $Fields = $this->Schema->GetFields();
1795 foreach ($Fields as $Field)
1802 # allow plugins to modify result of permission check
1803 $SignalResult = $GLOBALS[
"AF"]->SignalEvent(
1804 "EVENT_RESOURCE_EDIT_PERMISSION_CHECK", array(
1805 "Resource" => $this,
1807 "CanEdit" => $CanEdit));
1808 $CanEdit = $SignalResult[
"CanEdit"];
1810 # report back to caller whether user can edit field
1822 # get field object (if not supplied)
1823 if (is_object($FieldOrFieldName)
1826 $Field = $FieldOrFieldName;
1828 elseif (strlen(trim($FieldOrFieldName)))
1830 if ($this->Schema->FieldExists($FieldOrFieldName))
1832 $Field = $this->Schema->GetFieldByName($FieldOrFieldName);
1836 # field absolutely cannot be viewed if it is not valid
1837 if (!isset($Field)) {
return FALSE; }
1839 # field should not be viewed if it is disabled
1840 if (!$Field->Enabled())
1846 # if the user can edit the field they can also view it
1853 # assume user can view field
1856 # check viewing privilege constraint
1857 if ($Field->ViewingPrivilege() != 0)
1859 if (!$User->HasPriv($Field->ViewingPrivilege()))
1865 # check "user is value of field" constraint
1866 $UserIsLogic = $Field->ViewingUserIsValue();
1867 $ValueToCheck = $this->
Get($this->Schema->GetField(
1868 $Field->ViewingUserValue()));
1871 if ($ValueToCheck != $User->Name())
1878 if ($ValueToCheck == $User->Name())
1886 # allow plugins to modify result of permission check
1887 $SignalResult = $GLOBALS[
"AF"]->SignalEvent(
1888 "EVENT_FIELD_VIEW_PERMISSION_CHECK", array(
1890 "Resource" => $this,
1892 "CanView" => $CanView));
1893 $CanView = $SignalResult[
"CanView"];
1895 # report back to caller whether user can view field
1907 # fields hard-coded to not be authorable
1908 $UnauthorableFields = array(
1909 "Cumulative Rating",
1910 "Date Of Record Creation",
1911 "Date Of Record Release",
1912 "Date Last Modified",
1913 "Last Modified By Id");
1915 # get field object (if not supplied)
1916 if (is_object($FieldOrFieldName)
1919 $Field = $FieldOrFieldName;
1921 elseif (strlen(trim($FieldOrFieldName)))
1923 if ($this->Schema->FieldExists($FieldOrFieldName))
1925 $Field = $this->Schema->GetFieldByName($FieldOrFieldName);
1929 # field absolutely cannot be authored if it is not valid
1930 if (!isset($Field)) {
return FALSE; }
1932 # field should not be authored if it is disabled or is on "no author" list
1933 # or user is not the resource creator
1934 if (!$Field->Enabled()
1935 || in_array($Field->Name(), $UnauthorableFields)
1936 || ($User->Name() != $this->
Get(
"Added By Id")))
1942 # assume user can author field
1945 # check authoring privilege constraint
1946 if ($Field->AuthoringPrivilege() != 0)
1948 if (!$User->HasPriv($Field->AuthoringPrivilege()))
1954 # check "user is value of field" constraint
1955 $UserIsLogic = $Field->AuthoringUserIsValue();
1956 $ValueToCheck = $this->
Get($this->Schema->GetField(
1957 $Field->AuthoringUserValue()));
1960 if ($ValueToCheck != $User->Name())
1967 if ($ValueToCheck == $User->Name())
1974 # allow plugins to modify result of permission check
1975 $SignalResult = $GLOBALS[
"AF"]->SignalEvent(
1976 "EVENT_FIELD_AUTHOR_PERMISSION_CHECK", array(
1978 "Resource" => $this,
1980 "CanAuthor" => $CanAuthor));
1981 $CanAuthor = $SignalResult[
"CanAuthor"];
1983 # report back to caller whether user can author field
1995 # fields hard-coded to not be editable
1996 $UneditableFields = array(
1997 "Cumulative Rating",
1998 "Date Of Record Creation",
1999 "Date Of Record Release",
2000 "Date Last Modified",
2001 "Last Modified By Id");
2003 # get field object (if not supplied)
2004 if (is_object($FieldOrFieldName)
2007 $Field = $FieldOrFieldName;
2009 elseif (strlen(trim($FieldOrFieldName)))
2011 if ($this->Schema->FieldExists($FieldOrFieldName))
2013 $Field = $this->Schema->GetFieldByName($FieldOrFieldName);
2017 # field absolutely cannot be edited if it is not valid
2018 if (!isset($Field)) {
return FALSE; }
2020 # field should not be edited if it is disabled or is on "no edit" list
2021 if (!$Field->Enabled() || in_array($Field->Name(), $UneditableFields))
2027 # if the user can author the field they can also edit it
2034 # assume user can edit field
2037 # check editing privilege constraint
2038 if ($Field->EditingPrivilege() != 0)
2040 if (!$User->HasPriv($Field->EditingPrivilege()))
2046 # check "user is value of field" constraint
2047 $UserIsLogic = $Field->EditingUserIsValue();
2048 $ValueToCheck = $this->
Get($this->Schema->GetField(
2049 $Field->EditingUserValue()));
2052 if ($ValueToCheck != $User->Name())
2059 if ($ValueToCheck == $User->Name())
2067 # allow plugins to modify result of permission check
2068 $SignalResult = $GLOBALS[
"AF"]->SignalEvent(
2069 "EVENT_FIELD_EDIT_PERMISSION_CHECK", array(
2071 "Resource" => $this,
2073 "CanEdit" => $CanEdit));
2074 $CanEdit = $SignalResult[
"CanEdit"];
2076 # report back to caller whether user can edit field
2080 # ---- PRIVATE INTERFACE -------------------------------------------------
2086 private $NumberOfRatings;
2087 private $CumulativeRating;
2088 private $NumberOfComments;
2090 private $LastStatus;
2091 private $ControlledNameCache;
2092 private $ControlledNameVariantCache;
2093 private $ClassificationCache;
2095 # recalculate and save cumulative rating value for resource
2096 private function UpdateCumulativeRating()
2098 # grab totals from DB
2099 $this->DB->Query(
"SELECT COUNT(Rating) AS Count, "
2100 .
"SUM(Rating) AS Total FROM ResourceRatings "
2101 .
"WHERE ResourceId = ".$this->
Id);
2102 $Record = $this->DB->FetchRow();
2104 # calculate new cumulative rating
2107 # save new cumulative rating in DB
2108 $this->DB->Query(
"UPDATE Resources "
2110 .
"WHERE ResourceId = ".$this->Id);
2113 # add intersection if not already present
2114 private function AddAssociation($TableName, $TargetFieldName, $TargetValue)
2116 # if target not already associated with resource
2117 if ($this->DB->Query(
"SELECT COUNT(*) AS RecordCount FROM ".$TableName
2118 .
" WHERE ResourceId = ".$this->Id
2119 .
" AND ".$TargetFieldName.
" = '".$TargetValue.
"'",
2120 "RecordCount") == 0)
2122 # associate target with resource
2123 $this->DB->Query(
"INSERT INTO ".$TableName.
" SET"
2124 .
" ResourceId = ".$this->Id
2125 .
", ".$TargetFieldName.
" = '".$TargetValue.
"'");
2129 # remove intersections (if any)
2130 private function RemoveAssociation($TableName, $TargetFieldName, $TargetValue)
2132 # remove any intersections with target ID from DB
2133 $this->DB->Query(
"DELETE FROM ".$TableName
2134 .
" WHERE ResourceId = ".$this->
Id
2135 .
" AND ".$TargetFieldName.
" = '".$TargetValue.
"'");
2138 # remove all intersections for resource and field (if any)
2139 private function RemoveAllAssociations($TableName, $TargetFieldName, $Field)
2141 # retrieve list of entries for this field and resource
2142 $Entries = $this->
Get($Field);
2145 foreach ($Entries as $EntryId => $EntryName)
2147 # remove intersection
2148 $this->RemoveAssociation($TableName, $TargetFieldName, $EntryId);