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 Resource($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  $DB->Query("
74  INSERT INTO Resources
75  SET `ResourceId` = '".intval($Id)."',
76  `SchemaId` = '".intval($SchemaId)."'");
77 
78  # release DB tables
79  $DB->Query("UNLOCK TABLES");
80 
81  # create new Resource object
82  $Resource = new Resource($Id);
83 
84  # set some additional fields for default resources
85  if ($SchemaId == MetadataSchema::SCHEMAID_DEFAULT)
86  {
87  $Resource->Set("Added By Id", $GLOBALS["G_User"]->Id());
88  $Resource->Set("Last Modified By Id", $GLOBALS["G_User"]->Id());
89  $Resource->Set("Date Of Record Creation", date("Y-m-d H:i:s"));
90  $Resource->Set("Date Last Modified", date("Y-m-d H:i:s"));
91  }
92 
93  # set any default values
94  $Schema = new MetadataSchema($SchemaId);
95  $Fields = $Schema->GetFields(MetadataSchema::MDFTYPE_OPTION
100  foreach ($Fields as $Field)
101  {
102  $DefaultValue = $Field->DefaultValue();
103 
104  # flip option default values to get into the form that
105  # Resource::Set() expects
106  if ($Field->Type() == MetadataSchema::MDFTYPE_OPTION
107  && is_array($DefaultValue))
108  {
109  $DefaultValue = array_flip($DefaultValue);
110  }
111 
112  $Resource->SetByField($Field, $DefaultValue);
113  }
114 
115  # update timestamps as required
116  $TimestampFields = $Schema->GetFields(MetadataSchema::MDFTYPE_TIMESTAMP);
117  foreach ($TimestampFields as $Field)
118  {
119  if ($Field->UpdateMethod() ==
121  {
122  $Resource->SetByField($Field, "now");
123  }
124  }
125 
126  # signal resource creation
127  $GLOBALS["AF"]->SignalEvent("EVENT_RESOURCE_CREATE", array(
128  "Resource" => $Resource,
129  ));
130 
131  # return new Resource object to caller
132  return $Resource;
133  }
134 
139  function Delete()
140  {
141  global $SysConfig;
142 
143  # signal that resource deletion is about to occur
144  global $AF;
145  $AF->SignalEvent("EVENT_RESOURCE_DELETE", array(
146  "Resource" => $this,
147  ));
148 
149  # grab list of classifications
150  $Classifications = $this->Classifications();
151 
152  # delete resource/classification intersections
153  $DB = $this->DB;
154  $DB->Query("DELETE FROM ResourceClassInts WHERE ResourceId = ".$this->Id());
155 
156  # for each classification type
157  foreach ($Classifications as $ClassType => $ClassesOfType)
158  {
159  # for each classification of that type
160  foreach ($ClassesOfType as $ClassId => $ClassName)
161  {
162  # recalculate resource count for classification
163  $Class = new Classification($ClassId);
164  $Class->RecalcResourceCount();
165  }
166  }
167 
168  # delete resource references
169  $DB->Query("
170  DELETE FROM ReferenceInts
171  WHERE SrcResourceId = '".addslashes($this->Id())."'
172  OR DstResourceId = '".addslashes($this->Id())."'");
173 
174  # delete resource/name intersections
175  $DB->Query("DELETE FROM ResourceNameInts WHERE ResourceId = ".$this->Id());
176 
177  # delete any associated images not in use by other resources
178  $DB->Query("SELECT ImageId FROM ResourceImageInts"
179  ." WHERE ResourceId = ".intval($this->Id()));
180  $ImageIds = $DB->FetchColumn("ImageId");
181  foreach ($ImageIds as $ImageId)
182  {
183  $DB->Query("SELECT ResourceId FROM ResourceImageInts"
184  ." WHERE ImageId = ".intval($ImageId)
185  ." AND ResourceId != ".intval($this->Id()));
186  if ($DB->NumRowsSelected() == 0)
187  {
188  $Image = new SPTImage($ImageId);
189  $Image->Delete();
190  }
191  }
192 
193  # delete any associated files
194  $Factory = new FileFactory(NULL);
195  $Files = $Factory->GetFilesForResource($this->Id());
196  foreach ($Files as $File)
197  {
198  $File->Delete();
199  }
200 
201  # delete resource record from database
202  $DB->Query("DELETE FROM Resources WHERE ResourceId = ".$this->Id());
203 
204  # drop item from search engine and recommender system
205  if ($SysConfig->SearchDBEnabled())
206  {
207  $SearchEngine = new SPTSearchEngine();
208  $SearchEngine->DropItem($this->Id());
209  }
210  if ($SysConfig->RecommenderDBEnabled())
211  {
212  $Recommender = new SPTRecommender();
213  $Recommender->DropItem($this->Id());
214  }
215 
216  # get the folders containing the resource
217  $FolderFactory = new FolderFactory();
218  $Folders = $FolderFactory->GetFoldersContainingItem(
219  $this->Id,
220  "Resource");
221 
222  # drop the resource from each folder it belongs to
223  foreach ($Folders as $Folder)
224  {
225  # mixed item type folder
226  if ($Folder->ContainsItem($this->Id, "Resource"))
227  {
228  $Folder->RemoveItem($this->Id, "Resource");
229  }
230 
231  # single item type folder
232  else
233  {
234  $Folder->RemoveItem($this->Id);
235  }
236  }
237 
238  # delete any resource comments
239  $DB->Query("DELETE FROM Messages WHERE ParentId = ".$this->Id);
240  }
241 
246  function Status() { return $this->LastStatus; }
247 
252  function Id() { return $this->Id; }
253 
258  function SchemaId() { return $this->DBFields["SchemaId"]; }
259 
266  function IsTempResource($NewSetting = NULL)
267  {
268  # if new temp resource setting supplied
269  if (!is_null($NewSetting))
270  {
271  # if caller requested to switch
272  $DB = $this->DB;
273  if ((($this->Id() < 0) && ($NewSetting == FALSE))
274  || (($this->Id() >= 0) && ($NewSetting == TRUE)))
275  {
276  # lock DB tables to prevent next ID from being grabbed
277  $DB->Query("LOCK TABLES Resources write");
278 
279  # get next resource ID as appropriate
280  $OldResourceId = $this->Id;
281  $Factory = new ResourceFactory($this->SchemaId());
282  if ($NewSetting == TRUE)
283  {
284  $this->Id = $Factory->GetNextTempItemId();
285  }
286  else
287  {
288  $this->Id = $Factory->GetNextItemId();
289  }
290 
291  # change resource ID
292  $DB->Query("UPDATE Resources SET ResourceId = ".
293  $this->Id. " WHERE ResourceId = ".$OldResourceId);
294 
295  # release DB tables
296  $DB->Query("UNLOCK TABLES");
297 
298  # change associations
299  unset($this->ClassificationCache);
300  $DB->Query("UPDATE ResourceClassInts SET ResourceId = ".
301  $this->Id. " WHERE ResourceId = ".$OldResourceId);
302  unset($this->ControlledNameCache);
303  unset($this->ControlledNameVariantCache);
304  $DB->Query("UPDATE ResourceNameInts SET ResourceId = ".
305  $this->Id. " WHERE ResourceId = ".$OldResourceId);
306  $DB->Query("UPDATE Files SET ResourceId = ".
307  $this->Id. " WHERE ResourceId = ".$OldResourceId);
308  $DB->Query("UPDATE ReferenceInts SET SrcResourceId = ".
309  $this->Id. " WHERE SrcResourceId = ".$OldResourceId);
310  $DB->Query("UPDATE ResourceImageInts SET ResourceId = ".
311  $this->Id. " WHERE ResourceId = ".$OldResourceId);
312 
313  # signal event as appropriate
314  if ($NewSetting === FALSE)
315  {
316  $GLOBALS["AF"]->SignalEvent("EVENT_RESOURCE_ADD", array(
317  "Resource" => $this,
318  ));
319  }
320  }
321  }
322 
323  # report to caller whether we are a temp resource
324  return ($this->Id() < 0) ? TRUE : FALSE;
325  }
326 
327 
328  # --- Generic Attribute Retrieval Methods -------------------------------
329 
344  function Get($FieldNameOrObject, $ReturnObject = FALSE, $IncludeVariants = FALSE)
345  {
346  # load field object if needed
347  $Field = is_object($FieldNameOrObject) ? $FieldNameOrObject
348  : $this->Schema->GetFieldByName($FieldNameOrObject);
349 
350  # return no value found if we don't have a valid field
351  if (!($Field instanceof MetadataField)) { return NULL; }
352 
353  # grab database field name
354  $DBFieldName = $Field->DBFieldName();
355 
356  # format return value based on field type
357  switch ($Field->Type())
358  {
362  $ReturnValue = isset($this->DBFields[$DBFieldName])
363  ? (string)$this->DBFields[$DBFieldName] : NULL;
364  break;
365 
367  $ReturnValue = isset($this->DBFields[$DBFieldName])
368  ? (int)$this->DBFields[$DBFieldName] : NULL;
369  break;
370 
372  $ReturnValue = isset($this->DBFields[$DBFieldName])
373  ? (bool)$this->DBFields[$DBFieldName] : NULL;
374  break;
375 
377  $ReturnValue = array("X" => (float)$this->DBFields[$DBFieldName."X"],
378  "Y" => (float)$this->DBFields[$DBFieldName."Y"]);
379  break;
380 
382  $Date = new Date($this->DBFields[$DBFieldName."Begin"],
383  $this->DBFields[$DBFieldName."End"],
384  $this->DBFields[$DBFieldName."Precision"]);
385  if ($ReturnObject)
386  {
387  $ReturnValue = $Date;
388  }
389  else
390  {
391  $ReturnValue = $Date->Formatted();
392  }
393  break;
394 
396  $ReturnValue = $this->DBFields[$DBFieldName];
397  break;
398 
400  # start with empty array
401  $ReturnValue = array();
402 
403  # if classification cache has not been loaded
404  if (!isset($this->ClassificationCache))
405  {
406  # load all classifications associated with this resource into cache
407  $this->ClassificationCache = array();
408  $this->DB->Query(
409  "SELECT Classifications.ClassificationId,"
410  ." Classifications.FieldId,ClassificationName"
411  ." FROM ResourceClassInts, Classifications"
412  ." WHERE ResourceClassInts.ResourceId = ".$this->Id
413  ." AND ResourceClassInts.ClassificationId"
414  ." = Classifications.ClassificationId");
415  while ($Record = $this->DB->FetchRow())
416  {
417  $this->ClassificationCache[$Record["ClassificationId"]]["Name"] =
418  $Record["ClassificationName"];
419  $this->ClassificationCache[$Record["ClassificationId"]]["FieldId"] =
420  $Record["FieldId"];
421  }
422  }
423 
424  # for each entry in classification cache
425  foreach ($this->ClassificationCache as $ClassificationId => $ClassificationInfo)
426  {
427  # if classification ID matches field we are looking for
428  if ($ClassificationInfo["FieldId"] == $Field->Id())
429  {
430  # add field to result
431  if ($ReturnObject)
432  {
433  $ReturnValue[$ClassificationId] = new Classification($ClassificationId);
434  }
435  else
436  {
437  $ReturnValue[$ClassificationId] = $ClassificationInfo["Name"];
438  }
439  }
440  }
441  break;
442 
445  # start with empty array
446  $ReturnValue = array();
447 
448  # if controlled name cache has not been loaded
449  if (!isset($this->ControlledNameCache))
450  {
451  # load all controlled names associated with this resource into cache
452  $this->ControlledNameCache = array();
453  $this->DB->Query(
454  "SELECT ControlledNames.ControlledNameId,"
455  ." ControlledNames.FieldId,ControlledName"
456  ." FROM ResourceNameInts, ControlledNames"
457  ." WHERE ResourceNameInts.ResourceId = ".$this->Id
458  ." AND ResourceNameInts.ControlledNameId"
459  ." = ControlledNames.ControlledNameId"
460  ." ORDER BY ControlledNames.ControlledName ASC");
461  while ($Record = $this->DB->FetchRow())
462  {
463  $this->ControlledNameCache[$Record["ControlledNameId"]]["Name"] = $Record["ControlledName"];
464  $this->ControlledNameCache[$Record["ControlledNameId"]]["FieldId"] = $Record["FieldId"];
465  }
466  }
467 
468  # if variant names requested and variant name cache has not been loaded
469  if ($IncludeVariants && !isset($this->ControlledNameVariantCache))
470  {
471  # load all controlled names associated with this resource into cache
472  $this->ControlledNameVariantCache = array();
473  $this->DB->Query("SELECT ControlledNames.ControlledNameId,"
474  ." ControlledNames.FieldId,"
475  ." ControlledName, VariantName"
476  ." FROM ResourceNameInts, ControlledNames, VariantNames"
477  ." WHERE ResourceNameInts.ResourceId = ".$this->Id
478  ." AND ResourceNameInts.ControlledNameId"
479  ." = ControlledNames.ControlledNameId"
480  ." AND VariantNames.ControlledNameId"
481  ." = ControlledNames.ControlledNameId");
482  while ($Record = $this->DB->FetchRow())
483  {
484  $this->ControlledNameVariantCache[$Record["ControlledNameId"]][]
485  = $Record["VariantName"];
486  }
487  }
488 
489  # for each entry in controlled name cache
490  foreach ($this->ControlledNameCache as $ControlledNameId => $ControlledNameInfo)
491  {
492  # if controlled name type matches field we are looking for
493  if ($ControlledNameInfo["FieldId"] == $Field->Id())
494  {
495  # if objects requested
496  if ($ReturnObject)
497  {
498  $ReturnValue[$ControlledNameId] =
499  new ControlledName($ControlledNameId);
500  }
501  else
502  {
503  # if variant names requested
504  if ($IncludeVariants)
505  {
506  # add field to result
507  $ReturnValue[] = $ControlledNameInfo["Name"];
508 
509  # add any variant names to result
510  if (isset($this->ControlledNameVariantCache[$ControlledNameId]))
511  {
512  $ReturnValue = array_merge(
513  $ReturnValue,
514  $this->ControlledNameVariantCache[$ControlledNameId]);
515  }
516  }
517  else
518  {
519  # add field with index to result
520  $ReturnValue[$ControlledNameId] =
521  $ControlledNameInfo["Name"];
522  }
523  }
524  }
525  }
526  break;
527 
529  $User = new CWUser(intval($this->DBFields[$DBFieldName]));
530  if ($ReturnObject)
531  {
532  $ReturnValue = $User;
533  }
534  else
535  {
536  $ReturnValue = $User->Get("UserName");
537  }
538  break;
539 
541  # start out assuming no images will be found
542  $ReturnValue = array();
543 
544  # find all images associated with this resource
545  $this->DB->Query("SELECT ImageId FROM ResourceImageInts"
546  ." WHERE ResourceId = ".intval($this->Id())
547  ." AND FieldId = ".intval($Field->Id()));
548 
549  # if images were found
550  if ($this->DB->NumRowsSelected())
551  {
552  # if we are to return an object
553  $ImageIds = $this->DB->FetchColumn("ImageId");
554  if ($ReturnObject)
555  {
556  # load array of Image objects for return value
557  foreach ($ImageIds as $ImageId)
558  {
559  $ReturnValue[$ImageId] = new SPTImage($ImageId);
560  }
561  }
562  else
563  {
564  # load array of Image ids for return value
565  $ReturnValue = $ImageIds;
566  }
567  }
568  break;
569 
571  # retrieve files using factory
572  $Factory = new FileFactory($Field->Id());
573  $ReturnValue = $Factory->GetFilesForResource(
574  $this->Id, $ReturnObject);
575  break;
576 
578  # query for resource references
579  $this->DB->Query("
580  SELECT * FROM ReferenceInts
581  WHERE FieldId = '".addslashes($Field->Id())."'
582  AND SrcResourceId = '".addslashes($this->Id())."'");
583 
584  $ReturnValue = array();
585 
586  # return each reference as a Resource object
587  if ($ReturnObject)
588  {
589  $FoundErrors = FALSE;
590 
591  while (FALSE !== ($Record = $this->DB->FetchRow()))
592  {
593  $ReferenceId = $Record["DstResourceId"];
594  $Reference = new Resource($ReferenceId);
595 
596  # the reference is bad, so flag that there were errors
597  if ($Reference->Status() != 1)
598  {
599  $FoundErrors = TRUE;
600  }
601 
602  else
603  {
604  $ReturnValue[$ReferenceId] = $Reference;
605  }
606  }
607 
608  # try to fix the errors by removing any references to
609  # resources that were bad
610  if ($FoundErrors)
611  {
612  $this->Set($Field, $ReturnValue);
613  }
614  }
615 
616  # return each reference as a resource ID
617  else
618  {
619  while (FALSE !== ($Record = $this->DB->FetchRow()))
620  {
621  $ReferenceId = $Record["DstResourceId"];
622  $ReturnValue[$ReferenceId] = $ReferenceId;
623  }
624  }
625  break;
626 
627  default:
628  # ERROR OUT
629  exit("<br>SPT - ERROR: attempt to retrieve unknown resource field type (".$Field->Type().")<br>\n");
630  break;
631  }
632 
633  # return formatted value to caller
634  return $ReturnValue;
635  }
640  function GetByField($FieldNameOrObject,
641  $ReturnObject = FALSE, $IncludeVariants = FALSE)
642  { return $this->Get($FieldNameOrObject, $ReturnObject, $IncludeVariants); }
643 
657  function GetByFieldId($FieldId, $ReturnObject = FALSE, $IncludeVariants = FALSE)
658  {
659  $Field = $this->Schema->GetField($FieldId);
660  return ($Field) ? $this->Get($Field, $ReturnObject, $IncludeVariants) : NULL;
661  }
662 
675  function GetAsArray($IncludeDisabledFields = FALSE, $ReturnObjects = TRUE)
676  {
677  # retrieve field info
678  $Fields = $this->Schema->GetFields();
679 
680  # for each field
681  foreach ($Fields as $Field)
682  {
683  # if field is enabled or caller requested disabled fields
684  if ($Field->Enabled() || $IncludeDisabledFields)
685  {
686  # retrieve info and add it to the array
687  $FieldStrings[$Field->Name()] = $this->Get($Field, $ReturnObjects);
688 
689  # if field uses qualifiers
690  if ($Field->UsesQualifiers())
691  {
692  # get qualifier attributes and add to the array
693  $FieldStrings[$Field->Name()." Qualifier"] =
694  $this->GetQualifierByField($Field, $ReturnObjects);
695  }
696  }
697  }
698 
699  # add in internal values
700  $FieldStrings["ResourceId"] = $this->Id();
701  $FieldStrings["CumulativeRating"] = $this->CumulativeRating();
702 
703  # return array to caller
704  return $FieldStrings;
705  }
706 
721  function GetMapped($MappedName, $ReturnObject = FALSE, $IncludeVariants = FALSE)
722  {
723  return $this->Schema->StdNameToFieldMapping($MappedName)
724  ? $this->GetByFieldId($this->Schema->StdNameToFieldMapping($MappedName),
725  $ReturnObject, $IncludeVariants)
726  : NULL;
727  }
728 
737  function GetQualifier($FieldName, $ReturnObject = TRUE)
738  {
739  $Field = $this->Schema->GetFieldByName($FieldName);
740  return $this->GetQualifierByField($Field, $ReturnObject);
741  }
742 
751  function GetQualifierByFieldId($FieldId, $ReturnObject = TRUE)
752  {
753  $Field = $this->Schema->GetField($FieldId);
754  return ($Field) ? $this->GetQualifierByField($Field, $ReturnObject) : NULL;
755  }
756 
765  function GetQualifierByField($Field, $ReturnObject = TRUE)
766  {
767  # return NULL if field is invalid
768  if (!($Field instanceof MetadataField)) { return NULL; }
769 
770  # assume no qualifiers if not otherwise determined
771  $ReturnValue = NULL;
772 
773  # if field uses qualifiers
774  if ($Field->UsesQualifiers())
775  {
776  # retrieve qualifiers based on field type
777  switch ($Field->Type())
778  {
782  # retrieve list of items
783  $Items = $this->Get($Field);
784 
785  # if field uses item-level qualifiers
786  if ($Field->HasItemLevelQualifiers())
787  {
788  # determine general item name in DB
789  $TableName = ($Field->Type() == MetadataSchema::MDFTYPE_TREE)
790  ? "Classification" : "ControlledName";
791 
792  # for each item
793  foreach ($Items as $ItemId => $ItemName)
794  {
795  # look up qualifier for item
796  $QualId = $this->DB->Query(
797  "SELECT * FROM ".$TableName."s"
798  ." WHERE ".$TableName."Id = ".$ItemId
799  , "QualifierId");
800 
801 
802  if ($QualId > 0)
803  {
804  # if object was requested by caller
805  if ($ReturnObject)
806  {
807  # load qualifier and add to return value array
808  $ReturnValue[$ItemId] = new Qualifier($QualId);
809  }
810  else
811  {
812  # add qualifier ID to return value array
813  $ReturnValue[$ItemId] = $QualId;
814  }
815  }
816  else
817  {
818  # add NULL to return value array for this item
819  $ReturnValue[$ItemId] = NULL;
820  }
821  }
822  }
823  else
824  {
825  # for each item
826  foreach ($Items as $ItemId => $ItemName)
827  {
828  # if object was requested by caller
829  if ($ReturnObject)
830  {
831  # load default qualifier and add to return value array
832  $ReturnValue[$ItemId] = new Qualifier($Field->DefaultQualifier());
833  }
834  else
835  {
836  # add default qualifier ID to return value array
837  $ReturnValue[$ItemId] = $Field->DefaultQualifier();
838  }
839  }
840  }
841  break;
842 
843  default:
844  # if field uses item-level qualifiers
845  if ($Field->HasItemLevelQualifiers())
846  {
847  # if qualifier available
848  if ($this->DBFields[$Field->DBFieldName()."Qualifier"] > 0)
849  {
850  # if object was requested by caller
851  if ($ReturnObject)
852  {
853  # return qualifier for field
854  $ReturnValue = new Qualifier($this->DBFields[$Field->DBFieldName()."Qualifier"]);
855  }
856  else
857  {
858  # return qualifier ID for field
859  $ReturnValue = $this->DBFields[$Field->DBFieldName()."Qualifier"];
860  }
861  }
862  }
863  else
864  {
865  # if default qualifier available
866  if ($Field->DefaultQualifier() > 0)
867  {
868  # if object was requested by caller
869  if ($ReturnObject)
870  {
871  # return default qualifier
872  $ReturnValue = new Qualifier($Field->DefaultQualifier());
873  }
874  else
875  {
876  # return default qualifier ID
877  $ReturnValue = $Field->DefaultQualifier();
878  }
879  }
880  }
881  break;
882  }
883  }
884 
885  # return qualifier object or ID (or array of same) to caller
886  return $ReturnValue;
887  }
888 
896  function FieldIsSet($FieldNameOrObject, $IgnorePadding=FALSE)
897  {
898  # load field object if needed
899  $Field = is_object($FieldNameOrObject) ? $FieldNameOrObject
900  : $this->Schema->GetFieldByName($FieldNameOrObject);
901 
902  # return no value found if we don't have a valid field
903  if (!($Field instanceof MetadataField)) { return FALSE; }
904 
905  # get the value
906  $Value = $this->Get($Field);
907 
908  # checks depend on the field type
909  switch ($Field->Type())
910  {
915  return isset($Value)
916  && strlen($Value)
917  && (!$IgnorePadding || ($IgnorePadding && strlen(trim($Value))));
918 
920  return isset($Value)
921  && strlen($Value);
922 
924  return isset($Value["X"])
925  && isset($Value["Y"])
926  && strlen(trim($Value["X"]))
927  && strlen(trim($Value["Y"]));
928 
930  return isset($Value)
931  && strlen(trim($Value))
932  && $Value != "0000-00-00";
933 
935  return isset($Value)
936  && strlen(trim($Value))
937  && $Value != "0000-00-00 00:00:00";
938 
945  return count($Value) > 0;
946 
948  $Factory = new CWUserFactory();
949  return isset($Value)
950  && strlen($Value)
951  && $Factory->UserNameExists($Value);
952 
953  default:
954  return FALSE;
955  }
956  }
957 
958  # --- Generic Attribute Setting Methods ---------------------------------
959 
965  function Set($FieldNameOrObject, $NewValue)
966  {
967  # load field object if needed
968  $Field = is_object($FieldNameOrObject) ? $FieldNameOrObject
969  : $this->Schema->GetFieldByName($FieldNameOrObject);
970 
971  # return if we don't have a valid field
972  if (!($Field instanceof MetadataField)) { return; }
973 
974  # grab commonly-used values for local use
975  $DB = $this->DB;
976  $ResourceId = $this->Id;
977 
978  # grab database field name
979  $DBFieldName = $Field->DBFieldName();
980 
981  # Flag to deterimine if we've actually changed anything.
982  $UpdateModTime = FALSE;
983 
984  # store value in DB based on field type
985  switch ($Field->Type())
986  {
990  if ($this->DBFields[$DBFieldName] != $NewValue)
991  {
992  # save value directly to DB
993  $DB->Query("UPDATE Resources SET `"
994  .$DBFieldName."` = '".addslashes($NewValue)."' "
995  ."WHERE ResourceId = ".$ResourceId);
996 
997  # save value locally
998  $this->DBFields[$DBFieldName] = $NewValue;
999  $UpdateModTime=TRUE;
1000  }
1001  break;
1002 
1004  if ( $this->DBFields[$DBFieldName] != $NewValue )
1005  {
1006  # save value directly to DB
1007  if (is_null($NewValue))
1008  {
1009  $DB->Query("UPDATE Resources SET `"
1010  .$DBFieldName."` = NULL"
1011  ." WHERE ResourceId = ".$ResourceId);
1012  }
1013  else
1014  {
1015  $DB->Query("UPDATE Resources SET `"
1016  .$DBFieldName."` = ".intval($NewValue)
1017  ." WHERE ResourceId = ".$ResourceId);
1018  }
1019 
1020  # save value locally
1021  $this->DBFields[$DBFieldName] = $NewValue;
1022  $UpdateModTime = TRUE;
1023  }
1024  break;
1025 
1026 
1028  if ($this->DBFields[$DBFieldName."X"] != $NewValue["X"] ||
1029  $this->DBFields[$DBFieldName."Y"] != $NewValue["Y"] )
1030  {
1031  if (is_null($NewValue))
1032  {
1033  $DB->Query("UPDATE Resources SET "
1034  ."`".$DBFieldName."X` = NULL, "
1035  ."`".$DBFieldName."Y` = NULL "
1036  ."WHERE ResourceId = ".$ResourceId);
1037  $this->DBFields[$DBFieldName."X"] = NULL;
1038  $this->DBFields[$DBFieldName."Y"] = NULL;
1039  }
1040  else
1041  {
1042  $DB->Query("UPDATE Resources SET "
1043  ."`".$DBFieldName."X` = ".(strlen($NewValue["X"])
1044  ? "'".$NewValue["X"]."'" : "NULL").", "
1045  ."`".$DBFieldName."Y` = ".(strlen($NewValue["Y"])
1046  ? "'".$NewValue["Y"]."'" : "NULL")
1047  ." WHERE ResourceId = ".$ResourceId);
1048 
1049  $Digits = $Field->PointDecimalDigits();
1050 
1051  $this->DBFields[$DBFieldName."X"] =
1052  strlen($NewValue["X"]) ? round($NewValue["X"], $Digits) : NULL;
1053  $this->DBFields[$DBFieldName."Y"] =
1054  strlen($NewValue["Y"]) ? round($NewValue["Y"], $Digits) : NULL;
1055  }
1056  $UpdateModTime = TRUE;
1057  }
1058  break;
1059 
1061  if ($this->DBFields[$DBFieldName] != $NewValue)
1062  {
1063  # save value directly to DB
1064  if (is_null($NewValue))
1065  {
1066  $DB->Query("UPDATE Resources SET `"
1067  .$DBFieldName."` = NULL"
1068  ." WHERE ResourceId = ".$ResourceId);
1069  }
1070  else
1071  {
1072  $NewValue = $NewValue ? "1" : "0";
1073  $DB->Query("UPDATE Resources SET `"
1074  .$DBFieldName."` = ".$NewValue
1075  ." WHERE ResourceId = ".$ResourceId);
1076  }
1077 
1078  $this->DBFields[$DBFieldName] = $NewValue;
1079 
1080  # recalculate counts for any associated classifications if necessary
1081  if ($DBFieldName == "ReleaseFlag")
1082  {
1083  $DB->Query("SELECT ClassificationId FROM ResourceClassInts"
1084  ." WHERE ResourceId = ".$ResourceId);
1085  while ($ClassId = $DB->FetchField("ClassificationId"))
1086  {
1087  $Class = new Classification($ClassId);
1088  $Class->RecalcResourceCount();
1089  }
1090  }
1091  $UpdateModTime = TRUE;
1092  }
1093  break;
1094 
1096  # if value passed in was object
1097  if (is_object($NewValue))
1098  {
1099  # retrieve user ID from object
1100  $UserId = $NewValue->Get("UserId");
1101  }
1102  # else if value passed in was user name
1103  elseif (is_string($NewValue) && strlen($NewValue))
1104  {
1105  # create user object and retrieve user ID from there
1106  $User = new CWUser($NewValue);
1107  $UserId = $User->Get("UserId");
1108  }
1109  else
1110  {
1111  # assume value is user ID and use value directly
1112  $UserId = $NewValue;
1113  }
1114 
1115  if ($this->DBFields[$DBFieldName] != $UserId)
1116  {
1117  # save value directly to DB
1118  $DB->Query("UPDATE Resources SET `"
1119  .$DBFieldName."` = '".$UserId."' "
1120  ."WHERE ResourceId = ".$ResourceId);
1121 
1122  # save value locally
1123  $this->DBFields[$DBFieldName] = $UserId;
1124  $UpdateModTime = TRUE;
1125  }
1126  break;
1127 
1129  # if we were given a date object
1130  if (is_object($NewValue))
1131  {
1132  # use supplied date object
1133  $Date = $NewValue;
1134  }
1135  else
1136  {
1137  # create date object
1138  $Date = new Date($NewValue);
1139  }
1140 
1141  $OldDate = new Date(
1142  $this->DBFields[$DBFieldName."Begin"],
1143  $this->DBFields[$DBFieldName."End"]);
1144 
1145  if ($OldDate->BeginDate() != $Date->BeginDate() ||
1146  $OldDate->EndDate() != $Date->EndDate() ||
1147  $OldDate->Precision() != $Date->Precision() )
1148  {
1149  # extract values from date object and store in DB
1150  $BeginDate = "'".$Date->BeginDate()."'";
1151  if (strlen($BeginDate) < 3) { $BeginDate = "NULL"; }
1152  $EndDate = "'".$Date->EndDate()."'";
1153  if (strlen($EndDate) < 3) { $EndDate = "NULL"; }
1154 
1155  $DB->Query("UPDATE Resources SET "
1156  .$DBFieldName."Begin = ".$BeginDate.", "
1157  .$DBFieldName."End = ".$EndDate.", "
1158  .$DBFieldName."Precision = '".$Date->Precision()."' "
1159  ."WHERE ResourceId = ".$ResourceId);
1160 
1161  # save values locally
1162  $this->DBFields[$DBFieldName."Begin"] = $Date->BeginDate();
1163  $this->DBFields[$DBFieldName."End"] = $Date->EndDate();
1164  $this->DBFields[$DBFieldName."Precision"] = $Date->Precision();
1165  $UpdateModTime=TRUE;
1166  }
1167  break;
1168 
1170  if (is_null($NewValue) || !strlen(trim($NewValue)))
1171  {
1172  $DateValue = $NewValue;
1173 
1174  if (!is_null($this->DBFields[$DBFieldName]))
1175  {
1176  # save value directly to DB
1177  $DB->Query("UPDATE Resources SET "
1178  ."`".$DBFieldName."` = NULL "
1179  ."WHERE ResourceId = ".$ResourceId);
1180  $UpdateModTime = TRUE;
1181  }
1182  }
1183  else
1184  {
1185  # assume value is date and use directly
1186  $TimestampValue = strtotime($NewValue);
1187 
1188  # use the new value if the date is valid
1189  if ($TimestampValue !== FALSE && $TimestampValue >= 0)
1190  {
1191  $DateValue = date("Y-m-d H:i:s", $TimestampValue);
1192 
1193  if ($this->DBFields[$DBFieldName] != $DateValue)
1194  {
1195  # save value directly to DB
1196  $DB->Query("UPDATE Resources SET "
1197  ."`".$DBFieldName."` = '".addslashes($DateValue)."' "
1198  ."WHERE ResourceId = ".$ResourceId);
1199  $UpdateModTime=TRUE;
1200  }
1201  }
1202 
1203  # continue using the old value if invalid
1204  else
1205  {
1206  $DateValue = $this->Get($Field);
1207  }
1208  }
1209 
1210  # save value locally
1211  $this->DBFields[$DBFieldName] = $DateValue;
1212  break;
1213 
1215  $OldValue = $this->Get($Field);
1216 
1217  # if incoming value is array
1218  if (is_array($NewValue))
1219  {
1220  if ($OldValue != $NewValue)
1221  {
1222  # for each element of array
1223  foreach ($NewValue as
1224  $ClassificationId => $ClassificationName)
1225  {
1226  $Class = new Classification($ClassificationId);
1227  if ($Class->Status() == Classification::CLASSSTAT_OK)
1228  {
1229  # associate with resource if not already associated
1230  $this->AddAssociation("ResourceClassInts",
1231  "ClassificationId",
1232  $ClassificationId);
1233  $Class->RecalcResourceCount();
1234  }
1235  }
1236  $UpdateModTime=TRUE;
1237  }
1238  }
1239  else
1240  {
1241  # associate with resource if not already associated
1242  if (is_object($NewValue))
1243  {
1244  $Class = $NewValue;
1245  $NewValue = $Class->Id();
1246  }
1247  else
1248  {
1249  $Class = new Classification($NewValue);
1250  }
1251 
1252  if (!array_key_exists($Class->Id(), $OldValue))
1253  {
1254 
1255  $this->AddAssociation("ResourceClassInts",
1256  "ClassificationId",
1257  $NewValue);
1258  $Class->RecalcResourceCount();
1259  $UpdateModTime=TRUE;
1260  }
1261  }
1262 
1263  # clear our classification cache
1264  if ($UpdateModTime)
1265  {
1266  unset($this->ClassificationCache);
1267  }
1268  break;
1269 
1272  $OldValue = $this->Get($Field);
1273 
1274  # Clear other values if this field expects unique options
1275  if ($Field->AllowMultiple() === FALSE)
1276  {
1277  # If we're fed an array for a unique option,
1278  # just use the last element of the array
1279  if (is_array($NewValue)){
1280  $NewValue = array_pop($NewValue);
1281  }
1282 
1283  if (!array_key_exists($NewValue, $OldValue))
1284  {
1285 
1286  $this->RemoveAllAssociations("ResourceNameInts",
1287  "ControlledNameId",
1288  $Field );
1289  $UpdateModTime=TRUE;
1290  }
1291  }
1292 
1293  # if incoming value is array
1294  if (is_array($NewValue) && ($Field->AllowMultiple() !== FALSE) )
1295  {
1296  if ($OldValue != $NewValue)
1297  {
1298  # for each element of array
1299  foreach ($NewValue as $ControlledNameId => $ControlledName)
1300  {
1301  # associate with resource if not already associated
1302  $this->AddAssociation("ResourceNameInts",
1303  "ControlledNameId",
1304  $ControlledNameId);
1305  }
1306  $UpdateModTime=TRUE;
1307  }
1308  }
1309  else
1310  {
1311  # associate with resource if not already associated
1312  if (is_object($NewValue)) { $NewValue = $NewValue->Id(); }
1313  if (!array_key_exists($NewValue, $OldValue))
1314  {
1315  $this->AddAssociation("ResourceNameInts",
1316  "ControlledNameId",
1317  $NewValue);
1318  $UpdateModTime=TRUE;
1319  }
1320  }
1321 
1322  if ($UpdateModTime)
1323  {
1324  # clear our controlled name cache
1325  unset($this->ControlledNameCache);
1326  unset($this->ControlledNameVariantCache);
1327  }
1328 
1329  break;
1330 
1332  # associate value(s) with resource
1333  $this->AddAssociation(
1334  "ResourceImageInts", "ImageId", $NewValue, $Field);
1335  break;
1336 
1338  # convert incoming value to array if necessary
1339  if (!is_array($NewValue)) { $NewValue = array($NewValue); }
1340 
1341  # for each incoming file
1342  $Factory = new FileFactory($Field->Id());
1343  foreach ($NewValue as $File)
1344  {
1345  # make copy of file
1346  $NewFile = $Factory->Copy($File);
1347 
1348  # associate copy with this resource and field
1349  $NewFile->ResourceId($this->Id);
1350  $NewFile->FieldId($Field->Id());
1351  }
1352  # Since we make a fresh copy of the File whenever Set is called,
1353  # we'll always update the modification time for this field.
1354  $UpdateModTime = TRUE;
1355  break;
1356 
1358  # convert incoming value to array to simplify the workflow
1359  if (is_scalar($NewValue) || $NewValue instanceof Resource)
1360  {
1361  $NewValue = array($NewValue);
1362  }
1363 
1364  # delete existing resource references
1365  $this->ClearByField($Field);
1366 
1367  # add each reference
1368  foreach ($NewValue as $ReferenceOrId)
1369  {
1370  # initially issume it's a reference ID and not an object...
1371  $ReferenceId = $ReferenceOrId;
1372 
1373  # ... but get the reference ID if it's an object
1374  if ($ReferenceOrId instanceof Resource)
1375  {
1376  $ReferenceId = $ReferenceOrId->Id();
1377  }
1378 
1379  # skip blank reference IDs
1380  if (strlen(trim($ReferenceId)) < 1)
1381  {
1382  continue;
1383  }
1384 
1385  # skip reference IDs that don't look right
1386  if (!is_numeric($ReferenceId))
1387  {
1388  continue;
1389  }
1390 
1391  # skip references to the current resource
1392  if ($ReferenceId == $this->Id())
1393  {
1394  continue;
1395  }
1396 
1397  # add the reference to the references table
1398  $DB->Query("
1399  INSERT INTO ReferenceInts (
1400  FieldId,
1401  SrcResourceId,
1402  DstResourceId)
1403  VALUES (
1404  ".addslashes($Field->Id()).",
1405  ".addslashes($this->Id()).",
1406  ".addslashes($ReferenceId).")");
1407  }
1408  break;
1409 
1410  default:
1411  # ERROR OUT
1412  exit("<br>SPT - ERROR: attempt to set unknown resource field type<br>\n");
1413  break;
1414  }
1415 
1416  if ($UpdateModTime && !$this->IsTempResource())
1417  {
1418  # update modification timestamps
1419  global $G_User;
1420  $UserId = $G_User->IsLoggedIn() ? $G_User->Get("UserId") : -1;
1421  $DB->Query("DELETE FROM ResourceFieldTimestamps "
1422  ."WHERE ResourceId=".$this->Id." AND "
1423  ."FieldId=".$Field->Id() );
1424  $DB->Query("INSERT INTO ResourceFieldTimestamps "
1425  ."(ResourceId,FieldId,ModifiedBy,Timestamp) VALUES ("
1426  .$this->Id.",".$Field->Id().","
1427  .$UserId.",NOW())");
1428  }
1429  }
1434  function SetByField($Field, $NewValue) { $this->Set($Field, $NewValue); }
1435 
1436  # set value by field ID
1437  function SetByFieldId($FieldId, $NewValue)
1438  {
1439  $Field = $this->Schema->GetField($FieldId);
1440  $this->Set($Field, $NewValue);
1441  }
1442 
1443  # set qualifier by field name
1444  function SetQualifier($FieldName, $NewValue)
1445  {
1446  $Field = $this->Schema->GetFieldByName($FieldName);
1447  $this->SetQualifierByField($Field, $NewValue);
1448  }
1449 
1450  # set qualifier by field ID
1451  function SetQualifierByFieldId($FieldId, $NewValue)
1452  {
1453  $Field = $this->Schema->GetField($FieldId);
1454  $this->SetQualifierByField($Field, $NewValue);
1455  }
1456 
1457  # set qualifier using field object
1458  function SetQualifierByField($Field, $NewValue)
1459  {
1460  # if field uses qualifiers and uses item-level qualifiers
1461  if ($Field->UsesQualifiers() && $Field->HasItemLevelQualifiers())
1462  {
1463  # if qualifier object passed in
1464  if (is_object($NewValue))
1465  {
1466  # grab qualifier ID from object
1467  $QualifierId = $NewValue->Id();
1468  }
1469  else
1470  {
1471  # assume value passed in is qualifier ID
1472  $QualifierId = $NewValue;
1473  }
1474 
1475  # update qualifier value in database
1476  $DBFieldName = $Field->DBFieldName();
1477  $this->DB->Query("UPDATE Resources SET "
1478  .$DBFieldName."Qualifier = '".$QualifierId."' "
1479  ."WHERE ResourceId = ".$this->Id);
1480 
1481  # update local qualifier value
1482  $this->DBFields[$DBFieldName."Qualifier"] = $QualifierId;
1483  }
1484  }
1485 
1486  # clear value by field ID
1487  function ClearByFieldId($FieldId, $ValueToClear = NULL)
1488  {
1489  $Field = $this->Schema->GetField($FieldId);
1490  $this->ClearByField($Field, $ValueToClear);
1491  }
1492 
1493  # clear value using field object
1494  function Clear($Field, $ValueToClear = NULL)
1495  {
1496  # convert field name to object if necessary
1497  if (!is_object($Field))
1498  {
1499  $Field = $this->Schema->GetFieldByName($Field);
1500  }
1501 
1502  # grab commonly-used values for local use
1503  $DB = $this->DB;
1504  $ResourceId = $this->Id;
1505 
1506  # grab database field name
1507  $DBFieldName = $Field->DBFieldName();
1508 
1509  $UpdateModTime=FALSE;
1510 
1511  # store value in DB based on field type
1512  switch ($Field->Type())
1513  {
1521  if (strlen($this->DBFields[$DBFieldName])>0)
1522  {
1523  # clear value in DB
1524  $DB->Query("UPDATE Resources SET `"
1525  .$DBFieldName."` = NULL "
1526  ."WHERE ResourceId = ".$ResourceId);
1527 
1528  # clear value locally
1529  $this->DBFields[$DBFieldName] = NULL;
1530  $UpdateModTime=TRUE;
1531  }
1532  break;
1533 
1535  if (!is_null($this->DBFields[$DBFieldName."X"]) ||
1536  !is_null($this->DBFields[$DBFieldName."Y"]) )
1537  {
1538  # Clear DB Values
1539  $DB->Query("UPDATE Resources SET "
1540  ."`".$DBFieldName."X` = NULL ,"
1541  ."`".$DBFieldName."Y` = NULL "
1542  ."WHERE ResourceId = ".$ResourceId);
1543 
1544  # Clear local values
1545  $this->DBFields[$DBFieldName."X"] = NULL;
1546  $this->DBFields[$DBFieldName."Y"] = NULL;
1547  $UpdateModTime=TRUE;
1548  }
1549  break;
1550 
1552  if (!is_null($this->DBFields[$DBFieldName."Begin"]) ||
1553  !is_null($this->DBFields[$DBFieldName."End"]) ||
1554  !is_null($this->DBFields[$DBFieldName."Precision"]))
1555  {
1556  # clear date object values in DB
1557  $DB->Query("UPDATE Resources SET "
1558  .$DBFieldName."Begin = '', "
1559  .$DBFieldName."End = '', "
1560  .$DBFieldName."Precision = '' "
1561  ."WHERE ResourceId = ".$ResourceId);
1562 
1563  # clear value locally
1564  $this->DBFields[$DBFieldName."Begin"] = NULL;
1565  $this->DBFields[$DBFieldName."End"] = NULL;
1566  $this->DBFields[$DBFieldName."Precision"] = NULL;
1567  $UpdateModTime=TRUE;
1568  }
1569  break;
1570 
1572  $OldValue = $this->Get($Field);
1573 
1574  # if value to clear supplied
1575  if ($ValueToClear !== NULL)
1576  {
1577  # if supplied value is array
1578  if (is_array($ValueToClear))
1579  {
1580  # for each element of array
1581  foreach ($ValueToClear as $ClassificationId => $Dummy)
1582  {
1583  if (array_key_exists($ClassificationId, $OldValue))
1584  {
1585  # remove association with resource (if any)
1586  $this->RemoveAssociation("ResourceClassInts",
1587  "ClassificationId",
1588  $ClassificationId);
1589  $Class = new Classification($ClassificationId);
1590  $Class->RecalcResourceCount();
1591  $UpdateModTime=TRUE;
1592  }
1593  }
1594  }
1595  else
1596  {
1597  if (array_key_exists($ValueToClear, $OldValue))
1598  {
1599  # remove association with resource (if any)
1600  $this->RemoveAssociation("ResourceClassInts",
1601  "ClassificationId",
1602  $ValueToClear);
1603  $Class = new Classification($ValueToClear);
1604  $Class->RecalcResourceCount();
1605  $UpdateModTime=TRUE;
1606  }
1607  }
1608  }
1609  else
1610  {
1611  if (count($OldValue)>0)
1612  {
1613  # remove all associations for resource and field
1614  $this->RemoveAllAssociations("ResourceClassInts", "ClassificationId", $Field);
1615 
1616  # recompute resource count
1617  $Values = $this->Get($Field);
1618  foreach ($Values as $ClassificationId => $Dummy)
1619  {
1620  $Class = new Classification($ClassificationId);
1621  $Class->RecalcResourceCount();
1622  }
1623  $UpdateModTime=TRUE;
1624  }
1625  }
1626 
1627  # clear our classification cache
1628  if ($UpdateModTime)
1629  {
1630  unset($this->ClassificationCache);
1631  }
1632  break;
1633 
1636  $OldValue = $this->Get($Field);
1637  # if value to clear supplied
1638  if ($ValueToClear !== NULL)
1639  {
1640  # if incoming value is array
1641  if (is_array($ValueToClear))
1642  {
1643  # for each element of array
1644  foreach ($ValueToClear as $ControlledNameId =>
1645  $ControlledName)
1646  {
1647  if (array_key_exists($ControlledNameId, $OldValue))
1648  {
1649  # remove association with resource (if any)
1650  $this->RemoveAssociation("ResourceNameInts",
1651  "ControlledNameId",
1652  $ControlledNameId);
1653  $UpdateModTime=TRUE;
1654  }
1655  }
1656  }
1657  else
1658  {
1659  if (array_key_exists($ValueToClear, $OldValue))
1660  {
1661  # remove association with resource (if any)
1662  $this->RemoveAssociation("ResourceNameInts",
1663  "ControlledNameId",
1664  $ValueToClear);
1665  $UpdateModTime=TRUE;
1666  }
1667  }
1668  }
1669  else
1670  {
1671  if (count($OldValue)>0)
1672  {
1673  # remove all associations for resource and field
1674  $this->RemoveAllAssociations("ResourceNameInts", "ControlledNameId", $Field);
1675  $UpdateModTime=TRUE;
1676  }
1677  }
1678 
1679  if ($UpdateModTime)
1680  {
1681  # clear our controlled name cache
1682  unset($this->ControlledNameCache);
1683  unset($this->ControlledNameVariantCache);
1684  }
1685  break;
1686 
1688  # if value to clear supplied
1689  if ($ValueToClear !== NULL)
1690  {
1691  # convert value to array if necessary
1692  $Files = $ValueToClear;
1693  if (!is_array($Files)) { $Files = array($Files); }
1694 
1695  # convert values to objects if necessary
1696  foreach ($Files as $Index => $File)
1697  {
1698  if (!is_object($File))
1699  {
1700  $Files[$Index] = new File($File);
1701  }
1702  }
1703  }
1704  else
1705  {
1706  # use all files associated with resource
1707  $Files = $this->Get($Field, TRUE);
1708  }
1709 
1710  # delete files
1711  foreach ($Files as $File) { $File->Delete(); }
1712  break;
1713 
1715  # if value to clear supplied
1716  if ($ValueToClear !== NULL)
1717  {
1718  # convert value to array if necessary
1719  $Images = $ValueToClear;
1720  if (!is_array($Images)) { $Images = array($Images); }
1721 
1722  # convert values to objects if necessary
1723  foreach ($Images as $Index => $Image)
1724  {
1725  if (!is_object($Image))
1726  {
1727  $Images[$Index] = new SPTImage($Image);
1728  }
1729  }
1730  }
1731  else
1732  {
1733  # use all images associated with resource
1734  $Images = $this->Get($Field, TRUE);
1735  }
1736 
1737  # delete images
1738  foreach ($Images as $Image) { $Image->Delete(); }
1739 
1740  # remove connections to images
1741  $UpdateModTime = $this->RemoveAssociation(
1742  "ResourceImageInts", "ImageId", $Images, $Field);
1743  break;
1744 
1746  # remove references from the references table
1747  $DB->Query("
1748  DELETE FROM ReferenceInts
1749  WHERE FieldId = '".addslashes($Field->Id())."'
1750  AND SrcResourceId = '".addslashes($this->Id())."'");
1751  break;
1752 
1753  default:
1754  # ERROR OUT
1755  exit("<br>SPT - ERROR: attempt to clear unknown resource field type<br>\n");
1756  break;
1757  }
1758 
1759  if ($UpdateModTime && !$this->IsTempResource())
1760  {
1761  # update modification timestamps
1762  global $G_User;
1763  $UserId = $G_User->IsLoggedIn() ? $G_User->Get("UserId") : -1;
1764  $DB->Query("DELETE FROM ResourceFieldTimestamps "
1765  ."WHERE ResourceId=".$this->Id." AND "
1766  ."FieldId=".$Field->Id() );
1767  $DB->Query("INSERT INTO ResourceFieldTimestamps "
1768  ."(ResourceId,FieldId,ModifiedBy,Timestamp) VALUES ("
1769  .$this->Id.",".$Field->Id().","
1770  .$UserId.",NOW())");
1771  }
1772  }
1773  function ClearByField($Field, $ValueToClear = NULL)
1774  { $this->Clear($Field, $ValueToClear); }
1775 
1776 
1777  # --- Field-Specific or Type-Specific Attribute Retrieval Methods -------
1778 
1779  # return 2D array of classifications associated with resource
1780  # (first index is classification (field) name, second index is classification ID)
1781  function Classifications()
1782  {
1783  $DB = $this->DB;
1784 
1785  # start with empty array
1786  $Names = array();
1787 
1788  # for each controlled name
1789  $DB->Query("SELECT ClassificationName, MetadataFields.FieldName, "
1790  ."ResourceClassInts.ClassificationId FROM ResourceClassInts, "
1791  ."Classifications, MetadataFields "
1792  ."WHERE ResourceClassInts.ResourceId = ".$this->Id." "
1793  ."AND ResourceClassInts.ClassificationId = Classifications.ClassificationId "
1794  ."AND Classifications.FieldId = MetadataFields.FieldId ");
1795  while ($Record = $DB->FetchRow())
1796  {
1797  # add name to array
1798  $Names[$Record["FieldName"]][$Record["ClassificationId"]] =
1799  $Record["ClassificationName"];
1800  }
1801 
1802  # return array to caller
1803  return $Names;
1804  }
1805 
1806 
1807  # --- Ratings Methods ---------------------------------------------------
1808 
1809  # return cumulative rating (range is usually 0-100)
1810  function CumulativeRating() { return $this->CumulativeRating; }
1811 
1812  # return cumulative rating scaled to 1/10th (range is usually 0-10)
1814  {
1815  if ($this->CumulativeRating == NULL)
1816  {
1817  return NULL;
1818  }
1819  else
1820  {
1821  return intval(($this->CumulativeRating + 5) / 10);
1822  }
1823  }
1824 
1825  # return current number of ratings for resource
1826  function NumberOfRatings()
1827  {
1828  # if number of ratings not already set
1829  if (!isset($this->NumberOfRatings))
1830  {
1831  # obtain number of ratings
1832  $this->NumberOfRatings =
1833  $this->DB->Query("SELECT Count(*) AS NumberOfRatings "
1834  ."FROM ResourceRatings "
1835  ."WHERE ResourceId = ".$this->Id,
1836  "NumberOfRatings"
1837  );
1838 
1839  # recalculate cumulative rating if it looks erroneous
1840  if (($this->NumberOfRatings > 0) && !$this->CumulativeRating())
1841  {
1842  $this->UpdateCumulativeRating();
1843  }
1844  }
1845 
1846  # return number of ratings to caller
1847  return $this->NumberOfRatings;
1848  }
1849 
1850  # update individual rating for resource
1851  function Rating($NewRating = NULL, $UserId = NULL)
1852  {
1853  $DB = $this->DB;
1854 
1855  # if user ID not supplied
1856  if ($UserId == NULL)
1857  {
1858  # if user is logged in
1859  global $User;
1860  if ($User->IsLoggedIn())
1861  {
1862  # use ID of current user
1863  $UserId = $User->Get("UserId");
1864  }
1865  else
1866  {
1867  # return NULL to caller
1868  return NULL;
1869  }
1870  }
1871 
1872  # sanitize $NewRating
1873  if (!is_null($NewRating))
1874  {
1875  $NewRating = intval($NewRating);
1876  }
1877 
1878  # if there is a rating for resource and user
1879  $DB->Query("SELECT Rating FROM ResourceRatings "
1880  ."WHERE UserId = ${UserId} AND ResourceId = ".$this->Id);
1881  if ($Record = $DB->FetchRow())
1882  {
1883  # if new rating was supplied
1884  if ($NewRating != NULL)
1885  {
1886  # update existing rating
1887  $DB->Query("UPDATE ResourceRatings "
1888  ."SET Rating = ${NewRating}, DateRated = NOW() "
1889  ."WHERE UserId = ${UserId} AND ResourceId = ".$this->Id);
1890 
1891  # update cumulative rating value
1892  $this->UpdateCumulativeRating();
1893 
1894  # return value is new rating
1895  $Rating = $NewRating;
1896  }
1897  else
1898  {
1899  # get rating value to return to caller
1900  $Rating = $Record["Rating"];
1901  }
1902  }
1903  else
1904  {
1905  # if new rating was supplied
1906  if ($NewRating != NULL)
1907  {
1908  # add new rating
1909  $DB->Query("INSERT INTO ResourceRatings "
1910  ."(ResourceId, UserId, DateRated, Rating) "
1911  ."VALUES ("
1912  .$this->Id.", "
1913  ."${UserId}, "
1914  ."NOW(), "
1915  ."${NewRating})");
1916 
1917  # update cumulative rating value
1918  $this->UpdateCumulativeRating();
1919 
1920  # return value is new rating
1921  $Rating = $NewRating;
1922  }
1923  else
1924  {
1925  # return value is NULL
1926  $Rating = NULL;
1927  }
1928  }
1929 
1930  # return rating value to caller
1931  return $Rating;
1932  }
1933 
1934 
1935  # --- Resource Comment Methods ------------------------------------------
1936 
1937  # return comments as array of Message objects
1938  function Comments()
1939  {
1940  # read in comments if not already loaded
1941  if (!isset($this->Comments))
1942  {
1943  $this->DB->Query("SELECT MessageId FROM Messages "
1944  ."WHERE ParentId = ".$this->Id
1945  ." AND ParentType = 2 "
1946  ."ORDER BY DatePosted DESC");
1947  while ($MessageId = $this->DB->FetchField("MessageId"))
1948  {
1949  $this->Comments[] = new Message($MessageId);
1950  }
1951  }
1952 
1953  # return array of comments to caller
1954  return $this->Comments;
1955  }
1956 
1957  # return current number of comments
1958  function NumberOfComments()
1959  {
1960  # obtain number of comments if not already set
1961  if (!isset($this->NumberOfComments))
1962  {
1963  $this->NumberOfComments =
1964  $this->DB->Query("SELECT Count(*) AS NumberOfComments "
1965  ."FROM Messages "
1966  ."WHERE ParentId = ".$this->Id
1967  ." AND ParentType = 2",
1968  "NumberOfComments"
1969  );
1970  }
1971 
1972  # return number of comments to caller
1973  return $this->NumberOfComments;
1974  }
1975 
1976 
1977  # --- Permission Methods -------------------------------------------------
1978 
1986  function UserCanView(User $User)
1987  {
1988  # cannot view a resource that is not valid
1989  if ($this->Status() !== 1) { return FALSE; }
1990 
1991  # get viewing privilege set for resource
1992  $Schema = new MetadataSchema($this->SchemaId());
1993  $ResourcePrivs = $Schema->ViewingPrivileges();
1994 
1995  # get privilege set for user
1996  $UserPrivs = $User->Privileges();
1997 
1998  # user can view if privileges are greater than resource set
1999  $CanView = $UserPrivs->IsGreaterThan($ResourcePrivs, $this);
2000 
2001  # allow plugins to modify result of the permission check
2002  $SignalResult = $GLOBALS["AF"]->SignalEvent(
2003  "EVENT_RESOURCE_VIEW_PERMISSION_CHECK",
2004  array("Resource" => $this, "User" => $User, "CanView" => $CanView));
2005  $CanView = $SignalResult["CanView"];
2006 
2007  return $CanView;
2008  }
2009 
2016  function UserCanEdit($User)
2017  {
2018  # cannot edit a resource that you cannot view
2019  if (!$this->UserCanView($User)) { return FALSE; }
2020 
2021  # get editing privilege set for resource
2022  $Schema = new MetadataSchema($this->SchemaId());
2023  $ResourcePrivs = $Schema->EditingPrivileges();
2024 
2025  # get privilege set for user
2026  $UserPrivs = $User->Privileges();
2027 
2028  # user can edit if privileges are greater than resource set
2029  $CanEdit = $UserPrivs->IsGreaterThan($ResourcePrivs, $this);
2030 
2031  # allow plugins to modify result of permission check
2032  $SignalResult = $GLOBALS["AF"]->SignalEvent(
2033  "EVENT_RESOURCE_EDIT_PERMISSION_CHECK", array(
2034  "Resource" => $this,
2035  "User" => $User,
2036  "CanEdit" => $CanEdit));
2037  $CanEdit = $SignalResult["CanEdit"];
2038 
2039  # report back to caller whether user can edit field
2040  return $CanEdit;
2041  }
2042 
2049  function UserCanViewField($User, $FieldOrFieldName)
2050  {
2051  # get field object (if not supplied)
2052  $Field = is_object($FieldOrFieldName) ? $FieldOrFieldName
2053  : $this->Schema->GetFieldByName($FieldOrFieldName);
2054 
2055  # field absolutely cannot be viewed if it is not valid
2056  if (!($Field instanceof MetadataField)) { return FALSE; }
2057 
2058  # field should not be viewed if it is disabled
2059  if (!$Field->Enabled())
2060  {
2061  $CanView = FALSE;
2062  }
2063  else
2064  {
2065  # if the user can edit the field they can also view it
2066  if ($this->UserCanEditField($User, $Field))
2067  {
2068  $CanView = TRUE;
2069  }
2070  else
2071  {
2072  # get appropriate privilege set for field
2073  $FieldPrivs = $Field->ViewingPrivileges();
2074 
2075  # get privilege set for user
2076  $UserPrivs = $User->Privileges();
2077 
2078  # user can view if privileges are greater than field set
2079  $CanView = $UserPrivs->IsGreaterThan($FieldPrivs, $this);
2080  }
2081  }
2082 
2083  # allow plugins to modify result of permission check
2084  $SignalResult = $GLOBALS["AF"]->SignalEvent(
2085  "EVENT_FIELD_VIEW_PERMISSION_CHECK", array(
2086  "Field" => $Field,
2087  "Resource" => $this,
2088  "User" => $User,
2089  "CanView" => $CanView));
2090  $CanView = $SignalResult["CanView"];
2091 
2092  # report back to caller whether user can view field
2093  return $CanView;
2094  }
2095 
2102  function UserCanAuthorField($User, $FieldOrFieldName)
2103  {
2104  # fields hard-coded to not be authorable
2105  $UnauthorableFields = array(
2106  "Cumulative Rating",
2107  "Date Of Record Creation",
2108  "Date Of Record Release",
2109  "Date Last Modified",
2110  "Last Modified By Id");
2111 
2112  # get field object (if not supplied)
2113  $Field = is_object($FieldOrFieldName) ? $FieldOrFieldName
2114  : $this->Schema->GetFieldByName($FieldOrFieldName);
2115 
2116  # field absolutely cannot be authored if it is not valid
2117  if (!($Field instanceof MetadataField)) { return FALSE; }
2118 
2119  # field should not be authored if it is disabled or is on "no author" list
2120  # or user is not the resource creator
2121  if (!$Field->Enabled()
2122  || in_array($Field->Name(), $UnauthorableFields)
2123  || ($User->Name() != $this->Get("Added By Id")))
2124  {
2125  $CanAuthor = FALSE;
2126  }
2127  else
2128  {
2129  # get appropriate privilege set for field
2130  $FieldPrivs = $Field->AuthoringPrivileges();
2131 
2132  # get privilege set for user
2133  $UserPrivs = $User->Privileges();
2134 
2135  # user can author if privileges are greater than field set
2136  $CanAuthor = $UserPrivs->IsGreaterThan($FieldPrivs, $this);
2137  }
2138 
2139  # allow plugins to modify result of permission check
2140  $SignalResult = $GLOBALS["AF"]->SignalEvent(
2141  "EVENT_FIELD_AUTHOR_PERMISSION_CHECK", array(
2142  "Field" => $Field,
2143  "Resource" => $this,
2144  "User" => $User,
2145  "CanAuthor" => $CanAuthor));
2146  $CanAuthor = $SignalResult["CanAuthor"];
2147 
2148  # report back to caller whether user can author field
2149  return $CanAuthor;
2150  }
2151 
2158  function UserCanEditField($User, $FieldOrFieldName)
2159  {
2160  # fields hard-coded to not be editable
2161  $UneditableFields = array(
2162  "Cumulative Rating",
2163  "Date Of Record Creation",
2164  "Date Of Record Release",
2165  "Date Last Modified",
2166  "Last Modified By Id");
2167 
2168  # get field object (if not supplied)
2169  $Field = is_object($FieldOrFieldName) ? $FieldOrFieldName
2170  : $this->Schema->GetFieldByName($FieldOrFieldName);
2171 
2172  # field absolutely cannot be edited if it is not valid
2173  if (!($Field instanceof MetadataField)) { return FALSE; }
2174 
2175  # field should not be edited if it is disabled or is on "no edit" list
2176  if (!$Field->Enabled() || in_array($Field->Name(), $UneditableFields))
2177  {
2178  $CanEdit = FALSE;
2179  }
2180  else
2181  {
2182  # get appropriate privilege set for field
2183  $FieldPrivs = $Field->EditingPrivileges();
2184 
2185  # get privilege set for user
2186  $UserPrivs = $User->Privileges();
2187 
2188  # user can edit if privileges are greater than field set
2189  $CanEdit = $UserPrivs->IsGreaterThan($FieldPrivs, $this);
2190  }
2191 
2192  # allow plugins to modify result of permission check
2193  $SignalResult = $GLOBALS["AF"]->SignalEvent(
2194  "EVENT_FIELD_EDIT_PERMISSION_CHECK", array(
2195  "Field" => $Field,
2196  "Resource" => $this,
2197  "User" => $User,
2198  "CanEdit" => $CanEdit));
2199  $CanEdit = $SignalResult["CanEdit"];
2200 
2201  # report back to caller whether user can edit field
2202  return $CanEdit;
2203  }
2204 
2205  # ---- PRIVATE INTERFACE -------------------------------------------------
2206 
2207  private $DB;
2208  private $Schema;
2209  private $DBFields;
2210  private $Id;
2211  private $NumberOfRatings;
2212  private $CumulativeRating;
2213  private $NumberOfComments;
2214  private $Comments;
2215  private $LastStatus;
2216  private $ControlledNameCache;
2217  private $ControlledNameVariantCache;
2218  private $ClassificationCache;
2219 
2220  # recalculate and save cumulative rating value for resource
2221  private function UpdateCumulativeRating()
2222  {
2223  # grab totals from DB
2224  $this->DB->Query("SELECT COUNT(Rating) AS Count, "
2225  ."SUM(Rating) AS Total FROM ResourceRatings "
2226  ."WHERE ResourceId = ".$this->Id);
2227  $Record = $this->DB->FetchRow();
2228 
2229  # calculate new cumulative rating
2230  $this->CumulativeRating = round($Record["Total"] / $Record["Count"]);
2231 
2232  # save new cumulative rating in DB
2233  $this->DB->Query("UPDATE Resources "
2234  ."SET CumulativeRating = ".$this->CumulativeRating." "
2235  ."WHERE ResourceId = ".$this->Id);
2236  }
2237 
2248  private function AddAssociation($TableName, $FieldName, $Value, $Field = NULL)
2249  {
2250  # start out assuming no association will be added
2251  $AssociationAdded = FALSE;
2252 
2253  # convert new value to array if necessary
2254  $Values = is_array($Value) ? $Value : array($Value);
2255 
2256  # for each new value
2257  foreach ($Values as $Value)
2258  {
2259  # retrieve ID from value if necessary
2260  if (is_object($Value)) { $Value = $Value->Id(); }
2261 
2262  # if value is not already associated with resource
2263  if ($this->DB->Query("SELECT COUNT(*) AS RecordCount FROM ".$TableName
2264  ." WHERE ResourceId = ".$this->Id
2265  ." AND ".$FieldName." = ".intval($Value)
2266  .($Field ? " AND FieldId = ".intval($Field->Id()) : ""),
2267  "RecordCount") == 0)
2268  {
2269  # associate value with resource
2270  $this->DB->Query("INSERT INTO ".$TableName." SET"
2271  ." ResourceId = ".intval($this->Id)
2272  .", ".$FieldName." = ".intval($Value)
2273  .($Field ? ", FieldId = ".intval($Field->Id()) : ""));
2274  $AssociationAdded = TRUE;
2275  }
2276  }
2277 
2278  # report to caller whether association was added
2279  return $AssociationAdded;
2280  }
2281 
2292  private function RemoveAssociation($TableName, $FieldName, $Value, $Field = NULL)
2293  {
2294  # start out assuming no association will be removed
2295  $AssociationRemoved = FALSE;
2296 
2297  # convert value to array if necessary
2298  $Values = is_array($Value) ? $Value : array($Value);
2299 
2300  # for each value
2301  foreach ($Values as $Value)
2302  {
2303  # retrieve ID from value if necessary
2304  if (is_object($Value)) { $Value = $Value->Id(); }
2305 
2306  # remove any intersections with target ID from DB
2307  $this->DB->Query("DELETE FROM ".$TableName
2308  ." WHERE ResourceId = ".intval($this->Id)
2309  .($Field ? " AND FieldId = ".intval($Field->Id()) : "")
2310  ." AND ".$FieldName." = ".intval($Value));
2311  }
2312 
2313  # report to caller whether association was added
2314  return $AssociationRemoved;
2315  }
2316 
2317  # remove all intersections for resource and field (if any)
2318  private function RemoveAllAssociations($TableName, $TargetFieldName, $Field)
2319  {
2320  # retrieve list of entries for this field and resource
2321  $Entries = $this->Get($Field);
2322 
2323  # for each entry
2324  foreach ($Entries as $EntryId => $EntryName)
2325  {
2326  # remove intersection
2327  $this->RemoveAssociation($TableName, $TargetFieldName, $EntryId);
2328  }
2329  }
2330 }
GetByField($FieldNameOrObject, $ReturnObject=FALSE, $IncludeVariants=FALSE)
Old method for retrieving values, deprecated in favor of Get().
Definition: Resource.php:640
GetFilesForResource($ResourceOrResourceId, $ReturnObjects=TRUE)
Retrieve all files (names or objects) for specified resource.
Definition: FileFactory.php:38
Set($FieldNameOrObject, $NewValue)
Set value using field name or field object.
Definition: Resource.php:965
SetQualifier($FieldName, $NewValue)
Definition: Resource.php:1444
Metadata schema (in effect a Factory class for MetadataField).
Resource($ResourceId)
Object constructor for loading an existing resource.
Definition: Resource.php:23
Abstraction for forum messages and resource comments.
Definition: Message.php:15
SQL database abstraction object with smart query caching.
GetAsArray($IncludeDisabledFields=FALSE, $ReturnObjects=TRUE)
Retrieve all resource values as an array.
Definition: Resource.php:675
Id()
Retrieve numerical resource ID.
Definition: Resource.php:252
UserCanEditField($User, $FieldOrFieldName)
Check whether user is allowed to edit specified metadata field.
Definition: Resource.php:2158
SetQualifierByField($Field, $NewValue)
Definition: Resource.php:1458
Rating($NewRating=NULL, $UserId=NULL)
Definition: Resource.php:1851
Status()
Retrieve result of last operation if available.
Definition: Resource.php:246
NumberOfComments()
Definition: Resource.php:1958
NumberOfRatings()
Definition: Resource.php:1826
GetQualifier($FieldName, $ReturnObject=TRUE)
Retrieve qualifier by field name.
Definition: Resource.php:737
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:2016
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:751
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:2102
UserCanView(User $User)
Determine if the given user can view the resource, e.g., on the full record page. ...
Definition: Resource.php:1986
Clear($Field, $ValueToClear=NULL)
Definition: Resource.php:1494
GetByFieldId($FieldId, $ReturnObject=FALSE, $IncludeVariants=FALSE)
Retrieve value using field ID.
Definition: Resource.php:657
IsTempResource($NewSetting=NULL)
Get/set whether resource is a temporary record.
Definition: Resource.php:266
Get($FieldNameOrObject, $ReturnObject=FALSE, $IncludeVariants=FALSE)
Retrieve value using field name or field object.
Definition: Resource.php:344
SetByField($Field, $NewValue)
Method replaced by Resource::Set(), preserved for backward compatibility.
Definition: Resource.php:1434
Object representing a locally-defined type of metadata field.
GetMapped($MappedName, $ReturnObject=FALSE, $IncludeVariants=FALSE)
Retrieve value using standard (mapped) field name.
Definition: Resource.php:721
Represents a &quot;resource&quot; in CWIS.
Definition: Resource.php:13
GetQualifierByField($Field, $ReturnObject=TRUE)
Retrieve qualifier by Field object.
Definition: Resource.php:765
ClearByFieldId($FieldId, $ValueToClear=NULL)
Definition: Resource.php:1487
const CLASSSTAT_OK
Status code indicating operation completed successfully.
SetQualifierByFieldId($FieldId, $NewValue)
Definition: Resource.php:1451
SchemaId()
Retrieve ID of schema for resource.
Definition: Resource.php:258
ScaledCumulativeRating()
Definition: Resource.php:1813
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:2049
Metadata type representing hierarchical (&quot;Tree&quot;) controlled vocabulary values.
SetByFieldId($FieldId, $NewValue)
Definition: Resource.php:1437
Classifications()
Definition: Resource.php:1781
ClearByField($Field, $ValueToClear=NULL)
Definition: Resource.php:1773
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:1810
FieldIsSet($FieldNameOrObject, $IgnorePadding=FALSE)
Determine if the value for a field is set.
Definition: Resource.php:896
Delete()
Remove resource (and accompanying associations) from database and delete any associated files...
Definition: Resource.php:139