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-2016 Edward Almasy and Internet Scout Research Group
7 # http://scout.wisc.edu/cwis/
8 #
9 
13 class Resource extends Item
14 {
15 
16  # ---- PUBLIC INTERFACE --------------------------------------------------
17 
25  public function __construct($ResourceId)
26  {
27  # call parent contstructor to load info from DB
28  parent::__construct($ResourceId);
29 
30  # load local attributes from database value cache
31  $this->CumulativeRating = $this->ValueCache["CumulativeRating"];
32 
33  # load our local metadata schema
34  $this->SchemaId = $this->ValueCache["SchemaId"];
35  if (!isset(self::$Schemas[$this->SchemaId]))
36  {
37  self::$Schemas[$this->SchemaId] =
38  new MetadataSchema($this->SchemaId);
39  }
40  }
41 
48  public static function Create($SchemaId)
49  {
50  # clean out any temp resource records more than three days old
51  $RFactory = new ResourceFactory();
52  $RFactory->CleanOutStaleTempItems(60 * 24 * 3);
53 
54  # lock DB tables to prevent next ID from being grabbed
55  $DB = new Database;
56  $DB->Query("LOCK TABLES Resources WRITE");
57 
58  # find next temp resource ID
59  $Id = $RFactory->GetNextTempItemId();
60 
61  # write out new resource record with temp resource ID
62  # Set DateLastModified = NOW() to avoid being pruned as a
63  # stale temp resource.
64  $DB->Query(
65  "INSERT INTO Resources
66  SET `ResourceId` = '".intval($Id)."',
67  `SchemaId` = '".intval($SchemaId)."',
68  `DateLastModified` = NOW() " );
69 
70  # release DB tables
71  $DB->Query("UNLOCK TABLES");
72 
73  # create new Resource object
74  $Resource = new Resource($Id);
75 
76  # set some additional fields for default resources
77  if ($SchemaId == MetadataSchema::SCHEMAID_DEFAULT)
78  {
79  $Resource->Set("Date Of Record Creation", date("Y-m-d H:i:s"));
80  $Resource->Set("Date Last Modified", date("Y-m-d H:i:s"));
81  if ($GLOBALS["G_User"]->IsLoggedIn())
82  {
83  $Resource->Set("Added By Id", $GLOBALS["G_User"]->Id());
84  $Resource->Set("Last Modified By Id", $GLOBALS["G_User"]->Id());
85  }
86  }
87 
88  # for each field that can have a default value
89  $Schema = new MetadataSchema($SchemaId);
90  $Fields = $Schema->GetFields(MetadataSchema::MDFTYPE_OPTION
95  foreach ($Fields as $Field)
96  {
97  # if there is a default value available
98  $DefaultValue = $Field->DefaultValue();
99  if ($DefaultValue !== NULL)
100  {
101  # if the default value is an array
102  if (is_array($DefaultValue))
103  {
104  # if there are values in the array
105  if (!empty($DefaultValue))
106  {
107  # flip values for Set() if necessary
108  if ($Field->Type() == MetadataSchema::MDFTYPE_OPTION)
109  {
110  $DefaultValue = array_flip($DefaultValue);
111  }
112 
113  # set default value
114  $Resource->Set($Field, $DefaultValue);
115  }
116  }
117  else
118  {
119  # set default value
120  $Resource->Set($Field, $DefaultValue);
121  }
122  }
123  }
124 
125  $Resource->UpdateAutoupdateFields(
127  $GLOBALS["G_User"]);
128 
129  # signal resource creation
130  $GLOBALS["AF"]->SignalEvent("EVENT_RESOURCE_CREATE", array(
131  "Resource" => $Resource,
132  ));
133 
134  # return new Resource object to caller
135  return $Resource;
136  }
137 
142  public function Delete()
143  {
144  global $G_SysConfig;
145 
146  # signal that resource deletion is about to occur
147  global $AF;
148  $AF->SignalEvent("EVENT_RESOURCE_DELETE", array(
149  "Resource" => $this,
150  ));
151 
152  # grab list of classifications
153  $Classifications = $this->Classifications();
154 
155  # delete resource/classification intersections
156  $DB = $this->DB;
157  $DB->Query("DELETE FROM ResourceClassInts WHERE ResourceId = ".$this->Id());
158 
159  # for each classification type
160  foreach ($Classifications as $ClassType => $ClassesOfType)
161  {
162  # for each classification of that type
163  foreach ($ClassesOfType as $ClassId => $ClassName)
164  {
165  # recalculate resource count for classification
166  $Class = new Classification($ClassId);
167  $Class->RecalcResourceCount();
168  }
169  }
170 
171  # delete resource references
172  $DB->Query("
173  DELETE FROM ReferenceInts
174  WHERE SrcResourceId = '".addslashes($this->Id())."'
175  OR DstResourceId = '".addslashes($this->Id())."'");
176 
177  # delete resource/name intersections
178  $DB->Query("DELETE FROM ResourceNameInts WHERE ResourceId = ".$this->Id());
179 
180  # delete resource/user intersections
181  $DB->Query("DELETE FROM ResourceUserInts WHERE ResourceId = ".$this->Id());
182 
183  # get the list of all images associated with this resource
184  $DB->Query("SELECT ImageId FROM ResourceImageInts"
185  ." WHERE ResourceId = ".intval($this->Id()));
186  $ImageIds = $DB->FetchColumn("ImageId");
187 
188  # disassociate this resource from all images
189  $DB->Query("DELETE FROM ResourceImageInts"
190  ." WHERE ResourceId = ".intval($this->Id()));
191 
192  # delete any images that no longer belong to any resources
193  foreach ($ImageIds as $ImageId)
194  {
195  $DB->Query("SELECT ResourceId FROM ResourceImageInts"
196  ." WHERE ImageId = ".intval($ImageId) );
197  if ($DB->NumRowsSelected() == 0)
198  {
199  $Image = new SPTImage($ImageId);
200  $Image->Delete();
201  }
202  }
203 
204  # delete any associated files
205  $Factory = new FileFactory(NULL);
206  $Files = $Factory->GetFilesForResource($this->Id());
207  foreach ($Files as $File)
208  {
209  $File->Delete();
210  }
211 
212  # delete resource ratings
213  $DB->Query("DELETE FROM ResourceRatings WHERE ResourceId = ".$this->Id());
214 
215  # delete resource record from database
216  $DB->Query("DELETE FROM Resources WHERE ResourceId = ".$this->Id());
217 
218  # drop item from search engine and recommender system
219  if ($G_SysConfig->SearchDBEnabled())
220  {
221  $SearchEngine = new SPTSearchEngine();
222  $SearchEngine->DropItem($this->Id());
223  }
224  if ($G_SysConfig->RecommenderDBEnabled())
225  {
226  $Recommender = new SPTRecommender();
227  $Recommender->DropItem($this->Id());
228  }
229 
230  # get the folders containing the resource
231  $FolderFactory = new FolderFactory();
232  $Folders = $FolderFactory->GetFoldersContainingItem(
233  $this->Id,
234  "Resource");
235 
236  # drop the resource from each folder it belongs to
237  foreach ($Folders as $Folder)
238  {
239  # mixed item type folder
240  if ($Folder->ContainsItem($this->Id, "Resource"))
241  {
242  $Folder->RemoveItem($this->Id, "Resource");
243  }
244 
245  # single item type folder
246  else
247  {
248  $Folder->RemoveItem($this->Id);
249  }
250  }
251 
252  # delete any resource comments
253  $DB->Query("DELETE FROM Messages WHERE ParentId = ".$this->Id);
254  }
255 
262  public function UpdateAutoupdateFields($UpdateType, $User=NULL)
263  {
264  # update all the timestamp fields as required
265  $TimestampFields = $this->Schema()->GetFields(
267  foreach ($TimestampFields as $Field)
268  {
269  if ($Field->UpdateMethod() == $UpdateType)
270  {
271  $this->Set($Field, "now");
272  }
273  }
274 
275  # if a user was provided, update the user fields as well
276  if (!is_null($User) && !$User->IsAnonymous())
277  {
278  $UserFields = $this->Schema()->GetFields(
280  foreach ($UserFields as $Field)
281  {
282  if ($Field->UpdateMethod() == $UpdateType)
283  {
284  $this->Set($Field, $User);
285  }
286  }
287  }
288  }
289 
294  public function Id()
295  {
296  return $this->Id;
297  }
298 
303  public function SchemaId()
304  {
305  return $this->SchemaId;
306  }
307 
312  public function Schema()
313  {
314  return self::$Schemas[$this->SchemaId];
315  }
316 
323  public function IsTempResource($NewSetting = NULL)
324  {
325  # if new temp resource setting supplied
326  if (!is_null($NewSetting))
327  {
328  # if caller requested to switch
329  $DB = $this->DB;
330  if ((($this->Id() < 0) && ($NewSetting == FALSE))
331  || (($this->Id() >= 0) && ($NewSetting == TRUE)))
332  {
333  $Factory = new ResourceFactory($this->SchemaId);
334 
335  # lock DB tables to prevent next ID from being grabbed
336  $DB->Query("LOCK TABLES Resources WRITE");
337 
338  # get next resource ID as appropriate
339  $OldResourceId = $this->Id;
340  if ($NewSetting == TRUE)
341  {
342  $this->Id = $Factory->GetNextTempItemId();
343  }
344  else
345  {
346  $this->Id = $Factory->GetNextItemId();
347  }
348 
349  # change resource ID
350  $DB->Query("UPDATE Resources SET ResourceId = ".
351  $this->Id. " WHERE ResourceId = ".$OldResourceId);
352 
353  # release DB tables
354  $DB->Query("UNLOCK TABLES");
355 
356  # change associations
357  unset($this->ClassificationCache);
358  $DB->Query("UPDATE ResourceClassInts SET ResourceId = ".
359  $this->Id. " WHERE ResourceId = ".$OldResourceId);
360  unset($this->ControlledNameCache);
361  unset($this->ControlledNameVariantCache);
362  $DB->Query("UPDATE ResourceNameInts SET ResourceId = ".
363  $this->Id. " WHERE ResourceId = ".$OldResourceId);
364  $DB->Query("UPDATE Files SET ResourceId = ".
365  $this->Id. " WHERE ResourceId = ".$OldResourceId);
366  $DB->Query("UPDATE ReferenceInts SET SrcResourceId = ".
367  $this->Id. " WHERE SrcResourceId = ".$OldResourceId);
368  $DB->Query("UPDATE ResourceImageInts SET ResourceId = ".
369  $this->Id. " WHERE ResourceId = ".$OldResourceId);
370  $DB->Query("UPDATE ResourceUserInts SET ResourceId = ".
371  $this->Id. " WHERE ResourceId = ".$OldResourceId);
372  $DB->Query("UPDATE ResourceRatings SET ResourceId = ".
373  $this->Id. " WHERE ResourceId = ".$OldResourceId);
374 
375  # signal event as appropriate
376  if ($NewSetting === FALSE)
377  {
378  $GLOBALS["AF"]->SignalEvent("EVENT_RESOURCE_ADD", array(
379  "Resource" => $this,
380  ));
381  }
382  }
383  }
384 
385  # report to caller whether we are a temp resource
386  return ($this->Id() < 0) ? TRUE : FALSE;
387  }
388 
389 
390  # --- Generic Attribute Retrieval Methods -------------------------------
391 
396  public function GetViewPageUrl()
397  {
398  # put our Id into the ViewPage from our schema
399  $Url = str_replace(
400  "\$ID", $this->Id(),
401  $this->Schema()->ViewPage());
402 
403  # return clean url, if one is available
404  return $GLOBALS["AF"]->GetCleanUrlForPath($Url);
405  }
406 
420  public function Get($Field, $ReturnObject = FALSE, $IncludeVariants = FALSE)
421  {
422  # load field object if not already supplied
423  $Field = is_object($Field) ? $Field : $this->Schema()->GetField($Field);
424 
425  if ($Field->SchemaId() != $this->SchemaId())
426  {
427  throw new Exception("Attempt to get a value for a field"
428  ." from a different schema."
429  ." (Field: ".$Field->Name()." [".$Field->Id()
430  ."], Field Schema: ".$Field->SchemaId()
431  .", Resource Schema: ".$this->SchemaId()
432  .")");
433  }
434 
435  # grab database field name
436  $DBFieldName = $Field->DBFieldName();
437 
438  # format return value based on field type
439  switch ($Field->Type())
440  {
444  $ReturnValue = isset($this->ValueCache[$DBFieldName])
445  ? (string)$this->ValueCache[$DBFieldName] : NULL;
446  break;
447 
449  $ReturnValue = isset($this->ValueCache[$DBFieldName])
450  ? (int)$this->ValueCache[$DBFieldName] : NULL;
451  break;
452 
454  $ReturnValue = isset($this->ValueCache[$DBFieldName])
455  ? (bool)$this->ValueCache[$DBFieldName] : NULL;
456  break;
457 
459  if (is_null($this->ValueCache[$DBFieldName."X"]) &&
460  is_null($this->ValueCache[$DBFieldName."Y"]))
461  {
462  $ReturnValue = ["X" => NULL, "Y" => NULL];
463  }
464  else
465  {
466  $ReturnValue = [
467  "X" => (float)$this->ValueCache[$DBFieldName."X"],
468  "Y" => (float)$this->ValueCache[$DBFieldName."Y"]
469  ];
470  }
471  break;
472 
474  $Date = new Date($this->ValueCache[$DBFieldName."Begin"],
475  $this->ValueCache[$DBFieldName."End"],
476  $this->ValueCache[$DBFieldName."Precision"]);
477  if ($ReturnObject)
478  {
479  $ReturnValue = $Date;
480  }
481  else
482  {
483  $ReturnValue = $Date->Formatted();
484  }
485  break;
486 
488  $ReturnValue = $this->ValueCache[$DBFieldName];
489  break;
490 
492  # start with empty array
493  $ReturnValue = array();
494 
495  # if classification cache has not been loaded
496  if (!isset($this->ClassificationCache))
497  {
498  # load all classifications associated with this resource into cache
499  $this->ClassificationCache = array();
500  $this->DB->Query(
501  "SELECT Classifications.ClassificationId,"
502  ." Classifications.FieldId,ClassificationName"
503  ." FROM ResourceClassInts, Classifications"
504  ." WHERE ResourceClassInts.ResourceId = ".$this->Id
505  ." AND ResourceClassInts.ClassificationId"
506  ." = Classifications.ClassificationId");
507  while ($Record = $this->DB->FetchRow())
508  {
509  $ClassId = $Record["ClassificationId"];
510  $this->ClassificationCache[$ClassId]["Name"]
511  = $Record["ClassificationName"];
512  $this->ClassificationCache[$ClassId]["FieldId"]
513  = $Record["FieldId"];
514  }
515  }
516  # for each entry in classification cache
517  foreach ($this->ClassificationCache as
518  $ClassificationId => $ClassificationInfo)
519  {
520  # if classification ID matches field we are looking for
521  if ($ClassificationInfo["FieldId"] == $Field->Id())
522  {
523  # add field to result
524  if ($ReturnObject)
525  {
526  $ReturnValue[$ClassificationId] =
527  new Classification($ClassificationId);
528  }
529  else
530  {
531  $ReturnValue[$ClassificationId] = $ClassificationInfo["Name"];
532  }
533  }
534  }
535  break;
536 
539  # start with empty array
540  $ReturnValue = array();
541 
542  # if controlled name cache has not been loaded
543  if (!isset($this->ControlledNameCache))
544  {
545  # load all controlled names associated with this resource into cache
546  $this->ControlledNameCache = array();
547  $this->DB->Query(
548  "SELECT ControlledNames.ControlledNameId,"
549  ." ControlledNames.FieldId,ControlledName"
550  ." FROM ResourceNameInts, ControlledNames"
551  ." WHERE ResourceNameInts.ResourceId = ".$this->Id
552  ." AND ResourceNameInts.ControlledNameId"
553  ." = ControlledNames.ControlledNameId"
554  ." ORDER BY ControlledNames.ControlledName ASC");
555  while ($Record = $this->DB->FetchRow())
556  {
557  $CNameId = $Record["ControlledNameId"];
558  $this->ControlledNameCache[$CNameId]["Name"]
559  = $Record["ControlledName"];
560  $this->ControlledNameCache[$CNameId]["FieldId"]
561  = $Record["FieldId"];
562  }
563  }
564 
565  # if variant names requested and variant name cache has not been loaded
566  if ($IncludeVariants && !isset($this->ControlledNameVariantCache))
567  {
568  # load all controlled names associated with this resource into cache
569  $this->ControlledNameVariantCache = array();
570  $this->DB->Query("SELECT ControlledNames.ControlledNameId,"
571  ." ControlledNames.FieldId,"
572  ." ControlledName, VariantName"
573  ." FROM ResourceNameInts, ControlledNames, VariantNames"
574  ." WHERE ResourceNameInts.ResourceId = ".$this->Id
575  ." AND ResourceNameInts.ControlledNameId"
576  ." = ControlledNames.ControlledNameId"
577  ." AND VariantNames.ControlledNameId"
578  ." = ControlledNames.ControlledNameId");
579  while ($Record = $this->DB->FetchRow())
580  {
581  $this->ControlledNameVariantCache[$Record["ControlledNameId"]][]
582  = $Record["VariantName"];
583  }
584  }
585 
586  # for each entry in controlled name cache
587  foreach ($this->ControlledNameCache as
588  $CNameId => $ControlledNameInfo)
589  {
590  # if controlled name type matches field we are looking for
591  if ($ControlledNameInfo["FieldId"] == $Field->Id())
592  {
593  # if objects requested
594  if ($ReturnObject)
595  {
596  $ReturnValue[$CNameId] =
597  new ControlledName($CNameId);
598  }
599  else
600  {
601  # if variant names requested
602  if ($IncludeVariants)
603  {
604  # add field to result
605  $ReturnValue[] = $ControlledNameInfo["Name"];
606 
607  # add any variant names to result
608  if (isset($this->ControlledNameVariantCache[$CNameId]))
609  {
610  $ReturnValue = array_merge(
611  $ReturnValue,
612  $this->ControlledNameVariantCache[$CNameId]);
613  }
614  }
615  else
616  {
617  # add field with index to result
618  $ReturnValue[$CNameId] =
619  $ControlledNameInfo["Name"];
620  }
621  }
622  }
623  }
624  break;
625 
627  # start out assuming no associated users
628  $ReturnValue = array();
629 
630  # query the database to get the associated userids
631  $this->DB->Query(
632  "SELECT UserId FROM ResourceUserInts WHERE ".
633  "ResourceId=".intval($this->Id).
634  " AND FieldId=".intval($Field->Id())
635  ." AND UserId IN (SELECT UserId FROM APUsers)"
636  );
637  $UserIds = $this->DB->FetchColumn("UserId");
638 
639  # convert each userid to either a name or a CWUser object
640  foreach ($UserIds as $UserId)
641  {
642  $User = new CWUser(intval($UserId));
643  if ($ReturnObject)
644  {
645  $ReturnValue[$UserId] = $User;
646  }
647  else
648  {
649  $ReturnValue[$UserId] = $User->Get("UserName");
650  }
651  }
652  break;
653 
655  # start out assuming no images will be found
656  $ReturnValue = array();
657 
658  # find all images associated with this resource
659  $this->DB->Query("SELECT ImageId FROM ResourceImageInts"
660  ." WHERE ResourceId = ".intval($this->Id())
661  ." AND FieldId = ".intval($Field->Id()));
662 
663  # if images were found
664  if ($this->DB->NumRowsSelected())
665  {
666  # if we are to return an object
667  $ImageIds = $this->DB->FetchColumn("ImageId");
668  if ($ReturnObject)
669  {
670  # load array of Image objects for return value
671  foreach ($ImageIds as $ImageId)
672  {
673  $ReturnValue[$ImageId] = new SPTImage($ImageId);
674  }
675  }
676  else
677  {
678  # load array of Image ids for return value
679  $ReturnValue = $ImageIds;
680  }
681  }
682  break;
683 
685  # retrieve files using factory
686  $Factory = new FileFactory($Field->Id());
687  $ReturnValue = $Factory->GetFilesForResource(
688  $this->Id, $ReturnObject);
689  break;
690 
692  # query for resource references
693  $this->DB->Query("
694  SELECT * FROM ReferenceInts
695  WHERE FieldId = '".addslashes($Field->Id())."'
696  AND SrcResourceId = '".addslashes($this->Id())."'");
697 
698  $ReturnValue = array();
699 
700  # return each reference as a Resource object
701  if ($ReturnObject)
702  {
703  $FoundErrors = FALSE;
704 
705  while (FALSE !== ($Record = $this->DB->FetchRow()))
706  {
707  $ReferenceId = $Record["DstResourceId"];
708  $Reference = new Resource($ReferenceId);
709  $ReturnValue[$ReferenceId] = $Reference;
710  }
711  }
712 
713  # return each reference as a resource ID
714  else
715  {
716  while (FALSE !== ($Record = $this->DB->FetchRow()))
717  {
718  $ReferenceId = $Record["DstResourceId"];
719  $ReturnValue[$ReferenceId] = $ReferenceId;
720  }
721  }
722  break;
723 
724  default:
725  # ERROR OUT
726  throw new Exception("Attempt to retrieve "
727  ."unknown field type (".$Field->Type().")");
728  break;
729  }
730 
731  # return formatted value to caller
732  return $ReturnValue;
733  }
734 
754  public function GetForDisplay(
755  $FieldNameOrObject, $ReturnObject = TRUE, $IncludeVariants = FALSE)
756  {
757  # normalize metadata field for use by any hooked code
758  $Field = is_object($FieldNameOrObject) ? $FieldNameOrObject
759  : $this->Schema()->GetFieldByName($FieldNameOrObject);
760 
761  # retrieve value
762  $Value = $this->Get($Field, $ReturnObject, $IncludeVariants);
763 
764  # signal event to allowed hooked code to modify value
765  $SignalResult = $GLOBALS["AF"]->SignalEvent(
766  "EVENT_FIELD_DISPLAY_FILTER", array(
767  "Field" => $Field,
768  "Resource" => $this,
769  "Value" => $Value));
770 
771  # return possibly modified value to caller
772  return $SignalResult["Value"];
773  }
774 
790  public function GetByField($FieldNameOrObject,
791  $ReturnObject = FALSE, $IncludeVariants = FALSE)
792  {
793  return $this->Get($FieldNameOrObject, $ReturnObject, $IncludeVariants);
794  }
795 
810  public function GetByFieldId(
811  $FieldId, $ReturnObject = FALSE, $IncludeVariants = FALSE)
812  {
813  return $this->Get($FieldId, $ReturnObject, $IncludeVariants);
814  }
815 
828  public function GetAsArray($IncludeDisabledFields = FALSE, $ReturnObjects = TRUE)
829  {
830  # retrieve field info
831  $Fields = $this->Schema()->GetFields();
832 
833  # for each field
834  foreach ($Fields as $Field)
835  {
836  # if field is enabled or caller requested disabled fields
837  if ($Field->Enabled() || $IncludeDisabledFields)
838  {
839  # retrieve info and add it to the array
840  $FieldStrings[$Field->Name()] = $this->Get($Field, $ReturnObjects);
841 
842  # if field uses qualifiers
843  if ($Field->UsesQualifiers())
844  {
845  # get qualifier attributes and add to the array
846  $FieldStrings[$Field->Name()." Qualifier"] =
847  $this->GetQualifierByField($Field, $ReturnObjects);
848  }
849  }
850  }
851 
852  # add in internal values
853  $FieldStrings["ResourceId"] = $this->Id();
854  $FieldStrings["CumulativeRating"] = $this->CumulativeRating();
855 
856  # return array to caller
857  return $FieldStrings;
858  }
859 
874  public function GetMapped(
875  $MappedName, $ReturnObject = FALSE, $IncludeVariants = FALSE)
876  {
877  $FieldId = $this->Schema()->StdNameToFieldMapping($MappedName);
878  return $FieldId
879  ? $this->Get($FieldId, $ReturnObject, $IncludeVariants)
880  : NULL;
881  }
882 
891  public function GetQualifier($FieldName, $ReturnObject = TRUE)
892  {
893  $Field = $this->Schema()->GetFieldByName($FieldName);
894  return $this->GetQualifierByField($Field, $ReturnObject);
895  }
896 
905  public function GetQualifierByFieldId($FieldId, $ReturnObject = TRUE)
906  {
907  $Field = $this->Schema()->GetField($FieldId);
908  return ($Field) ? $this->GetQualifierByField($Field, $ReturnObject) : NULL;
909  }
910 
919  public function GetQualifierByField($Field, $ReturnObject = TRUE)
920  {
921  # return NULL if field is invalid
922  if (!($Field instanceof MetadataField)) { return NULL; }
923 
924  # assume no qualifiers if not otherwise determined
925  $ReturnValue = NULL;
926 
927  # if field uses qualifiers
928  if ($Field->UsesQualifiers())
929  {
930  # retrieve qualifiers based on field type
931  switch ($Field->Type())
932  {
936  # retrieve list of items
937  $Items = $this->Get($Field);
938 
939  # if field uses item-level qualifiers
940  if ($Field->HasItemLevelQualifiers())
941  {
942  # determine general item name in DB
943  $TableName = ($Field->Type() == MetadataSchema::MDFTYPE_TREE)
944  ? "Classification" : "ControlledName";
945 
946  # for each item
947  foreach ($Items as $ItemId => $ItemName)
948  {
949  # look up qualifier for item
950  $QualId = $this->DB->Query(
951  "SELECT * FROM ".$TableName."s"
952  ." WHERE ".$TableName."Id = ".$ItemId,
953  "QualifierId");
954 
955 
956  if ($QualId > 0)
957  {
958  # if object was requested by caller
959  if ($ReturnObject)
960  {
961  # load qualifier and add to return value array
962  $ReturnValue[$ItemId] = new Qualifier($QualId);
963  }
964  else
965  {
966  # add qualifier ID to return value array
967  $ReturnValue[$ItemId] = $QualId;
968  }
969  }
970  else
971  {
972  # add NULL to return value array for this item
973  $ReturnValue[$ItemId] = NULL;
974  }
975  }
976  }
977  else
978  {
979  # for each item
980  foreach ($Items as $ItemId => $ItemName)
981  {
982  # if object was requested by caller
983  if ($ReturnObject)
984  {
985  # load default qualifier and add to return value array
986  $ReturnValue[$ItemId] = new Qualifier(
987  $Field->DefaultQualifier());
988  }
989  else
990  {
991  # add default qualifier ID to return value array
992  $ReturnValue[$ItemId] = $Field->DefaultQualifier();
993  }
994  }
995  }
996  break;
997 
998  default:
999  # if field uses item-level qualifiers
1000  if ($Field->HasItemLevelQualifiers())
1001  {
1002  # if qualifier available
1003  if ($this->ValueCache[$Field->DBFieldName()."Qualifier"] > 0)
1004  {
1005  # if object was requested by caller
1006  $QFieldName = $Field->DBFieldName()."Qualifier";
1007  if ($ReturnObject)
1008  {
1009  # return qualifier for field
1010  $ReturnValue = new Qualifier(
1011  $this->ValueCache[$QFieldName]);
1012  }
1013  else
1014  {
1015  # return qualifier ID for field
1016  $ReturnValue = $this->ValueCache[$QFieldName];
1017  }
1018  }
1019  }
1020  else
1021  {
1022  # if default qualifier available
1023  if ($Field->DefaultQualifier() > 0)
1024  {
1025  # if object was requested by caller
1026  if ($ReturnObject)
1027  {
1028  # return default qualifier
1029  $ReturnValue = new Qualifier($Field->DefaultQualifier());
1030  }
1031  else
1032  {
1033  # return default qualifier ID
1034  $ReturnValue = $Field->DefaultQualifier();
1035  }
1036  }
1037  }
1038  break;
1039  }
1040  }
1041 
1042  # return qualifier object or ID (or array of same) to caller
1043  return $ReturnValue;
1044  }
1045 
1053  public function FieldIsSet($FieldNameOrObject, $IgnorePadding=FALSE)
1054  {
1055  # load field object if needed
1056  $Field = is_object($FieldNameOrObject) ? $FieldNameOrObject
1057  : $this->Schema()->GetFieldByName($FieldNameOrObject);
1058 
1059  # return no value found if we don't have a valid field
1060  if (!($Field instanceof MetadataField)) { return FALSE; }
1061 
1062  # get the value
1063  $Value = $this->Get($Field);
1064 
1065  # checks depend on the field type
1066  switch ($Field->Type())
1067  {
1072  return !is_null($Value)
1073  && strlen($Value)
1074  && (!$IgnorePadding || ($IgnorePadding && strlen(trim($Value))));
1075 
1077  return !is_null($Value)
1078  && strlen($Value);
1079 
1081  return !is_null($Value["X"])
1082  && !is_null($Value["Y"])
1083  && strlen(trim($Value["X"]))
1084  && strlen(trim($Value["Y"]));
1085 
1087  return !is_null($Value)
1088  && strlen(trim($Value))
1089  && $Value != "0000-00-00";
1090 
1092  return !is_null($Value)
1093  && strlen(trim($Value))
1094  && $Value != "0000-00-00 00:00:00";
1095 
1103  return count($Value) > 0 ? TRUE : FALSE;
1104 
1105  default:
1106  return FALSE;
1107  }
1108  }
1109 
1118  public function GetImageUrls($FieldNameOrObject, $ImageSize=SPTImage::SIZE_FULL)
1119  {
1120  $Result = array();
1121 
1122  # get our target field and extract its values
1123  $Field = is_object($FieldNameOrObject) ? $FieldNameOrObject
1124  : $this->Schema()->GetField($FieldNameOrObject);
1125  $Images = $this->Get($Field, TRUE);
1126 
1127  # iterate over our images getting URLs for each
1128  $Index = 0;
1129  foreach ($Images as $Image)
1130  {
1131  $Result[$Image->Id()] = $Image->GetImageUrlForResource(
1132  $this->Id(), $Field->Id(), $Index, $ImageSize);
1133  $Index++;
1134  }
1135 
1136  return $Result;
1137  }
1138 
1139  # --- Generic Attribute Setting Methods ---------------------------------
1140 
1153  public function Set($Field, $NewValue, $Reset=FALSE)
1154  {
1155  # load field object if not already supplied
1156  $Field = is_object($Field) ? $Field
1157  : (is_numeric($Field) ? $this->Schema()->GetField($Field)
1158  : $this->Schema()->GetFieldByName($Field));
1159 
1160  # return if we don't have a valid field
1161  if (!($Field instanceof MetadataField)) { return; }
1162 
1163  if ($Field->SchemaId() != $this->SchemaId())
1164  {
1165  throw new Exception("Attempt to set a value for a field "
1166  ."from a different schema.");
1167  }
1168 
1169  # grab commonly-used values for local use
1170  $DB = $this->DB;
1171  $ResourceId = $this->Id;
1172 
1173  # grab database field name
1174  $DBFieldName = $Field->DBFieldName();
1175 
1176  # Flag to deterimine if we've actually changed anything.
1177  $UpdateModTime = FALSE;
1178 
1179  # store value in DB based on field type
1180  switch ($Field->Type())
1181  {
1185  if ($this->ValueCache[$DBFieldName] != $NewValue)
1186  {
1187  # save value directly to DB
1188  $DB->Query("UPDATE Resources SET `"
1189  .$DBFieldName."` = '".addslashes($NewValue)."' "
1190  ."WHERE ResourceId = ".$ResourceId);
1191 
1192  # save value locally
1193  $this->ValueCache[$DBFieldName] = $NewValue;
1194  $UpdateModTime=TRUE;
1195  }
1196  break;
1197 
1199  if ( $this->ValueCache[$DBFieldName] != $NewValue )
1200  {
1201  # save value directly to DB
1202  if (is_null($NewValue))
1203  {
1204  $DB->Query("UPDATE Resources SET `"
1205  .$DBFieldName."` = NULL"
1206  ." WHERE ResourceId = ".$ResourceId);
1207  }
1208  else
1209  {
1210  $DB->Query("UPDATE Resources SET `"
1211  .$DBFieldName."` = ".intval($NewValue)
1212  ." WHERE ResourceId = ".$ResourceId);
1213  }
1214 
1215  # save value locally
1216  $this->ValueCache[$DBFieldName] = $NewValue;
1217  $UpdateModTime = TRUE;
1218  }
1219  break;
1220 
1221 
1223  if ($this->ValueCache[$DBFieldName."X"] != $NewValue["X"] ||
1224  $this->ValueCache[$DBFieldName."Y"] != $NewValue["Y"] )
1225  {
1226  if (is_null($NewValue))
1227  {
1228  $DB->Query("UPDATE Resources SET "
1229  ."`".$DBFieldName."X` = NULL, "
1230  ."`".$DBFieldName."Y` = NULL "
1231  ."WHERE ResourceId = ".$ResourceId);
1232  $this->ValueCache[$DBFieldName."X"] = NULL;
1233  $this->ValueCache[$DBFieldName."Y"] = NULL;
1234  }
1235  else
1236  {
1237  $DB->Query("UPDATE Resources SET "
1238  ."`".$DBFieldName."X` = " .(strlen($NewValue["X"])
1239  ? "'".$NewValue["X"]."'" : "NULL").", "
1240  ."`".$DBFieldName."Y` = ".(strlen($NewValue["Y"])
1241  ? "'".$NewValue["Y"]."'" : "NULL")
1242  ." WHERE ResourceId = ".$ResourceId);
1243 
1244  $Digits = $Field->PointDecimalDigits();
1245 
1246  $this->ValueCache[$DBFieldName."X"] =
1247  strlen($NewValue["X"]) ?
1248  round($NewValue["X"], $Digits) : NULL;
1249  $this->ValueCache[$DBFieldName."Y"] =
1250  strlen($NewValue["Y"]) ?
1251  round($NewValue["Y"], $Digits) : NULL;
1252  }
1253  $UpdateModTime = TRUE;
1254  }
1255  break;
1256 
1258  if ($this->ValueCache[$DBFieldName] != $NewValue)
1259  {
1260  # save value directly to DB
1261  if (is_null($NewValue))
1262  {
1263  $DB->Query("UPDATE Resources SET `"
1264  .$DBFieldName."` = NULL"
1265  ." WHERE ResourceId = ".$ResourceId);
1266  }
1267  else
1268  {
1269  $NewValue = $NewValue ? "1" : "0";
1270  $DB->Query("UPDATE Resources SET `"
1271  .$DBFieldName."` = ".$NewValue
1272  ." WHERE ResourceId = ".$ResourceId);
1273  }
1274 
1275  $this->ValueCache[$DBFieldName] = $NewValue;
1276 
1277  $UpdateModTime = TRUE;
1278  }
1279  break;
1280 
1282  $OldValue = $this->Get($Field);
1283  # value comes back as array (UserId => UserName), just get the Ids
1284  $OldValue = array_keys($OldValue);
1285 
1286  # input to Set() for these fields is one of
1287  # 1. an int specifying a UserId
1288  if (is_numeric($NewValue))
1289  {
1290  $NewValue = array($NewValue);
1291  }
1292  # 2. a CWUser object
1293  elseif ($NewValue instanceof CWUser)
1294  {
1295  $NewValue = array($NewValue->Id());
1296  }
1297  # 3. an array keyed by UserId (don't care about the values)
1298  elseif (is_array($NewValue))
1299  {
1300  $NewValue = array_keys($NewValue);
1301  }
1302  else
1303  {
1304  throw new Exception("Unknown format for NewValue in a User field");
1305  }
1306 
1307  # if this is a unique field, only accept the first of the options given
1308  if ($Field->AllowMultiple() == FALSE && count($NewValue) > 1)
1309  {
1310  $NewValue = array_slice($NewValue, 0, 1, TRUE);
1311  }
1312 
1313  # sort new and old values so we can directly compare
1314  sort($OldValue);
1315  sort($NewValue);
1316 
1317  # if the value has changed
1318  if ($OldValue != $NewValue)
1319  {
1320  if ($Reset || $Field->AllowMultiple() == FALSE )
1321  {
1322  $ToRemove = array_diff($OldValue, $NewValue);
1323  $this->RemoveAssociation(
1324  "ResourceUserInts", "UserId", $ToRemove, $Field);
1325  }
1326 
1327  # associate with resource if not already associated
1328  $this->AddAssociation("ResourceUserInts",
1329  "UserId",
1330  $NewValue, $Field);
1331 
1332  $UpdateModTime=TRUE;
1333  }
1334  break;
1335 
1337  if (is_null($NewValue))
1338  {
1339  if (!is_null($this->ValueCache[$DBFieldName."Begin"]) ||
1340  !is_null($this->ValueCache[$DBFieldName."End"]) ||
1341  !is_null($this->ValueCache[$DBFieldName."Precision"]))
1342  {
1343  # clear date object values in DB
1344  $DB->Query("UPDATE Resources SET "
1345  .$DBFieldName."Begin = '', "
1346  .$DBFieldName."End = '', "
1347  .$DBFieldName."Precision = '' "
1348  ."WHERE ResourceId = ".$ResourceId);
1349 
1350  # clear value locally
1351  $this->ValueCache[$DBFieldName."Begin"] = NULL;
1352  $this->ValueCache[$DBFieldName."End"] = NULL;
1353  $this->ValueCache[$DBFieldName."Precision"] = NULL;
1354  $UpdateModTime=TRUE;
1355  }
1356  }
1357  else
1358  {
1359 
1360  # if we were given a date object
1361  if (is_object($NewValue))
1362  {
1363  # use supplied date object
1364  $Date = $NewValue;
1365  }
1366  else
1367  {
1368  # create date object
1369  $Date = new Date($NewValue);
1370  }
1371 
1372  $OldDate = new Date(
1373  $this->ValueCache[$DBFieldName."Begin"],
1374  $this->ValueCache[$DBFieldName."End"],
1375  $this->ValueCache[$DBFieldName."Precision"]);
1376 
1377  if ($OldDate->BeginDate() != $Date->BeginDate() ||
1378  $OldDate->EndDate() != $Date->EndDate() ||
1379  $OldDate->Precision() != $Date->Precision() )
1380  {
1381  # extract values from date object and store in DB
1382  $BeginDate = !is_null($Date->BeginDate()) ?
1383  "'".$Date->BeginDate()."'" : "NULL" ;
1384  $EndDate = !is_null($Date->EndDate()) ?
1385  "'".$Date->EndDate()."'" : "NULL" ;
1386 
1387  $DB->Query("UPDATE Resources SET "
1388  .$DBFieldName."Begin = ".$BeginDate.", "
1389  .$DBFieldName."End = ".$EndDate.", "
1390  .$DBFieldName."Precision = '".$Date->Precision()."' "
1391  ."WHERE ResourceId = ".$ResourceId);
1392 
1393  # save values locally
1394  $this->ValueCache[$DBFieldName."Begin"] = $Date->BeginDate();
1395  $this->ValueCache[$DBFieldName."End"] = $Date->EndDate();
1396  $this->ValueCache[$DBFieldName."Precision"] = $Date->Precision();
1397  $UpdateModTime=TRUE;
1398  }
1399  }
1400  break;
1401 
1403  if (is_null($NewValue) || !strlen(trim($NewValue)))
1404  {
1405  $DateValue = $NewValue;
1406 
1407  if (!is_null($this->ValueCache[$DBFieldName]))
1408  {
1409  # save value directly to DB
1410  $DB->Query("UPDATE Resources SET "
1411  ."`".$DBFieldName."` = NULL "
1412  ."WHERE ResourceId = ".$ResourceId);
1413  $UpdateModTime = TRUE;
1414  }
1415  }
1416  else
1417  {
1418  # assume value is date and use directly
1419  $TimestampValue = strtotime($NewValue);
1420 
1421  # use the new value if the date is valid
1422  if ($TimestampValue !== FALSE && $TimestampValue >= 0)
1423  {
1424  $DateValue = date("Y-m-d H:i:s", $TimestampValue);
1425 
1426  if ($this->ValueCache[$DBFieldName] != $DateValue)
1427  {
1428  # save value directly to DB
1429  $DB->Query("UPDATE Resources SET "
1430  ."`".$DBFieldName."` = '".addslashes($DateValue)."' "
1431  ."WHERE ResourceId = ".$ResourceId);
1432  $UpdateModTime=TRUE;
1433  }
1434  }
1435 
1436  # continue using the old value if invalid
1437  else
1438  {
1439  $DateValue = $this->Get($Field);
1440  }
1441  }
1442 
1443  # save value locally
1444  $this->ValueCache[$DBFieldName] = $DateValue;
1445  break;
1446 
1448  $OldValue = $this->Get($Field);
1449 
1450  # if incoming value is array
1451  if (is_array($NewValue))
1452  {
1453  if ($OldValue != $NewValue)
1454  {
1455  if ($Reset)
1456  {
1457  # remove values that were in the old value
1458  # but not the new one
1459  $ToRemove = array_diff(array_keys($OldValue),
1460  array_keys($NewValue));
1461  foreach ($ToRemove as $ClassificationId)
1462  {
1463  $this->RemoveAssociation("ResourceClassInts",
1464  "ClassificationId",
1465  $ClassificationId);
1466  $Class = new Classification($ClassificationId);
1467  $Class->RecalcResourceCount();
1468  }
1469  }
1470 
1471  # for each element of array
1472  foreach ($NewValue as
1473  $ClassificationId => $ClassificationName)
1474  {
1475  $Class = new Classification($ClassificationId);
1476  if ($Class->FieldId() == $Field->Id())
1477  {
1478  # associate with resource if not already associated
1479  if ($this->AddAssociation("ResourceClassInts",
1480  "ClassificationId", $ClassificationId))
1481  {
1482  $Class->UpdateLastAssigned();
1483  $Class->RecalcResourceCount();
1484  }
1485  }
1486  else
1487  {
1488  throw new Exception(
1489  "Attempting to store classification from "
1490  ."Field ".$Class->FieldId()." into Field "
1491  .$Field->Id() );
1492  }
1493 
1494  }
1495 
1496  $UpdateModTime=TRUE;
1497  }
1498  }
1499  else
1500  {
1501  # associate with resource if not already associated
1502  if (is_object($NewValue))
1503  {
1504  $Class = $NewValue;
1505  $NewValue = $Class->Id();
1506  }
1507  else
1508  {
1509  $Class = new Classification($NewValue);
1510  }
1511 
1512  if (!array_key_exists($Class->Id(), $OldValue))
1513  {
1514 
1515  $this->AddAssociation("ResourceClassInts",
1516  "ClassificationId",
1517  $NewValue);
1518  $Class->UpdateLastAssigned();
1519  $Class->RecalcResourceCount();
1520  $UpdateModTime=TRUE;
1521  }
1522  }
1523 
1524  # clear our classification cache
1525  if ($UpdateModTime)
1526  {
1527  unset($this->ClassificationCache);
1528  }
1529  break;
1530 
1533  $OldValue = $this->Get($Field);
1534 
1535  # input to Set() for these fields is one of
1536  # 1. an int specifying a ControlledNameId
1537  # 2. a ControlledName object
1538  # 3. an array with keys giving Ids and values giving ControlledNames
1539  #
1540  # normalize 1 and 2 into 3 for simplicity of processing
1541  if (is_object($NewValue) || !is_array($NewValue) )
1542  {
1543  if (!is_object($NewValue))
1544  {
1545  $NewValue = new ControlledName($NewValue);
1546  }
1547 
1548  $TmpValue = array();
1549  $TmpValue[$NewValue->Id()] = $NewValue->Name();
1550 
1551  $NewValue = $TmpValue;
1552  }
1553 
1554  # if this is a unique field, only accept the first of the options given
1555  # NB: all ControlledNames implicitly AllowMultiple
1556  if ($Field->Type() == MetadataSchema::MDFTYPE_OPTION &&
1557  $Field->AllowMultiple() == FALSE && count($NewValue) > 1)
1558  {
1559  $NewValue = array_slice($NewValue, 0, 1, TRUE);
1560  }
1561 
1562  # if the value has changed
1563  if ($OldValue != $NewValue)
1564  {
1565  if ($Reset || ($Field->Type() == MetadataSchema::MDFTYPE_OPTION
1566  && $Field->AllowMultiple() == FALSE ) )
1567  {
1568  $ToRemove = array_diff(array_keys($OldValue),
1569  array_keys($NewValue));
1570  foreach ($ToRemove as $CNId)
1571  {
1572  $this->RemoveAssociation("ResourceNameInts",
1573  "ControlledNameId",
1574  $CNId);
1575  }
1576  }
1577 
1578  # for each element of array
1579  foreach ($NewValue as $ControlledNameId => $ControlledName)
1580  {
1581  # associate with resource if not already associated
1582  if ($this->AddAssociation("ResourceNameInts",
1583  "ControlledNameId",
1584  $ControlledNameId))
1585  {
1586 
1587  if (ControlledName::ItemExists($ControlledNameId))
1588  {
1589  $CN = new ControlledName($ControlledNameId);
1590  $CN->UpdateLastAssigned();
1591  }
1592  else
1593  {
1594  $this->RemoveAssociation("ResourceNameInts",
1595  "ControlledNameId", $ControlledNameId);
1596  throw new InvalidArgumentException(
1597  "Attempt to set controlled name with"
1598  ." invalid ID (".$ControlledNameId.").");
1599  }
1600  }
1601  }
1602  $UpdateModTime = TRUE;
1603  }
1604 
1605  if ($UpdateModTime)
1606  {
1607  # clear our controlled name cache
1608  unset($this->ControlledNameCache);
1609  unset($this->ControlledNameVariantCache);
1610 
1611  # clear visible count cache for any affected CNames
1612  $RFactory = new ResourceFactory($this->SchemaId);
1613  $RFactory->ClearVisibleResourceCountForValues(
1614  array_keys($OldValue + $NewValue) );
1615  }
1616 
1617  break;
1618 
1620  # associate value(s) with resource
1621  $this->AddAssociation(
1622  "ResourceImageInts", "ImageId", $NewValue, $Field);
1623  # clear cached image mappings
1624  SPTImage::ClearImageSymlinksForResource($this->Id(), $Field->Id());
1625  break;
1626 
1628  # convert incoming value to array if necessary
1629  if (!is_array($NewValue)) { $NewValue = array($NewValue); }
1630 
1631  # for each incoming file
1632  $Factory = new FileFactory($Field->Id());
1633  foreach ($NewValue as $File)
1634  {
1635  # make copy of file
1636  $NewFile = $Factory->Copy($File);
1637 
1638  # associate copy with this resource and field
1639  $NewFile->ResourceId($this->Id);
1640  $NewFile->FieldId($Field->Id());
1641  }
1642  # Since we make a fresh copy of the File whenever Set is called,
1643  # we'll always update the modification time for this field.
1644  $UpdateModTime = TRUE;
1645  break;
1646 
1648  # convert incoming value to array to simplify the workflow
1649  if (!is_array($NewValue))
1650  {
1651  $NewValue = [$NewValue];
1652  }
1653 
1654  # delete existing resource references
1655  $this->DB->Query(
1656  "DELETE FROM ReferenceInts "
1657  ."WHERE FieldId = '".addslashes($Field->Id())."' "
1658  ."AND SrcResourceId = '".addslashes($this->Id())."'");
1659 
1660  # add each reference
1661  foreach ($NewValue as $ReferenceId)
1662  {
1663  if ($ReferenceId instanceof Resource)
1664  {
1665  $ReferenceId = $ReferenceId->Id();
1666  }
1667 
1668  # skip blank reference IDs
1669  if (strlen(trim($ReferenceId)) < 1)
1670  {
1671  continue;
1672  }
1673 
1674  # skip reference IDs that don't look right
1675  if (!is_numeric($ReferenceId))
1676  {
1677  continue;
1678  }
1679 
1680  # skip references to the current resource
1681  if ($ReferenceId == $this->Id())
1682  {
1683  continue;
1684  }
1685 
1686  # add the reference to the references table
1687  $DB->Query(
1688  "INSERT INTO ReferenceInts ("
1689  ."FieldId, "
1690  ."SrcResourceId, "
1691  ."DstResourceId"
1692  .") VALUES ("
1693  .addslashes($Field->Id()).","
1694  .addslashes($this->Id()).","
1695  .addslashes($ReferenceId).")");
1696  }
1697  break;
1698 
1699  default:
1700  # ERROR OUT
1701  exit("<br>SPT - ERROR: attempt to set unknown resource field type<br>\n");
1702  break;
1703  }
1704 
1705  if ($UpdateModTime && !$this->IsTempResource())
1706  {
1707  # update modification timestamps
1708  global $G_User;
1709  $UserId = $G_User->IsLoggedIn() ? $G_User->Get("UserId") : -1;
1710  $DB->Query("DELETE FROM ResourceFieldTimestamps "
1711  ."WHERE ResourceId=".$this->Id." AND "
1712  ."FieldId=".$Field->Id() );
1713  $DB->Query("INSERT INTO ResourceFieldTimestamps "
1714  ."(ResourceId,FieldId,ModifiedBy,Timestamp) VALUES ("
1715  .$this->Id.",".$Field->Id().","
1716  .$UserId.",NOW())");
1717 
1718  # on resource modification, clear the UserPermsCache entry
1719  # so that stale permissions checks are not cached
1720  $DB->Query("DELETE FROM UserPermsCache WHERE ResourceId=".$this->Id);
1721 
1722  # if this field is not an option or a cname, but it is
1723  # checked for visibility, then we need to clear resource
1724  # visibility cache (for example, if this is AddedById and
1725  # our schema allows users to view resources where they are
1726  # the AddedById)
1727  if (!in_array($Field->Type(),
1730  $this->Schema()->ViewingPrivileges()->ChecksField($Field->Id()))
1731  {
1732  $RFactory = new ResourceFactory($this->SchemaId);
1733  $RFactory->ClearVisibleResourceCount($this);
1734  }
1735  }
1736  }
1737 
1745  public function SetByField($Field, $NewValue)
1746  {
1747  $this->Set($Field, $NewValue);
1748  }
1749 
1757  public function SetByFieldId($FieldId, $NewValue)
1758  {
1759  $this->Set($FieldId, $NewValue);
1760  }
1761 
1767  public function SetQualifier($FieldName, $NewValue)
1768  {
1769  $Field = $this->Schema()->GetFieldByName($FieldName);
1770  $this->SetQualifierByField($Field, $NewValue);
1771  }
1772 
1778  public function SetQualifierByFieldId($FieldId, $NewValue)
1779  {
1780  $Field = $this->Schema()->GetField($FieldId);
1781  $this->SetQualifierByField($Field, $NewValue);
1782  }
1783 
1789  public function SetQualifierByField($Field, $NewValue)
1790  {
1791  # if field uses qualifiers and uses item-level qualifiers
1792  if ($Field->UsesQualifiers() && $Field->HasItemLevelQualifiers())
1793  {
1794  # if qualifier object passed in
1795  if (is_object($NewValue))
1796  {
1797  # grab qualifier ID from object
1798  $QualifierId = $NewValue->Id();
1799  }
1800  else
1801  {
1802  # assume value passed in is qualifier ID
1803  $QualifierId = $NewValue;
1804  }
1805 
1806  # update qualifier value in database
1807  $DBFieldName = $Field->DBFieldName();
1808  $this->DB->Query("UPDATE Resources SET "
1809  .$DBFieldName."Qualifier = '".$QualifierId."' "
1810  ."WHERE ResourceId = ".$this->Id);
1811 
1812  # update local qualifier value
1813  $this->ValueCache[$DBFieldName."Qualifier"] = $QualifierId;
1814  }
1815  }
1816 
1823  public function ClearByFieldId($FieldId, $ValueToClear = NULL)
1824  {
1825  $Field = $this->Schema()->GetField($FieldId);
1826  $this->Clear($Field, $ValueToClear);
1827  }
1828 
1835  public function Clear($Field, $ValueToClear = NULL)
1836  {
1837  # convert field name to object if necessary
1838  if (!is_object($Field))
1839  {
1840  $Field = $this->Schema()->GetFieldByName($Field);
1841  }
1842 
1843  $UpdateModTime = FALSE;
1844 
1845  # store value in DB based on field type
1846  switch ($Field->Type())
1847  {
1856  $this->Set($Field, NULL);
1857  break;
1858 
1863  # if value to clear supplied
1864  if ($ValueToClear !== NULL)
1865  {
1866  $Value = $this->Get($Field);
1867 
1868  if (!is_array($ValueToClear))
1869  {
1870  $ValueToClear = [$ValueToClear => "Dummy"];
1871  }
1872 
1873  # for each element of array
1874  foreach ($ValueToClear as $Id => $Dummy)
1875  {
1876  if (array_key_exists($Id, $Value))
1877  {
1878  unset($Value[$Id]);
1879  }
1880  }
1881 
1882  $this->Set($Field, $Value, TRUE);
1883  }
1884  else
1885  {
1886  $this->Set($Field, [], TRUE);
1887  }
1888 
1889  break;
1890 
1892  # if value to clear supplied
1893  if ($ValueToClear !== NULL)
1894  {
1895  # convert value to array if necessary
1896  $Files = $ValueToClear;
1897  if (!is_array($Files)) { $Files = array($Files); }
1898 
1899  # convert values to objects if necessary
1900  foreach ($Files as $Index => $File)
1901  {
1902  if (!is_object($File))
1903  {
1904  $Files[$Index] = new File($File);
1905  }
1906  }
1907  }
1908  else
1909  {
1910  # use all files associated with resource
1911  $Files = $this->Get($Field, TRUE);
1912  }
1913 
1914  # delete files
1915  foreach ($Files as $File) { $File->Delete(); }
1916  break;
1917 
1919  # if value to clear supplied
1920  if ($ValueToClear !== NULL)
1921  {
1922  # convert value to array if necessary
1923  $Images = $ValueToClear;
1924  if (!is_array($Images)) { $Images = array($Images); }
1925 
1926  # convert values to objects if necessary
1927  foreach ($Images as $Index => $Image)
1928  {
1929  if (!is_object($Image))
1930  {
1931  $Images[$Index] = new SPTImage($Image);
1932  }
1933  }
1934  }
1935  else
1936  {
1937  # use all images associated with resource
1938  $Images = $this->Get($Field, TRUE);
1939  }
1940 
1941  # delete images if we are the last resource referencing
1942  # a particular image.
1943  foreach ($Images as $Image)
1944  {
1945  $Cnt = $this->DB->Query(
1946  "SELECT COUNT(*) AS Cnt FROM ResourceImageInts WHERE ".
1947  "ImageId=".$Image->Id(), "Cnt");
1948  if ($Cnt==1)
1949  {
1950  $Image->Delete();
1951  }
1952  }
1953 
1954  # clear cached image mappings
1955  SPTImage::ClearImageSymlinksForResource($this->Id(), $Field->Id());
1956 
1957  # remove connections to images
1958  $UpdateModTime = $this->RemoveAssociation(
1959  "ResourceImageInts", "ImageId", $Images, $Field);
1960  break;
1961 
1963  $this->Set($Field, []);
1964  break;
1965 
1966  default:
1967  # ERROR OUT
1968  exit("<br>SPT - ERROR: attempt to clear "
1969  ."unknown resource field type<br>\n");
1970  break;
1971  }
1972 
1973  if ($UpdateModTime && !$this->IsTempResource())
1974  {
1975  # update modification timestamps
1976  global $G_User;
1977  $UserId = $G_User->IsLoggedIn() ? $G_User->Get("UserId") : -1;
1978  $this->DB->Query("DELETE FROM ResourceFieldTimestamps "
1979  ."WHERE ResourceId=".$this->Id." AND "
1980  ."FieldId=".$Field->Id() );
1981  $this->DB->Query("INSERT INTO ResourceFieldTimestamps "
1982  ."(ResourceId,FieldId,ModifiedBy,Timestamp) VALUES ("
1983  .$this->Id.",".$Field->Id().","
1984  .$UserId.",NOW())");
1985  }
1986  }
1987 
1996  public function ClearByField($Field, $ValueToClear = NULL)
1997  {
1998  $this->Clear($Field, $ValueToClear);
1999  }
2000 
2001  # --- Field-Specific or Type-Specific Attribute Retrieval Methods -------
2002 
2008  public function Classifications()
2009  {
2010  $DB = $this->DB;
2011 
2012  # start with empty array
2013  $Names = array();
2014 
2015  # for each controlled name
2016  $DB->Query("SELECT ClassificationName, MetadataFields.FieldName, "
2017  ."ResourceClassInts.ClassificationId FROM ResourceClassInts, "
2018  ."Classifications, MetadataFields "
2019  ."WHERE ResourceClassInts.ResourceId = ".$this->Id." "
2020  ."AND ResourceClassInts.ClassificationId = "
2021  ."Classifications.ClassificationId "
2022  ."AND Classifications.FieldId = MetadataFields.FieldId ");
2023  while ($Record = $DB->FetchRow())
2024  {
2025  # add name to array
2026  $Names[$Record["FieldName"]][$Record["ClassificationId"]] =
2027  $Record["ClassificationName"];
2028  }
2029 
2030  # return array to caller
2031  return $Names;
2032  }
2033 
2034 
2035  # --- Ratings Methods ---------------------------------------------------
2036 
2041  public function CumulativeRating()
2042  {
2043  return $this->CumulativeRating;
2044  }
2045 
2050  public function ScaledCumulativeRating()
2051  {
2052  if ($this->CumulativeRating == NULL)
2053  {
2054  return NULL;
2055  }
2056  else
2057  {
2058  return intval(($this->CumulativeRating + 5) / 10);
2059  }
2060  }
2061 
2066  public function NumberOfRatings()
2067  {
2068  # if number of ratings not already set
2069  if (!isset($this->NumberOfRatings))
2070  {
2071  $this->FetchAndPossiblyUpdateCumulativeRating();
2072  }
2073 
2074  # return number of ratings to caller
2075  return $this->NumberOfRatings;
2076  }
2077 
2085  public function Rating($NewRating = NULL, $UserId = NULL)
2086  {
2087  $DB = $this->DB;
2088 
2089  # if user ID not supplied
2090  if ($UserId == NULL)
2091  {
2092  # if user is logged in
2093  global $G_User;
2094  if ($G_User->IsLoggedIn())
2095  {
2096  # use ID of current user
2097  $UserId = $G_User->Get("UserId");
2098  }
2099  else
2100  {
2101  # return NULL to caller
2102  return NULL;
2103  }
2104  }
2105 
2106  # sanitize $NewRating
2107  if (!is_null($NewRating))
2108  {
2109  $NewRating = intval($NewRating);
2110  }
2111 
2112  # if there is a rating for resource and user
2113  $DB->Query("SELECT Rating FROM ResourceRatings "
2114  ."WHERE UserId = ".intval($UserId)." AND ResourceId = ".$this->Id);
2115  if ($Record = $DB->FetchRow())
2116  {
2117  # if new rating was supplied
2118  if ($NewRating != NULL)
2119  {
2120  # update existing rating
2121  $DB->Query("UPDATE ResourceRatings "
2122  ."SET Rating = ".$NewRating.", DateRated = NOW() "
2123  ."WHERE UserId = ".intval($UserId)
2124  ." AND ResourceId = ".$this->Id);
2125 
2126  # update cumulative rating value
2127  $this->FetchAndPossiblyUpdateCumulativeRating();
2128 
2129  # return value is new rating
2130  $Rating = $NewRating;
2131  }
2132  else
2133  {
2134  # get rating value to return to caller
2135  $Rating = $Record["Rating"];
2136  }
2137  }
2138  else
2139  {
2140  # if new rating was supplied
2141  if ($NewRating != NULL)
2142  {
2143  # add new rating
2144  $DB->Query(
2145  "INSERT INTO ResourceRatings "
2146  ."(ResourceId, UserId, DateRated, Rating) "
2147  ."VALUES ("
2148  .$this->Id.", "
2149  .intval($UserId).", "
2150  ."NOW(), "
2151  .$NewRating.")");
2152 
2153  # update cumulative rating value
2154  $this->FetchAndPossiblyUpdateCumulativeRating();
2155 
2156  # return value is new rating
2157  $Rating = $NewRating;
2158  }
2159  else
2160  {
2161  # return value is NULL
2162  $Rating = NULL;
2163  }
2164  }
2165 
2166  # return rating value to caller
2167  return $Rating;
2168  }
2169 
2170 
2171  # --- Resource Comment Methods ------------------------------------------
2172 
2177  public function Comments()
2178  {
2179  # read in comments if not already loaded
2180  if (!isset($this->Comments))
2181  {
2182  $this->DB->Query("SELECT MessageId FROM Messages "
2183  ."WHERE ParentId = ".$this->Id
2184  ." AND ParentType = 2 "
2185  ."ORDER BY DatePosted DESC");
2186  while ($MessageId = $this->DB->FetchField("MessageId"))
2187  {
2188  $this->Comments[] = new Message($MessageId);
2189  }
2190  }
2191 
2192  # return array of comments to caller
2193  return $this->Comments;
2194  }
2195 
2200  public function NumberOfComments()
2201  {
2202  # obtain number of comments if not already set
2203  if (!isset($this->NumberOfComments))
2204  {
2205  $this->NumberOfComments =
2206  $this->DB->Query("SELECT Count(*) AS NumberOfComments "
2207  ."FROM Messages "
2208  ."WHERE ParentId = ".$this->Id
2209  ." AND ParentType = 2",
2210  "NumberOfComments"
2211  );
2212  }
2213 
2214  # return number of comments to caller
2215  return $this->NumberOfComments;
2216  }
2217 
2218 
2219  # --- Permission Methods -------------------------------------------------
2220 
2230  public function UserCanView(User $User, $AllowHooksToModify=TRUE)
2231  {
2232  return $this->CheckSchemaPermissions($User, "View", $AllowHooksToModify);
2233  }
2234 
2241  public function UserCanEdit($User)
2242  {
2243  return $this->CheckSchemaPermissions($User, "Edit");
2244  }
2245 
2252  public function UserCanAuthor($User)
2253  {
2254  return $this->CheckSchemaPermissions($User, "Author");
2255  }
2256 
2263  public function UserCanModify($User)
2264  {
2265  $CheckFn = "UserCan".(($this->Id()<0) ? "Author" : "Edit");
2266  return $this->$CheckFn($User);
2267  }
2268 
2275  public function UserCanViewField($User, $FieldOrFieldName)
2276  {
2277  return $this->CheckFieldPermissions($User, $FieldOrFieldName, "View");
2278  }
2279 
2286  public function UserCanViewMappedField($User, $MappedName)
2287  {
2288  $FieldId = $this->Schema()->StdNameToFieldMapping($MappedName);
2289  return ($FieldId === NULL) ? FALSE
2290  : $this->CheckFieldPermissions($User, $FieldId, "View");
2291  }
2292 
2299  public function UserCanEditField($User, $FieldOrFieldName)
2300  {
2301  return $this->CheckFieldPermissions($User, $FieldOrFieldName, "Edit");
2302  }
2303 
2310  public function UserCanAuthorField($User, $FieldOrFieldName)
2311  {
2312  return $this->CheckFieldPermissions( $User, $FieldOrFieldName, "Author" );
2313  }
2314 
2322  public function UserCanModifyField($User, $FieldOrFieldName)
2323  {
2324  $CheckFn = "UserCan".(($this->Id()<0) ? "Author" : "Edit")."Field";
2325 
2326  return $this->$CheckFn($User, $FieldOrFieldName);
2327  }
2328 
2329  # --- Utility Methods ----------------------------------------------------
2330 
2335  {
2336  if (!$this->IsTempResource())
2337  {
2338  $SearchEngine = new SPTSearchEngine();
2339  $SearchEngine->QueueUpdateForItem($this);
2340 
2341  $Recommender = new SPTRecommender();
2342  $Recommender->QueueUpdateForItem($this);
2343  }
2344  }
2345 
2351  public static function GetSchemaForResource($ResourceId)
2352  {
2353  # if schema IDs are not loaded
2354  if (!isset(self::$SchemaIdCache))
2355  {
2356  # load schema IDs
2357  $DB = new Database();
2358  $DB->Query("SELECT ResourceId, SchemaId FROM Resources");
2359  self::$SchemaIdCache = $DB->FetchColumn("SchemaId", "ResourceId");
2360  }
2361 
2362  # if multiple resources specified
2363  if (is_array($ResourceId))
2364  {
2365  # find schema IDs for specified resources
2366  $SchemaIds = array_intersect_key(self::$SchemaIdCache,
2367  array_flip($ResourceId));
2368 
2369  # check that specified resource IDs were all valid
2370  if (count($SchemaIds) < count($ResourceId))
2371  {
2372  $BadIds = array_diff($ResourceId, array_keys($SchemaIds));
2373  throw new InvalidArgumentException("Unknown resource IDs ("
2374  .implode(", ", $BadIds).").");
2375  }
2376 
2377  # return schema IDs to caller
2378  return $SchemaIds;
2379  }
2380  else
2381  {
2382  # check that specified resource was valid
2383  if (!isset(self::$SchemaIdCache[$ResourceId]))
2384  {
2385  throw new InvalidArgumentException("Unknown resource ID ("
2386  .$ResourceId.").");
2387  }
2388 
2389  # return schema IDs for specified resource
2390  return self::$SchemaIdCache[$ResourceId];
2391  }
2392  }
2393 
2394 
2395  # ---- PRIVATE INTERFACE -------------------------------------------------
2396 
2397  private $ClassificationCache;
2398  private $Comments;
2399  private $ControlledNameCache;
2400  private $ControlledNameVariantCache;
2401  private $CumulativeRating;
2402  private $NumberOfComments;
2403  private $NumberOfRatings;
2404  private $PermissionCache;
2405  private $SchemaId;
2406 
2407  static private $Schemas;
2408  static private $SchemaIdCache;
2409 
2420  private function CheckSchemaPermissions($User, $CheckType, $AllowHooksToModify=TRUE)
2421  {
2422  # construct a key to use for our permissions cache
2423  $CacheKey = "UserCan".$CheckType.$User->Id();
2424 
2425  # if we don't have a cached value for this perm, compute one
2426  if (!isset($this->PermissionCache[$CacheKey]))
2427  {
2428  # get privileges for schema
2429  $PermsFn = $CheckType."ingPrivileges";
2430  $SchemaPrivs = $this->Schema()->$PermsFn();
2431 
2432  # check passes if user privileges are greater than resource set
2433  $CheckResult = $SchemaPrivs->MeetsRequirements($User, $this);
2434 
2435  # save the result of this check in our cache
2436  $this->PermissionCache[$CacheKey] = $CheckResult;
2437  }
2438 
2439  $Value = $this->PermissionCache[$CacheKey];
2440 
2441  if ($AllowHooksToModify)
2442  {
2443  $SignalResult = $GLOBALS["AF"]->SignalEvent(
2444  "EVENT_RESOURCE_".strtoupper($CheckType)."_PERMISSION_CHECK",
2445  array(
2446  "Resource" => $this,
2447  "User" => $User,
2448  "Can".$CheckType => $Value,
2449  "Schema" => $this->Schema(), ));
2450 
2451  $Value = $SignalResult["Can".$CheckType];
2452  }
2453 
2454  return $Value;
2455  }
2456 
2465  private function CheckFieldPermissions($User, $Field, $CheckType)
2466  {
2467  # get field object (if not supplied)
2468  if (!($Field instanceof MetadataField))
2469  {
2470  try
2471  {
2472  $Field = $this->Schema()->GetField($Field);
2473  }
2474  catch (InvalidArgumentException $Exception)
2475  {
2476  # (user cannot view/author/edit if field was invalid)
2477  return FALSE;
2478  }
2479  }
2480 
2481  # construct a key to use for our permissions cache
2482  $CacheKey = "UserCan".$CheckType."Field".$Field->Id()."-".$User->Id();
2483 
2484  # if we don't have a cahced value, compute one
2485  if (!isset($this->PermissionCache[$CacheKey]))
2486  {
2487  # if field is enabled and editable, do permission check
2488  if ($Field->Enabled() &&
2489  ($CheckType == "View" || $Field->Editable()))
2490  {
2491  # be sure schema privs allow View/Edit/Author for this resource
2492  $SchemaCheckFn = "UserCan".$CheckType;
2493  if ($this->$SchemaCheckFn($User))
2494  {
2495  # get appropriate privilege set for field
2496  $PermsFn = $CheckType."ingPrivileges";
2497  $FieldPrivs = $Field->$PermsFn();
2498 
2499  # user can View/Edit/Author if privileges are greater than field set
2500  $CheckResult = $FieldPrivs->MeetsRequirements($User, $this);
2501  }
2502  else
2503  {
2504  $CheckResult = FALSE;
2505  }
2506  }
2507  else
2508  {
2509  $CheckResult = FALSE;
2510  }
2511 
2512  # allow plugins to modify result of permission check
2513  $SignalResult = $GLOBALS["AF"]->SignalEvent(
2514  "EVENT_FIELD_".strtoupper($CheckType)."_PERMISSION_CHECK", array(
2515  "Field" => $Field,
2516  "Resource" => $this,
2517  "User" => $User,
2518  "Can".$CheckType => $CheckResult));
2519  $CheckResult = $SignalResult["Can".$CheckType];
2520 
2521  # save the result of this check in our cache
2522  $this->PermissionCache[$CacheKey] = $CheckResult;
2523  }
2524 
2525  # return cached permission value
2526  return $this->PermissionCache[$CacheKey];
2527  }
2528 
2532  private function FetchAndPossiblyUpdateCumulativeRating()
2533  {
2534  # grab totals from DB
2535  $this->DB->Query("SELECT COUNT(Rating) AS Count, "
2536  ."SUM(Rating) AS Total FROM ResourceRatings "
2537  ."WHERE ResourceId = ".$this->Id);
2538  $Record = $this->DB->FetchRow();
2539 
2540  $this->NumberOfRatings = $Record["Count"];
2541  $NewCumulativeRating = round($Record["Total"] / max(1, $Record["Count"]));
2542 
2543  # if saved cumulative rating is no longer accurate
2544  if ($this->CumulativeRating != $NewCumulativeRating)
2545  {
2546  # update local value and save new cumulative rating in DB
2547  $this->CumulativeRating = $NewCumulativeRating;
2548  $this->DB->Query("UPDATE Resources "
2549  ."SET CumulativeRating = ".$this->CumulativeRating." "
2550  ."WHERE ResourceId = ".$this->Id);
2551  $this->ValueCache["CumulativeRating"] = $this->CumulativeRating;
2552  }
2553  }
2554 
2566  private function AddAssociation($TableName, $FieldName, $Value, $Field = NULL)
2567  {
2568  # We should ignore duplicate key errors when doing inserts:
2569  $this->DB->SetQueryErrorsToIgnore( array(
2570  "/INSERT INTO ".$TableName."/" =>
2571  "/Duplicate entry '-?[0-9]+-[0-9]+(-[0-9]+)?' for key/"));
2572 
2573  # start out assuming no association will be added
2574  $AssociationAdded = FALSE;
2575 
2576  # convert new value to array if necessary
2577  $Values = is_array($Value) ? $Value : array($Value);
2578 
2579  # for each new value
2580  foreach ($Values as $Value)
2581  {
2582  # retrieve ID from value if necessary
2583  if (is_object($Value)) { $Value = $Value->Id(); }
2584 
2585  # Try to insert a new entry for this association.
2586  $this->DB->Query("INSERT INTO ".$TableName." SET"
2587  ." ResourceId = ".intval($this->Id)
2588  .", ".$FieldName." = ".intval($Value)
2589  .($Field ? ", FieldId = ".intval($Field->Id()) : ""));
2590 
2591  # If the insert ran without a duplicate key error,
2592  # then we added an assocation:
2593  if ($this->DB->IgnoredError() === FALSE)
2594  {
2595  $AssociationAdded = TRUE;
2596  }
2597  }
2598 
2599  # Clear ignored errors:
2600  $this->DB->SetQueryErrorsToIgnore( NULL );
2601 
2602  # report to caller whether association was added
2603  return $AssociationAdded;
2604  }
2605 
2617  private function RemoveAssociation($TableName, $FieldName, $Value, $Field = NULL)
2618  {
2619  # start out assuming no association will be removed
2620  $AssociationRemoved = FALSE;
2621 
2622  # convert value to array if necessary
2623  $Values = is_array($Value) ? $Value : array($Value);
2624 
2625  # for each value
2626  foreach ($Values as $Value)
2627  {
2628  # retrieve ID from value if necessary
2629  if (is_object($Value)) { $Value = $Value->Id(); }
2630 
2631  # remove any intersections with target ID from DB
2632  $this->DB->Query("DELETE FROM ".$TableName
2633  ." WHERE ResourceId = ".intval($this->Id)
2634  .($Field ? " AND FieldId = ".intval($Field->Id()) : "")
2635  ." AND ".$FieldName." = ".intval($Value));
2636  if ($this->DB->NumRowsAffected()) { $AssociationRemoved = TRUE; }
2637  }
2638 
2639  # report to caller whether association was added
2640  return $AssociationRemoved;
2641  }
2642 
2649  static protected function SetDatabaseAccessValues($ClassName)
2650  {
2651  if (!isset(self::$ItemIdColumnNames[$ClassName]))
2652  {
2653  self::$ItemIdColumnNames[$ClassName] = "ResourceId";
2654  self::$ItemNameColumnNames[$ClassName] = NULL;
2655  self::$ItemTableNames[$ClassName] = "Resources";
2656  }
2657  }
2658 }
GetByField($FieldNameOrObject, $ReturnObject=FALSE, $IncludeVariants=FALSE)
Old method for retrieving values, deprecated in favor of Get().
Definition: Resource.php:790
UserCanView(User $User, $AllowHooksToModify=TRUE)
Determine if the given user can view the resource, e.g., on the full record page. ...
Definition: Resource.php:2230
GetFilesForResource($ResourceOrResourceId, $ReturnObjects=TRUE)
Retrieve all files (names or objects) for specified resource.
Definition: FileFactory.php:39
GetImageUrls($FieldNameOrObject, $ImageSize=SPTImage::SIZE_FULL)
Get URLs for images, returning CleanURLs when possible and direct paths to image files otherwise...
Definition: Resource.php:1118
SetQualifier($FieldName, $NewValue)
Set qualifier using field name.
Definition: Resource.php:1767
UserCanViewMappedField($User, $MappedName)
Check whether user can view specified standard (mapped) metadata field.
Definition: Resource.php:2286
Metadata schema (in effect a Factory class for MetadataField).
Abstraction for forum messages and resource comments.
Definition: Message.php:14
SQL database abstraction object with smart query caching.
Definition: Database.php:22
UserCanModifyField($User, $FieldOrFieldName)
Check whether user is allowed to modify (Edit for perm resources, Author for temp) specified metadata...
Definition: Resource.php:2322
QueueSearchAndRecommenderUpdate()
Update search and recommender system DBs.
Definition: Resource.php:2334
GetAsArray($IncludeDisabledFields=FALSE, $ReturnObjects=TRUE)
Retrieve all resource values as an array.
Definition: Resource.php:828
Id()
Retrieve numerical resource ID.
Definition: Resource.php:294
$DB
Definition: Item.php:210
UserCanEditField($User, $FieldOrFieldName)
Check whether user is allowed to edit specified metadata field.
Definition: Resource.php:2299
SetQualifierByField($Field, $NewValue)
Set qualifier using field object.
Definition: Resource.php:1789
GetViewPageUrl()
Retrieve view page URL for this resource.
Definition: Resource.php:396
Rating($NewRating=NULL, $UserId=NULL)
Get/set rating by a specific user for resource.
Definition: Resource.php:2085
Definition: User.php:48
NumberOfComments()
Get current number of comments for resource.
Definition: Resource.php:2200
NumberOfRatings()
Get current number of ratings for resource.
Definition: Resource.php:2066
GetQualifier($FieldName, $ReturnObject=TRUE)
Retrieve qualifier by field name.
Definition: Resource.php:891
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:85
Schema()
Get MetadataSchema for resource.
Definition: Resource.php:312
Definition: Date.php:18
Metadata type representing non-hierarchical controlled vocabulary values.
UserCanEdit($User)
Determine if the given user can edit the resource.
Definition: Resource.php:2241
const MDFTYPE_CONTROLLEDNAME
GetForDisplay($FieldNameOrObject, $ReturnObject=TRUE, $IncludeVariants=FALSE)
Retrieve value using field name or field object, signaling EVENT_FIELD_DISPLAY_FILTER to allow other ...
Definition: Resource.php:754
Comments()
Get comments for resource.
Definition: Resource.php:2177
UpdateAutoupdateFields($UpdateType, $User=NULL)
Update the auto-updated fields as necessary.
Definition: Resource.php:262
Get($Field, $ReturnObject=FALSE, $IncludeVariants=FALSE)
Retrieve value using field name or field object.
Definition: Resource.php:420
static GetSchemaForResource($ResourceId)
Get schema ID for specified resource(s).
Definition: Resource.php:2351
Factory for manipulating File objects.
Definition: FileFactory.php:13
Common base class for persistent items store in database.
Definition: Item.php:13
GetQualifierByFieldId($FieldId, $ReturnObject=TRUE)
Retrieve qualifier by field ID.
Definition: Resource.php:905
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:2310
Clear($Field, $ValueToClear=NULL)
Clear field value.
Definition: Resource.php:1835
UserCanModify($User)
Check if the user is allowed to modify (Edit for perm resources, Author for temp) a specified resourc...
Definition: Resource.php:2263
UserCanAuthor($User)
Determine if the given user can edit the resource.
Definition: Resource.php:2252
GetByFieldId($FieldId, $ReturnObject=FALSE, $IncludeVariants=FALSE)
Retrieve value using field ID.
Definition: Resource.php:810
IsTempResource($NewSetting=NULL)
Get/set whether resource is a temporary record.
Definition: Resource.php:323
SetByField($Field, $NewValue)
Method replaced by Resource::Set(), preserved for backward compatibility.
Definition: Resource.php:1745
Object representing a locally-defined type of metadata field.
__construct($ResourceId)
Object constructor for loading an existing resource.
Definition: Resource.php:25
GetMapped($MappedName, $ReturnObject=FALSE, $IncludeVariants=FALSE)
Retrieve value using standard (mapped) field name.
Definition: Resource.php:874
$Id
Definition: Item.php:211
static SetDatabaseAccessValues($ClassName)
Set the database access values (table name, ID column name, name column name) for specified class...
Definition: Resource.php:2649
Represents a "resource" in CWIS.
Definition: Resource.php:13
GetQualifierByField($Field, $ReturnObject=TRUE)
Retrieve qualifier by Field object.
Definition: Resource.php:919
ClearByFieldId($FieldId, $ValueToClear=NULL)
Clear field value specified by field ID.
Definition: Resource.php:1823
SetQualifierByFieldId($FieldId, $NewValue)
Set qualifier using field ID.
Definition: Resource.php:1778
const SIZE_FULL
Definition: SPTImage.php:21
static ClearImageSymlinksForResource($ResourceId, $FieldId)
Remove symlinks used for to cache image mappings.
Definition: SPTImage.php:576
SchemaId()
Retrieve ID of schema for resource.
Definition: Resource.php:303
ScaledCumulativeRating()
Return cumulative rating scaled to 1/10th.
Definition: Resource.php:2050
Set($Field, $NewValue, $Reset=FALSE)
Set value using field name or field object.
Definition: Resource.php:1153
const UPDATEMETHOD_ONRECORDCREATE
static Create($SchemaId)
Create a new resource.
Definition: Resource.php:48
UserCanViewField($User, $FieldOrFieldName)
Check whether user is allowed to view specified metadata field.
Definition: Resource.php:2275
Metadata type representing hierarchical ("Tree") controlled vocabulary values.
SetByFieldId($FieldId, $NewValue)
Set field value using field ID.
Definition: Resource.php:1757
Classifications()
Get 2D array of classifications associated with resource.
Definition: Resource.php:2008
ClearByField($Field, $ValueToClear=NULL)
Clear field value.
Definition: Resource.php:1996
Class representing a stored (usually uploaded) file.
Definition: File.php:13
static ItemExists($Id)
Check whether an item exists with the specified ID.
Definition: Item.php:162
Factory for Resource objects.
CWIS-specific user class.
Definition: CWUser.php:13
CumulativeRating()
Get cumulative rating (range is usually 0-100)
Definition: Resource.php:2041
FieldIsSet($FieldNameOrObject, $IgnorePadding=FALSE)
Determine if the value for a field is set.
Definition: Resource.php:1053
Delete()
Remove resource (and accompanying associations) from database and delete any associated files...
Definition: Resource.php:142