CWIS Developer Documentation
ResourceFactory.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # FILE: ResourceFactory.php
4 #
5 # METHODS PROVIDED:
6 # ResourceFactory()
7 # - constructor
8 # DuplicateResource($ResourceId)
9 # - create duplicate resource and return to caller
10 # (SEE ALSO: ItemFactory.php)
11 #
12 # AUTHOR: Edward Almasy
13 #
14 # Part of the Collection Workflow Integration System (CWIS)
15 # Copyright 2011 Internet Scout Project
16 # http://scout.wisc.edu/
17 #
18 
20 
21  # ---- PUBLIC INTERFACE --------------------------------------------------
22 
23  # object constructor
24  function ResourceFactory()
25  {
26  # set up item factory base class
27  $this->ItemFactory("Resource", "Resources", "ResourceId");
28  }
29 
30  # create duplicate resource and return to caller
31  function DuplicateResource($ResourceId)
32  {
33  # create new target resource
34  $DstResource = new Resource();
35 
36  # load up resource to duplicate
37  $SrcResource = new Resource($ResourceId);
38 
39  # if resource to duplicate was found
40  if ($SrcResource->Status() > 0)
41  {
42  # for each metadata field
43  $Schema = new MetadataSchema();
44  $Fields = $Schema->GetFields();
45  foreach ($Fields as $Field)
46  {
47  # skip the cumulative rating field
48  if ($Field->Name() != "Cumulative Rating")
49  {
50  $NewValue = $SrcResource->GetByField($Field, TRUE);
51 
52  # clear default value from destination resource that is
53  # set when creating a new resource
54  $DstResource->ClearByField($Field);
55 
56  # copy value from source resource to destination resource
57  $DstResource->SetByField($Field, $NewValue);
58  }
59  }
60  }
61 
62  # return new resource to caller
63  return $DstResource;
64  }
65 
66  # clear or change specific qualifier for all resources
67  function ClearQualifier($ObjectOrId, $NewObjectOrId = NULL)
68  {
69  # sanitize qualifier ID or retrieve from object
70  $QualifierId = is_object($ObjectOrId)
71  ? $ObjectOrId->Id() : intval($ObjectOrId);
72 
73  # if new qualifier passed in
74  if ($NewObjectOrId !== NULL)
75  {
76  # sanitize qualifier ID to change to or retrieve it from object
77  $NewQualifierIdVal = is_object($NewObjectOrId)
78  ? $NewObjectOrId->Id() : intval($NewObjectOrId);
79  }
80  else
81  {
82  # qualifier should be cleared
83  $NewQualifierIdVal = "NULL";
84  }
85 
86  # for each metadata field
87  $Schema = new MetadataSchema();
88  $Fields = $Schema->GetFields();
89  foreach ($Fields as $Field)
90  {
91  # if field uses qualifiers and uses item-level qualifiers
92  $QualColName = $Field->DBFieldName()."Qualifier";
93  if ($Field->UsesQualifiers()
94  && $Field->HasItemLevelQualifiers()
95  && $this->DB->FieldExists("Resources", $QualColName))
96  {
97  # set all occurrences to new qualifier value
98  $this->DB->Query("UPDATE Resources"
99  ." SET ".$QualColName." = ".$NewQualifierIdVal.""
100  ." WHERE ".$QualColName." = '".$QualifierId."'");
101  }
102  }
103 
104  # clear or change qualifier association with controlled names
105  # (NOTE: this should probably be done in a controlled name factory object)
106  $this->DB->Query("UPDATE ControlledNames"
107  ." SET QualifierId = ".$NewQualifierIdVal
108  ." WHERE QualifierId = '".$QualifierId."'");
109 
110  # clear or change qualifier association with classifications
111  # (NOTE: this should probably be done in a classification factory object)
112  $this->DB->Query("UPDATE Classifications"
113  ." SET QualifierId = ".$NewQualifierIdVal
114  ." WHERE QualifierId = '".$QualifierId."'");
115  }
116 
117  # return count of rated resources
119  {
120  $RatedResourceCount = $this->DB->Query(
121  "SELECT COUNT(DISTINCT ResourceId) AS ResourceCount "
122  ."FROM ResourceRatings", "ResourceCount");
123  return $RatedResourceCount;
124  }
125 
126  # return count of users who have rated resources
128  {
129  $RatedResourceCount = $this->DB->Query(
130  "SELECT COUNT(DISTINCT UserId) AS UserCount "
131  ."FROM ResourceRatings", "UserCount");
132  return $RatedResourceCount;
133  }
134 
135  # return recently released resources
136  function GetRecentlyReleasedResources($Count = 10, $Offset = 0, $MaxDaysToGoBack = 90)
137  {
138  # assume that no resources will be found
139  $Resources = array();
140 
141  # calculate cutoff date for resources
142  $CutoffDate = date("Y-m-d H:i:s", strtotime($MaxDaysToGoBack." days ago"));
143 
144  # query for resource IDs
145  $this->DB->Query("SELECT ResourceId FROM Resources WHERE"
146  ." DateOfRecordRelease > '".$CutoffDate."'"
147  ." AND ReleaseFlag = 1"
148  ." AND ResourceId >= 0"
149  ." ORDER BY DateOfRecordRelease DESC, DateOfRecordCreation DESC"
150  ." LIMIT ".intval($Offset).", ".intval($Count));
151  $ResourceIds = $this->DB->FetchColumn("ResourceId");
152 
153  # for each resource ID found
154  foreach ($ResourceIds as $ResourceId)
155  {
156  # load resource and add to list of found resources
157  $Resources[$ResourceId] = new Resource($ResourceId);
158  }
159 
160  # return found resources to caller
161  return $Resources;
162  }
163 
164  # return resources sorted by specified field
165  function GetResourceIdsSortedBy($FieldName, $Ascending = TRUE, $Limit = NULL)
166  {
167  # assume no resources will be found
168  $ResourceIds = array();
169 
170  # get field
171  $Schema = new MetadataSchema();
172  $Field = $Schema->GetFieldByName($FieldName);
173 
174  # if field was found
175  if ($Field != NULL)
176  {
177  # construct query based on field type
178  switch ($Field->Type())
179  {
183  $Count = $this->DB->Query("SELECT COUNT(*) AS ResourceCount"
184  ." FROM Resources WHERE "
185  .$Field->DBFieldName()." IS NOT NULL"
186  ." AND LENGTH(LTRIM(RTRIM(".$Field->DBFieldName()."))) > 0",
187  "ResourceCount");
188  if ($Count > 1)
189  {
190  $Query = "SELECT ResourceId FROM Resources"
191  ." ORDER BY ".$Field->DBFieldName()
192  .($Ascending ? " ASC" : " DESC");
193  }
194  break;
195 
198  $Count = $this->DB->Query("SELECT COUNT(*) AS ResourceCount"
199  ." FROM Resources WHERE "
200  .$Field->DBFieldName()." IS NOT NULL",
201  "ResourceCount");
202  if ($Count > 1)
203  {
204  $Query = "SELECT ResourceId FROM Resources"
205  ." ORDER BY ".$Field->DBFieldName()
206  .($Ascending ? " ASC" : " DESC");
207  }
208  break;
209 
211  $Count = $this->DB->Query("SELECT COUNT(*) AS ResourceCount"
212  ." FROM Resources WHERE "
213  .$Field->DBFieldName()."Begin IS NOT NULL",
214  "ResourceCount");
215  if ($Count > 1)
216  {
217  $Query = "SELECT ResourceId FROM Resources"
218  ." ORDER BY ".$Field->DBFieldName()."Begin"
219  .($Ascending ? " ASC" : " DESC");
220  }
221  break;
222  }
223 
224  # if appropriate query was found
225  if (isset($Query))
226  {
227  # if limited number of results were requested
228  if ($Limit !== NULL)
229  {
230  # add limit to query
231  $Query .= " LIMIT ".intval($Limit);
232  }
233 
234  # perform query and retrieve resource IDs
235  $this->DB->Query($Query);
236  $ResourceIds = $this->DB->FetchColumn("ResourceId");
237  }
238  }
239 
240  # return resource IDs to caller
241  return $ResourceIds;
242  }
243 
244  # get date/time of last resource modification (returned as Unix timestamp)
245  function GetTimestampOfLastResourceModification($OnlyReleasedResources = TRUE)
246  {
247  $LastChangeDate = $this->DB->Query(
248  "SELECT MAX(DateLastModified) AS LastChangeDate"
249  ." FROM Resources".($OnlyReleasedResources ? " WHERE ReleaseFlag = 1" : ""),
250  "LastChangeDate");
251  return ($LastChangeDate ? strtotime($LastChangeDate) : NULL);
252  }
253 
254  # get list of possible field names for resources
256  {
257  # retrieve field names from schema
258  $FieldNames = array();
259  $Schema = new MetadataSchema();
260  $Fields = $Schema->GetFields();
261  foreach ($Fields as $Field)
262  {
263  $FieldNames[$Field->Id()] = $Field->Name();
264  }
265 
266  # return field names to caller
267  return $FieldNames;
268  }
269 
270  # find resources with values that match those specified
271  # (index of $ValuesToMatch is field IDs)
272  function GetMatchingResources($ValuesToMatch)
273  {
274  # start out assuming we won't find any resources
275  $Resources = array();
276 
277  # for each value
278  $Schema = new MetadataSchema();
279  $Fields = $Schema->GetFields(
286  $LinkingTerm = "";
287  $Condition = "";
288  foreach ($ValuesToMatch as $FieldId => $Value)
289  {
290  # if field can be used for comparison
291  if (isset($Fields[$FieldId]))
292  {
293  # add comparison to condition
294  $Condition .= $LinkingTerm.$Fields[$FieldId]->DBFieldName()
295  ." = '".addslashes($Value)."'";
296  $LinkingTerm = " AND ";
297  }
298  }
299 
300  # if there were valid conditions
301  if (strlen($Condition))
302  {
303  # build query statment
304  $Query = "SELECT ResourceId FROM Resources WHERE ".$Condition;
305 
306  # execute query to retrieve matching resource IDs
307  $this->DB->Query($Query);
308  $ResourceIds = $this->DB->FetchColumn("ResourceId");
309 
310  # retrieve resource objects
311  foreach ($ResourceIds as $Id)
312  {
313  $Resources[$Id] = new Resource($Id);
314  }
315  }
316 
317  # return any resources found to caller
318  return $Resources;
319  }
320 
321  # Functions for keeping per-field resource counts updated:
322  function GetResourceCount($FieldId, $Value, $CountType="All")
323  {
324  if ($this->ResourceCount === NULL)
325  {
326  $this->DB->Query(
327  "SELECT FieldId, ClassName, CountType, Count from ResourceCounts");
328 
329  while ($Row = $this->DB->FetchRow())
330  {
331  $FieldId = $Row["FieldId"];
332  $ClassName = $Row["ClassName"];
333  $CountType = $Row["CountType"];
334  $Count = $Row["Count"];
335 
336  $this->ResourceCount[$FieldId][$ClassName][$CountType] = $Count;
337  }
338  }
339 
340  $Schema = new MetadataSchema();
341  $Field = $Schema->GetField($FieldId);
342 
343  if ($Field->Status() === MetadataSchema::MDFSTAT_OK &&
344  ( $Field->Type() === MetadataSchema::MDFTYPE_OPTION ||
345  $Field->Type() === MetadataSchema::MDFTYPE_CONTROLLEDNAME ) )
346  {
347  return isset($this->ResourceCount[$FieldId][$Value][$CountType]) ?
348  $this->ResourceCount[$FieldId][$Value][$CountType] :
349  0 ;
350  }
351  else
352  {
353  return NULL;
354  }
355  }
356 
361  public function GetReleasedResourceTotal()
362  {
363  return $this->DB->Query("
364  SELECT COUNT(*) AS ResourceTotal
365  FROM Resources
366  WHERE ResourceId > 0 AND ReleaseFlag = 1", "ResourceTotal");
367  }
368 
374  public function GetResourceTotal()
375  {
376  return $this->DB->Query("
377  SELECT COUNT(*) AS ResourceTotal
378  FROM Resources
379  WHERE ResourceId > 0", "ResourceTotal");
380  }
381 
383  {
384  global $AF;
385 
386  # be sure that we're not a gigantic object when the task is queued
387  $TmpResourceCount = $this->ResourceCount;
388  $this->ResourceCount = NULL;
389 
390  $AF->QueueUniqueTask(
391  array($this,"UpdateResourceCountCallback"), array());
392  $this->ResourceCount = $TmpResourceCount;
393  }
394 
396  {
397  $DB = new Database();
398  $DB->Query(
399  "CREATE TABLE ResourceCountsNew (FieldId INT, ClassName TEXT, CountType TEXT, Count INT);");
400 
401  $Start = microtime(TRUE);
402 
403  foreach ($this->ResourceCountConditions as $CountType => $CountCondition)
404  {
405  $DB->Query(
406  "INSERT INTO ResourceCountsNew "
407  ."SELECT FieldId, ControlledName AS ClassName,"
408  . "'".$CountType."' AS CountType, Count(ResourceId) AS Count "
409  . "FROM (SELECT * FROM ResourceNameInts WHERE ResourceId IN "
410  . "(SELECT ResourceId FROM Resources "
411  . (($CountCondition!==NULL)?"WHERE ".$CountCondition:"").")) AS T0 "
412  . "JOIN ControlledNames USING(ControlledNameId) GROUP BY ControlledNameId;" );
413  }
414 
415  $Stop = microtime(TRUE);
416 
417  $DB->Query(
418  "INSERT INTO ResourceCountsNew VALUES (-1, '__LAST_UPDATED__', '', UNIX_TIMESTAMP()); ");
419  $DB->Query(
420  "INSERT INTO ResourceCountsNew VALUES (-2, '__UPDATE_RUNTIME__','',".($Stop-$Start).");");
421  $DB->Query(
422  "RENAME TABLE ResourceCounts TO ResourceCountsOld, ResourceCountsNew TO ResourceCounts; ");
423  $DB->Query(
424  "DROP TABLE ResourceCountsOld; ");
425  }
426 
427  # ---- PRIVATE INTERFACE -------------------------------------------------
428 
429  private $ResourceCount = NULL;
430  private $ResourceCountConditions = array("All" => NULL, "Released" => "ReleaseFlag=1");
431 }