CWIS Developer Documentation
Resource.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # FILE: Resource.php
4 #
5 # Part of the Collection Workflow Integration System (CWIS)
6 # Copyright 2011-2013 Edward Almasy and Internet Scout Research Group
7 # http://scout.wisc.edu/cwis/
8 #
9 
13 class Resource {
14 
15  # ---- PUBLIC INTERFACE --------------------------------------------------
16 
23  function __construct($ResourceId)
24  {
25  $this->DB = new Database();
26 
27  # save resource ID
28  $this->Id = intval($ResourceId);
29 
30  # locate resource in database
31  $this->DB->Query("SELECT * FROM Resources WHERE ResourceId = ".$this->Id);
32 
33  # if unable to locate resource
34  $Record = $this->DB->FetchRow();
35  if ($Record == FALSE)
36  {
37  # set status to -1 to indicate that creation failed
38  $this->LastStatus = -1;
39  }
40  else
41  {
42  # load in attributes from database
43  $this->DBFields = $Record;
44  $this->CumulativeRating = $Record["CumulativeRating"];
45 
46  # load our local metadata schema
47  $this->Schema = new MetadataSchema($this->DBFields["SchemaId"]);
48 
49  # set status to 1 to indicate that creation succeeded
50  $this->LastStatus = 1;
51  }
52  }
53 
59  static function Create($SchemaId)
60  {
61  # clean out any temp resource records more than three days old
62  $RFactory = new ResourceFactory();
63  $RFactory->CleanOutStaleTempItems(60 * 24 * 3);
64 
65  # lock DB tables to prevent next ID from being grabbed
66  $DB = new Database;
67  $DB->Query("LOCK TABLES Resources WRITE");
68 
69  # find next temp resource ID
70  $Id = $RFactory->GetNextTempItemId();
71 
72  # write out new resource record with temp resource ID
73  # Set DateLastModified = NOW() to avoid being pruned as a
74  # stale temp resource.
75  $DB->Query(
76  "INSERT INTO Resources
77  SET `ResourceId` = '".intval($Id)."',
78  `SchemaId` = '".intval($SchemaId)."',
79  `DateLastModified` = NOW() " );
80 
81  # release DB tables
82  $DB->Query("UNLOCK TABLES");
83 
84  # create new Resource object
85  $Resource = new Resource($Id);
86 
87  # set some additional fields for default resources
88  if ($SchemaId == MetadataSchema::SCHEMAID_DEFAULT)
89  {
90  $Resource->Set("Added By Id", $GLOBALS["G_User"]->Id());
91  $Resource->Set("Last Modified By Id", $GLOBALS["G_User"]->Id());
92  $Resource->Set("Date Of Record Creation", date("Y-m-d H:i:s"));
93  $Resource->Set("Date Last Modified", date("Y-m-d H:i:s"));
94  }
95 
96  # set any default values
97  $Schema = new MetadataSchema($SchemaId);
98  $Fields = $Schema->GetFields(MetadataSchema::MDFTYPE_OPTION
103  foreach ($Fields as $Field)
104  {
105  $DefaultValue = $Field->DefaultValue();
106 
107  # flip option default values to get into the form that
108  # Resource::Set() expects
109  if ($Field->Type() == MetadataSchema::MDFTYPE_OPTION
110  && is_array($DefaultValue))
111  {
112  $DefaultValue = array_flip($DefaultValue);
113  }
114 
115  # there is no default value when DefaultValue is null,
116  # or when it is an empty array
117  if ( !($DefaultValue === NULL ||
118  (is_array($DefaultValue) && empty($DefaultValue)) ))
119  {
120  $Resource->SetByField($Field, $DefaultValue);
121  }
122  }
123 
124  # update timestamps as required
125  $TimestampFields = $Schema->GetFields(MetadataSchema::MDFTYPE_TIMESTAMP);
126  foreach ($TimestampFields as $Field)
127  {
128  if ($Field->UpdateMethod() ==
130  {
131  $Resource->SetByField($Field, "now");
132  }
133  }
134 
135  # signal resource creation
136  $GLOBALS["AF"]->SignalEvent("EVENT_RESOURCE_CREATE", array(
137  "Resource" => $Resource,
138  ));
139 
140  # return new Resource object to caller
141  return $Resource;
142  }
143 
148  function Delete()
149  {
150  global $SysConfig;
151 
152  # signal that resource deletion is about to occur
153  global $AF;
154  $AF->SignalEvent("EVENT_RESOURCE_DELETE", array(
155  "Resource" => $this,
156  ));
157 
158  # grab list of classifications
159  $Classifications = $this->Classifications();
160 
161  # delete resource/classification intersections
162  $DB = $this->DB;
163  $DB->Query("DELETE FROM ResourceClassInts WHERE ResourceId = ".$this->Id());
164 
165  # for each classification type
166  foreach ($Classifications as $ClassType => $ClassesOfType)
167  {
168  # for each classification of that type
169  foreach ($ClassesOfType as $ClassId => $ClassName)
170  {
171  # recalculate resource count for classification
172  $Class = new Classification($ClassId);
173  $Class->RecalcResourceCount();
174  }
175  }
176 
177  # delete resource references
178  $DB->Query("
179  DELETE FROM ReferenceInts
180  WHERE SrcResourceId = '".addslashes($this->Id())."'
181  OR DstResourceId = '".addslashes($this->Id())."'");
182 
183  # delete resource/name intersections
184  $DB->Query("DELETE FROM ResourceNameInts WHERE ResourceId = ".$this->Id());
185 
186  # delete any associated images not in use by other resources
187  $DB->Query("SELECT ImageId FROM ResourceImageInts"
188  ." WHERE ResourceId = ".intval($this->Id()));
189  $ImageIds = $DB->FetchColumn("ImageId");
190  foreach ($ImageIds as $ImageId)
191  {
192  $DB->Query("SELECT ResourceId FROM ResourceImageInts"
193  ." WHERE ImageId = ".intval($ImageId)
194  ." AND ResourceId != ".intval($this->Id()));
195  if ($DB->NumRowsSelected() == 0)
196  {
197  $Image = new SPTImage($ImageId);
198  $Image->Delete();
199  }
200  }
201 
202  # delete any associated files
203  $Factory = new FileFactory(NULL);
204  $Files = $Factory->GetFilesForResource($this->Id());
205  foreach ($Files as $File)
206  {
207  $File->Delete();
208  }
209 
210  # delete resource record from database
211  $DB->Query("DELETE FROM Resources WHERE ResourceId = ".$this->Id());
212 
213  # drop item from search engine and recommender system
214  if ($SysConfig->SearchDBEnabled())
215  {
216  $SearchEngine = new SPTSearchEngine();
217  $SearchEngine->DropItem($this->Id());
218  }
219  if ($SysConfig->RecommenderDBEnabled())
220  {
221  $Recommender = new SPTRecommender();
222  $Recommender->DropItem($this->Id());
223  }
224 
225  # get the folders containing the resource
226  $FolderFactory = new FolderFactory();
227  $Folders = $FolderFactory->GetFoldersContainingItem(
228  $this->Id,
229  "Resource");
230 
231  # drop the resource from each folder it belongs to
232  foreach ($Folders as $Folder)
233  {
234  # mixed item type folder
235  if ($Folder->ContainsItem($this->Id, "Resource"))
236  {
237  $Folder->RemoveItem($this->Id, "Resource");
238  }
239 
240  # single item type folder
241  else
242  {
243  $Folder->RemoveItem($this->Id);
244  }
245  }
246 
247  # delete any resource comments
248  $DB->Query("DELETE FROM Messages WHERE ParentId = ".$this->Id);
249  }
250 
255  function Status() { return $this->LastStatus; }
256 
261  function Id() { return $this->Id; }
262 
267  function SchemaId() { return $this->DBFields["SchemaId"]; }
268 
275  function IsTempResource($NewSetting = NULL)
276  {
277  # if new temp resource setting supplied
278  if (!is_null($NewSetting))
279  {
280  # if caller requested to switch
281  $DB = $this->DB;
282  if ((($this->Id() < 0) && ($NewSetting == FALSE))
283  || (($this->Id() >= 0) && ($NewSetting == TRUE)))
284  {
285  # lock DB tables to prevent next ID from being grabbed
286  $DB->Query("LOCK TABLES Resources write");
287 
288  # get next resource ID as appropriate
289  $OldResourceId = $this->Id;
290  $Factory = new ResourceFactory($this->SchemaId());
291  if ($NewSetting == TRUE)
292  {
293  $this->Id = $Factory->GetNextTempItemId();
294  }
295  else
296  {
297  $this->Id = $Factory->GetNextItemId();
298  }
299 
300  # change resource ID
301  $DB->Query("UPDATE Resources SET ResourceId = ".
302  $this->Id. " WHERE ResourceId = ".$OldResourceId);
303 
304  # release DB tables
305  $DB->Query("UNLOCK TABLES");
306 
307  # change associations
308  unset($this->ClassificationCache);
309  $DB->Query("UPDATE ResourceClassInts SET ResourceId = ".
310  $this->Id. " WHERE ResourceId = ".$OldResourceId);
311  unset($this->ControlledNameCache);
312  unset($this->ControlledNameVariantCache);
313  $DB->Query("UPDATE ResourceNameInts SET ResourceId = ".
314  $this->Id. " WHERE ResourceId = ".$OldResourceId);
315  $DB->Query("UPDATE Files SET ResourceId = ".
316  $this->Id. " WHERE ResourceId = ".$OldResourceId);
317  $DB->Query("UPDATE ReferenceInts SET SrcResourceId = ".
318  $this->Id. " WHERE SrcResourceId = ".$OldResourceId);
319  $DB->Query("UPDATE ResourceImageInts SET ResourceId = ".
320  $this->Id. " WHERE ResourceId = ".$OldResourceId);
321 
322  # signal event as appropriate
323  if ($NewSetting === FALSE)
324  {
325  $GLOBALS["AF"]->SignalEvent("EVENT_RESOURCE_ADD", array(
326  "Resource" => $this,
327  ));
328  }
329  }
330  }
331 
332  # report to caller whether we are a temp resource
333  return ($this->Id() < 0) ? TRUE : FALSE;
334  }
335 
336 
337  # --- Generic Attribute Retrieval Methods -------------------------------
338 
353  function Get($FieldNameOrObject, $ReturnObject = FALSE, $IncludeVariants = FALSE)
354  {
355  # load field object if needed
356  $Field = is_object($FieldNameOrObject) ? $FieldNameOrObject
357  : $this->Schema->GetFieldByName($FieldNameOrObject);
358 
359  # return no value found if we don't have a valid field
360  if (!($Field instanceof MetadataField)) { return NULL; }
361 
362  # grab database field name
363  $DBFieldName = $Field->DBFieldName();
364 
365  # format return value based on field type
366  switch ($Field->Type())
367  {
371  $ReturnValue = isset($this->DBFields[$DBFieldName])
372  ? (string)$this->DBFields[$DBFieldName] : NULL;
373  break;
374 
376  $ReturnValue = isset($this->DBFields[$DBFieldName])
377  ? (int)$this->DBFields[$DBFieldName] : NULL;
378  break;
379 
381  $ReturnValue = isset($this->DBFields[$DBFieldName])
382  ? (bool)$this->DBFields[$DBFieldName] : NULL;
383  break;
384 
386  $ReturnValue = array("X" => (float)$this->DBFields[$DBFieldName."X"],
387  "Y" => (float)$this->DBFields[$DBFieldName."Y"]);
388  break;
389 
391  $Date = new Date($this->DBFields[$DBFieldName."Begin"],
392  $this->DBFields[$DBFieldName."End"],
393  $this->DBFields[$DBFieldName."Precision"]);
394  if ($ReturnObject)
395  {
396  $ReturnValue = $Date;
397  }
398  else
399  {
400  $ReturnValue = $Date->Formatted();
401  }
402  break;
403 
405  $ReturnValue = $this->DBFields[$DBFieldName];
406  break;
407 
409  # start with empty array
410  $ReturnValue = array();
411 
412  # if classification cache has not been loaded
413  if (!isset($this->ClassificationCache))
414  {
415  # load all classifications associated with this resource into cache
416  $this->ClassificationCache = array();
417  $this->DB->Query(
418  "SELECT Classifications.ClassificationId,"
419  ." Classifications.FieldId,ClassificationName"
420  ." FROM ResourceClassInts, Classifications"
421  ." WHERE ResourceClassInts.ResourceId = ".$this->Id
422  ." AND ResourceClassInts.ClassificationId"
423  ." = Classifications.ClassificationId");
424  while ($Record = $this->DB->FetchRow())
425  {
426  $this->ClassificationCache[$Record["ClassificationId"]]["Name"] =
427  $Record["ClassificationName"];
428  $this->ClassificationCache[$Record["ClassificationId"]]["FieldId"] =
429  $Record["FieldId"];
430  }
431  }
432 
433  # for each entry in classification cache
434  foreach ($this->ClassificationCache as $ClassificationId => $ClassificationInfo)
435  {
436  # if classification ID matches field we are looking for
437  if ($ClassificationInfo["FieldId"] == $Field->Id())
438  {
439  # add field to result
440  if ($ReturnObject)
441  {
442  $ReturnValue[$ClassificationId] = new Classification($ClassificationId);
443  }
444  else
445  {
446  $ReturnValue[$ClassificationId] = $ClassificationInfo["Name"];
447  }
448  }
449  }
450  break;
451 
454  # start with empty array
455  $ReturnValue = array();
456 
457  # if controlled name cache has not been loaded
458  if (!isset($this->ControlledNameCache))
459  {
460  # load all controlled names associated with this resource into cache
461  $this->ControlledNameCache = array();
462  $this->DB->Query(
463  "SELECT ControlledNames.ControlledNameId,"
464  ." ControlledNames.FieldId,ControlledName"
465  ." FROM ResourceNameInts, ControlledNames"
466  ." WHERE ResourceNameInts.ResourceId = ".$this->Id
467  ." AND ResourceNameInts.ControlledNameId"
468  ." = ControlledNames.ControlledNameId"
469  ." ORDER BY ControlledNames.ControlledName ASC");
470  while ($Record = $this->DB->FetchRow())
471  {
472  $this->ControlledNameCache[$Record["ControlledNameId"]]["Name"] = $Record["ControlledName"];
473  $this->ControlledNameCache[$Record["ControlledNameId"]]["FieldId"] = $Record["FieldId"];
474  }
475  }
476 
477  # if variant names requested and variant name cache has not been loaded
478  if ($IncludeVariants && !isset($this->ControlledNameVariantCache))
479  {
480  # load all controlled names associated with this resource into cache
481  $this->ControlledNameVariantCache = array();
482  $this->DB->Query("SELECT ControlledNames.ControlledNameId,"
483  ." ControlledNames.FieldId,"
484  ." ControlledName, VariantName"
485  ." FROM ResourceNameInts, ControlledNames, VariantNames"
486  ." WHERE ResourceNameInts.ResourceId = ".$this->Id
487  ." AND ResourceNameInts.ControlledNameId"
488  ." = ControlledNames.ControlledNameId"
489  ." AND VariantNames.ControlledNameId"
490  ." = ControlledNames.ControlledNameId");
491  while ($Record = $this->DB->FetchRow())
492  {
493  $this->ControlledNameVariantCache[$Record["ControlledNameId"]][]
494  = $Record["VariantName"];
495  }
496  }
497 
498  # for each entry in controlled name cache
499  foreach ($this->ControlledNameCache as $ControlledNameId => $ControlledNameInfo)
500  {
501  # if controlled name type matches field we are looking for
502  if ($ControlledNameInfo["FieldId"] == $Field->Id())
503  {
504  # if objects requested
505  if ($ReturnObject)
506  {
507  $ReturnValue[$ControlledNameId] =
508  new ControlledName($ControlledNameId);
509  }
510  else
511  {
512  # if variant names requested
513  if ($IncludeVariants)
514  {
515  # add field to result
516  $ReturnValue[] = $ControlledNameInfo["Name"];
517 
518  # add any variant names to result
519  if (isset($this->ControlledNameVariantCache[$ControlledNameId]))
520  {
521  $ReturnValue = array_merge(
522  $ReturnValue,
523  $this->ControlledNameVariantCache[$ControlledNameId]);
524  }
525  }
526  else
527  {
528  # add field with index to result
529  $ReturnValue[$ControlledNameId] =
530  $ControlledNameInfo["Name"];
531  }
532  }
533  }
534  }
535  break;
536 
538  $User = new CWUser(intval($this->DBFields[$DBFieldName]));
539  if ($ReturnObject)
540  {
541  $ReturnValue = $User;
542  }
543  else
544  {
545  $ReturnValue = $User->Get("UserName");
546  }
547  break;
548 
550  # start out assuming no images will be found
551  $ReturnValue = array();
552 
553  # find all images associated with this resource
554  $this->DB->Query("SELECT ImageId FROM ResourceImageInts"
555  ." WHERE ResourceId = ".intval($this->Id())
556  ." AND FieldId = ".intval($Field->Id()));
557 
558  # if images were found
559  if ($this->DB->NumRowsSelected())
560  {
561  # if we are to return an object
562  $ImageIds = $this->DB->FetchColumn("ImageId");
563  if ($ReturnObject)
564  {
565  # load array of Image objects for return value
566  foreach ($ImageIds as $ImageId)
567  {
568  $ReturnValue[$ImageId] = new SPTImage($ImageId);
569  }
570  }
571  else
572  {
573  # load array of Image ids for return value
574  $ReturnValue = $ImageIds;
575  }
576  }
577  break;
578 
580  # retrieve files using factory
581  $Factory = new FileFactory($Field->Id());
582  $ReturnValue = $Factory->GetFilesForResource(
583  $this->Id, $ReturnObject);
584  break;
585 
587  # query for resource references
588  $this->DB->Query("
589  SELECT * FROM ReferenceInts
590  WHERE FieldId = '".addslashes($Field->Id())."'
591  AND SrcResourceId = '".addslashes($this->Id())."'");
592 
593  $ReturnValue = array();
594 
595  # return each reference as a Resource object
596  if ($ReturnObject)
597  {
598  $FoundErrors = FALSE;
599 
600  while (FALSE !== ($Record = $this->DB->FetchRow()))
601  {
602  $ReferenceId = $Record["DstResourceId"];
603  $Reference = new Resource($ReferenceId);
604 
605  # the reference is bad, so flag that there were errors
606  if ($Reference->Status() != 1)
607  {
608  $FoundErrors = TRUE;
609  }
610 
611  else
612  {
613  $ReturnValue[$ReferenceId] = $Reference;
614  }
615  }
616 
617  # try to fix the errors by removing any references to
618  # resources that were bad
619  if ($FoundErrors)
620  {
621  $this->Set($Field, $ReturnValue);
622  }
623  }
624 
625  # return each reference as a resource ID
626  else
627  {
628  while (FALSE !== ($Record = $this->DB->FetchRow()))
629  {
630  $ReferenceId = $Record["DstResourceId"];
631  $ReturnValue[$ReferenceId] = $ReferenceId;
632  }
633  }
634  break;
635 
636  default:
637  # ERROR OUT
638  exit("<br>SPT - ERROR: attempt to retrieve unknown resource field type (".$Field->Type().")<br>\n");
639  break;
640  }
641 
642  # return formatted value to caller
643  return $ReturnValue;
644  }
649  function GetByField($FieldNameOrObject,
650  $ReturnObject = FALSE, $IncludeVariants = FALSE)
651  { return $this->Get($FieldNameOrObject, $ReturnObject, $IncludeVariants); }
652 
666  function GetByFieldId($FieldId, $ReturnObject = FALSE, $IncludeVariants = FALSE)
667  {
668  $Field = $this->Schema->GetField($FieldId);
669  return ($Field) ? $this->Get($Field, $ReturnObject, $IncludeVariants) : NULL;
670  }
671 
684  function GetAsArray($IncludeDisabledFields = FALSE, $ReturnObjects = TRUE)
685  {
686  # retrieve field info
687  $Fields = $this->Schema->GetFields();
688 
689  # for each field
690  foreach ($Fields as $Field)
691  {
692  # if field is enabled or caller requested disabled fields
693  if ($Field->Enabled() || $IncludeDisabledFields)
694  {
695  # retrieve info and add it to the array
696  $FieldStrings[$Field->Name()] = $this->Get($Field, $ReturnObjects);
697 
698  # if field uses qualifiers
699  if ($Field->UsesQualifiers())
700  {
701  # get qualifier attributes and add to the array
702  $FieldStrings[$Field->Name()." Qualifier"] =
703  $this->GetQualifierByField($Field, $ReturnObjects);
704  }
705  }
706  }
707 
708  # add in internal values
709  $FieldStrings["ResourceId"] = $this->Id();
710  $FieldStrings["CumulativeRating"] = $this->CumulativeRating();
711 
712  # return array to caller
713  return $FieldStrings;
714  }
715 
730  function GetMapped($MappedName, $ReturnObject = FALSE, $IncludeVariants = FALSE)
731  {
732  return $this->Schema->StdNameToFieldMapping($MappedName)
733  ? $this->GetByFieldId($this->Schema->StdNameToFieldMapping($MappedName),
734  $ReturnObject, $IncludeVariants)
735  : NULL;
736  }
737 
746  function GetQualifier($FieldName, $ReturnObject = TRUE)
747  {
748  $Field = $this->Schema->GetFieldByName($FieldName);
749  return $this->GetQualifierByField($Field, $ReturnObject);
750  }
751 
760  function GetQualifierByFieldId($FieldId, $ReturnObject = TRUE)
761  {
762  $Field = $this->Schema->GetField($FieldId);
763  return ($Field) ? $this->GetQualifierByField($Field, $ReturnObject) : NULL;
764  }
765 
774  function GetQualifierByField($Field, $ReturnObject = TRUE)
775  {
776  # return NULL if field is invalid
777  if (!($Field instanceof MetadataField)) { return NULL; }
778 
779  # assume no qualifiers if not otherwise determined
780  $ReturnValue = NULL;
781 
782  # if field uses qualifiers
783  if ($Field->UsesQualifiers())
784  {
785  # retrieve qualifiers based on field type
786  switch ($Field->Type())
787  {
791  # retrieve list of items
792  $Items = $this->Get($Field);
793 
794  # if field uses item-level qualifiers
795  if ($Field->HasItemLevelQualifiers())
796  {
797  # determine general item name in DB
798  $TableName = ($Field->Type() == MetadataSchema::MDFTYPE_TREE)
799  ? "Classification" : "ControlledName";
800 
801  # for each item
802  foreach ($Items as $ItemId => $ItemName)
803  {
804  # look up qualifier for item
805  $QualId = $this->DB->Query(
806  "SELECT * FROM ".$TableName."s"
807  ." WHERE ".$TableName."Id = ".$ItemId,
808  "QualifierId");
809 
810 
811  if ($QualId > 0)
812  {
813  # if object was requested by caller
814  if ($ReturnObject)
815  {
816  # load qualifier and add to return value array
817  $ReturnValue[$ItemId] = new Qualifier($QualId);
818  }
819  else
820  {
821  # add qualifier ID to return value array
822  $ReturnValue[$ItemId] = $QualId;
823  }
824  }
825  else
826  {
827  # add NULL to return value array for this item
828  $ReturnValue[$ItemId] = NULL;
829  }
830  }
831  }
832  else
833  {
834  # for each item
835  foreach ($Items as $ItemId => $ItemName)
836  {
837  # if object was requested by caller
838  if ($ReturnObject)
839  {
840  # load default qualifier and add to return value array
841  $ReturnValue[$ItemId] = new Qualifier($Field->DefaultQualifier());
842  }
843  else
844  {
845  # add default qualifier ID to return value array
846  $ReturnValue[$ItemId] = $Field->DefaultQualifier();
847  }
848  }
849  }
850  break;
851 
852  default:
853  # if field uses item-level qualifiers
854  if ($Field->HasItemLevelQualifiers())
855  {
856  # if qualifier available
857  if ($this->DBFields[$Field->DBFieldName()."Qualifier"] > 0)
858  {
859  # if object was requested by caller
860  if ($ReturnObject)
861  {
862  # return qualifier for field
863  $ReturnValue = new Qualifier($this->DBFields[$Field->DBFieldName()."Qualifier"]);
864  }
865  else
866  {
867  # return qualifier ID for field
868  $ReturnValue = $this->DBFields[$Field->DBFieldName()."Qualifier"];
869  }
870  }
871  }
872  else
873  {
874  # if default qualifier available
875  if ($Field->DefaultQualifier() > 0)
876  {
877  # if object was requested by caller
878  if ($ReturnObject)
879  {
880  # return default qualifier
881  $ReturnValue = new Qualifier($Field->DefaultQualifier());
882  }
883  else
884  {
885  # return default qualifier ID
886  $ReturnValue = $Field->DefaultQualifier();
887  }
888  }
889  }
890  break;
891  }
892  }
893 
894  # return qualifier object or ID (or array of same) to caller
895  return $ReturnValue;
896  }
897 
905  function FieldIsSet($FieldNameOrObject, $IgnorePadding=FALSE)
906  {
907  # load field object if needed
908  $Field = is_object($FieldNameOrObject) ? $FieldNameOrObject
909  : $this->Schema->GetFieldByName($FieldNameOrObject);
910 
911  # return no value found if we don't have a valid field
912  if (!($Field instanceof MetadataField)) { return FALSE; }
913 
914  # get the value
915  $Value = $this->Get($Field);
916 
917  # checks depend on the field type
918  switch ($Field->Type())
919  {
924  return isset($Value)
925  && strlen($Value)
926  && (!$IgnorePadding || ($IgnorePadding && strlen(trim($Value))));
927 
929  return isset($Value)
930  && strlen($Value);
931 
933  return isset($Value["X"])
934  && isset($Value["Y"])
935  && strlen(trim($Value["X"]))
936  && strlen(trim($Value["Y"]));
937 
939  return isset($Value)
940  && strlen(trim($Value))
941  && $Value != "0000-00-00";
942 
944  return isset($Value)
945  && strlen(trim($Value))
946  && $Value != "0000-00-00 00:00:00";
947 
954  return count($Value) > 0;
955 
957  $Factory = new CWUserFactory();
958  return isset($Value)
959  && strlen($Value)
960  && $Factory->UserNameExists($Value);
961 
962  default:
963  return FALSE;
964  }
965  }
966 
967  # --- Generic Attribute Setting Methods ---------------------------------
968 
977  function Set($FieldNameOrObject, $NewValue, $Reset=FALSE)
978  {
979  # load field object if needed
980  $Field = is_object($FieldNameOrObject) ? $FieldNameOrObject
981  : $this->Schema->GetFieldByName($FieldNameOrObject);
982 
983  # return if we don't have a valid field
984  if (!($Field instanceof MetadataField)) { return; }
985 
986  # grab commonly-used values for local use
987  $DB = $this->DB;
988  $ResourceId = $this->Id;
989 
990  # grab database field name
991  $DBFieldName = $Field->DBFieldName();
992 
993  # Flag to deterimine if we've actually changed anything.
994  $UpdateModTime = FALSE;
995 
996  # store value in DB based on field type
997  switch ($Field->Type())
998  {
1002  if ($this->DBFields[$DBFieldName] != $NewValue)
1003  {
1004  # save value directly to DB
1005  $DB->Query("UPDATE Resources SET `"
1006  .$DBFieldName."` = '".addslashes($NewValue)."' "
1007  ."WHERE ResourceId = ".$ResourceId);
1008 
1009  # save value locally
1010  $this->DBFields[$DBFieldName] = $NewValue;
1011  $UpdateModTime=TRUE;
1012  }
1013  break;
1014 
1016  if ( $this->DBFields[$DBFieldName] != $NewValue )
1017  {
1018  # save value directly to DB
1019  if (is_null($NewValue))
1020  {
1021  $DB->Query("UPDATE Resources SET `"
1022  .$DBFieldName."` = NULL"
1023  ." WHERE ResourceId = ".$ResourceId);
1024  }
1025  else
1026  {
1027  $DB->Query("UPDATE Resources SET `"
1028  .$DBFieldName."` = ".intval($NewValue)
1029  ." WHERE ResourceId = ".$ResourceId);
1030  }
1031 
1032  # save value locally
1033  $this->DBFields[$DBFieldName] = $NewValue;
1034  $UpdateModTime = TRUE;
1035  }
1036  break;
1037 
1038 
1040  if ($this->DBFields[$DBFieldName."X"] != $NewValue["X"] ||
1041  $this->DBFields[$DBFieldName."Y"] != $NewValue["Y"] )
1042  {
1043  if (is_null($NewValue))
1044  {
1045  $DB->Query("UPDATE Resources SET "
1046  ."`".$DBFieldName."X` = NULL, "
1047  ."`".$DBFieldName."Y` = NULL "
1048  ."WHERE ResourceId = ".$ResourceId);
1049  $this->DBFields[$DBFieldName."X"] = NULL;
1050  $this->DBFields[$DBFieldName."Y"] = NULL;
1051  }
1052  else
1053  {
1054  $DB->Query("UPDATE Resources SET "
1055  ."`".$DBFieldName."X` = ".(strlen($NewValue["X"])
1056  ? "'".$NewValue["X"]."'" : "NULL").", "
1057  ."`".$DBFieldName."Y` = ".(strlen($NewValue["Y"])
1058  ? "'".$NewValue["Y"]."'" : "NULL")
1059  ." WHERE ResourceId = ".$ResourceId);
1060 
1061  $Digits = $Field->PointDecimalDigits();
1062 
1063  $this->DBFields[$DBFieldName."X"] =
1064  strlen($NewValue["X"]) ? round($NewValue["X"], $Digits) : NULL;
1065  $this->DBFields[$DBFieldName."Y"] =
1066  strlen($NewValue["Y"]) ? round($NewValue["Y"], $Digits) : NULL;
1067  }
1068  $UpdateModTime = TRUE;
1069  }
1070  break;
1071 
1073  if ($this->DBFields[$DBFieldName] != $NewValue)
1074  {
1075  # save value directly to DB
1076  if (is_null($NewValue))
1077  {
1078  $DB->Query("UPDATE Resources SET `"
1079  .$DBFieldName."` = NULL"
1080  ." WHERE ResourceId = ".$ResourceId);
1081  }
1082  else
1083  {
1084  $NewValue = $NewValue ? "1" : "0";
1085  $DB->Query("UPDATE Resources SET `"
1086  .$DBFieldName."` = ".$NewValue
1087  ." WHERE ResourceId = ".$ResourceId);
1088  }
1089 
1090  $this->DBFields[$DBFieldName] = $NewValue;
1091 
1092  # recalculate counts for any associated classifications if necessary
1093  if ($DBFieldName == "ReleaseFlag")
1094  {
1095  $DB->Query("SELECT ClassificationId FROM ResourceClassInts"
1096  ." WHERE ResourceId = ".$ResourceId);
1097  while ($ClassId = $DB->FetchField("ClassificationId"))
1098  {
1099  $Class = new Classification($ClassId);
1100  $Class->RecalcResourceCount();
1101  }
1102  }
1103  $UpdateModTime = TRUE;
1104  }
1105  break;
1106 
1108  # if value passed in was object
1109  if (is_object($NewValue))
1110  {
1111  # retrieve user ID from object
1112  $UserId = $NewValue->Get("UserId");
1113  }
1114  # else if value passed in was user name
1115  elseif (is_string($NewValue) && strlen($NewValue))
1116  {
1117  # create user object and retrieve user ID from there
1118  $User = new CWUser($NewValue);
1119  $UserId = $User->Get("UserId");
1120  }
1121  else
1122  {
1123  # assume value is user ID and use value directly
1124  $UserId = $NewValue;
1125  }
1126 
1127  if ($this->DBFields[$DBFieldName] != $UserId)
1128  {
1129  # save value directly to DB
1130  $DB->Query("UPDATE Resources SET `"
1131  .$DBFieldName."` = '".$UserId."' "
1132  ."WHERE ResourceId = ".$ResourceId);
1133 
1134  # save value locally
1135  $this->DBFields[$DBFieldName] = $UserId;
1136  $UpdateModTime = TRUE;
1137  }
1138  break;
1139 
1141  # if we were given a date object
1142  if (is_object($NewValue))
1143  {
1144  # use supplied date object
1145  $Date = $NewValue;
1146  }
1147  else
1148  {
1149  # create date object
1150  $Date = new Date($NewValue);
1151  }
1152 
1153  $OldDate = new Date(
1154  $this->DBFields[$DBFieldName."Begin"],
1155  $this->DBFields[$DBFieldName."End"]);
1156 
1157  if ($OldDate->BeginDate() != $Date->BeginDate() ||
1158  $OldDate->EndDate() != $Date->EndDate() ||
1159  $OldDate->Precision() != $Date->Precision() )
1160  {
1161  # extract values from date object and store in DB
1162  $BeginDate = "'".$Date->BeginDate()."'";
1163  if (strlen($BeginDate) < 3) { $BeginDate = "NULL"; }
1164  $EndDate = "'".$Date->EndDate()."'";
1165  if (strlen($EndDate) < 3) { $EndDate = "NULL"; }
1166 
1167  $DB->Query("UPDATE Resources SET "
1168  .$DBFieldName."Begin = ".$BeginDate.", "
1169  .$DBFieldName."End = ".$EndDate.", "
1170  .$DBFieldName."Precision = '".$Date->Precision()."' "
1171  ."WHERE ResourceId = ".$ResourceId);
1172 
1173  # save values locally
1174  $this->DBFields[$DBFieldName."Begin"] = $Date->BeginDate();
1175  $this->DBFields[$DBFieldName."End"] = $Date->EndDate();
1176  $this->DBFields[$DBFieldName."Precision"] = $Date->Precision();
1177  $UpdateModTime=TRUE;
1178  }
1179  break;
1180 
1182  if (is_null($NewValue) || !strlen(trim($NewValue)))
1183  {
1184  $DateValue = $NewValue;
1185 
1186  if (!is_null($this->DBFields[$DBFieldName]))
1187  {
1188  # save value directly to DB
1189  $DB->Query("UPDATE Resources SET "
1190  ."`".$DBFieldName."` = NULL "
1191  ."WHERE ResourceId = ".$ResourceId);
1192  $UpdateModTime = TRUE;
1193  }
1194  }
1195  else
1196  {
1197  # assume value is date and use directly
1198  $TimestampValue = strtotime($NewValue);
1199 
1200  # use the new value if the date is valid
1201  if ($TimestampValue !== FALSE && $TimestampValue >= 0)
1202  {
1203  $DateValue = date("Y-m-d H:i:s", $TimestampValue);
1204 
1205  if ($this->DBFields[$DBFieldName] != $DateValue)
1206  {
1207  # save value directly to DB
1208  $DB->Query("UPDATE Resources SET "
1209  ."`".$DBFieldName."` = '".addslashes($DateValue)."' "
1210  ."WHERE ResourceId = ".$ResourceId);
1211  $UpdateModTime=TRUE;
1212  }
1213  }
1214 
1215  # continue using the old value if invalid
1216  else
1217  {
1218  $DateValue = $this->Get($Field);
1219  }
1220  }
1221 
1222  # save value locally
1223  $this->DBFields[$DBFieldName] = $DateValue;
1224  break;
1225 
1227  $OldValue = $this->Get($Field);
1228 
1229  # if incoming value is array
1230  if (is_array($NewValue))
1231  {
1232  if ($OldValue != $NewValue)
1233  {
1234  if ($Reset)
1235  {
1236  # Remove values that were in the old value, but not the new one:
1237  $ToRemove = array_diff(array_keys($OldValue), array_keys($NewValue));
1238  foreach ($ToRemove as $ClassificationId)
1239  {
1240  $this->RemoveAssociation("ResourceClassInts",
1241  "ClassificationId",
1242  $ClassificationId);
1243  $Class = new Classification($ClassificationId);
1244  if ($Class->Status() == Classification::CLASSSTAT_OK)
1245  $Class->RecalcResourceCount();
1246  }
1247  }
1248 
1249  # for each element of array
1250  foreach ($NewValue as
1251  $ClassificationId => $ClassificationName)
1252  {
1253  $Class = new Classification($ClassificationId);
1254  if ($Class->Status() == Classification::CLASSSTAT_OK)
1255  {
1256  # associate with resource if not already associated
1257  if ($this->AddAssociation("ResourceClassInts",
1258  "ClassificationId",
1259  $ClassificationId) )
1260  {
1261  $Class->UpdateLastAssigned();
1262  $Class->RecalcResourceCount();
1263  }
1264  }
1265  }
1266 
1267  $UpdateModTime=TRUE;
1268  }
1269  }
1270  else
1271  {
1272  # associate with resource if not already associated
1273  if (is_object($NewValue))
1274  {
1275  $Class = $NewValue;
1276  $NewValue = $Class->Id();
1277  }
1278  else
1279  {
1280  $Class = new Classification($NewValue);
1281  }
1282 
1283  if (!array_key_exists($Class->Id(), $OldValue))
1284  {
1285 
1286  $this->AddAssociation("ResourceClassInts",
1287  "ClassificationId",
1288  $NewValue);
1289  $Class->UpdateLastAssigned();
1290  $Class->RecalcResourceCount();
1291  $UpdateModTime=TRUE;
1292  }
1293  }
1294 
1295  # clear our classification cache
1296  if ($UpdateModTime)
1297  {
1298  unset($this->ClassificationCache);
1299  }
1300  break;
1301 
1304  $OldValue = $this->Get($Field);
1305 
1306  # Clear other values if this field expects unique options
1307  if ($Field->AllowMultiple() === FALSE)
1308  {
1309  # If we're fed an array for a unique option,
1310  # just use the last element of the array
1311  if (is_array($NewValue)){
1312  $NewValue = array_pop($NewValue);
1313  }
1314 
1315  if (!array_key_exists($NewValue, $OldValue))
1316  {
1317 
1318  $this->RemoveAllAssociations("ResourceNameInts",
1319  "ControlledNameId",
1320  $Field );
1321  $UpdateModTime=TRUE;
1322  }
1323  }
1324 
1325  # if incoming value is array
1326  if (is_array($NewValue) && ($Field->AllowMultiple() !== FALSE) )
1327  {
1328  if ($OldValue != $NewValue)
1329  {
1330  if ($Reset)
1331  {
1332  $ToRemove = array_diff(array_keys($OldValue), array_keys($NewValue));
1333  foreach ($ToRemove as $CNId)
1334  {
1335  $this->RemoveAssociation("ResourceNameInts",
1336  "ControlledNameId",
1337  $CNId);
1338  }
1339  }
1340 
1341  # for each element of array
1342  foreach ($NewValue as $ControlledNameId => $ControlledName)
1343  {
1344  # associate with resource if not already associated
1345  if ($this->AddAssociation("ResourceNameInts",
1346  "ControlledNameId",
1347  $ControlledNameId))
1348  {
1349  $CN = new ControlledName( $ControlledNameId );
1350  $CN->UpdateLastAssigned();
1351  }
1352  }
1353  $UpdateModTime=TRUE;
1354  }
1355  }
1356  else
1357  {
1358  # associate with resource if not already associated
1359  if (is_object($NewValue)) { $NewValue = $NewValue->Id(); }
1360  if (!array_key_exists($NewValue, $OldValue))
1361  {
1362  $this->AddAssociation("ResourceNameInts",
1363  "ControlledNameId",
1364  $NewValue);
1365  $UpdateModTime=TRUE;
1366  }
1367  }
1368 
1369  if ($UpdateModTime)
1370  {
1371  # clear our controlled name cache
1372  unset($this->ControlledNameCache);
1373  unset($this->ControlledNameVariantCache);
1374  }
1375 
1376  break;
1377 
1379  # associate value(s) with resource
1380  $this->AddAssociation(
1381  "ResourceImageInts", "ImageId", $NewValue, $Field);
1382  break;
1383 
1385  # convert incoming value to array if necessary
1386  if (!is_array($NewValue)) { $NewValue = array($NewValue); }
1387 
1388  # for each incoming file
1389  $Factory = new FileFactory($Field->Id());
1390  foreach ($NewValue as $File)
1391  {
1392  # make copy of file
1393  $NewFile = $Factory->Copy($File);
1394 
1395  # associate copy with this resource and field
1396  $NewFile->ResourceId($this->Id);
1397  $NewFile->FieldId($Field->Id());
1398  }
1399  # Since we make a fresh copy of the File whenever Set is called,
1400  # we'll always update the modification time for this field.
1401  $UpdateModTime = TRUE;
1402  break;
1403 
1405  # convert incoming value to array to simplify the workflow
1406  if (is_scalar($NewValue) || $NewValue instanceof Resource)
1407  {
1408  $NewValue = array($NewValue);
1409  }
1410 
1411  # delete existing resource references
1412  $this->ClearByField($Field);
1413 
1414  # add each reference
1415  foreach ($NewValue as $ReferenceOrId)
1416  {
1417  # initially issume it's a reference ID and not an object...
1418  $ReferenceId = $ReferenceOrId;
1419 
1420  # ... but get the reference ID if it's an object
1421  if ($ReferenceOrId instanceof Resource)
1422  {
1423  $ReferenceId = $ReferenceOrId->Id();
1424  }
1425 
1426  # skip blank reference IDs
1427  if (strlen(trim($ReferenceId)) < 1)
1428  {
1429  continue;
1430  }
1431 
1432  # skip reference IDs that don't look right
1433  if (!is_numeric($ReferenceId))
1434  {
1435  continue;
1436  }
1437 
1438  # skip references to the current resource
1439  if ($ReferenceId == $this->Id())
1440  {
1441  continue;
1442  }
1443 
1444  # add the reference to the references table
1445  $DB->Query("
1446  INSERT INTO ReferenceInts (
1447  FieldId,
1448  SrcResourceId,
1449  DstResourceId)
1450  VALUES (
1451  ".addslashes($Field->Id()).",
1452  ".addslashes($this->Id()).",
1453  ".addslashes($ReferenceId).")");
1454  }
1455  break;
1456 
1457  default:
1458  # ERROR OUT
1459  exit("<br>SPT - ERROR: attempt to set unknown resource field type<br>\n");
1460  break;
1461  }
1462 
1463  if ($UpdateModTime && !$this->IsTempResource())
1464  {
1465  # update modification timestamps
1466  global $G_User;
1467  $UserId = $G_User->IsLoggedIn() ? $G_User->Get("UserId") : -1;
1468  $DB->Query("DELETE FROM ResourceFieldTimestamps "
1469  ."WHERE ResourceId=".$this->Id." AND "
1470  ."FieldId=".$Field->Id() );
1471  $DB->Query("INSERT INTO ResourceFieldTimestamps "
1472  ."(ResourceId,FieldId,ModifiedBy,Timestamp) VALUES ("
1473  .$this->Id.",".$Field->Id().","
1474  .$UserId.",NOW())");
1475 
1476  # on resource modification, clear the UserPermsCache entry
1477  # so that stale permissions checks are not cached
1478  $DB->Query("DELETE FROM UserPermsCache WHERE ResourceId=".$this->Id);
1479  }
1480  }
1485  function SetByField($Field, $NewValue) { $this->Set($Field, $NewValue); }
1486 
1487  # set value by field ID
1488  function SetByFieldId($FieldId, $NewValue)
1489  {
1490  $Field = $this->Schema->GetField($FieldId);
1491  $this->Set($Field, $NewValue);
1492  }
1493 
1494  # set qualifier by field name
1495  function SetQualifier($FieldName, $NewValue)
1496  {
1497  $Field = $this->Schema->GetFieldByName($FieldName);
1498  $this->SetQualifierByField($Field, $NewValue);
1499  }
1500 
1501  # set qualifier by field ID
1502  function SetQualifierByFieldId($FieldId, $NewValue)
1503  {
1504  $Field = $this->Schema->GetField($FieldId);
1505  $this->SetQualifierByField($Field, $NewValue);
1506  }
1507 
1508  # set qualifier using field object
1509  function SetQualifierByField($Field, $NewValue)
1510  {
1511  # if field uses qualifiers and uses item-level qualifiers
1512  if ($Field->UsesQualifiers() && $Field->HasItemLevelQualifiers())
1513  {
1514  # if qualifier object passed in
1515  if (is_object($NewValue))
1516  {
1517  # grab qualifier ID from object
1518  $QualifierId = $NewValue->Id();
1519  }
1520  else
1521  {
1522  # assume value passed in is qualifier ID
1523  $QualifierId = $NewValue;
1524  }
1525 
1526  # update qualifier value in database
1527  $DBFieldName = $Field->DBFieldName();
1528  $this->DB->Query("UPDATE Resources SET "
1529  .$DBFieldName."Qualifier = '".$QualifierId."' "
1530  ."WHERE ResourceId = ".$this->Id);
1531 
1532  # update local qualifier value
1533  $this->DBFields[$DBFieldName."Qualifier"] = $QualifierId;
1534  }
1535  }
1536 
1537  # clear value by field ID
1538  function ClearByFieldId($FieldId, $ValueToClear = NULL)
1539  {
1540  $Field = $this->Schema->GetField($FieldId);
1541  $this->ClearByField($Field, $ValueToClear);
1542  }
1543 
1544  # clear value using field object
1545  function Clear($Field, $ValueToClear = NULL)
1546  {
1547  # convert field name to object if necessary
1548  if (!is_object($Field))
1549  {
1550  $Field = $this->Schema->GetFieldByName($Field);
1551  }
1552 
1553  # grab commonly-used values for local use
1554  $DB = $this->DB;
1555  $ResourceId = $this->Id;
1556 
1557  # grab database field name
1558  $DBFieldName = $Field->DBFieldName();
1559 
1560  $UpdateModTime=FALSE;
1561 
1562  # store value in DB based on field type
1563  switch ($Field->Type())
1564  {
1572  if (strlen($this->DBFields[$DBFieldName])>0)
1573  {
1574  # clear value in DB
1575  $DB->Query("UPDATE Resources SET `"
1576  .$DBFieldName."` = NULL "
1577  ."WHERE ResourceId = ".$ResourceId);
1578 
1579  # clear value locally
1580  $this->DBFields[$DBFieldName] = NULL;
1581  $UpdateModTime=TRUE;
1582  }
1583  break;
1584 
1586  if (!is_null($this->DBFields[$DBFieldName."X"]) ||
1587  !is_null($this->DBFields[$DBFieldName."Y"]) )
1588  {
1589  # Clear DB Values
1590  $DB->Query("UPDATE Resources SET "
1591  ."`".$DBFieldName."X` = NULL ,"
1592  ."`".$DBFieldName."Y` = NULL "
1593  ."WHERE ResourceId = ".$ResourceId);
1594 
1595  # Clear local values
1596  $this->DBFields[$DBFieldName."X"] = NULL;
1597  $this->DBFields[$DBFieldName."Y"] = NULL;
1598  $UpdateModTime=TRUE;
1599  }
1600  break;
1601 
1603  if (!is_null($this->DBFields[$DBFieldName."Begin"]) ||
1604  !is_null($this->DBFields[$DBFieldName."End"]) ||
1605  !is_null($this->DBFields[$DBFieldName."Precision"]))
1606  {
1607  # clear date object values in DB
1608  $DB->Query("UPDATE Resources SET "
1609  .$DBFieldName."Begin = '', "
1610  .$DBFieldName."End = '', "
1611  .$DBFieldName."Precision = '' "
1612  ."WHERE ResourceId = ".$ResourceId);
1613 
1614  # clear value locally
1615  $this->DBFields[$DBFieldName."Begin"] = NULL;
1616  $this->DBFields[$DBFieldName."End"] = NULL;
1617  $this->DBFields[$DBFieldName."Precision"] = NULL;
1618  $UpdateModTime=TRUE;
1619  }
1620  break;
1621 
1623  $OldValue = $this->Get($Field);
1624 
1625  # if value to clear supplied
1626  if ($ValueToClear !== NULL)
1627  {
1628  # if supplied value is array
1629  if (is_array($ValueToClear))
1630  {
1631  # for each element of array
1632  foreach ($ValueToClear as $ClassificationId => $Dummy)
1633  {
1634  if (array_key_exists($ClassificationId, $OldValue))
1635  {
1636  # remove association with resource (if any)
1637  $this->RemoveAssociation("ResourceClassInts",
1638  "ClassificationId",
1639  $ClassificationId);
1640  $Class = new Classification($ClassificationId);
1641  $Class->RecalcResourceCount();
1642  $UpdateModTime=TRUE;
1643  }
1644  }
1645  }
1646  else
1647  {
1648  if (array_key_exists($ValueToClear, $OldValue))
1649  {
1650  # remove association with resource (if any)
1651  $this->RemoveAssociation("ResourceClassInts",
1652  "ClassificationId",
1653  $ValueToClear);
1654  $Class = new Classification($ValueToClear);
1655  $Class->RecalcResourceCount();
1656  $UpdateModTime=TRUE;
1657  }
1658  }
1659  }
1660  else
1661  {
1662  if (count($OldValue)>0)
1663  {
1664  # remove all associations for resource and field
1665  $this->RemoveAllAssociations("ResourceClassInts", "ClassificationId", $Field);
1666 
1667  # recompute resource count
1668  $Values = $this->Get($Field);
1669  foreach ($Values as $ClassificationId => $Dummy)
1670  {
1671  $Class = new Classification($ClassificationId);
1672  $Class->RecalcResourceCount();
1673  }
1674  $UpdateModTime=TRUE;
1675  }
1676  }
1677 
1678  # clear our classification cache
1679  if ($UpdateModTime)
1680  {
1681  unset($this->ClassificationCache);
1682  }
1683  break;
1684 
1687  $OldValue = $this->Get($Field);
1688  # if value to clear supplied
1689  if ($ValueToClear !== NULL)
1690  {
1691  # if incoming value is array
1692  if (is_array($ValueToClear))
1693  {
1694  # for each element of array
1695  foreach ($ValueToClear as $ControlledNameId =>
1696  $ControlledName)
1697  {
1698  if (array_key_exists($ControlledNameId, $OldValue))
1699  {
1700  # remove association with resource (if any)
1701  $this->RemoveAssociation("ResourceNameInts",
1702  "ControlledNameId",
1703  $ControlledNameId);
1704  $UpdateModTime=TRUE;
1705  }
1706  }
1707  }
1708  else
1709  {
1710  if (array_key_exists($ValueToClear, $OldValue))
1711  {
1712  # remove association with resource (if any)
1713  $this->RemoveAssociation("ResourceNameInts",
1714  "ControlledNameId",
1715  $ValueToClear);
1716  $UpdateModTime=TRUE;
1717  }
1718  }
1719  }
1720  else
1721  {
1722  if (count($OldValue)>0)
1723  {
1724  # remove all associations for resource and field
1725  $this->RemoveAllAssociations("ResourceNameInts", "ControlledNameId", $Field);
1726  $UpdateModTime=TRUE;
1727  }
1728  }
1729 
1730  if ($UpdateModTime)
1731  {
1732  # clear our controlled name cache
1733  unset($this->ControlledNameCache);
1734  unset($this->ControlledNameVariantCache);
1735  }
1736  break;
1737 
1739  # if value to clear supplied
1740  if ($ValueToClear !== NULL)
1741  {
1742  # convert value to array if necessary
1743  $Files = $ValueToClear;
1744  if (!is_array($Files)) { $Files = array($Files); }
1745 
1746  # convert values to objects if necessary
1747  foreach ($Files as $Index => $File)
1748  {
1749  if (!is_object($File))
1750  {
1751  $Files[$Index] = new File($File);
1752  }
1753  }
1754  }
1755  else
1756  {
1757  # use all files associated with resource
1758  $Files = $this->Get($Field, TRUE);
1759  }
1760 
1761  # delete files
1762  foreach ($Files as $File) { $File->Delete(); }
1763  break;
1764 
1766  # if value to clear supplied
1767  if ($ValueToClear !== NULL)
1768  {
1769  # convert value to array if necessary
1770  $Images = $ValueToClear;
1771  if (!is_array($Images)) { $Images = array($Images); }
1772 
1773  # convert values to objects if necessary
1774  foreach ($Images as $Index => $Image)
1775  {
1776  if (!is_object($Image))
1777  {
1778  $Images[$Index] = new SPTImage($Image);
1779  }
1780  }
1781  }
1782  else
1783  {
1784  # use all images associated with resource
1785  $Images = $this->Get($Field, TRUE);
1786  }
1787 
1788  # delete images if we are the last resource referencing
1789  # a particular image.
1790  foreach ($Images as $Image) {
1791  $Cnt = $this->DB->Query(
1792  "SELECT COUNT(*) AS Cnt FROM ResourceImageInts WHERE ".
1793  "ImageId=".$Image->Id(), "Cnt");
1794  if ($Cnt==1)
1795  $Image->Delete();
1796  }
1797 
1798  # remove connections to images
1799  $UpdateModTime = $this->RemoveAssociation(
1800  "ResourceImageInts", "ImageId", $Images, $Field);
1801  break;
1802 
1804  # remove references from the references table
1805  $DB->Query("
1806  DELETE FROM ReferenceInts
1807  WHERE FieldId = '".addslashes($Field->Id())."'
1808  AND SrcResourceId = '".addslashes($this->Id())."'");
1809  break;
1810 
1811  default:
1812  # ERROR OUT
1813  exit("<br>SPT - ERROR: attempt to clear unknown resource field type<br>\n");
1814  break;
1815  }
1816 
1817  if ($UpdateModTime && !$this->IsTempResource())
1818  {
1819  # update modification timestamps
1820  global $G_User;
1821  $UserId = $G_User->IsLoggedIn() ? $G_User->Get("UserId") : -1;
1822  $DB->Query("DELETE FROM ResourceFieldTimestamps "
1823  ."WHERE ResourceId=".$this->Id." AND "
1824  ."FieldId=".$Field->Id() );
1825  $DB->Query("INSERT INTO ResourceFieldTimestamps "
1826  ."(ResourceId,FieldId,ModifiedBy,Timestamp) VALUES ("
1827  .$this->Id.",".$Field->Id().","
1828  .$UserId.",NOW())");
1829  }
1830  }
1831  function ClearByField($Field, $ValueToClear = NULL)
1832  { $this->Clear($Field, $ValueToClear); }
1833 
1834 
1835  # --- Field-Specific or Type-Specific Attribute Retrieval Methods -------
1836 
1837  # return 2D array of classifications associated with resource
1838  # (first index is classification (field) name, second index is classification ID)
1839  function Classifications()
1840  {
1841  $DB = $this->DB;
1842 
1843  # start with empty array
1844  $Names = array();
1845 
1846  # for each controlled name
1847  $DB->Query("SELECT ClassificationName, MetadataFields.FieldName, "
1848  ."ResourceClassInts.ClassificationId FROM ResourceClassInts, "
1849  ."Classifications, MetadataFields "
1850  ."WHERE ResourceClassInts.ResourceId = ".$this->Id." "
1851  ."AND ResourceClassInts.ClassificationId = Classifications.ClassificationId "
1852  ."AND Classifications.FieldId = MetadataFields.FieldId ");
1853  while ($Record = $DB->FetchRow())
1854  {
1855  # add name to array
1856  $Names[$Record["FieldName"]][$Record["ClassificationId"]] =
1857  $Record["ClassificationName"];
1858  }
1859 
1860  # return array to caller
1861  return $Names;
1862  }
1863 
1864 
1865  # --- Ratings Methods ---------------------------------------------------
1866 
1867  # return cumulative rating (range is usually 0-100)
1868  function CumulativeRating() { return $this->CumulativeRating; }
1869 
1870  # return cumulative rating scaled to 1/10th (range is usually 0-10)
1872  {
1873  if ($this->CumulativeRating == NULL)
1874  {
1875  return NULL;
1876  }
1877  else
1878  {
1879  return intval(($this->CumulativeRating + 5) / 10);
1880  }
1881  }
1882 
1883  # return current number of ratings for resource
1884  function NumberOfRatings()
1885  {
1886  # if number of ratings not already set
1887  if (!isset($this->NumberOfRatings))
1888  {
1889  # obtain number of ratings
1890  $this->NumberOfRatings =
1891  $this->DB->Query("SELECT Count(*) AS NumberOfRatings "
1892  ."FROM ResourceRatings "
1893  ."WHERE ResourceId = ".$this->Id,
1894  "NumberOfRatings"
1895  );
1896 
1897  # recalculate cumulative rating if it looks erroneous
1898  if (($this->NumberOfRatings > 0) && !$this->CumulativeRating())
1899  {
1900  $this->UpdateCumulativeRating();
1901  }
1902  }
1903 
1904  # return number of ratings to caller
1905  return $this->NumberOfRatings;
1906  }
1907 
1908  # update individual rating for resource
1909  function Rating($NewRating = NULL, $UserId = NULL)
1910  {
1911  $DB = $this->DB;
1912 
1913  # if user ID not supplied
1914  if ($UserId == NULL)
1915  {
1916  # if user is logged in
1917  global $User;
1918  if ($User->IsLoggedIn())
1919  {
1920  # use ID of current user
1921  $UserId = $User->Get("UserId");
1922  }
1923  else
1924  {
1925  # return NULL to caller
1926  return NULL;
1927  }
1928  }
1929 
1930  # sanitize $NewRating
1931  if (!is_null($NewRating))
1932  {
1933  $NewRating = intval($NewRating);
1934  }
1935 
1936  # if there is a rating for resource and user
1937  $DB->Query("SELECT Rating FROM ResourceRatings "
1938  ."WHERE UserId = ${UserId} AND ResourceId = ".$this->Id);
1939  if ($Record = $DB->FetchRow())
1940  {
1941  # if new rating was supplied
1942  if ($NewRating != NULL)
1943  {
1944  # update existing rating
1945  $DB->Query("UPDATE ResourceRatings "
1946  ."SET Rating = ${NewRating}, DateRated = NOW() "
1947  ."WHERE UserId = ${UserId} AND ResourceId = ".$this->Id);
1948 
1949  # update cumulative rating value
1950  $this->UpdateCumulativeRating();
1951 
1952  # return value is new rating
1953  $Rating = $NewRating;
1954  }
1955  else
1956  {
1957  # get rating value to return to caller
1958  $Rating = $Record["Rating"];
1959  }
1960  }
1961  else
1962  {
1963  # if new rating was supplied
1964  if ($NewRating != NULL)
1965  {
1966  # add new rating
1967  $DB->Query("INSERT INTO ResourceRatings "
1968  ."(ResourceId, UserId, DateRated, Rating) "
1969  ."VALUES ("
1970  .$this->Id.", "
1971  ."${UserId}, "
1972  ."NOW(), "
1973  ."${NewRating})");
1974 
1975  # update cumulative rating value
1976  $this->UpdateCumulativeRating();
1977 
1978  # return value is new rating
1979  $Rating = $NewRating;
1980  }
1981  else
1982  {
1983  # return value is NULL
1984  $Rating = NULL;
1985  }
1986  }
1987 
1988  # return rating value to caller
1989  return $Rating;
1990  }
1991 
1992 
1993  # --- Resource Comment Methods ------------------------------------------
1994 
1995  # return comments as array of Message objects
1996  function Comments()
1997  {
1998  # read in comments if not already loaded
1999  if (!isset($this->Comments))
2000  {
2001  $this->DB->Query("SELECT MessageId FROM Messages "
2002  ."WHERE ParentId = ".$this->Id
2003  ." AND ParentType = 2 "
2004  ."ORDER BY DatePosted DESC");
2005  while ($MessageId = $this->DB->FetchField("MessageId"))
2006  {
2007  $this->Comments[] = new Message($MessageId);
2008  }
2009  }
2010 
2011  # return array of comments to caller
2012  return $this->Comments;
2013  }
2014 
2015  # return current number of comments
2016  function NumberOfComments()
2017  {
2018  # obtain number of comments if not already set
2019  if (!isset($this->NumberOfComments))
2020  {
2021  $this->NumberOfComments =
2022  $this->DB->Query("SELECT Count(*) AS NumberOfComments "
2023  ."FROM Messages "
2024  ."WHERE ParentId = ".$this->Id
2025  ." AND ParentType = 2",
2026  "NumberOfComments"
2027  );
2028  }
2029 
2030  # return number of comments to caller
2031  return $this->NumberOfComments;
2032  }
2033 
2034 
2035  # --- Permission Methods -------------------------------------------------
2036 
2046  function UserCanView(User $User, $AllowHooksToModify=TRUE)
2047  {
2048  return $this->CheckSchemaPermissions($User, "View", $AllowHooksToModify);
2049  }
2050 
2057  function UserCanEdit($User)
2058  {
2059  return $this->CheckSchemaPermissions($User, "Edit");
2060  }
2061 
2068  function UserCanAuthor($User)
2069  {
2070  return $this->CheckSchemaPermissions($User, "Author");
2071  }
2072 
2079  function UserCanViewField($User, $FieldOrFieldName)
2080  {
2081  return $this->CheckFieldPermissions( $User, $FieldOrFieldName, "View" );
2082  }
2083 
2090  function UserCanEditField($User, $FieldOrFieldName)
2091  {
2092  return $this->CheckFieldPermissions( $User, $FieldOrFieldName, "Edit" );
2093  }
2094 
2101  function UserCanAuthorField($User, $FieldOrFieldName)
2102  {
2103  return $this->CheckFieldPermissions( $User, $FieldOrFieldName, "Author" );
2104  }
2105 
2113  function UserCanModifyField($User, $FieldOrFieldName)
2114  {
2115  $CheckFn = "UserCan".(($this->Id()<0) ? "Author" : "Edit")."Field";
2116 
2117  return $this->$CheckFn($User, $FieldOrFieldName);
2118  }
2119 
2120  # ---- PRIVATE INTERFACE -------------------------------------------------
2121 
2122  private $DB;
2123  private $Schema;
2124  private $DBFields;
2125  private $Id;
2126  private $NumberOfRatings;
2127  private $CumulativeRating;
2128  private $NumberOfComments;
2129  private $Comments;
2130  private $LastStatus;
2131  private $ControlledNameCache;
2132  private $ControlledNameVariantCache;
2133  private $ClassificationCache;
2134  private $PermissionCache;
2135 
2144  private function CheckSchemaPermissions($User, $CheckType, $AllowHooksToModify=TRUE)
2145  {
2146  # checks against invalid reosurces should always fail
2147  if ($this->Status() !== 1) { return FALSE; }
2148 
2149  # construct a key to use for our permissions cache
2150  $CacheKey = "UserCan".$CheckType.$User->Id();
2151 
2152  # if we don't have a cached value for this perm, compute one
2153  if (!isset($this->PermissionCache[$CacheKey]))
2154  {
2155  # get privileges for schema
2156  $PermsFn = $CheckType."ingPrivileges";
2157  $SchemaPrivs = $this->Schema->$PermsFn();
2158 
2159  # check passes if user privileges are greater than resource set
2160  $CheckResult = $SchemaPrivs->MeetsRequirements($User, $this);
2161 
2162  # save the result of this check in our cache
2163  $this->PermissionCache[$CacheKey] = $CheckResult;
2164  }
2165 
2166  $Value = $this->PermissionCache[$CacheKey];
2167 
2168  if ($AllowHooksToModify)
2169  {
2170  $SignalResult = $GLOBALS["AF"]->SignalEvent(
2171  "EVENT_RESOURCE_".strtoupper($CheckType)."_PERMISSION_CHECK",
2172  array(
2173  "Resource" => $this,
2174  "User" => $User,
2175  "Can".$CheckType => $Value));
2176 
2177  $Value = $SignalResult["Can".$CheckType];
2178  }
2179 
2180  return $Value;
2181  }
2182 
2190  private function CheckFieldPermissions($User, $FieldOrFieldName, $CheckType)
2191  {
2192  # checks against invalid resources should always fail
2193  if ($this->Status() !== 1) { return FALSE; }
2194 
2195  # get field object (if not supplied)
2196  $Field = is_object($FieldOrFieldName) ? $FieldOrFieldName
2197  : $this->Schema->GetFieldByName($FieldOrFieldName);
2198 
2199  # checks against invalid fields should also fail
2200  if (!($Field instanceof MetadataField)) { return FALSE; }
2201 
2202  # construct a key to use for our permissions cache
2203  $CacheKey = "UserCan".$CheckType."Field".$Field->Id()."-".$User->Id();
2204 
2205  # if we don't have a cahced value, compute one
2206  if (!isset($this->PermissionCache[$CacheKey]))
2207  {
2208  # checks for disabled fields should not pass
2209  if (!$Field->Enabled())
2210  {
2211  $CheckResult = FALSE;
2212  }
2213  else
2214  {
2215  # be sure schema privs allow View/Edit/Author for this resource
2216  $SchemaCheckFn = "UserCan".$CheckType;
2217  if ($this->$SchemaCheckFn($User))
2218  {
2219  # get appropriate privilege set for field
2220  $PermsFn = $CheckType."ingPrivileges";
2221  $FieldPrivs = $Field->$PermsFn();
2222 
2223  # user can View/Edit/Author if privileges are greater than field set
2224  $CheckResult = $FieldPrivs->MeetsRequirements($User, $this);
2225  }
2226  else
2227  {
2228  $CheckResult = FALSE;
2229  }
2230  }
2231 
2232  # allow plugins to modify result of permission check
2233  $SignalResult = $GLOBALS["AF"]->SignalEvent(
2234  "EVENT_FIELD_".strtoupper($CheckType)."_PERMISSION_CHECK", array(
2235  "Field" => $Field,
2236  "Resource" => $this,
2237  "User" => $User,
2238  "Can".$CheckType => $CheckResult));
2239  $CheckResult = $SignalResult["Can".$CheckType];
2240 
2241  # save the result of this check in our cache
2242  $this->PermissionCache[$CacheKey] = $CheckResult;
2243  }
2244 
2245  # return cached permission value
2246  return $this->PermissionCache[$CacheKey];
2247  }
2248 
2249  # recalculate and save cumulative rating value for resource
2250  private function UpdateCumulativeRating()
2251  {
2252  # grab totals from DB
2253  $this->DB->Query("SELECT COUNT(Rating) AS Count, "
2254  ."SUM(Rating) AS Total FROM ResourceRatings "
2255  ."WHERE ResourceId = ".$this->Id);
2256  $Record = $this->DB->FetchRow();
2257 
2258  # calculate new cumulative rating
2259  $this->CumulativeRating = round($Record["Total"] / $Record["Count"]);
2260 
2261  # save new cumulative rating in DB
2262  $this->DB->Query("UPDATE Resources "
2263  ."SET CumulativeRating = ".$this->CumulativeRating." "
2264  ."WHERE ResourceId = ".$this->Id);
2265  }
2266 
2277  private function AddAssociation($TableName, $FieldName, $Value, $Field = NULL)
2278  {
2279  # We should ignore duplicate key errors when doing inserts:
2280  $this->DB->SetQueryErrorsToIgnore( array(
2281  "/INSERT INTO ".$TableName."/" =>
2282  "/Duplicate entry '[0-9]+-[0-9]+' for key/"));
2283 
2284  # start out assuming no association will be added
2285  $AssociationAdded = FALSE;
2286 
2287  # convert new value to array if necessary
2288  $Values = is_array($Value) ? $Value : array($Value);
2289 
2290  # for each new value
2291  foreach ($Values as $Value)
2292  {
2293  # retrieve ID from value if necessary
2294  if (is_object($Value)) { $Value = $Value->Id(); }
2295 
2296  # Try to insert a new entry for this association.
2297  $this->DB->Query("INSERT INTO ".$TableName." SET"
2298  ." ResourceId = ".intval($this->Id)
2299  .", ".$FieldName." = ".intval($Value)
2300  .($Field ? ", FieldId = ".intval($Field->Id()) : ""));
2301 
2302  # If the insert ran without a duplicate key error,
2303  # then we added an assocation:
2304  if ($this->DB->IgnoredError() === FALSE)
2305  $AssociationAdded = TRUE;
2306  }
2307 
2308  # Clear ignored errors:
2309  $this->DB->SetQueryErrorsToIgnore( NULL );
2310 
2311  # report to caller whether association was added
2312  return $AssociationAdded;
2313  }
2314 
2325  private function RemoveAssociation($TableName, $FieldName, $Value, $Field = NULL)
2326  {
2327  # start out assuming no association will be removed
2328  $AssociationRemoved = FALSE;
2329 
2330  # convert value to array if necessary
2331  $Values = is_array($Value) ? $Value : array($Value);
2332 
2333  # for each value
2334  foreach ($Values as $Value)
2335  {
2336  # retrieve ID from value if necessary
2337  if (is_object($Value)) { $Value = $Value->Id(); }
2338 
2339  # remove any intersections with target ID from DB
2340  $this->DB->Query("DELETE FROM ".$TableName
2341  ." WHERE ResourceId = ".intval($this->Id)
2342  .($Field ? " AND FieldId = ".intval($Field->Id()) : "")
2343  ." AND ".$FieldName." = ".intval($Value));
2344  if ($this->DB->NumRowsAffected()) { $AssociationRemoved = TRUE; }
2345  }
2346 
2347  # report to caller whether association was added
2348  return $AssociationRemoved;
2349  }
2350 
2351  # remove all intersections for resource and field (if any)
2352  private function RemoveAllAssociations($TableName, $TargetFieldName, $Field)
2353  {
2354  # retrieve list of entries for this field and resource
2355  $Entries = $this->Get($Field);
2356 
2357  # Divide them into chunks of not more than 50:
2358  foreach (array_chunk($Entries, 100, TRUE) as $Chunk)
2359  {
2360  # Construct a query that will remove assocations in this chunk:
2361  $this->DB->Query("DELETE FROM ".$TableName
2362  ." WHERE ResourceId = ".intval($this->Id)
2363  ." AND ".$TargetFieldName." IN "
2364  ."(".implode(",", array_keys($Chunk)).")");
2365  }
2366  }
2367 }
GetByField($FieldNameOrObject, $ReturnObject=FALSE, $IncludeVariants=FALSE)
Old method for retrieving values, deprecated in favor of Get().
Definition: Resource.php:649
UserCanView(User $User, $AllowHooksToModify=TRUE)
Determine if the given user can view the resource, e.g., on the full record page. ...
Definition: Resource.php:2046
GetFilesForResource($ResourceOrResourceId, $ReturnObjects=TRUE)
Retrieve all files (names or objects) for specified resource.
Definition: FileFactory.php:38
SetQualifier($FieldName, $NewValue)
Definition: Resource.php:1495
Metadata schema (in effect a Factory class for MetadataField).
Abstraction for forum messages and resource comments.
Definition: Message.php:15
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...
Definition: Resource.php:2113
GetAsArray($IncludeDisabledFields=FALSE, $ReturnObjects=TRUE)
Retrieve all resource values as an array.
Definition: Resource.php:684
Set($FieldNameOrObject, $NewValue, $Reset=FALSE)
Set value using field name or field object.
Definition: Resource.php:977
Id()
Retrieve numerical resource ID.
Definition: Resource.php:261
UserCanEditField($User, $FieldOrFieldName)
Check whether user is allowed to edit specified metadata field.
Definition: Resource.php:2090
SetQualifierByField($Field, $NewValue)
Definition: Resource.php:1509
Rating($NewRating=NULL, $UserId=NULL)
Definition: Resource.php:1909
Status()
Retrieve result of last operation if available.
Definition: Resource.php:255
NumberOfComments()
Definition: Resource.php:2016
NumberOfRatings()
Definition: Resource.php:1884
GetQualifier($FieldName, $ReturnObject=TRUE)
Retrieve qualifier by field name.
Definition: Resource.php:746
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.
Definition: FileFactory.php:84
Metadata type representing non-hierarchical controlled vocabulary values.
UserCanEdit($User)
Determine if the given user can edit the resource.
Definition: Resource.php:2057
const MDFTYPE_CONTROLLEDNAME
CWIS-specific user factory class.
PHP
Definition: OAIClient.php:39
Factory for manipulating File objects.
Definition: FileFactory.php:13
GetQualifierByFieldId($FieldId, $ReturnObject=TRUE)
Retrieve qualifier by field ID.
Definition: Resource.php:760
Encapsulates a full-size, preview, and thumbnail image.
Definition: SPTImage.php:13
UserCanAuthorField($User, $FieldOrFieldName)
Check whether user is allowed to author specified metadata field.
Definition: Resource.php:2101
Clear($Field, $ValueToClear=NULL)
Definition: Resource.php:1545
UserCanAuthor($User)
Determine if the given user can edit the resource.
Definition: Resource.php:2068
GetByFieldId($FieldId, $ReturnObject=FALSE, $IncludeVariants=FALSE)
Retrieve value using field ID.
Definition: Resource.php:666
IsTempResource($NewSetting=NULL)
Get/set whether resource is a temporary record.
Definition: Resource.php:275
Get($FieldNameOrObject, $ReturnObject=FALSE, $IncludeVariants=FALSE)
Retrieve value using field name or field object.
Definition: Resource.php:353
SetByField($Field, $NewValue)
Method replaced by Resource::Set(), preserved for backward compatibility.
Definition: Resource.php:1485
Object representing a locally-defined type of metadata field.
__construct($ResourceId)
Object constructor for loading an existing resource.
Definition: Resource.php:23
GetMapped($MappedName, $ReturnObject=FALSE, $IncludeVariants=FALSE)
Retrieve value using standard (mapped) field name.
Definition: Resource.php:730
Represents a "resource" in CWIS.
Definition: Resource.php:13
GetQualifierByField($Field, $ReturnObject=TRUE)
Retrieve qualifier by Field object.
Definition: Resource.php:774
ClearByFieldId($FieldId, $ValueToClear=NULL)
Definition: Resource.php:1538
const CLASSSTAT_OK
Status code indicating operation completed successfully.
SetQualifierByFieldId($FieldId, $NewValue)
Definition: Resource.php:1502
SchemaId()
Retrieve ID of schema for resource.
Definition: Resource.php:267
ScaledCumulativeRating()
Definition: Resource.php:1871
const UPDATEMETHOD_ONRECORDCREATE
static Create($SchemaId)
Create a new resource.
Definition: Resource.php:59
UserCanViewField($User, $FieldOrFieldName)
Check whether user is allowed to view specified metadata field.
Definition: Resource.php:2079
Metadata type representing hierarchical ("Tree") controlled vocabulary values.
SetByFieldId($FieldId, $NewValue)
Definition: Resource.php:1488
Classifications()
Definition: Resource.php:1839
ClearByField($Field, $ValueToClear=NULL)
Definition: Resource.php:1831
Class representing a stored (usually uploaded) file.
Definition: File.php:13
Factory for Resource objects.
CWIS-specific user class.
Definition: CWUser.php:13
CumulativeRating()
Definition: Resource.php:1868
FieldIsSet($FieldNameOrObject, $IgnorePadding=FALSE)
Determine if the value for a field is set.
Definition: Resource.php:905
Delete()
Remove resource (and accompanying associations) from database and delete any associated files...
Definition: Resource.php:148