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 if we are the last resource referencing
1738  # a particular image.
1739  foreach ($Images as $Image) {
1740  $Cnt = $this->DB->Query(
1741  "SELECT COUNT(*) AS Cnt FROM ResourceImageInts WHERE ".
1742  "ImageId=".$Image->Id(), "Cnt");
1743  if ($Cnt==1)
1744  $Image->Delete();
1745  }
1746 
1747  # remove connections to images
1748  $UpdateModTime = $this->RemoveAssociation(
1749  "ResourceImageInts", "ImageId", $Images, $Field);
1750  break;
1751 
1753  # remove references from the references table
1754  $DB->Query("
1755  DELETE FROM ReferenceInts
1756  WHERE FieldId = '".addslashes($Field->Id())."'
1757  AND SrcResourceId = '".addslashes($this->Id())."'");
1758  break;
1759 
1760  default:
1761  # ERROR OUT
1762  exit("<br>SPT - ERROR: attempt to clear unknown resource field type<br>\n");
1763  break;
1764  }
1765 
1766  if ($UpdateModTime && !$this->IsTempResource())
1767  {
1768  # update modification timestamps
1769  global $G_User;
1770  $UserId = $G_User->IsLoggedIn() ? $G_User->Get("UserId") : -1;
1771  $DB->Query("DELETE FROM ResourceFieldTimestamps "
1772  ."WHERE ResourceId=".$this->Id." AND "
1773  ."FieldId=".$Field->Id() );
1774  $DB->Query("INSERT INTO ResourceFieldTimestamps "
1775  ."(ResourceId,FieldId,ModifiedBy,Timestamp) VALUES ("
1776  .$this->Id.",".$Field->Id().","
1777  .$UserId.",NOW())");
1778  }
1779  }
1780  function ClearByField($Field, $ValueToClear = NULL)
1781  { $this->Clear($Field, $ValueToClear); }
1782 
1783 
1784  # --- Field-Specific or Type-Specific Attribute Retrieval Methods -------
1785 
1786  # return 2D array of classifications associated with resource
1787  # (first index is classification (field) name, second index is classification ID)
1788  function Classifications()
1789  {
1790  $DB = $this->DB;
1791 
1792  # start with empty array
1793  $Names = array();
1794 
1795  # for each controlled name
1796  $DB->Query("SELECT ClassificationName, MetadataFields.FieldName, "
1797  ."ResourceClassInts.ClassificationId FROM ResourceClassInts, "
1798  ."Classifications, MetadataFields "
1799  ."WHERE ResourceClassInts.ResourceId = ".$this->Id." "
1800  ."AND ResourceClassInts.ClassificationId = Classifications.ClassificationId "
1801  ."AND Classifications.FieldId = MetadataFields.FieldId ");
1802  while ($Record = $DB->FetchRow())
1803  {
1804  # add name to array
1805  $Names[$Record["FieldName"]][$Record["ClassificationId"]] =
1806  $Record["ClassificationName"];
1807  }
1808 
1809  # return array to caller
1810  return $Names;
1811  }
1812 
1813 
1814  # --- Ratings Methods ---------------------------------------------------
1815 
1816  # return cumulative rating (range is usually 0-100)
1817  function CumulativeRating() { return $this->CumulativeRating; }
1818 
1819  # return cumulative rating scaled to 1/10th (range is usually 0-10)
1821  {
1822  if ($this->CumulativeRating == NULL)
1823  {
1824  return NULL;
1825  }
1826  else
1827  {
1828  return intval(($this->CumulativeRating + 5) / 10);
1829  }
1830  }
1831 
1832  # return current number of ratings for resource
1833  function NumberOfRatings()
1834  {
1835  # if number of ratings not already set
1836  if (!isset($this->NumberOfRatings))
1837  {
1838  # obtain number of ratings
1839  $this->NumberOfRatings =
1840  $this->DB->Query("SELECT Count(*) AS NumberOfRatings "
1841  ."FROM ResourceRatings "
1842  ."WHERE ResourceId = ".$this->Id,
1843  "NumberOfRatings"
1844  );
1845 
1846  # recalculate cumulative rating if it looks erroneous
1847  if (($this->NumberOfRatings > 0) && !$this->CumulativeRating())
1848  {
1849  $this->UpdateCumulativeRating();
1850  }
1851  }
1852 
1853  # return number of ratings to caller
1854  return $this->NumberOfRatings;
1855  }
1856 
1857  # update individual rating for resource
1858  function Rating($NewRating = NULL, $UserId = NULL)
1859  {
1860  $DB = $this->DB;
1861 
1862  # if user ID not supplied
1863  if ($UserId == NULL)
1864  {
1865  # if user is logged in
1866  global $User;
1867  if ($User->IsLoggedIn())
1868  {
1869  # use ID of current user
1870  $UserId = $User->Get("UserId");
1871  }
1872  else
1873  {
1874  # return NULL to caller
1875  return NULL;
1876  }
1877  }
1878 
1879  # sanitize $NewRating
1880  if (!is_null($NewRating))
1881  {
1882  $NewRating = intval($NewRating);
1883  }
1884 
1885  # if there is a rating for resource and user
1886  $DB->Query("SELECT Rating FROM ResourceRatings "
1887  ."WHERE UserId = ${UserId} AND ResourceId = ".$this->Id);
1888  if ($Record = $DB->FetchRow())
1889  {
1890  # if new rating was supplied
1891  if ($NewRating != NULL)
1892  {
1893  # update existing rating
1894  $DB->Query("UPDATE ResourceRatings "
1895  ."SET Rating = ${NewRating}, DateRated = NOW() "
1896  ."WHERE UserId = ${UserId} AND ResourceId = ".$this->Id);
1897 
1898  # update cumulative rating value
1899  $this->UpdateCumulativeRating();
1900 
1901  # return value is new rating
1902  $Rating = $NewRating;
1903  }
1904  else
1905  {
1906  # get rating value to return to caller
1907  $Rating = $Record["Rating"];
1908  }
1909  }
1910  else
1911  {
1912  # if new rating was supplied
1913  if ($NewRating != NULL)
1914  {
1915  # add new rating
1916  $DB->Query("INSERT INTO ResourceRatings "
1917  ."(ResourceId, UserId, DateRated, Rating) "
1918  ."VALUES ("
1919  .$this->Id.", "
1920  ."${UserId}, "
1921  ."NOW(), "
1922  ."${NewRating})");
1923 
1924  # update cumulative rating value
1925  $this->UpdateCumulativeRating();
1926 
1927  # return value is new rating
1928  $Rating = $NewRating;
1929  }
1930  else
1931  {
1932  # return value is NULL
1933  $Rating = NULL;
1934  }
1935  }
1936 
1937  # return rating value to caller
1938  return $Rating;
1939  }
1940 
1941 
1942  # --- Resource Comment Methods ------------------------------------------
1943 
1944  # return comments as array of Message objects
1945  function Comments()
1946  {
1947  # read in comments if not already loaded
1948  if (!isset($this->Comments))
1949  {
1950  $this->DB->Query("SELECT MessageId FROM Messages "
1951  ."WHERE ParentId = ".$this->Id
1952  ." AND ParentType = 2 "
1953  ."ORDER BY DatePosted DESC");
1954  while ($MessageId = $this->DB->FetchField("MessageId"))
1955  {
1956  $this->Comments[] = new Message($MessageId);
1957  }
1958  }
1959 
1960  # return array of comments to caller
1961  return $this->Comments;
1962  }
1963 
1964  # return current number of comments
1965  function NumberOfComments()
1966  {
1967  # obtain number of comments if not already set
1968  if (!isset($this->NumberOfComments))
1969  {
1970  $this->NumberOfComments =
1971  $this->DB->Query("SELECT Count(*) AS NumberOfComments "
1972  ."FROM Messages "
1973  ."WHERE ParentId = ".$this->Id
1974  ." AND ParentType = 2",
1975  "NumberOfComments"
1976  );
1977  }
1978 
1979  # return number of comments to caller
1980  return $this->NumberOfComments;
1981  }
1982 
1983 
1984  # --- Permission Methods -------------------------------------------------
1985 
1993  function UserCanView(User $User)
1994  {
1995  # cannot view a resource that is not valid
1996  if ($this->Status() !== 1) { return FALSE; }
1997 
1998  # get viewing privilege set for resource
1999  $Schema = new MetadataSchema($this->SchemaId());
2000  $ResourcePrivs = $Schema->ViewingPrivileges();
2001 
2002  # get privilege set for user
2003  $UserPrivs = $User->Privileges();
2004 
2005  # user can view if privileges are greater than resource set
2006  $CanView = $UserPrivs->IsGreaterThan($ResourcePrivs, $this);
2007 
2008  # allow plugins to modify result of the permission check
2009  $SignalResult = $GLOBALS["AF"]->SignalEvent(
2010  "EVENT_RESOURCE_VIEW_PERMISSION_CHECK",
2011  array("Resource" => $this, "User" => $User, "CanView" => $CanView));
2012  $CanView = $SignalResult["CanView"];
2013 
2014  return $CanView;
2015  }
2016 
2023  function UserCanEdit($User)
2024  {
2025  # cannot edit a resource that you cannot view
2026  if (!$this->UserCanView($User)) { return FALSE; }
2027 
2028  # get editing privilege set for resource
2029  $Schema = new MetadataSchema($this->SchemaId());
2030  $ResourcePrivs = $Schema->EditingPrivileges();
2031 
2032  # get privilege set for user
2033  $UserPrivs = $User->Privileges();
2034 
2035  # user can edit if privileges are greater than resource set
2036  $CanEdit = $UserPrivs->IsGreaterThan($ResourcePrivs, $this);
2037 
2038  # allow plugins to modify result of permission check
2039  $SignalResult = $GLOBALS["AF"]->SignalEvent(
2040  "EVENT_RESOURCE_EDIT_PERMISSION_CHECK", array(
2041  "Resource" => $this,
2042  "User" => $User,
2043  "CanEdit" => $CanEdit));
2044  $CanEdit = $SignalResult["CanEdit"];
2045 
2046  # report back to caller whether user can edit field
2047  return $CanEdit;
2048  }
2049 
2056  function UserCanViewField($User, $FieldOrFieldName)
2057  {
2058  # get field object (if not supplied)
2059  $Field = is_object($FieldOrFieldName) ? $FieldOrFieldName
2060  : $this->Schema->GetFieldByName($FieldOrFieldName);
2061 
2062  # field absolutely cannot be viewed if it is not valid
2063  if (!($Field instanceof MetadataField)) { return FALSE; }
2064 
2065  # field should not be viewed if it is disabled
2066  if (!$Field->Enabled())
2067  {
2068  $CanView = FALSE;
2069  }
2070  else
2071  {
2072  # if the user can edit the field they can also view it
2073  if ($this->UserCanEditField($User, $Field))
2074  {
2075  $CanView = TRUE;
2076  }
2077  else
2078  {
2079  # get appropriate privilege set for field
2080  $FieldPrivs = $Field->ViewingPrivileges();
2081 
2082  # get privilege set for user
2083  $UserPrivs = $User->Privileges();
2084 
2085  # user can view if privileges are greater than field set
2086  $CanView = $UserPrivs->IsGreaterThan($FieldPrivs, $this);
2087  }
2088  }
2089 
2090  # allow plugins to modify result of permission check
2091  $SignalResult = $GLOBALS["AF"]->SignalEvent(
2092  "EVENT_FIELD_VIEW_PERMISSION_CHECK", array(
2093  "Field" => $Field,
2094  "Resource" => $this,
2095  "User" => $User,
2096  "CanView" => $CanView));
2097  $CanView = $SignalResult["CanView"];
2098 
2099  # report back to caller whether user can view field
2100  return $CanView;
2101  }
2102 
2109  function UserCanAuthorField($User, $FieldOrFieldName)
2110  {
2111  # fields hard-coded to not be authorable
2112  $UnauthorableFields = array(
2113  "Cumulative Rating",
2114  "Date Of Record Creation",
2115  "Date Of Record Release",
2116  "Date Last Modified",
2117  "Last Modified By Id");
2118 
2119  # get field object (if not supplied)
2120  $Field = is_object($FieldOrFieldName) ? $FieldOrFieldName
2121  : $this->Schema->GetFieldByName($FieldOrFieldName);
2122 
2123  # field absolutely cannot be authored if it is not valid
2124  if (!($Field instanceof MetadataField)) { return FALSE; }
2125 
2126  # field should not be authored if it is disabled or is on "no author" list
2127  # or user is not the resource creator
2128  if (!$Field->Enabled()
2129  || in_array($Field->Name(), $UnauthorableFields)
2130  || ($User->Name() != $this->Get("Added By Id")))
2131  {
2132  $CanAuthor = FALSE;
2133  }
2134  else
2135  {
2136  # get appropriate privilege set for field
2137  $FieldPrivs = $Field->AuthoringPrivileges();
2138 
2139  # get privilege set for user
2140  $UserPrivs = $User->Privileges();
2141 
2142  # user can author if privileges are greater than field set
2143  $CanAuthor = $UserPrivs->IsGreaterThan($FieldPrivs, $this);
2144  }
2145 
2146  # allow plugins to modify result of permission check
2147  $SignalResult = $GLOBALS["AF"]->SignalEvent(
2148  "EVENT_FIELD_AUTHOR_PERMISSION_CHECK", array(
2149  "Field" => $Field,
2150  "Resource" => $this,
2151  "User" => $User,
2152  "CanAuthor" => $CanAuthor));
2153  $CanAuthor = $SignalResult["CanAuthor"];
2154 
2155  # report back to caller whether user can author field
2156  return $CanAuthor;
2157  }
2158 
2165  function UserCanEditField($User, $FieldOrFieldName)
2166  {
2167  # fields hard-coded to not be editable
2168  $UneditableFields = array(
2169  "Cumulative Rating",
2170  "Date Of Record Creation",
2171  "Date Of Record Release",
2172  "Date Last Modified",
2173  "Last Modified By Id");
2174 
2175  # get field object (if not supplied)
2176  $Field = is_object($FieldOrFieldName) ? $FieldOrFieldName
2177  : $this->Schema->GetFieldByName($FieldOrFieldName);
2178 
2179  # field absolutely cannot be edited if it is not valid
2180  if (!($Field instanceof MetadataField)) { return FALSE; }
2181 
2182  # field should not be edited if it is disabled or is on "no edit" list
2183  if (!$Field->Enabled() || in_array($Field->Name(), $UneditableFields))
2184  {
2185  $CanEdit = FALSE;
2186  }
2187  else
2188  {
2189  # get appropriate privilege set for field
2190  $FieldPrivs = $Field->EditingPrivileges();
2191 
2192  # get privilege set for user
2193  $UserPrivs = $User->Privileges();
2194 
2195  # user can edit if privileges are greater than field set
2196  $CanEdit = $UserPrivs->IsGreaterThan($FieldPrivs, $this);
2197  }
2198 
2199  # allow plugins to modify result of permission check
2200  $SignalResult = $GLOBALS["AF"]->SignalEvent(
2201  "EVENT_FIELD_EDIT_PERMISSION_CHECK", array(
2202  "Field" => $Field,
2203  "Resource" => $this,
2204  "User" => $User,
2205  "CanEdit" => $CanEdit));
2206  $CanEdit = $SignalResult["CanEdit"];
2207 
2208  # report back to caller whether user can edit field
2209  return $CanEdit;
2210  }
2211 
2212  # ---- PRIVATE INTERFACE -------------------------------------------------
2213 
2214  private $DB;
2215  private $Schema;
2216  private $DBFields;
2217  private $Id;
2218  private $NumberOfRatings;
2219  private $CumulativeRating;
2220  private $NumberOfComments;
2221  private $Comments;
2222  private $LastStatus;
2223  private $ControlledNameCache;
2224  private $ControlledNameVariantCache;
2225  private $ClassificationCache;
2226 
2227  # recalculate and save cumulative rating value for resource
2228  private function UpdateCumulativeRating()
2229  {
2230  # grab totals from DB
2231  $this->DB->Query("SELECT COUNT(Rating) AS Count, "
2232  ."SUM(Rating) AS Total FROM ResourceRatings "
2233  ."WHERE ResourceId = ".$this->Id);
2234  $Record = $this->DB->FetchRow();
2235 
2236  # calculate new cumulative rating
2237  $this->CumulativeRating = round($Record["Total"] / $Record["Count"]);
2238 
2239  # save new cumulative rating in DB
2240  $this->DB->Query("UPDATE Resources "
2241  ."SET CumulativeRating = ".$this->CumulativeRating." "
2242  ."WHERE ResourceId = ".$this->Id);
2243  }
2244 
2255  private function AddAssociation($TableName, $FieldName, $Value, $Field = NULL)
2256  {
2257  # start out assuming no association will be added
2258  $AssociationAdded = FALSE;
2259 
2260  # convert new value to array if necessary
2261  $Values = is_array($Value) ? $Value : array($Value);
2262 
2263  # for each new value
2264  foreach ($Values as $Value)
2265  {
2266  # retrieve ID from value if necessary
2267  if (is_object($Value)) { $Value = $Value->Id(); }
2268 
2269  # if value is not already associated with resource
2270  if ($this->DB->Query("SELECT COUNT(*) AS RecordCount FROM ".$TableName
2271  ." WHERE ResourceId = ".$this->Id
2272  ." AND ".$FieldName." = ".intval($Value)
2273  .($Field ? " AND FieldId = ".intval($Field->Id()) : ""),
2274  "RecordCount") == 0)
2275  {
2276  # associate value with resource
2277  $this->DB->Query("INSERT INTO ".$TableName." SET"
2278  ." ResourceId = ".intval($this->Id)
2279  .", ".$FieldName." = ".intval($Value)
2280  .($Field ? ", FieldId = ".intval($Field->Id()) : ""));
2281  $AssociationAdded = TRUE;
2282  }
2283  }
2284 
2285  # report to caller whether association was added
2286  return $AssociationAdded;
2287  }
2288 
2299  private function RemoveAssociation($TableName, $FieldName, $Value, $Field = NULL)
2300  {
2301  # start out assuming no association will be removed
2302  $AssociationRemoved = FALSE;
2303 
2304  # convert value to array if necessary
2305  $Values = is_array($Value) ? $Value : array($Value);
2306 
2307  # for each value
2308  foreach ($Values as $Value)
2309  {
2310  # retrieve ID from value if necessary
2311  if (is_object($Value)) { $Value = $Value->Id(); }
2312 
2313  # remove any intersections with target ID from DB
2314  $this->DB->Query("DELETE FROM ".$TableName
2315  ." WHERE ResourceId = ".intval($this->Id)
2316  .($Field ? " AND FieldId = ".intval($Field->Id()) : "")
2317  ." AND ".$FieldName." = ".intval($Value));
2318  }
2319 
2320  # report to caller whether association was added
2321  return $AssociationRemoved;
2322  }
2323 
2324  # remove all intersections for resource and field (if any)
2325  private function RemoveAllAssociations($TableName, $TargetFieldName, $Field)
2326  {
2327  # retrieve list of entries for this field and resource
2328  $Entries = $this->Get($Field);
2329 
2330  # for each entry
2331  foreach ($Entries as $EntryId => $EntryName)
2332  {
2333  # remove intersection
2334  $this->RemoveAssociation($TableName, $TargetFieldName, $EntryId);
2335  }
2336  }
2337 }
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:2165
SetQualifierByField($Field, $NewValue)
Definition: Resource.php:1458
Rating($NewRating=NULL, $UserId=NULL)
Definition: Resource.php:1858
Status()
Retrieve result of last operation if available.
Definition: Resource.php:246
NumberOfComments()
Definition: Resource.php:1965
NumberOfRatings()
Definition: Resource.php:1833
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:2023
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:2109
UserCanView(User $User)
Determine if the given user can view the resource, e.g., on the full record page. ...
Definition: Resource.php:1993
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:1820
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:2056
Metadata type representing hierarchical (&quot;Tree&quot;) controlled vocabulary values.
SetByFieldId($FieldId, $NewValue)
Definition: Resource.php:1437
Classifications()
Definition: Resource.php:1788
ClearByField($Field, $ValueToClear=NULL)
Definition: Resource.php:1780
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:1817
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