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  if ($FieldId<0)
394  return NULL;
395 
396  $Schema = new MetadataSchema($this->SchemaId);
397  $Field = $Schema->GetField($FieldId);
398  if ($Field === NULL)
399  return NULL;
400 
401  if ($this->ResourceCount === NULL)
402  {
403  $this->DB->Query(
404  "SELECT FieldId, ClassName, CountType, Count FROM ResourceCounts");
405 
406  while ($Row = $this->DB->FetchRow())
407  {
408  $R_FieldId = $Row["FieldId"];
409  $R_ClassName = $Row["ClassName"];
410  $R_CountType = $Row["CountType"];
411  $R_Count = $Row["Count"];
412 
413  $this->ResourceCount[$R_FieldId][$R_ClassName][$R_CountType] = $R_Count;
414  }
415  }
416 
417  if ($Field->Type() === MetadataSchema::MDFTYPE_OPTION
418  || $Field->Type() === MetadataSchema::MDFTYPE_CONTROLLEDNAME)
419  {
420  return isset($this->ResourceCount[$FieldId][$Value][$CountType]) ?
421  $this->ResourceCount[$FieldId][$Value][$CountType] :
422  0 ;
423  }
424  else
425  {
426  return NULL;
427  }
428  }
429 
434  public function GetReleasedResourceTotal()
435  {
436  return $this->DB->Query("
437  SELECT COUNT(*) AS ResourceTotal
438  FROM Resources
439  WHERE ResourceId > 0
440  AND ReleaseFlag = 1
441  AND SchemaId = ".intval($this->SchemaId),
442  "ResourceTotal");
443  }
444 
450  public function GetResourceTotal()
451  {
452  return $this->DB->Query("
453  SELECT COUNT(*) AS ResourceTotal
454  FROM Resources
455  WHERE ResourceId > 0
456  AND SchemaId = ".intval($this->SchemaId),
457  "ResourceTotal");
458  }
459 
468  {
469  global $AF;
470 
471  # be sure that we're not a gigantic object when the task is queued
472  $TmpResourceCount = $this->ResourceCount;
473  $this->ResourceCount = NULL;
474 
475  $AF->QueueUniqueTask(
476  array($this,"UpdateResourceCountCallback"), array());
477  $this->ResourceCount = $TmpResourceCount;
478  }
479 
487  {
488  $DB = new Database();
489 
490  $DB->Query(
491  "CREATE TABLE ResourceCountsNew (FieldId INT, ClassName TEXT, CountType TEXT, Count INT);");
492 
493  $Start = microtime(TRUE);
494 
495  foreach ($this->ResourceCountConditions as $CountType => $CountCondition)
496  {
497  $DB->Query(
498  "INSERT INTO ResourceCountsNew "
499  ."SELECT FieldId, ControlledName AS ClassName,"
500  ."'".$CountType."' AS CountType, Count(ResourceId) AS Count "
501  ."FROM (SELECT * FROM ResourceNameInts WHERE ResourceId IN "
502  ."(SELECT ResourceId FROM Resources "
503  ." WHERE SchemaId = ".intval($this->SchemaId)
504  .(($CountCondition!==NULL)
505  ?" AND ".$CountCondition:"").")) AS T0 "
506  ."JOIN ControlledNames USING(ControlledNameId) GROUP BY ControlledNameId;" );
507  }
508 
509  $Stop = microtime(TRUE);
510 
511  $DB->Query(
512  "INSERT INTO ResourceCountsNew VALUES (-1, '__LAST_UPDATED__', '', UNIX_TIMESTAMP()); ");
513  $DB->Query(
514  "INSERT INTO ResourceCountsNew VALUES (-2, '__UPDATE_RUNTIME__','',".($Stop-$Start).");");
515  $DB->Query(
516  "RENAME TABLE ResourceCounts TO ResourceCountsOld, ResourceCountsNew TO ResourceCounts; ");
517  $DB->Query(
518  "DROP TABLE ResourceCountsOld; ");
519  }
520 
521  # ---- PRIVATE INTERFACE -------------------------------------------------
522 
523  private $ResourceCount = NULL;
524  private $ResourceCountConditions = array("All" => NULL, "Released" => "ReleaseFlag=1");
525  private $SchemaId;
526 }
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.