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 field
54  if ($Field->Name() != "Cumulative Rating")
55  {
56  $NewValue = $SrcResource->GetByField($Field, TRUE);
57 
58  # clear default value from destination resource that is
59  # set when creating a new resource
60  $DstResource->ClearByField($Field);
61 
62  # copy value from source resource to destination resource
63  $DstResource->SetByField($Field, $NewValue);
64  }
65  }
66  }
67 
68  # return new resource to caller
69  return $DstResource;
70  }
71 
78  function ClearQualifier($ObjectOrId, $NewObjectOrId = NULL)
79  {
80  # sanitize qualifier ID or retrieve from object
81  $QualifierId = is_object($ObjectOrId)
82  ? $ObjectOrId->Id() : intval($ObjectOrId);
83 
84  # if new qualifier passed in
85  if ($NewObjectOrId !== NULL)
86  {
87  # sanitize qualifier ID to change to or retrieve it from object
88  $NewQualifierIdVal = is_object($NewObjectOrId)
89  ? $NewObjectOrId->Id() : intval($NewObjectOrId);
90  }
91  else
92  {
93  # qualifier should be cleared
94  $NewQualifierIdVal = "NULL";
95  }
96 
97  # for each metadata field
98  $Schema = new MetadataSchema($this->SchemaId);
99  $Fields = $Schema->GetFields();
100  foreach ($Fields as $Field)
101  {
102  # if field uses qualifiers and uses item-level qualifiers
103  $QualColName = $Field->DBFieldName()."Qualifier";
104  if ($Field->UsesQualifiers()
105  && $Field->HasItemLevelQualifiers()
106  && $this->DB->FieldExists("Resources", $QualColName))
107  {
108  # set all occurrences to new qualifier value
109  $this->DB->Query("UPDATE Resources"
110  ." SET ".$QualColName." = ".$NewQualifierIdVal.""
111  ." WHERE ".$QualColName." = '".$QualifierId."'"
112  ." AND SchemaId = ".intval($this->SchemaId));
113  }
114  }
115 
116  # clear or change qualifier association with controlled names
117  # (NOTE: this should probably be done in a controlled name factory object)
118  $this->DB->Query("UPDATE ControlledNames"
119  ." SET QualifierId = ".$NewQualifierIdVal
120  ." WHERE QualifierId = '".$QualifierId."'");
121 
122  # clear or change qualifier association with classifications
123  # (NOTE: this should probably be done in a classification factory object)
124  $this->DB->Query("UPDATE Classifications"
125  ." SET QualifierId = ".$NewQualifierIdVal
126  ." WHERE QualifierId = '".$QualifierId."'");
127  }
128 
134  {
135  return $this->DB->Query(
136  "SELECT COUNT(DISTINCT ResourceId) AS ResourceCount"
137  ." FROM ResourceRatings",
138  "ResourceCount");
139  }
140 
146  {
147  return $this->DB->Query(
148  "SELECT COUNT(DISTINCT UserId) AS UserCount"
149  ." FROM ResourceRatings",
150  "UserCount");
151  }
152 
162  function GetRecentlyReleasedResources($Count = 10, $Offset = 0, $MaxDaysToGoBack = 90)
163  {
164  # assume that no resources will be found
165  $Resources = array();
166 
167  # calculate cutoff date for resources
168  $CutoffDate = date("Y-m-d H:i:s", strtotime($MaxDaysToGoBack." days ago"));
169 
170  # query for resource IDs
171  $this->DB->Query("SELECT ResourceId FROM Resources WHERE"
172  ." DateOfRecordRelease > '".$CutoffDate."'"
173  ." AND ReleaseFlag = 1"
174  ." AND ResourceId >= 0"
175  ." AND SchemaId = ".intval($this->SchemaId)
176  ." ORDER BY DateOfRecordRelease DESC, DateOfRecordCreation DESC"
177  ." LIMIT ".intval($Offset).", ".intval($Count));
178  $ResourceIds = $this->DB->FetchColumn("ResourceId");
179 
180  # for each resource ID found
181  foreach ($ResourceIds as $ResourceId)
182  {
183  # load resource and add to list of found resources
184  $Resources[$ResourceId] = new Resource($ResourceId);
185  }
186 
187  # return found resources to caller
188  return $Resources;
189  }
190 
199  function GetResourceIdsSortedBy($FieldName, $Ascending = TRUE, $Limit = NULL)
200  {
201  # assume no resources will be found
202  $ResourceIds = array();
203 
204  # get field
205  $Schema = new MetadataSchema($this->SchemaId);
206  $Field = $Schema->GetFieldByName($FieldName);
207 
208  # if field was found
209  if ($Field != NULL)
210  {
211  # construct query based on field type
212  switch ($Field->Type())
213  {
217  $Count = $this->DB->Query("SELECT COUNT(*) AS ResourceCount"
218  ." FROM Resources WHERE "
219  .$Field->DBFieldName()." IS NOT NULL"
220  ." AND LENGTH(LTRIM(RTRIM(".$Field->DBFieldName()."))) > 0"
221  ." AND SchemaId = ".intval($this->SchemaId),
222  "ResourceCount");
223  if ($Count > 1)
224  {
225  $Query = "SELECT ResourceId FROM Resources"
226  ." WHERE SchemaId = ".intval($this->SchemaId)
227  ." ORDER BY ".$Field->DBFieldName()
228  .($Ascending ? " ASC" : " DESC");
229  }
230  break;
231 
234  $Count = $this->DB->Query("SELECT COUNT(*) AS ResourceCount"
235  ." FROM Resources WHERE "
236  .$Field->DBFieldName()." IS NOT NULL"
237  ." AND SchemaId = ".intval($this->SchemaId),
238  "ResourceCount");
239  if ($Count > 1)
240  {
241  $Query = "SELECT ResourceId FROM Resources"
242  ." WHERE SchemaId = ".intval($this->SchemaId)
243  ." ORDER BY ".$Field->DBFieldName()
244  .($Ascending ? " ASC" : " DESC");
245  }
246  break;
247 
249  $Count = $this->DB->Query("SELECT COUNT(*) AS ResourceCount"
250  ." FROM Resources WHERE "
251  .$Field->DBFieldName()."Begin IS NOT NULL"
252  ." AND SchemaId = ".intval($this->SchemaId),
253  "ResourceCount");
254  if ($Count > 1)
255  {
256  $Query = "SELECT ResourceId FROM Resources"
257  ." WHERE SchemaId = ".intval($this->SchemaId)
258  ." ORDER BY ".$Field->DBFieldName()."Begin"
259  .($Ascending ? " ASC" : " DESC");
260  }
261  break;
262  }
263 
264  # if appropriate query was found
265  if (isset($Query))
266  {
267  # if limited number of results were requested
268  if ($Limit !== NULL)
269  {
270  # add limit to query
271  $Query .= " LIMIT ".intval($Limit);
272  }
273 
274  # perform query and retrieve resource IDs
275  $this->DB->Query($Query);
276  $ResourceIds = $this->DB->FetchColumn("ResourceId");
277  }
278  }
279 
280  # return resource IDs to caller
281  return $ResourceIds;
282  }
283 
290  function GetTimestampOfLastResourceModification($OnlyReleasedResources = TRUE)
291  {
292  $LastChangeDate = $this->DB->Query(
293  "SELECT MAX(DateLastModified) AS LastChangeDate"
294  ." FROM Resources"
295  ." WHERE SchemaId = ".intval($this->SchemaId)
296  .($OnlyReleasedResources ? " AND ReleaseFlag = 1" : ""),
297  "LastChangeDate");
298  return ($LastChangeDate ? strtotime($LastChangeDate) : NULL);
299  }
300 
307  {
308  # retrieve field names from schema
309  $FieldNames = array();
310  $Schema = new MetadataSchema($this->SchemaId);
311  $Fields = $Schema->GetFields();
312  foreach ($Fields as $Field)
313  {
314  $FieldNames[$Field->Id()] = $Field->Name();
315  }
316 
317  # return field names to caller
318  return $FieldNames;
319  }
320 
328  function GetMatchingResources($ValuesToMatch)
329  {
330  # start out assuming we won't find any resources
331  $Resources = array();
332 
333  # for each value
334  $Schema = new MetadataSchema($this->SchemaId);
335  $Fields = $Schema->GetFields(
343  $LinkingTerm = "";
344  $Condition = "";
345  foreach ($ValuesToMatch as $FieldId => $Value)
346  {
347  # if field can be used for comparison
348  if (isset($Fields[$FieldId]))
349  {
350  # add comparison to condition
351  $Condition .= $LinkingTerm.$Fields[$FieldId]->DBFieldName()
352  ." = '".addslashes($Value)."'";
353  $LinkingTerm = " AND ";
354  }
355  }
356 
357  # if there were valid conditions
358  if (strlen($Condition))
359  {
360  # build query statment
361  $Query = "SELECT ResourceId FROM Resources WHERE ".$Condition
362  ." AND SchemaId = ".intval($this->SchemaId);
363 
364  # execute query to retrieve matching resource IDs
365  $this->DB->Query($Query);
366  $ResourceIds = $this->DB->FetchColumn("ResourceId");
367 
368  # retrieve resource objects
369  foreach ($ResourceIds as $Id)
370  {
371  $Resources[$Id] = new Resource($Id);
372  }
373  }
374 
375  # return any resources found to caller
376  return $Resources;
377  }
378 
379  # Functions for keeping per-field resource counts updated:
380 
391  function GetResourceCount($FieldId, $Value, $CountType="All")
392  {
393  $Schema = new MetadataSchema($this->SchemaId);
394  $Field = $Schema->GetField($FieldId);
395  if ($Field === NULL) { return NULL; }
396 
397  if ($this->ResourceCount === NULL)
398  {
399  $this->DB->Query(
400  "SELECT FieldId, ClassName, CountType, Count FROM ResourceCounts");
401 
402  while ($Row = $this->DB->FetchRow())
403  {
404  $FieldId = $Row["FieldId"];
405  $ClassName = $Row["ClassName"];
406  $CountType = $Row["CountType"];
407  $Count = $Row["Count"];
408 
409  $this->ResourceCount[$FieldId][$ClassName][$CountType] = $Count;
410  }
411  }
412 
413  if ($Field->Type() === MetadataSchema::MDFTYPE_OPTION
414  || $Field->Type() === MetadataSchema::MDFTYPE_CONTROLLEDNAME)
415  {
416  return isset($this->ResourceCount[$FieldId][$Value][$CountType]) ?
417  $this->ResourceCount[$FieldId][$Value][$CountType] :
418  0 ;
419  }
420  else
421  {
422  return NULL;
423  }
424  }
425 
430  public function GetReleasedResourceTotal()
431  {
432  return $this->DB->Query("
433  SELECT COUNT(*) AS ResourceTotal
434  FROM Resources
435  WHERE ResourceId > 0
436  AND ReleaseFlag = 1
437  AND SchemaId = ".intval($this->SchemaId),
438  "ResourceTotal");
439  }
440 
446  public function GetResourceTotal()
447  {
448  return $this->DB->Query("
449  SELECT COUNT(*) AS ResourceTotal
450  FROM Resources
451  WHERE ResourceId > 0
452  AND SchemaId = ".intval($this->SchemaId),
453  "ResourceTotal");
454  }
455 
464  {
465  global $AF;
466 
467  # be sure that we're not a gigantic object when the task is queued
468  $TmpResourceCount = $this->ResourceCount;
469  $this->ResourceCount = NULL;
470 
471  $AF->QueueUniqueTask(
472  array($this,"UpdateResourceCountCallback"), array());
473  $this->ResourceCount = $TmpResourceCount;
474  }
475 
483  {
484  $DB = new Database();
485 
486  $DB->Query(
487  "CREATE TABLE ResourceCountsNew (FieldId INT, ClassName TEXT, CountType TEXT, Count INT);");
488 
489  $Start = microtime(TRUE);
490 
491  foreach ($this->ResourceCountConditions as $CountType => $CountCondition)
492  {
493  $DB->Query(
494  "INSERT INTO ResourceCountsNew "
495  ."SELECT FieldId, ControlledName AS ClassName,"
496  ."'".$CountType."' AS CountType, Count(ResourceId) AS Count "
497  ."FROM (SELECT * FROM ResourceNameInts WHERE ResourceId IN "
498  ."(SELECT ResourceId FROM Resources "
499  ." WHERE SchemaId = ".intval($this->SchemaId)
500  .(($CountCondition!==NULL)
501  ?" AND ".$CountCondition:"").")) AS T0 "
502  ."JOIN ControlledNames USING(ControlledNameId) GROUP BY ControlledNameId;" );
503  }
504 
505  $Stop = microtime(TRUE);
506 
507  $DB->Query(
508  "INSERT INTO ResourceCountsNew VALUES (-1, '__LAST_UPDATED__', '', UNIX_TIMESTAMP()); ");
509  $DB->Query(
510  "INSERT INTO ResourceCountsNew VALUES (-2, '__UPDATE_RUNTIME__','',".($Stop-$Start).");");
511  $DB->Query(
512  "RENAME TABLE ResourceCounts TO ResourceCountsOld, ResourceCountsNew TO ResourceCounts; ");
513  $DB->Query(
514  "DROP TABLE ResourceCountsOld; ");
515  }
516 
517  # ---- PRIVATE INTERFACE -------------------------------------------------
518 
519  private $ResourceCount = NULL;
520  private $ResourceCountConditions = array("All" => NULL, "Released" => "ReleaseFlag=1");
521  private $SchemaId;
522 }
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 &quot;resource&quot; 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.