CWIS Developer Documentation
ResourceFactory.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # FILE: ResourceFactory.php
4 #
5 # Part of the Collection Workflow Integration System (CWIS)
6 # Copyright 2011-2013 Edward Almasy and Internet Scout Research Group
7 # http://scout.wisc.edu/cwis/
8 #
9 
14 
15  # ---- PUBLIC INTERFACE --------------------------------------------------
16 
23  {
24  # save schema ID
25  $this->SchemaId = $SchemaId;
26 
27  # set up item factory base class
28  $this->ItemFactory("Resource", "Resources", "ResourceId", NULL, FALSE,
29  "SchemaId = ".intval($this->SchemaId));
30  }
31 
37  function DuplicateResource($ResourceId)
38  {
39  # create new target resource
40  $DstResource = Resource::Create($this->SchemaId);
41 
42  # load up resource to duplicate
43  $SrcResource = new Resource($ResourceId);
44 
45  # if resource to duplicate was found
46  if ($SrcResource->Status() > 0)
47  {
48  # for each metadata field
49  $Schema = new MetadataSchema($this->SchemaId);
50  $Fields = $Schema->GetFields();
51  foreach ($Fields as $Field)
52  {
53  # skip the Cumulative Rating and Date Last Modified fields
54  if ($Field->Name() != "Cumulative Rating" &&
55  $Field->Name() != "Date Last Modified")
56  {
57  $NewValue = $SrcResource->GetByField($Field, TRUE);
58 
59  # clear default value from destination resource that is
60  # set when creating a new resource
61  $DstResource->ClearByField($Field);
62 
63  # copy value from source resource to destination resource
64  $DstResource->SetByField($Field, $NewValue);
65  }
66  }
67  }
68 
69  # return new resource to caller
70  return $DstResource;
71  }
72 
79  function ClearQualifier($ObjectOrId, $NewObjectOrId = NULL)
80  {
81  # sanitize qualifier ID or retrieve from object
82  $QualifierId = is_object($ObjectOrId)
83  ? $ObjectOrId->Id() : intval($ObjectOrId);
84 
85  # if new qualifier passed in
86  if ($NewObjectOrId !== NULL)
87  {
88  # sanitize qualifier ID to change to or retrieve it from object
89  $NewQualifierIdVal = is_object($NewObjectOrId)
90  ? $NewObjectOrId->Id() : intval($NewObjectOrId);
91  }
92  else
93  {
94  # qualifier should be cleared
95  $NewQualifierIdVal = "NULL";
96  }
97 
98  # for each metadata field
99  $Schema = new MetadataSchema($this->SchemaId);
100  $Fields = $Schema->GetFields();
101  foreach ($Fields as $Field)
102  {
103  # if field uses qualifiers and uses item-level qualifiers
104  $QualColName = $Field->DBFieldName()."Qualifier";
105  if ($Field->UsesQualifiers()
106  && $Field->HasItemLevelQualifiers()
107  && $this->DB->FieldExists("Resources", $QualColName))
108  {
109  # set all occurrences to new qualifier value
110  $this->DB->Query("UPDATE Resources"
111  ." SET ".$QualColName." = ".$NewQualifierIdVal.""
112  ." WHERE ".$QualColName." = '".$QualifierId."'"
113  ." AND SchemaId = ".intval($this->SchemaId));
114  }
115  }
116 
117  # clear or change qualifier association with controlled names
118  # (NOTE: this should probably be done in a controlled name factory object)
119  $this->DB->Query("UPDATE ControlledNames"
120  ." SET QualifierId = ".$NewQualifierIdVal
121  ." WHERE QualifierId = '".$QualifierId."'");
122 
123  # clear or change qualifier association with classifications
124  # (NOTE: this should probably be done in a classification factory object)
125  $this->DB->Query("UPDATE Classifications"
126  ." SET QualifierId = ".$NewQualifierIdVal
127  ." WHERE QualifierId = '".$QualifierId."'");
128  }
129 
135  {
136  return $this->DB->Query(
137  "SELECT COUNT(DISTINCT ResourceId) AS ResourceCount"
138  ." FROM ResourceRatings",
139  "ResourceCount");
140  }
141 
147  {
148  return $this->DB->Query(
149  "SELECT COUNT(DISTINCT UserId) AS UserCount"
150  ." FROM ResourceRatings",
151  "UserCount");
152  }
153 
163  function GetRecentlyReleasedResources($Count = 10, $Offset = 0, $MaxDaysToGoBack = 90)
164  {
165  # assume that no resources will be found
166  $Resources = array();
167 
168  # calculate cutoff date for resources
169  $CutoffDate = date("Y-m-d H:i:s", strtotime($MaxDaysToGoBack." days ago"));
170 
171  # query for resource IDs
172  $this->DB->Query("SELECT ResourceId FROM Resources WHERE"
173  ." DateOfRecordRelease > '".$CutoffDate."'"
174  ." AND ReleaseFlag = 1"
175  ." AND ResourceId >= 0"
176  ." AND SchemaId = ".intval($this->SchemaId)
177  ." ORDER BY DateOfRecordRelease DESC, DateOfRecordCreation DESC"
178  ." LIMIT ".intval($Offset).", ".intval($Count));
179  $ResourceIds = $this->DB->FetchColumn("ResourceId");
180 
181  # for each resource ID found
182  foreach ($ResourceIds as $ResourceId)
183  {
184  # load resource and add to list of found resources
185  $Resources[$ResourceId] = new Resource($ResourceId);
186  }
187 
188  # return found resources to caller
189  return $Resources;
190  }
191 
200  function GetResourceIdsSortedBy($FieldName, $Ascending = TRUE, $Limit = NULL)
201  {
202  # assume no resources will be found
203  $ResourceIds = array();
204 
205  # get field
206  $Schema = new MetadataSchema($this->SchemaId);
207  $Field = $Schema->GetFieldByName($FieldName);
208 
209  # if field was found
210  if ($Field != NULL)
211  {
212  # construct query based on field type
213  switch ($Field->Type())
214  {
218  $Count = $this->DB->Query("SELECT COUNT(*) AS ResourceCount"
219  ." FROM Resources WHERE "
220  .$Field->DBFieldName()." IS NOT NULL"
221  ." AND LENGTH(LTRIM(RTRIM(".$Field->DBFieldName()."))) > 0"
222  ." AND SchemaId = ".intval($this->SchemaId),
223  "ResourceCount");
224  if ($Count > 1)
225  {
226  $Query = "SELECT ResourceId FROM Resources"
227  ." WHERE SchemaId = ".intval($this->SchemaId)
228  ." ORDER BY ".$Field->DBFieldName()
229  .($Ascending ? " ASC" : " DESC");
230  }
231  break;
232 
235  $Count = $this->DB->Query("SELECT COUNT(*) AS ResourceCount"
236  ." FROM Resources WHERE "
237  .$Field->DBFieldName()." IS NOT NULL"
238  ." AND SchemaId = ".intval($this->SchemaId),
239  "ResourceCount");
240  if ($Count > 1)
241  {
242  $Query = "SELECT ResourceId FROM Resources"
243  ." WHERE SchemaId = ".intval($this->SchemaId)
244  ." ORDER BY ".$Field->DBFieldName()
245  .($Ascending ? " ASC" : " DESC");
246  }
247  break;
248 
250  $Count = $this->DB->Query("SELECT COUNT(*) AS ResourceCount"
251  ." FROM Resources WHERE "
252  .$Field->DBFieldName()."Begin IS NOT NULL"
253  ." AND SchemaId = ".intval($this->SchemaId),
254  "ResourceCount");
255  if ($Count > 1)
256  {
257  $Query = "SELECT ResourceId FROM Resources"
258  ." WHERE SchemaId = ".intval($this->SchemaId)
259  ." ORDER BY ".$Field->DBFieldName()."Begin"
260  .($Ascending ? " ASC" : " DESC");
261  }
262  break;
263  }
264 
265  # if appropriate query was found
266  if (isset($Query))
267  {
268  # if limited number of results were requested
269  if ($Limit !== NULL)
270  {
271  # add limit to query
272  $Query .= " LIMIT ".intval($Limit);
273  }
274 
275  # perform query and retrieve resource IDs
276  $this->DB->Query($Query);
277  $ResourceIds = $this->DB->FetchColumn("ResourceId");
278  }
279  }
280 
281  # return resource IDs to caller
282  return $ResourceIds;
283  }
284 
291  function GetTimestampOfLastResourceModification($OnlyReleasedResources = TRUE)
292  {
293  $LastChangeDate = $this->DB->Query(
294  "SELECT MAX(DateLastModified) AS LastChangeDate"
295  ." FROM Resources"
296  ." WHERE SchemaId = ".intval($this->SchemaId)
297  .($OnlyReleasedResources ? " AND ReleaseFlag = 1" : ""),
298  "LastChangeDate");
299  return ($LastChangeDate ? strtotime($LastChangeDate) : NULL);
300  }
301 
308  {
309  # retrieve field names from schema
310  $FieldNames = array();
311  $Schema = new MetadataSchema($this->SchemaId);
312  $Fields = $Schema->GetFields();
313  foreach ($Fields as $Field)
314  {
315  $FieldNames[$Field->Id()] = $Field->Name();
316  }
317 
318  # return field names to caller
319  return $FieldNames;
320  }
321 
329  function GetMatchingResources($ValuesToMatch)
330  {
331  # start out assuming we won't find any resources
332  $Resources = array();
333 
334  # for each value
335  $Schema = new MetadataSchema($this->SchemaId);
336  $Fields = $Schema->GetFields(
344  $LinkingTerm = "";
345  $Condition = "";
346  foreach ($ValuesToMatch as $FieldId => $Value)
347  {
348  # if field can be used for comparison
349  if (isset($Fields[$FieldId]))
350  {
351  # add comparison to condition
352  $Condition .= $LinkingTerm.$Fields[$FieldId]->DBFieldName()
353  ." = '".addslashes($Value)."'";
354  $LinkingTerm = " AND ";
355  }
356  }
357 
358  # if there were valid conditions
359  if (strlen($Condition))
360  {
361  # build query statment
362  $Query = "SELECT ResourceId FROM Resources WHERE ".$Condition
363  ." AND SchemaId = ".intval($this->SchemaId);
364 
365  # execute query to retrieve matching resource IDs
366  $this->DB->Query($Query);
367  $ResourceIds = $this->DB->FetchColumn("ResourceId");
368 
369  # retrieve resource objects
370  foreach ($ResourceIds as $Id)
371  {
372  $Resources[$Id] = new Resource($Id);
373  }
374  }
375 
376  # return any resources found to caller
377  return $Resources;
378  }
379 
380  # Functions for keeping per-field resource counts updated:
381 
392  function GetResourceCount($FieldId, $Value, $CountType="All")
393  {
394  if ($FieldId<0)
395  return NULL;
396 
397  $Schema = new MetadataSchema($this->SchemaId);
398  $Field = $Schema->GetField($FieldId);
399  if ($Field === NULL)
400  return NULL;
401 
402  if ($this->ResourceCount === NULL)
403  {
404  $this->DB->Query(
405  "SELECT FieldId, ClassName, CountType, Count FROM ResourceCounts");
406 
407  while ($Row = $this->DB->FetchRow())
408  {
409  $R_FieldId = $Row["FieldId"];
410  $R_ClassName = $Row["ClassName"];
411  $R_CountType = $Row["CountType"];
412  $R_Count = $Row["Count"];
413 
414  $this->ResourceCount[$R_FieldId][$R_ClassName][$R_CountType] = $R_Count;
415  }
416  }
417 
418  if ($Field->Type() === MetadataSchema::MDFTYPE_OPTION
419  || $Field->Type() === MetadataSchema::MDFTYPE_CONTROLLEDNAME)
420  {
421  return isset($this->ResourceCount[$FieldId][$Value][$CountType]) ?
422  $this->ResourceCount[$FieldId][$Value][$CountType] :
423  0 ;
424  }
425  else
426  {
427  return NULL;
428  }
429  }
430 
435  public function GetReleasedResourceTotal()
436  {
437  return $this->DB->Query("
438  SELECT COUNT(*) AS ResourceTotal
439  FROM Resources
440  WHERE ResourceId > 0
441  AND ReleaseFlag = 1
442  AND SchemaId = ".intval($this->SchemaId),
443  "ResourceTotal");
444  }
445 
451  public function GetResourceTotal()
452  {
453  return $this->DB->Query("
454  SELECT COUNT(*) AS ResourceTotal
455  FROM Resources
456  WHERE ResourceId > 0
457  AND SchemaId = ".intval($this->SchemaId),
458  "ResourceTotal");
459  }
460 
469  {
470  global $AF;
471 
472  # be sure that we're not a gigantic object when the task is queued
473  $TmpResourceCount = $this->ResourceCount;
474  $this->ResourceCount = NULL;
475 
476  $AF->QueueUniqueTask(
477  array($this,"UpdateResourceCountCallback"), array());
478  $this->ResourceCount = $TmpResourceCount;
479  }
480 
488  {
489  $DB = new Database();
490 
491  $DB->Query(
492  "CREATE TABLE ResourceCountsNew (FieldId INT, ClassName TEXT, CountType TEXT, Count INT);");
493 
494  $Start = microtime(TRUE);
495 
496  foreach ($this->ResourceCountConditions as $CountType => $CountCondition)
497  {
498  $DB->Query(
499  "INSERT INTO ResourceCountsNew "
500  ."SELECT FieldId, ControlledName AS ClassName,"
501  ."'".$CountType."' AS CountType, Count(ResourceId) AS Count "
502  ."FROM (SELECT * FROM ResourceNameInts WHERE ResourceId IN "
503  ."(SELECT ResourceId FROM Resources "
504  ." WHERE SchemaId = ".intval($this->SchemaId)
505  .(($CountCondition!==NULL)
506  ?" AND ".$CountCondition:"").")) AS T0 "
507  ."JOIN ControlledNames USING(ControlledNameId) GROUP BY ControlledNameId;" );
508  }
509 
510  $Stop = microtime(TRUE);
511 
512  $DB->Query(
513  "INSERT INTO ResourceCountsNew VALUES (-1, '__LAST_UPDATED__', '', UNIX_TIMESTAMP()); ");
514  $DB->Query(
515  "INSERT INTO ResourceCountsNew VALUES (-2, '__UPDATE_RUNTIME__','',".($Stop-$Start).");");
516  $DB->Query(
517  "RENAME TABLE ResourceCounts TO ResourceCountsOld, ResourceCountsNew TO ResourceCounts; ");
518  $DB->Query(
519  "DROP TABLE ResourceCountsOld; ");
520  }
521 
522  # ---- PRIVATE INTERFACE -------------------------------------------------
523 
524  private $ResourceCount = NULL;
525  private $ResourceCountConditions = array("All" => NULL, "Released" => "ReleaseFlag=1");
526  private $SchemaId;
527 }
GetRatedResourceUserCount()
Return number of users who have rated resources.
Metadata schema (in effect a Factory class for MetadataField).
SQL database abstraction object with smart query caching.
GetTimestampOfLastResourceModification($OnlyReleasedResources=TRUE)
Get date/time of when last a resource was modified.
UpdateResourceCountCallback()
Update the stored counts of resources per controlled name, looking at the private var $ResourceCountC...
GetResourceCount($FieldId, $Value, $CountType="All")
Return the number of resources having a given value set for a specified ControlledName field...
GetResourceIdsSortedBy($FieldName, $Ascending=TRUE, $Limit=NULL)
Get resource IDs sorted by specified field.
ResourceFactory($SchemaId=MetadataSchema::SCHEMAID_DEFAULT)
Class constructor.
GetRecentlyReleasedResources($Count=10, $Offset=0, $MaxDaysToGoBack=90)
Get resources sorted by descending Date of Record Release, with Date of Record Creation as the second...
QueueResourceCountUpdate()
Add a task to the queue which will update the resource counts for ControlledNames.
const MDFTYPE_CONTROLLEDNAME
PHP
Definition: OAIClient.php:39
GetMatchingResources($ValuesToMatch)
Find resources with values that match those specified.
ClearQualifier($ObjectOrId, $NewObjectOrId=NULL)
Clear or change specific qualifier for all resources.
Represents a "resource" in CWIS.
Definition: Resource.php:13
GetPossibleFieldNames()
Get possible field names for resources.
GetReleasedResourceTotal()
Get the total number of released resources in the collection.
static Create($SchemaId)
Create a new resource.
Definition: Resource.php:59
Common factory class for item manipulation.
Definition: ItemFactory.php:17
GetRatedResourceCount()
Return number of resources that have ratings.
Factory for Resource objects.
ItemFactory($ItemClassName, $ItemTableName, $ItemIdFieldName, $ItemNameFieldName=NULL, $OrderOpsAllowed=FALSE, $SqlCondition=NULL)
Class constructor.
Definition: ItemFactory.php:36
GetResourceTotal()
Get the total number of resources in the collection, even if they are not released.
DuplicateResource($ResourceId)
Duplicate the specified resource and return to caller.