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 record from database
213  $DB->Query("DELETE FROM Resources WHERE ResourceId = ".$this->Id());
214 
215  # drop item from search engine and recommender system
216  if ($G_SysConfig->SearchDBEnabled())
217  {
218  $SearchEngine = new SPTSearchEngine();
219  $SearchEngine->DropItem($this->Id());
220  }
221  if ($G_SysConfig->RecommenderDBEnabled())
222  {
223  $Recommender = new SPTRecommender();
224  $Recommender->DropItem($this->Id());
225  }
226 
227  # get the folders containing the resource
228  $FolderFactory = new FolderFactory();
229  $Folders = $FolderFactory->GetFoldersContainingItem(
230  $this->Id,
231  "Resource");
232 
233  # drop the resource from each folder it belongs to
234  foreach ($Folders as $Folder)
235  {
236  # mixed item type folder
237  if ($Folder->ContainsItem($this->Id, "Resource"))
238  {
239  $Folder->RemoveItem($this->Id, "Resource");
240  }
241 
242  # single item type folder
243  else
244  {
245  $Folder->RemoveItem($this->Id);
246  }
247  }
248 
249  # delete any resource comments
250  $DB->Query("DELETE FROM Messages WHERE ParentId = ".$this->Id);
251  }
252 
259  public function UpdateAutoupdateFields($UpdateType, $User=NULL)
260  {
261  # update all the timestamp fields as required
262  $TimestampFields = $this->Schema()->GetFields(
264  foreach ($TimestampFields as $Field)
265  {
266  if ($Field->UpdateMethod() == $UpdateType)
267  {
268  $this->Set($Field, "now");
269  }
270  }
271 
272  # if a user was provided, update the user fields as well
273  if (!is_null($User) && !$User->IsAnonymous())
274  {
275  $UserFields = $this->Schema()->GetFields(
277  foreach ($UserFields as $Field)
278  {
279  if ($Field->UpdateMethod() == $UpdateType)
280  {
281  $this->Set($Field, $User);
282  }
283  }
284  }
285  }
286 
291  public function Id()
292  {
293  return $this->Id;
294  }
295 
300  public function SchemaId()
301  {
302  return $this->SchemaId;
303  }
304 
309  public function Schema()
310  {
311  return self::$Schemas[$this->SchemaId];
312  }
313 
320  public function IsTempResource($NewSetting = NULL)
321  {
322  # if new temp resource setting supplied
323  if (!is_null($NewSetting))
324  {
325  # if caller requested to switch
326  $DB = $this->DB;
327  if ((($this->Id() < 0) && ($NewSetting == FALSE))
328  || (($this->Id() >= 0) && ($NewSetting == TRUE)))
329  {
330  $Factory = new ResourceFactory($this->SchemaId);
331 
332  # lock DB tables to prevent next ID from being grabbed
333  $DB->Query("LOCK TABLES Resources WRITE");
334 
335  # get next resource ID as appropriate
336  $OldResourceId = $this->Id;
337  if ($NewSetting == TRUE)
338  {
339  $this->Id = $Factory->GetNextTempItemId();
340  }
341  else
342  {
343  $this->Id = $Factory->GetNextItemId();
344  }
345 
346  # change resource ID
347  $DB->Query("UPDATE Resources SET ResourceId = ".
348  $this->Id. " WHERE ResourceId = ".$OldResourceId);
349 
350  # release DB tables
351  $DB->Query("UNLOCK TABLES");
352 
353  # change associations
354  unset($this->ClassificationCache);
355  $DB->Query("UPDATE ResourceClassInts SET ResourceId = ".
356  $this->Id. " WHERE ResourceId = ".$OldResourceId);
357  unset($this->ControlledNameCache);
358  unset($this->ControlledNameVariantCache);
359  $DB->Query("UPDATE ResourceNameInts SET ResourceId = ".
360  $this->Id. " WHERE ResourceId = ".$OldResourceId);
361  $DB->Query("UPDATE Files SET ResourceId = ".
362  $this->Id. " WHERE ResourceId = ".$OldResourceId);
363  $DB->Query("UPDATE ReferenceInts SET SrcResourceId = ".
364  $this->Id. " WHERE SrcResourceId = ".$OldResourceId);
365  $DB->Query("UPDATE ResourceImageInts SET ResourceId = ".
366  $this->Id. " WHERE ResourceId = ".$OldResourceId);
367  $DB->Query("UPDATE ResourceUserInts SET ResourceId = ".
368  $this->Id. " WHERE ResourceId = ".$OldResourceId);
369 
370  # signal event as appropriate
371  if ($NewSetting === FALSE)
372  {
373  $GLOBALS["AF"]->SignalEvent("EVENT_RESOURCE_ADD", array(
374  "Resource" => $this,
375  ));
376  }
377  }
378  }
379 
380  # report to caller whether we are a temp resource
381  return ($this->Id() < 0) ? TRUE : FALSE;
382  }
383 
384 
385  # --- Generic Attribute Retrieval Methods -------------------------------
386 
391  public function GetViewPageUrl()
392  {
393  # put our Id into the ViewPage from our schema
394  $Url = str_replace(
395  "\$ID", $this->Id(),
396  $this->Schema()->ViewPage());
397 
398  # return clean url, if one is available
399  return $GLOBALS["AF"]->GetCleanUrlForPath($Url);
400  }
401 
415  public function Get($Field, $ReturnObject = FALSE, $IncludeVariants = FALSE)
416  {
417  # load field object if not already supplied
418  $Field = is_object($Field) ? $Field : $this->Schema()->GetField($Field);
419 
420  if ($Field->SchemaId() != $this->SchemaId())
421  {
422  throw new Exception("Attempt to get a value for a field"
423  ." from a different schema."
424  ." (Field: ".$Field->Name()." [".$Field->Id()
425  ."], Field Schema: ".$Field->SchemaId()
426  .", Resource Schema: ".$this->SchemaId()
427  .")");
428  }
429 
430  # grab database field name
431  $DBFieldName = $Field->DBFieldName();
432 
433  # format return value based on field type
434  switch ($Field->Type())
435  {
439  $ReturnValue = isset($this->ValueCache[$DBFieldName])
440  ? (string)$this->ValueCache[$DBFieldName] : NULL;
441  break;
442 
444  $ReturnValue = isset($this->ValueCache[$DBFieldName])
445  ? (int)$this->ValueCache[$DBFieldName] : NULL;
446  break;
447 
449  $ReturnValue = isset($this->ValueCache[$DBFieldName])
450  ? (bool)$this->ValueCache[$DBFieldName] : NULL;
451  break;
452 
454  $ReturnValue = array("X" => (float)$this->ValueCache[$DBFieldName."X"],
455  "Y" => (float)$this->ValueCache[$DBFieldName."Y"]);
456  break;
457 
459  $Date = new Date($this->ValueCache[$DBFieldName."Begin"],
460  $this->ValueCache[$DBFieldName."End"],
461  $this->ValueCache[$DBFieldName."Precision"]);
462  if ($ReturnObject)
463  {
464  $ReturnValue = $Date;
465  }
466  else
467  {
468  $ReturnValue = $Date->Formatted();
469  }
470  break;
471 
473  $ReturnValue = $this->ValueCache[$DBFieldName];
474  break;
475 
477  # start with empty array
478  $ReturnValue = array();
479 
480  # if classification cache has not been loaded
481  if (!isset($this->ClassificationCache))
482  {
483  # load all classifications associated with this resource into cache
484  $this->ClassificationCache = array();
485  $this->DB->Query(
486  "SELECT Classifications.ClassificationId,"
487  ." Classifications.FieldId,ClassificationName"
488  ." FROM ResourceClassInts, Classifications"
489  ." WHERE ResourceClassInts.ResourceId = ".$this->Id
490  ." AND ResourceClassInts.ClassificationId"
491  ." = Classifications.ClassificationId");
492  while ($Record = $this->DB->FetchRow())
493  {
494  $ClassId = $Record["ClassificationId"];
495  $this->ClassificationCache[$ClassId]["Name"]
496  = $Record["ClassificationName"];
497  $this->ClassificationCache[$ClassId]["FieldId"]
498  = $Record["FieldId"];
499  }
500  }
501  # for each entry in classification cache
502  foreach ($this->ClassificationCache as
503  $ClassificationId => $ClassificationInfo)
504  {
505  # if classification ID matches field we are looking for
506  if ($ClassificationInfo["FieldId"] == $Field->Id())
507  {
508  # add field to result
509  if ($ReturnObject)
510  {
511  $ReturnValue[$ClassificationId] =
512  new Classification($ClassificationId);
513  }
514  else
515  {
516  $ReturnValue[$ClassificationId] = $ClassificationInfo["Name"];
517  }
518  }
519  }
520  break;
521 
524  # start with empty array
525  $ReturnValue = array();
526 
527  # if controlled name cache has not been loaded
528  if (!isset($this->ControlledNameCache))
529  {
530  # load all controlled names associated with this resource into cache
531  $this->ControlledNameCache = array();
532  $this->DB->Query(
533  "SELECT ControlledNames.ControlledNameId,"
534  ." ControlledNames.FieldId,ControlledName"
535  ." FROM ResourceNameInts, ControlledNames"
536  ." WHERE ResourceNameInts.ResourceId = ".$this->Id
537  ." AND ResourceNameInts.ControlledNameId"
538  ." = ControlledNames.ControlledNameId"
539  ." ORDER BY ControlledNames.ControlledName ASC");
540  while ($Record = $this->DB->FetchRow())
541  {
542  $CNameId = $Record["ControlledNameId"];
543  $this->ControlledNameCache[$CNameId]["Name"]
544  = $Record["ControlledName"];
545  $this->ControlledNameCache[$CNameId]["FieldId"]
546  = $Record["FieldId"];
547  }
548  }
549 
550  # if variant names requested and variant name cache has not been loaded
551  if ($IncludeVariants && !isset($this->ControlledNameVariantCache))
552  {
553  # load all controlled names associated with this resource into cache
554  $this->ControlledNameVariantCache = array();
555  $this->DB->Query("SELECT ControlledNames.ControlledNameId,"
556  ." ControlledNames.FieldId,"
557  ." ControlledName, VariantName"
558  ." FROM ResourceNameInts, ControlledNames, VariantNames"
559  ." WHERE ResourceNameInts.ResourceId = ".$this->Id
560  ." AND ResourceNameInts.ControlledNameId"
561  ." = ControlledNames.ControlledNameId"
562  ." AND VariantNames.ControlledNameId"
563  ." = ControlledNames.ControlledNameId");
564  while ($Record = $this->DB->FetchRow())
565  {
566  $this->ControlledNameVariantCache[$Record["ControlledNameId"]][]
567  = $Record["VariantName"];
568  }
569  }
570 
571  # for each entry in controlled name cache
572  foreach ($this->ControlledNameCache as
573  $CNameId => $ControlledNameInfo)
574  {
575  # if controlled name type matches field we are looking for
576  if ($ControlledNameInfo["FieldId"] == $Field->Id())
577  {
578  # if objects requested
579  if ($ReturnObject)
580  {
581  $ReturnValue[$CNameId] =
582  new ControlledName($CNameId);
583  }
584  else
585  {
586  # if variant names requested
587  if ($IncludeVariants)
588  {
589  # add field to result
590  $ReturnValue[] = $ControlledNameInfo["Name"];
591 
592  # add any variant names to result
593  if (isset($this->ControlledNameVariantCache[$CNameId]))
594  {
595  $ReturnValue = array_merge(
596  $ReturnValue,
597  $this->ControlledNameVariantCache[$CNameId]);
598  }
599  }
600  else
601  {
602  # add field with index to result
603  $ReturnValue[$CNameId] =
604  $ControlledNameInfo["Name"];
605  }
606  }
607  }
608  }
609  break;
610 
612  # start out assuming no associated users
613  $ReturnValue = array();
614 
615  # query the database to get the associated userids
616  $this->DB->Query(
617  "SELECT UserId FROM ResourceUserInts WHERE ".
618  "ResourceId=".intval($this->Id).
619  " AND FieldId=".intval($Field->Id())
620  ." AND UserId IN (SELECT UserId FROM APUsers)"
621  );
622  $UserIds = $this->DB->FetchColumn("UserId");
623 
624  # convert each userid to either a name or a CWUser object
625  foreach ($UserIds as $UserId)
626  {
627  $User = new CWUser(intval($UserId));
628  if ($ReturnObject)
629  {
630  $ReturnValue[$UserId] = $User;
631  }
632  else
633  {
634  $ReturnValue[$UserId] = $User->Get("UserName");
635  }
636  }
637  break;
638 
640  # start out assuming no images will be found
641  $ReturnValue = array();
642 
643  # find all images associated with this resource
644  $this->DB->Query("SELECT ImageId FROM ResourceImageInts"
645  ." WHERE ResourceId = ".intval($this->Id())
646  ." AND FieldId = ".intval($Field->Id()));
647 
648  # if images were found
649  if ($this->DB->NumRowsSelected())
650  {
651  # if we are to return an object
652  $ImageIds = $this->DB->FetchColumn("ImageId");
653  if ($ReturnObject)
654  {
655  # load array of Image objects for return value
656  foreach ($ImageIds as $ImageId)
657  {
658  $ReturnValue[$ImageId] = new SPTImage($ImageId);
659  }
660  }
661  else
662  {
663  # load array of Image ids for return value
664  $ReturnValue = $ImageIds;
665  }
666  }
667  break;
668 
670  # retrieve files using factory
671  $Factory = new FileFactory($Field->Id());
672  $ReturnValue = $Factory->GetFilesForResource(
673  $this->Id, $ReturnObject);
674  break;
675 
677  # query for resource references
678  $this->DB->Query("
679  SELECT * FROM ReferenceInts
680  WHERE FieldId = '".addslashes($Field->Id())."'
681  AND SrcResourceId = '".addslashes($this->Id())."'");
682 
683  $ReturnValue = array();
684 
685  # return each reference as a Resource object
686  if ($ReturnObject)
687  {
688  $FoundErrors = FALSE;
689 
690  while (FALSE !== ($Record = $this->DB->FetchRow()))
691  {
692  $ReferenceId = $Record["DstResourceId"];
693  $Reference = new Resource($ReferenceId);
694  $ReturnValue[$ReferenceId] = $Reference;
695  }
696  }
697 
698  # return each reference as a resource ID
699  else
700  {
701  while (FALSE !== ($Record = $this->DB->FetchRow()))
702  {
703  $ReferenceId = $Record["DstResourceId"];
704  $ReturnValue[$ReferenceId] = $ReferenceId;
705  }
706  }
707  break;
708 
709  default:
710  # ERROR OUT
711  throw new Exception("Attempt to retrieve "
712  ."unknown field type (".$Field->Type().")");
713  break;
714  }
715 
716  # return formatted value to caller
717  return $ReturnValue;
718  }
719 
739  public function GetForDisplay(
740  $FieldNameOrObject, $ReturnObject = TRUE, $IncludeVariants = FALSE)
741  {
742  # normalize metadata field for use by any hooked code
743  $Field = is_object($FieldNameOrObject) ? $FieldNameOrObject
744  : $this->Schema()->GetFieldByName($FieldNameOrObject);
745 
746  # retrieve value
747  $Value = $this->Get($Field, $ReturnObject, $IncludeVariants);
748 
749  # signal event to allowed hooked code to modify value
750  $SignalResult = $GLOBALS["AF"]->SignalEvent(
751  "EVENT_FIELD_DISPLAY_FILTER", array(
752  "Field" => $Field,
753  "Resource" => $this,
754  "Value" => $Value));
755 
756  # return possibly modified value to caller
757  return $SignalResult["Value"];
758  }
759 
775  public function GetByField($FieldNameOrObject,
776  $ReturnObject = FALSE, $IncludeVariants = FALSE)
777  {
778  return $this->Get($FieldNameOrObject, $ReturnObject, $IncludeVariants);
779  }
780 
795  public function GetByFieldId(
796  $FieldId, $ReturnObject = FALSE, $IncludeVariants = FALSE)
797  {
798  return $this->Get($FieldId, $ReturnObject, $IncludeVariants);
799  }
800 
813  public function GetAsArray($IncludeDisabledFields = FALSE, $ReturnObjects = TRUE)
814  {
815  # retrieve field info
816  $Fields = $this->Schema()->GetFields();
817 
818  # for each field
819  foreach ($Fields as $Field)
820  {
821  # if field is enabled or caller requested disabled fields
822  if ($Field->Enabled() || $IncludeDisabledFields)
823  {
824  # retrieve info and add it to the array
825  $FieldStrings[$Field->Name()] = $this->Get($Field, $ReturnObjects);
826 
827  # if field uses qualifiers
828  if ($Field->UsesQualifiers())
829  {
830  # get qualifier attributes and add to the array
831  $FieldStrings[$Field->Name()." Qualifier"] =
832  $this->GetQualifierByField($Field, $ReturnObjects);
833  }
834  }
835  }
836 
837  # add in internal values
838  $FieldStrings["ResourceId"] = $this->Id();
839  $FieldStrings["CumulativeRating"] = $this->CumulativeRating();
840 
841  # return array to caller
842  return $FieldStrings;
843  }
844 
859  public function GetMapped(
860  $MappedName, $ReturnObject = FALSE, $IncludeVariants = FALSE)
861  {
862  $FieldId = $this->Schema()->StdNameToFieldMapping($MappedName);
863  return $FieldId
864  ? $this->Get($FieldId, $ReturnObject, $IncludeVariants)
865  : NULL;
866  }
867 
876  public function GetQualifier($FieldName, $ReturnObject = TRUE)
877  {
878  $Field = $this->Schema()->GetFieldByName($FieldName);
879  return $this->GetQualifierByField($Field, $ReturnObject);
880  }
881 
890  public function GetQualifierByFieldId($FieldId, $ReturnObject = TRUE)
891  {
892  $Field = $this->Schema()->GetField($FieldId);
893  return ($Field) ? $this->GetQualifierByField($Field, $ReturnObject) : NULL;
894  }
895 
904  public function GetQualifierByField($Field, $ReturnObject = TRUE)
905  {
906  # return NULL if field is invalid
907  if (!($Field instanceof MetadataField)) { return NULL; }
908 
909  # assume no qualifiers if not otherwise determined
910  $ReturnValue = NULL;
911 
912  # if field uses qualifiers
913  if ($Field->UsesQualifiers())
914  {
915  # retrieve qualifiers based on field type
916  switch ($Field->Type())
917  {
921  # retrieve list of items
922  $Items = $this->Get($Field);
923 
924  # if field uses item-level qualifiers
925  if ($Field->HasItemLevelQualifiers())
926  {
927  # determine general item name in DB
928  $TableName = ($Field->Type() == MetadataSchema::MDFTYPE_TREE)
929  ? "Classification" : "ControlledName";
930 
931  # for each item
932  foreach ($Items as $ItemId => $ItemName)
933  {
934  # look up qualifier for item
935  $QualId = $this->DB->Query(
936  "SELECT * FROM ".$TableName."s"
937  ." WHERE ".$TableName."Id = ".$ItemId,
938  "QualifierId");
939 
940 
941  if ($QualId > 0)
942  {
943  # if object was requested by caller
944  if ($ReturnObject)
945  {
946  # load qualifier and add to return value array
947  $ReturnValue[$ItemId] = new Qualifier($QualId);
948  }
949  else
950  {
951  # add qualifier ID to return value array
952  $ReturnValue[$ItemId] = $QualId;
953  }
954  }
955  else
956  {
957  # add NULL to return value array for this item
958  $ReturnValue[$ItemId] = NULL;
959  }
960  }
961  }
962  else
963  {
964  # for each item
965  foreach ($Items as $ItemId => $ItemName)
966  {
967  # if object was requested by caller
968  if ($ReturnObject)
969  {
970  # load default qualifier and add to return value array
971  $ReturnValue[$ItemId] = new Qualifier(
972  $Field->DefaultQualifier());
973  }
974  else
975  {
976  # add default qualifier ID to return value array
977  $ReturnValue[$ItemId] = $Field->DefaultQualifier();
978  }
979  }
980  }
981  break;
982 
983  default:
984  # if field uses item-level qualifiers
985  if ($Field->HasItemLevelQualifiers())
986  {
987  # if qualifier available
988  if ($this->ValueCache[$Field->DBFieldName()."Qualifier"] > 0)
989  {
990  # if object was requested by caller
991  $QFieldName = $Field->DBFieldName()."Qualifier";
992  if ($ReturnObject)
993  {
994  # return qualifier for field
995  $ReturnValue = new Qualifier(
996  $this->ValueCache[$QFieldName]);
997  }
998  else
999  {
1000  # return qualifier ID for field
1001  $ReturnValue = $this->ValueCache[$QFieldName];
1002  }
1003  }
1004  }
1005  else
1006  {
1007  # if default qualifier available
1008  if ($Field->DefaultQualifier() > 0)
1009  {
1010  # if object was requested by caller
1011  if ($ReturnObject)
1012  {
1013  # return default qualifier
1014  $ReturnValue = new Qualifier($Field->DefaultQualifier());
1015  }
1016  else
1017  {
1018  # return default qualifier ID
1019  $ReturnValue = $Field->DefaultQualifier();
1020  }
1021  }
1022  }
1023  break;
1024  }
1025  }
1026 
1027  # return qualifier object or ID (or array of same) to caller
1028  return $ReturnValue;
1029  }
1030 
1038  public function FieldIsSet($FieldNameOrObject, $IgnorePadding=FALSE)
1039  {
1040  # load field object if needed
1041  $Field = is_object($FieldNameOrObject) ? $FieldNameOrObject
1042  : $this->Schema()->GetFieldByName($FieldNameOrObject);
1043 
1044  # return no value found if we don't have a valid field
1045  if (!($Field instanceof MetadataField)) { return FALSE; }
1046 
1047  # get the value
1048  $Value = $this->Get($Field);
1049 
1050  # checks depend on the field type
1051  switch ($Field->Type())
1052  {
1057  return !is_null($Value)
1058  && strlen($Value)
1059  && (!$IgnorePadding || ($IgnorePadding && strlen(trim($Value))));
1060 
1062  return !is_null($Value)
1063  && strlen($Value);
1064 
1066  return !is_null($Value["X"])
1067  && !is_null($Value["Y"])
1068  && strlen(trim($Value["X"]))
1069  && strlen(trim($Value["Y"]));
1070 
1072  return !is_null($Value)
1073  && strlen(trim($Value))
1074  && $Value != "0000-00-00";
1075 
1077  return !is_null($Value)
1078  && strlen(trim($Value))
1079  && $Value != "0000-00-00 00:00:00";
1080 
1087  return count($Value) > 0;
1088 
1090  $Factory = new CWUserFactory();
1091  return !is_null($Value)
1092  && strlen($Value)
1093  && $Factory->UserNameExists($Value);
1094 
1095  default:
1096  return FALSE;
1097  }
1098  }
1099 
1108  public function GetImageUrls($FieldNameOrObject, $ImageSize=SPTImage::SIZE_FULL)
1109  {
1110  $Result = array();
1111 
1112  # get our target field and extract its values
1113  $Field = is_object($FieldNameOrObject) ? $FieldNameOrObject
1114  : $this->Schema()->GetField($FieldNameOrObject);
1115  $Images = $this->Get($Field, TRUE);
1116 
1117  # iterate over our images getting URLs for each
1118  $Index = 0;
1119  foreach ($Images as $Image)
1120  {
1121  $Result[$Image->Id()] = $Image->GetImageUrlForResource(
1122  $this->Id(), $Field->Id(), $Index, $ImageSize);
1123  $Index++;
1124  }
1125 
1126  return $Result;
1127  }
1128 
1129  # --- Generic Attribute Setting Methods ---------------------------------
1130 
1143  public function Set($Field, $NewValue, $Reset=FALSE)
1144  {
1145  # load field object if not already supplied
1146  $Field = is_object($Field) ? $Field
1147  : (is_numeric($Field) ? $this->Schema()->GetField($Field)
1148  : $this->Schema()->GetFieldByName($Field));
1149 
1150  # return if we don't have a valid field
1151  if (!($Field instanceof MetadataField)) { return; }
1152 
1153  if ($Field->SchemaId() != $this->SchemaId())
1154  {
1155  throw new Exception("Attempt to set a value for a field "
1156  ."from a different schema.");
1157  }
1158 
1159  # grab commonly-used values for local use
1160  $DB = $this->DB;
1161  $ResourceId = $this->Id;
1162 
1163  # grab database field name
1164  $DBFieldName = $Field->DBFieldName();
1165 
1166  # Flag to deterimine if we've actually changed anything.
1167  $UpdateModTime = FALSE;
1168 
1169  # store value in DB based on field type
1170  switch ($Field->Type())
1171  {
1175  if ($this->ValueCache[$DBFieldName] != $NewValue)
1176  {
1177  # save value directly to DB
1178  $DB->Query("UPDATE Resources SET `"
1179  .$DBFieldName."` = '".addslashes($NewValue)."' "
1180  ."WHERE ResourceId = ".$ResourceId);
1181 
1182  # save value locally
1183  $this->ValueCache[$DBFieldName] = $NewValue;
1184  $UpdateModTime=TRUE;
1185  }
1186  break;
1187 
1189  if ( $this->ValueCache[$DBFieldName] != $NewValue )
1190  {
1191  # save value directly to DB
1192  if (is_null($NewValue))
1193  {
1194  $DB->Query("UPDATE Resources SET `"
1195  .$DBFieldName."` = NULL"
1196  ." WHERE ResourceId = ".$ResourceId);
1197  }
1198  else
1199  {
1200  $DB->Query("UPDATE Resources SET `"
1201  .$DBFieldName."` = ".intval($NewValue)
1202  ." WHERE ResourceId = ".$ResourceId);
1203  }
1204 
1205  # save value locally
1206  $this->ValueCache[$DBFieldName] = $NewValue;
1207  $UpdateModTime = TRUE;
1208  }
1209  break;
1210 
1211 
1213  if ($this->ValueCache[$DBFieldName."X"] != $NewValue["X"] ||
1214  $this->ValueCache[$DBFieldName."Y"] != $NewValue["Y"] )
1215  {
1216  if (is_null($NewValue))
1217  {
1218  $DB->Query("UPDATE Resources SET "
1219  ."`".$DBFieldName."X` = NULL, "
1220  ."`".$DBFieldName."Y` = NULL "
1221  ."WHERE ResourceId = ".$ResourceId);
1222  $this->ValueCache[$DBFieldName."X"] = NULL;
1223  $this->ValueCache[$DBFieldName."Y"] = NULL;
1224  }
1225  else
1226  {
1227  $DB->Query("UPDATE Resources SET "
1228  ."`".$DBFieldName."X` = " .(strlen($NewValue["X"])
1229  ? "'".$NewValue["X"]."'" : "NULL").", "
1230  ."`".$DBFieldName."Y` = ".(strlen($NewValue["Y"])
1231  ? "'".$NewValue["Y"]."'" : "NULL")
1232  ." WHERE ResourceId = ".$ResourceId);
1233 
1234  $Digits = $Field->PointDecimalDigits();
1235 
1236  $this->ValueCache[$DBFieldName."X"] =
1237  strlen($NewValue["X"]) ?
1238  round($NewValue["X"], $Digits) : NULL;
1239  $this->ValueCache[$DBFieldName."Y"] =
1240  strlen($NewValue["Y"]) ?
1241  round($NewValue["Y"], $Digits) : NULL;
1242  }
1243  $UpdateModTime = TRUE;
1244  }
1245  break;
1246 
1248  if ($this->ValueCache[$DBFieldName] != $NewValue)
1249  {
1250  # save value directly to DB
1251  if (is_null($NewValue))
1252  {
1253  $DB->Query("UPDATE Resources SET `"
1254  .$DBFieldName."` = NULL"
1255  ." WHERE ResourceId = ".$ResourceId);
1256  }
1257  else
1258  {
1259  $NewValue = $NewValue ? "1" : "0";
1260  $DB->Query("UPDATE Resources SET `"
1261  .$DBFieldName."` = ".$NewValue
1262  ." WHERE ResourceId = ".$ResourceId);
1263  }
1264 
1265  $this->ValueCache[$DBFieldName] = $NewValue;
1266 
1267  $UpdateModTime = TRUE;
1268  }
1269  break;
1270 
1272  $OldValue = $this->Get($Field);
1273  # value comes back as array (UserId => UserName), just get the Ids
1274  $OldValue = array_keys($OldValue);
1275 
1276  # input to Set() for these fields is one of
1277  # 1. an int specifying a UserId
1278  if (is_numeric($NewValue))
1279  {
1280  $NewValue = array($NewValue);
1281  }
1282  # 2. a CWUser object
1283  elseif ($NewValue instanceof CWUser)
1284  {
1285  $NewValue = array($NewValue->Id());
1286  }
1287  # 3. an array keyed by UserId (don't care about the values)
1288  elseif (is_array($NewValue))
1289  {
1290  $NewValue = array_keys($NewValue);
1291  }
1292  else
1293  {
1294  throw new Exception("Unknown format for NewValue in a User field");
1295  }
1296 
1297  # if this is a unique field, only accept the first of the options given
1298  if ($Field->AllowMultiple() == FALSE && count($NewValue) > 1)
1299  {
1300  $NewValue = array_slice($NewValue, 0, 1, TRUE);
1301  }
1302 
1303  # sort new and old values so we can directly compare
1304  sort($OldValue);
1305  sort($NewValue);
1306 
1307  # if the value has changed
1308  if ($OldValue != $NewValue)
1309  {
1310  if ($Reset || $Field->AllowMultiple() == FALSE )
1311  {
1312  $ToRemove = array_diff($OldValue, $NewValue);
1313  $this->RemoveAssociation(
1314  "ResourceUserInts", "UserId", $ToRemove, $Field);
1315  }
1316 
1317  # associate with resource if not already associated
1318  $this->AddAssociation("ResourceUserInts",
1319  "UserId",
1320  $NewValue, $Field);
1321 
1322  $UpdateModTime=TRUE;
1323  }
1324  break;
1325 
1327  if (is_null($NewValue))
1328  {
1329  if (!is_null($this->ValueCache[$DBFieldName."Begin"]) ||
1330  !is_null($this->ValueCache[$DBFieldName."End"]) ||
1331  !is_null($this->ValueCache[$DBFieldName."Precision"]))
1332  {
1333  # clear date object values in DB
1334  $DB->Query("UPDATE Resources SET "
1335  .$DBFieldName."Begin = '', "
1336  .$DBFieldName."End = '', "
1337  .$DBFieldName."Precision = '' "
1338  ."WHERE ResourceId = ".$ResourceId);
1339 
1340  # clear value locally
1341  $this->ValueCache[$DBFieldName."Begin"] = NULL;
1342  $this->ValueCache[$DBFieldName."End"] = NULL;
1343  $this->ValueCache[$DBFieldName."Precision"] = NULL;
1344  $UpdateModTime=TRUE;
1345  }
1346  }
1347  else
1348  {
1349 
1350  # if we were given a date object
1351  if (is_object($NewValue))
1352  {
1353  # use supplied date object
1354  $Date = $NewValue;
1355  }
1356  else
1357  {
1358  # create date object
1359  $Date = new Date($NewValue);
1360  }
1361 
1362  $OldDate = new Date(
1363  $this->ValueCache[$DBFieldName."Begin"],
1364  $this->ValueCache[$DBFieldName."End"],
1365  $this->ValueCache[$DBFieldName."Precision"]);
1366 
1367  if ($OldDate->BeginDate() != $Date->BeginDate() ||
1368  $OldDate->EndDate() != $Date->EndDate() ||
1369  $OldDate->Precision() != $Date->Precision() )
1370  {
1371  # extract values from date object and store in DB
1372  $BeginDate = !is_null($Date->BeginDate()) ?
1373  "'".$Date->BeginDate()."'" : "NULL" ;
1374  $EndDate = !is_null($Date->EndDate()) ?
1375  "'".$Date->EndDate()."'" : "NULL" ;
1376 
1377  $DB->Query("UPDATE Resources SET "
1378  .$DBFieldName."Begin = ".$BeginDate.", "
1379  .$DBFieldName."End = ".$EndDate.", "
1380  .$DBFieldName."Precision = '".$Date->Precision()."' "
1381  ."WHERE ResourceId = ".$ResourceId);
1382 
1383  # save values locally
1384  $this->ValueCache[$DBFieldName."Begin"] = $Date->BeginDate();
1385  $this->ValueCache[$DBFieldName."End"] = $Date->EndDate();
1386  $this->ValueCache[$DBFieldName."Precision"] = $Date->Precision();
1387  $UpdateModTime=TRUE;
1388  }
1389  }
1390  break;
1391 
1393  if (is_null($NewValue) || !strlen(trim($NewValue)))
1394  {
1395  $DateValue = $NewValue;
1396 
1397  if (!is_null($this->ValueCache[$DBFieldName]))
1398  {
1399  # save value directly to DB
1400  $DB->Query("UPDATE Resources SET "
1401  ."`".$DBFieldName."` = NULL "
1402  ."WHERE ResourceId = ".$ResourceId);
1403  $UpdateModTime = TRUE;
1404  }
1405  }
1406  else
1407  {
1408  # assume value is date and use directly
1409  $TimestampValue = strtotime($NewValue);
1410 
1411  # use the new value if the date is valid
1412  if ($TimestampValue !== FALSE && $TimestampValue >= 0)
1413  {
1414  $DateValue = date("Y-m-d H:i:s", $TimestampValue);
1415 
1416  if ($this->ValueCache[$DBFieldName] != $DateValue)
1417  {
1418  # save value directly to DB
1419  $DB->Query("UPDATE Resources SET "
1420  ."`".$DBFieldName."` = '".addslashes($DateValue)."' "
1421  ."WHERE ResourceId = ".$ResourceId);
1422  $UpdateModTime=TRUE;
1423  }
1424  }
1425 
1426  # continue using the old value if invalid
1427  else
1428  {
1429  $DateValue = $this->Get($Field);
1430  }
1431  }
1432 
1433  # save value locally
1434  $this->ValueCache[$DBFieldName] = $DateValue;
1435  break;
1436 
1438  $OldValue = $this->Get($Field);
1439 
1440  # if incoming value is array
1441  if (is_array($NewValue))
1442  {
1443  if ($OldValue != $NewValue)
1444  {
1445  if ($Reset)
1446  {
1447  # remove values that were in the old value
1448  # but not the new one
1449  $ToRemove = array_diff(array_keys($OldValue),
1450  array_keys($NewValue));
1451  foreach ($ToRemove as $ClassificationId)
1452  {
1453  $this->RemoveAssociation("ResourceClassInts",
1454  "ClassificationId",
1455  $ClassificationId);
1456  $Class = new Classification($ClassificationId);
1457  $Class->RecalcResourceCount();
1458  }
1459  }
1460 
1461  # for each element of array
1462  foreach ($NewValue as
1463  $ClassificationId => $ClassificationName)
1464  {
1465  $Class = new Classification($ClassificationId);
1466  if ($Class->FieldId() == $Field->Id())
1467  {
1468  # associate with resource if not already associated
1469  if ($this->AddAssociation("ResourceClassInts",
1470  "ClassificationId", $ClassificationId))
1471  {
1472  $Class->UpdateLastAssigned();
1473  $Class->RecalcResourceCount();
1474  }
1475  }
1476  else
1477  {
1478  throw new Exception(
1479  "Attempting to store classification from "
1480  ."Field ".$Class->FieldId()." into Field "
1481  .$Field->Id() );
1482  }
1483 
1484  }
1485 
1486  $UpdateModTime=TRUE;
1487  }
1488  }
1489  else
1490  {
1491  # associate with resource if not already associated
1492  if (is_object($NewValue))
1493  {
1494  $Class = $NewValue;
1495  $NewValue = $Class->Id();
1496  }
1497  else
1498  {
1499  $Class = new Classification($NewValue);
1500  }
1501 
1502  if (!array_key_exists($Class->Id(), $OldValue))
1503  {
1504 
1505  $this->AddAssociation("ResourceClassInts",
1506  "ClassificationId",
1507  $NewValue);
1508  $Class->UpdateLastAssigned();
1509  $Class->RecalcResourceCount();
1510  $UpdateModTime=TRUE;
1511  }
1512  }
1513 
1514  # clear our classification cache
1515  if ($UpdateModTime)
1516  {
1517  unset($this->ClassificationCache);
1518  }
1519  break;
1520 
1523  $OldValue = $this->Get($Field);
1524 
1525  # input to Set() for these fields is one of
1526  # 1. an int specifying a ControlledNameId
1527  # 2. a ControlledName object
1528  # 3. an array with keys giving Ids and values giving ControlledNames
1529  #
1530  # normalize 1 and 2 into 3 for simplicity of processing
1531  if (is_object($NewValue) || !is_array($NewValue) )
1532  {
1533  if (!is_object($NewValue))
1534  {
1535  $NewValue = new ControlledName($NewValue);
1536  }
1537 
1538  $TmpValue = array();
1539  $TmpValue[$NewValue->Id()] = $NewValue->Name();
1540 
1541  $NewValue = $TmpValue;
1542  }
1543 
1544  # if this is a unique field, only accept the first of the options given
1545  # NB: all ControlledNames implicitly AllowMultiple
1546  if ($Field->Type() == MetadataSchema::MDFTYPE_OPTION &&
1547  $Field->AllowMultiple() == FALSE && count($NewValue) > 1)
1548  {
1549  $NewValue = array_slice($NewValue, 0, 1, TRUE);
1550  }
1551 
1552  # if the value has changed
1553  if ($OldValue != $NewValue)
1554  {
1555  if ($Reset || ($Field->Type() == MetadataSchema::MDFTYPE_OPTION
1556  && $Field->AllowMultiple() == FALSE ) )
1557  {
1558  $ToRemove = array_diff(array_keys($OldValue),
1559  array_keys($NewValue));
1560  foreach ($ToRemove as $CNId)
1561  {
1562  $this->RemoveAssociation("ResourceNameInts",
1563  "ControlledNameId",
1564  $CNId);
1565  }
1566  }
1567 
1568  # for each element of array
1569  foreach ($NewValue as $ControlledNameId => $ControlledName)
1570  {
1571  # associate with resource if not already associated
1572  if ($this->AddAssociation("ResourceNameInts",
1573  "ControlledNameId",
1574  $ControlledNameId))
1575  {
1576 
1577  if (ControlledName::ItemExists($ControlledNameId))
1578  {
1579  $CN = new ControlledName($ControlledNameId);
1580  $CN->UpdateLastAssigned();
1581  }
1582  else
1583  {
1584  $this->RemoveAssociation("ResourceNameInts",
1585  "ControlledNameId", $ControlledNameId);
1586  throw new InvalidArgumentException(
1587  "Attempt to set controlled name with"
1588  ." invalid ID (".$ControlledNameId.").");
1589  }
1590  }
1591  }
1592  $UpdateModTime = TRUE;
1593  }
1594 
1595  if ($UpdateModTime)
1596  {
1597  # clear our controlled name cache
1598  unset($this->ControlledNameCache);
1599  unset($this->ControlledNameVariantCache);
1600 
1601  # clear visible count cache for any affected CNames
1602  $RFactory = new ResourceFactory($this->SchemaId);
1603  $RFactory->ClearVisibleResourceCountForValues(
1604  array_keys($OldValue + $NewValue) );
1605  }
1606 
1607  break;
1608 
1610  # associate value(s) with resource
1611  $this->AddAssociation(
1612  "ResourceImageInts", "ImageId", $NewValue, $Field);
1613  # clear cached image mappings
1614  SPTImage::ClearImageSymlinksForResource($this->Id(), $Field->Id());
1615  break;
1616 
1618  # convert incoming value to array if necessary
1619  if (!is_array($NewValue)) { $NewValue = array($NewValue); }
1620 
1621  # for each incoming file
1622  $Factory = new FileFactory($Field->Id());
1623  foreach ($NewValue as $File)
1624  {
1625  # make copy of file
1626  $NewFile = $Factory->Copy($File);
1627 
1628  # associate copy with this resource and field
1629  $NewFile->ResourceId($this->Id);
1630  $NewFile->FieldId($Field->Id());
1631  }
1632  # Since we make a fresh copy of the File whenever Set is called,
1633  # we'll always update the modification time for this field.
1634  $UpdateModTime = TRUE;
1635  break;
1636 
1638  # convert incoming value to array to simplify the workflow
1639  if (!is_array($NewValue))
1640  {
1641  $NewValue = [$NewValue];
1642  }
1643 
1644  # delete existing resource references
1645  $this->DB->Query(
1646  "DELETE FROM ReferenceInts "
1647  ."WHERE FieldId = '".addslashes($Field->Id())."' "
1648  ."AND SrcResourceId = '".addslashes($this->Id())."'");
1649 
1650  # add each reference
1651  foreach ($NewValue as $ReferenceId)
1652  {
1653  if ($ReferenceId instanceof Resource)
1654  {
1655  $ReferenceId = $ReferenceId->Id();
1656  }
1657 
1658  # skip blank reference IDs
1659  if (strlen(trim($ReferenceId)) < 1)
1660  {
1661  continue;
1662  }
1663 
1664  # skip reference IDs that don't look right
1665  if (!is_numeric($ReferenceId))
1666  {
1667  continue;
1668  }
1669 
1670  # skip references to the current resource
1671  if ($ReferenceId == $this->Id())
1672  {
1673  continue;
1674  }
1675 
1676  # add the reference to the references table
1677  $DB->Query(
1678  "INSERT INTO ReferenceInts ("
1679  ."FieldId, "
1680  ."SrcResourceId, "
1681  ."DstResourceId"
1682  .") VALUES ("
1683  .addslashes($Field->Id()).","
1684  .addslashes($this->Id()).","
1685  .addslashes($ReferenceId).")");
1686  }
1687  break;
1688 
1689  default:
1690  # ERROR OUT
1691  exit("<br>SPT - ERROR: attempt to set unknown resource field type<br>\n");
1692  break;
1693  }
1694 
1695  if ($UpdateModTime && !$this->IsTempResource())
1696  {
1697  # update modification timestamps
1698  global $G_User;
1699  $UserId = $G_User->IsLoggedIn() ? $G_User->Get("UserId") : -1;
1700  $DB->Query("DELETE FROM ResourceFieldTimestamps "
1701  ."WHERE ResourceId=".$this->Id." AND "
1702  ."FieldId=".$Field->Id() );
1703  $DB->Query("INSERT INTO ResourceFieldTimestamps "
1704  ."(ResourceId,FieldId,ModifiedBy,Timestamp) VALUES ("
1705  .$this->Id.",".$Field->Id().","
1706  .$UserId.",NOW())");
1707 
1708  # on resource modification, clear the UserPermsCache entry
1709  # so that stale permissions checks are not cached
1710  $DB->Query("DELETE FROM UserPermsCache WHERE ResourceId=".$this->Id);
1711 
1712  # if this field is not an option or a cname, but it is
1713  # checked for visibility, then we need to clear resource
1714  # visibility cache (for example, if this is AddedById and
1715  # our schema allows users to view resources where they are
1716  # the AddedById)
1717  if (!in_array($Field->Type(),
1720  $this->Schema()->ViewingPrivileges()->ChecksField($Field->Id()))
1721  {
1722  $RFactory = new ResourceFactory($this->SchemaId);
1723  $RFactory->ClearVisibleResourceCount($this);
1724  }
1725  }
1726  }
1727 
1735  public function SetByField($Field, $NewValue)
1736  {
1737  $this->Set($Field, $NewValue);
1738  }
1739 
1747  public function SetByFieldId($FieldId, $NewValue)
1748  {
1749  $this->Set($FieldId, $NewValue);
1750  }
1751 
1757  public function SetQualifier($FieldName, $NewValue)
1758  {
1759  $Field = $this->Schema()->GetFieldByName($FieldName);
1760  $this->SetQualifierByField($Field, $NewValue);
1761  }
1762 
1768  public function SetQualifierByFieldId($FieldId, $NewValue)
1769  {
1770  $Field = $this->Schema()->GetField($FieldId);
1771  $this->SetQualifierByField($Field, $NewValue);
1772  }
1773 
1779  public function SetQualifierByField($Field, $NewValue)
1780  {
1781  # if field uses qualifiers and uses item-level qualifiers
1782  if ($Field->UsesQualifiers() && $Field->HasItemLevelQualifiers())
1783  {
1784  # if qualifier object passed in
1785  if (is_object($NewValue))
1786  {
1787  # grab qualifier ID from object
1788  $QualifierId = $NewValue->Id();
1789  }
1790  else
1791  {
1792  # assume value passed in is qualifier ID
1793  $QualifierId = $NewValue;
1794  }
1795 
1796  # update qualifier value in database
1797  $DBFieldName = $Field->DBFieldName();
1798  $this->DB->Query("UPDATE Resources SET "
1799  .$DBFieldName."Qualifier = '".$QualifierId."' "
1800  ."WHERE ResourceId = ".$this->Id);
1801 
1802  # update local qualifier value
1803  $this->ValueCache[$DBFieldName."Qualifier"] = $QualifierId;
1804  }
1805  }
1806 
1813  public function ClearByFieldId($FieldId, $ValueToClear = NULL)
1814  {
1815  $Field = $this->Schema()->GetField($FieldId);
1816  $this->Clear($Field, $ValueToClear);
1817  }
1818 
1825  public function Clear($Field, $ValueToClear = NULL)
1826  {
1827  # convert field name to object if necessary
1828  if (!is_object($Field))
1829  {
1830  $Field = $this->Schema()->GetFieldByName($Field);
1831  }
1832 
1833  $UpdateModTime = FALSE;
1834 
1835  # store value in DB based on field type
1836  switch ($Field->Type())
1837  {
1846  $this->Set($Field, NULL);
1847  break;
1848 
1853  # if value to clear supplied
1854  if ($ValueToClear !== NULL)
1855  {
1856  $Value = $this->Get($Field);
1857 
1858  if (!is_array($ValueToClear))
1859  {
1860  $ValueToClear = [$ValueToClear => "Dummy"];
1861  }
1862 
1863  # for each element of array
1864  foreach ($ValueToClear as $Id => $Dummy)
1865  {
1866  if (array_key_exists($Id, $Value))
1867  {
1868  unset($Value[$Id]);
1869  }
1870  }
1871 
1872  $this->Set($Field, $Value, TRUE);
1873  }
1874  else
1875  {
1876  $this->Set($Field, [], TRUE);
1877  }
1878 
1879  break;
1880 
1882  # if value to clear supplied
1883  if ($ValueToClear !== NULL)
1884  {
1885  # convert value to array if necessary
1886  $Files = $ValueToClear;
1887  if (!is_array($Files)) { $Files = array($Files); }
1888 
1889  # convert values to objects if necessary
1890  foreach ($Files as $Index => $File)
1891  {
1892  if (!is_object($File))
1893  {
1894  $Files[$Index] = new File($File);
1895  }
1896  }
1897  }
1898  else
1899  {
1900  # use all files associated with resource
1901  $Files = $this->Get($Field, TRUE);
1902  }
1903 
1904  # delete files
1905  foreach ($Files as $File) { $File->Delete(); }
1906  break;
1907 
1909  # if value to clear supplied
1910  if ($ValueToClear !== NULL)
1911  {
1912  # convert value to array if necessary
1913  $Images = $ValueToClear;
1914  if (!is_array($Images)) { $Images = array($Images); }
1915 
1916  # convert values to objects if necessary
1917  foreach ($Images as $Index => $Image)
1918  {
1919  if (!is_object($Image))
1920  {
1921  $Images[$Index] = new SPTImage($Image);
1922  }
1923  }
1924  }
1925  else
1926  {
1927  # use all images associated with resource
1928  $Images = $this->Get($Field, TRUE);
1929  }
1930 
1931  # delete images if we are the last resource referencing
1932  # a particular image.
1933  foreach ($Images as $Image)
1934  {
1935  $Cnt = $this->DB->Query(
1936  "SELECT COUNT(*) AS Cnt FROM ResourceImageInts WHERE ".
1937  "ImageId=".$Image->Id(), "Cnt");
1938  if ($Cnt==1)
1939  {
1940  $Image->Delete();
1941  }
1942  }
1943 
1944  # clear cached image mappings
1945  SPTImage::ClearImageSymlinksForResource($this->Id(), $Field->Id());
1946 
1947  # remove connections to images
1948  $UpdateModTime = $this->RemoveAssociation(
1949  "ResourceImageInts", "ImageId", $Images, $Field);
1950  break;
1951 
1953  $this->Set($Field, []);
1954  break;
1955 
1956  default:
1957  # ERROR OUT
1958  exit("<br>SPT - ERROR: attempt to clear "
1959  ."unknown resource field type<br>\n");
1960  break;
1961  }
1962 
1963  if ($UpdateModTime && !$this->IsTempResource())
1964  {
1965  # update modification timestamps
1966  global $G_User;
1967  $UserId = $G_User->IsLoggedIn() ? $G_User->Get("UserId") : -1;
1968  $this->DB->Query("DELETE FROM ResourceFieldTimestamps "
1969  ."WHERE ResourceId=".$this->Id." AND "
1970  ."FieldId=".$Field->Id() );
1971  $this->DB->Query("INSERT INTO ResourceFieldTimestamps "
1972  ."(ResourceId,FieldId,ModifiedBy,Timestamp) VALUES ("
1973  .$this->Id.",".$Field->Id().","
1974  .$UserId.",NOW())");
1975  }
1976  }
1977 
1986  public function ClearByField($Field, $ValueToClear = NULL)
1987  {
1988  $this->Clear($Field, $ValueToClear);
1989  }
1990 
1991  # --- Field-Specific or Type-Specific Attribute Retrieval Methods -------
1992 
1998  public function Classifications()
1999  {
2000  $DB = $this->DB;
2001 
2002  # start with empty array
2003  $Names = array();
2004 
2005  # for each controlled name
2006  $DB->Query("SELECT ClassificationName, MetadataFields.FieldName, "
2007  ."ResourceClassInts.ClassificationId FROM ResourceClassInts, "
2008  ."Classifications, MetadataFields "
2009  ."WHERE ResourceClassInts.ResourceId = ".$this->Id." "
2010  ."AND ResourceClassInts.ClassificationId = "
2011  ."Classifications.ClassificationId "
2012  ."AND Classifications.FieldId = MetadataFields.FieldId ");
2013  while ($Record = $DB->FetchRow())
2014  {
2015  # add name to array
2016  $Names[$Record["FieldName"]][$Record["ClassificationId"]] =
2017  $Record["ClassificationName"];
2018  }
2019 
2020  # return array to caller
2021  return $Names;
2022  }
2023 
2024 
2025  # --- Ratings Methods ---------------------------------------------------
2026 
2031  public function CumulativeRating()
2032  {
2033  return $this->CumulativeRating;
2034  }
2035 
2040  public function ScaledCumulativeRating()
2041  {
2042  if ($this->CumulativeRating == NULL)
2043  {
2044  return NULL;
2045  }
2046  else
2047  {
2048  return intval(($this->CumulativeRating + 5) / 10);
2049  }
2050  }
2051 
2056  public function NumberOfRatings()
2057  {
2058  # if number of ratings not already set
2059  if (!isset($this->NumberOfRatings))
2060  {
2061  # obtain number of ratings
2062  $this->NumberOfRatings =
2063  $this->DB->Query("SELECT Count(*) AS NumberOfRatings "
2064  ."FROM ResourceRatings "
2065  ."WHERE ResourceId = ".$this->Id,
2066  "NumberOfRatings"
2067  );
2068 
2069  # recalculate cumulative rating if it looks erroneous
2070  if (($this->NumberOfRatings > 0) && !$this->CumulativeRating())
2071  {
2072  $this->UpdateCumulativeRating();
2073  }
2074  }
2075 
2076  # return number of ratings to caller
2077  return $this->NumberOfRatings;
2078  }
2079 
2087  public function Rating($NewRating = NULL, $UserId = NULL)
2088  {
2089  $DB = $this->DB;
2090 
2091  # if user ID not supplied
2092  if ($UserId == NULL)
2093  {
2094  # if user is logged in
2095  global $G_User;
2096  if ($G_User->IsLoggedIn())
2097  {
2098  # use ID of current user
2099  $UserId = $G_User->Get("UserId");
2100  }
2101  else
2102  {
2103  # return NULL to caller
2104  return NULL;
2105  }
2106  }
2107 
2108  # sanitize $NewRating
2109  if (!is_null($NewRating))
2110  {
2111  $NewRating = intval($NewRating);
2112  }
2113 
2114  # if there is a rating for resource and user
2115  $DB->Query("SELECT Rating FROM ResourceRatings "
2116  ."WHERE UserId = ${UserId} AND ResourceId = ".$this->Id);
2117  if ($Record = $DB->FetchRow())
2118  {
2119  # if new rating was supplied
2120  if ($NewRating != NULL)
2121  {
2122  # update existing rating
2123  $DB->Query("UPDATE ResourceRatings "
2124  ."SET Rating = ${NewRating}, DateRated = NOW() "
2125  ."WHERE UserId = ${UserId} AND ResourceId = ".$this->Id);
2126 
2127  # update cumulative rating value
2128  $this->UpdateCumulativeRating();
2129 
2130  # return value is new rating
2131  $Rating = $NewRating;
2132  }
2133  else
2134  {
2135  # get rating value to return to caller
2136  $Rating = $Record["Rating"];
2137  }
2138  }
2139  else
2140  {
2141  # if new rating was supplied
2142  if ($NewRating != NULL)
2143  {
2144  # add new rating
2145  $DB->Query("INSERT INTO ResourceRatings "
2146  ."(ResourceId, UserId, DateRated, Rating) "
2147  ."VALUES ("
2148  .$this->Id.", "
2149  ."${UserId}, "
2150  ."NOW(), "
2151  ."${NewRating})");
2152 
2153  # update cumulative rating value
2154  $this->UpdateCumulativeRating();
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 UpdateCumulativeRating()
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  # calculate new cumulative rating
2541  $this->CumulativeRating = round($Record["Total"] / $Record["Count"]);
2542 
2543  # save new cumulative rating in DB
2544  $this->DB->Query("UPDATE Resources "
2545  ."SET CumulativeRating = ".$this->CumulativeRating." "
2546  ."WHERE ResourceId = ".$this->Id);
2547  }
2548 
2560  private function AddAssociation($TableName, $FieldName, $Value, $Field = NULL)
2561  {
2562  # We should ignore duplicate key errors when doing inserts:
2563  $this->DB->SetQueryErrorsToIgnore( array(
2564  "/INSERT INTO ".$TableName."/" =>
2565  "/Duplicate entry '-?[0-9]+-[0-9]+(-[0-9]+)?' for key/"));
2566 
2567  # start out assuming no association will be added
2568  $AssociationAdded = FALSE;
2569 
2570  # convert new value to array if necessary
2571  $Values = is_array($Value) ? $Value : array($Value);
2572 
2573  # for each new value
2574  foreach ($Values as $Value)
2575  {
2576  # retrieve ID from value if necessary
2577  if (is_object($Value)) { $Value = $Value->Id(); }
2578 
2579  # Try to insert a new entry for this association.
2580  $this->DB->Query("INSERT INTO ".$TableName." SET"
2581  ." ResourceId = ".intval($this->Id)
2582  .", ".$FieldName." = ".intval($Value)
2583  .($Field ? ", FieldId = ".intval($Field->Id()) : ""));
2584 
2585  # If the insert ran without a duplicate key error,
2586  # then we added an assocation:
2587  if ($this->DB->IgnoredError() === FALSE)
2588  {
2589  $AssociationAdded = TRUE;
2590  }
2591  }
2592 
2593  # Clear ignored errors:
2594  $this->DB->SetQueryErrorsToIgnore( NULL );
2595 
2596  # report to caller whether association was added
2597  return $AssociationAdded;
2598  }
2599 
2611  private function RemoveAssociation($TableName, $FieldName, $Value, $Field = NULL)
2612  {
2613  # start out assuming no association will be removed
2614  $AssociationRemoved = FALSE;
2615 
2616  # convert value to array if necessary
2617  $Values = is_array($Value) ? $Value : array($Value);
2618 
2619  # for each value
2620  foreach ($Values as $Value)
2621  {
2622  # retrieve ID from value if necessary
2623  if (is_object($Value)) { $Value = $Value->Id(); }
2624 
2625  # remove any intersections with target ID from DB
2626  $this->DB->Query("DELETE FROM ".$TableName
2627  ." WHERE ResourceId = ".intval($this->Id)
2628  .($Field ? " AND FieldId = ".intval($Field->Id()) : "")
2629  ." AND ".$FieldName." = ".intval($Value));
2630  if ($this->DB->NumRowsAffected()) { $AssociationRemoved = TRUE; }
2631  }
2632 
2633  # report to caller whether association was added
2634  return $AssociationRemoved;
2635  }
2636 
2643  private function RemoveAllAssociations($TableName, $TargetFieldName, $Field)
2644  {
2645  # retrieve list of entries for this field and resource
2646  $Entries = $this->Get($Field);
2647 
2648  # divide them into chunks of not more than 100
2649  foreach (array_chunk($Entries, 100, TRUE) as $Chunk)
2650  {
2651  # remove assocations from this chunk
2652  $this->DB->Query("DELETE FROM ".$TableName
2653  ." WHERE ResourceId = ".intval($this->Id)
2654  ." AND ".$TargetFieldName." IN "
2655  ."(".implode(",", array_keys($Chunk)).")");
2656  }
2657  }
2658 
2665  static protected function SetDatabaseAccessValues($ClassName)
2666  {
2667  if (!isset(self::$ItemIdColumnNames[$ClassName]))
2668  {
2669  self::$ItemIdColumnNames[$ClassName] = "ResourceId";
2670  self::$ItemNameColumnNames[$ClassName] = NULL;
2671  self::$ItemTableNames[$ClassName] = "Resources";
2672  }
2673  }
2674 }
GetByField($FieldNameOrObject, $ReturnObject=FALSE, $IncludeVariants=FALSE)
Old method for retrieving values, deprecated in favor of Get().
Definition: Resource.php:775
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:1108
SetQualifier($FieldName, $NewValue)
Set qualifier using field name.
Definition: Resource.php:1757
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:813
Id()
Retrieve numerical resource ID.
Definition: Resource.php:291
$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:1779
GetViewPageUrl()
Retrieve view page URL for this resource.
Definition: Resource.php:391
Rating($NewRating=NULL, $UserId=NULL)
Get/set rating by a specific user for resource.
Definition: Resource.php:2087
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:2056
GetQualifier($FieldName, $ReturnObject=TRUE)
Retrieve qualifier by field name.
Definition: Resource.php:876
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:309
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:739
Comments()
Get comments for resource.
Definition: Resource.php:2177
UpdateAutoupdateFields($UpdateType, $User=NULL)
Update the auto-updated fields as necessary.
Definition: Resource.php:259
CWIS-specific user factory class.
Get($Field, $ReturnObject=FALSE, $IncludeVariants=FALSE)
Retrieve value using field name or field object.
Definition: Resource.php:415
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:890
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:1825
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:795
IsTempResource($NewSetting=NULL)
Get/set whether resource is a temporary record.
Definition: Resource.php:320
SetByField($Field, $NewValue)
Method replaced by Resource::Set(), preserved for backward compatibility.
Definition: Resource.php:1735
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:859
$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:2665
Represents a "resource" in CWIS.
Definition: Resource.php:13
GetQualifierByField($Field, $ReturnObject=TRUE)
Retrieve qualifier by Field object.
Definition: Resource.php:904
ClearByFieldId($FieldId, $ValueToClear=NULL)
Clear field value specified by field ID.
Definition: Resource.php:1813
SetQualifierByFieldId($FieldId, $NewValue)
Set qualifier using field ID.
Definition: Resource.php:1768
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:300
ScaledCumulativeRating()
Return cumulative rating scaled to 1/10th.
Definition: Resource.php:2040
Set($Field, $NewValue, $Reset=FALSE)
Set value using field name or field object.
Definition: Resource.php:1143
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:1747
Classifications()
Get 2D array of classifications associated with resource.
Definition: Resource.php:1998
ClearByField($Field, $ValueToClear=NULL)
Clear field value.
Definition: Resource.php:1986
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:2031
FieldIsSet($FieldNameOrObject, $IgnorePadding=FALSE)
Determine if the value for a field is set.
Definition: Resource.php:1038
Delete()
Remove resource (and accompanying associations) from database and delete any associated files...
Definition: Resource.php:142