CWIS Developer Documentation

- Home
- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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
19 class ResourceFactory extends ItemFactory {
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
118 function GetRatedResourceCount()
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
127 function GetRatedResourceUserCount()
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 {
180 case MetadataSchema::MDFTYPE_TEXT:
181 case MetadataSchema::MDFTYPE_PARAGRAPH:
182 case MetadataSchema::MDFTYPE_URL:
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
196 case MetadataSchema::MDFTYPE_NUMBER:
197 case MetadataSchema::MDFTYPE_TIMESTAMP:
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
210 case MetadataSchema::MDFTYPE_DATE:
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
255 function GetPossibleFieldNames()
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(
280 MetadataSchema::MDFTYPE_TEXT |
281 MetadataSchema::MDFTYPE_PARAGRAPH |
282 MetadataSchema::MDFTYPE_NUMBER | MetadataSchema::MDFTYPE_DATE |
283 MetadataSchema::MDFTYPE_TIMESTAMP |
284 MetadataSchema::MDFTYPE_FLAG | MetadataSchema::MDFTYPE_URL |
285 MetadataSchema::MDFTYPE_POINT);
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 $Schema = new MetadataSchema();
325 $Field = $Schema->GetField($FieldId);
326 if ($Field === NULL) { return NULL; }
327
328 if ($this->ResourceCount === NULL)
329 {
330 $this->DB->Query(
331 "SELECT FieldId, ClassName, CountType, Count from ResourceCounts");
332
333 while ($Row = $this->DB->FetchRow())
334 {
335 $FieldId = $Row["FieldId"];
336 $ClassName = $Row["ClassName"];
337 $CountType = $Row["CountType"];
338 $Count = $Row["Count"];
339
340 $this->ResourceCount[$FieldId][$ClassName][$CountType] = $Count;
341 }
342 }
343
344 if ($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
382 function QueueResourceCountUpdate()
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
395 function UpdateResourceCountCallback()
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 }