ResourceFactory.php
Go to the documentation of this file.
00001 <?PHP 00002 # 00003 # FILE: ResourceFactory.php 00004 # 00005 # METHODS PROVIDED: 00006 # ResourceFactory() 00007 # - constructor 00008 # DuplicateResource($ResourceId) 00009 # - create duplicate resource and return to caller 00010 # (SEE ALSO: ItemFactory.php) 00011 # 00012 # AUTHOR: Edward Almasy 00013 # 00014 # Part of the Collection Workflow Integration System (CWIS) 00015 # Copyright 2011 Internet Scout Project 00016 # http://scout.wisc.edu/ 00017 # 00018 00019 class ResourceFactory extends ItemFactory { 00020 00021 # ---- PUBLIC INTERFACE -------------------------------------------------- 00022 00023 # object constructor 00024 function ResourceFactory() 00025 { 00026 # set up item factory base class 00027 $this->ItemFactory("Resource", "Resources", "ResourceId"); 00028 } 00029 00030 # create duplicate resource and return to caller 00031 function DuplicateResource($ResourceId) 00032 { 00033 # create new target resource 00034 $DstResource = new Resource(); 00035 00036 # load up resource to duplicate 00037 $SrcResource = new Resource($ResourceId); 00038 00039 # if resource to duplicate was found 00040 if ($SrcResource->Status() > 0) 00041 { 00042 # for each metadata field 00043 $Schema = new MetadataSchema(); 00044 $Fields = $Schema->GetFields(); 00045 foreach ($Fields as $Field) 00046 { 00047 # skip the cumulative rating field 00048 if ($Field->Name() != "Cumulative Rating") 00049 { 00050 $NewValue = $SrcResource->GetByField($Field, TRUE); 00051 00052 # clear default value from destination resource that is 00053 # set when creating a new resource 00054 $DstResource->ClearByField($Field); 00055 00056 # copy value from source resource to destination resource 00057 $DstResource->SetByField($Field, $NewValue); 00058 } 00059 } 00060 } 00061 00062 # return new resource to caller 00063 return $DstResource; 00064 } 00065 00066 # clear or change specific qualifier for all resources 00067 function ClearQualifier($ObjectOrId, $NewObjectOrId = NULL) 00068 { 00069 # sanitize qualifier ID or retrieve from object 00070 $QualifierId = is_object($ObjectOrId) 00071 ? $ObjectOrId->Id() : intval($ObjectOrId); 00072 00073 # if new qualifier passed in 00074 if ($NewObjectOrId !== NULL) 00075 { 00076 # sanitize qualifier ID to change to or retrieve it from object 00077 $NewQualifierIdVal = is_object($NewObjectOrId) 00078 ? $NewObjectOrId->Id() : intval($NewObjectOrId); 00079 } 00080 else 00081 { 00082 # qualifier should be cleared 00083 $NewQualifierIdVal = "NULL"; 00084 } 00085 00086 # for each metadata field 00087 $Schema = new MetadataSchema(); 00088 $Fields = $Schema->GetFields(); 00089 foreach ($Fields as $Field) 00090 { 00091 # if field uses qualifiers and uses item-level qualifiers 00092 $QualColName = $Field->DBFieldName()."Qualifier"; 00093 if ($Field->UsesQualifiers() 00094 && $Field->HasItemLevelQualifiers() 00095 && $this->DB->FieldExists("Resources", $QualColName)) 00096 { 00097 # set all occurrences to new qualifier value 00098 $this->DB->Query("UPDATE Resources" 00099 ." SET ".$QualColName." = ".$NewQualifierIdVal."" 00100 ." WHERE ".$QualColName." = '".$QualifierId."'"); 00101 } 00102 } 00103 00104 # clear or change qualifier association with controlled names 00105 # (NOTE: this should probably be done in a controlled name factory object) 00106 $this->DB->Query("UPDATE ControlledNames" 00107 ." SET QualifierId = ".$NewQualifierIdVal 00108 ." WHERE QualifierId = '".$QualifierId."'"); 00109 00110 # clear or change qualifier association with classifications 00111 # (NOTE: this should probably be done in a classification factory object) 00112 $this->DB->Query("UPDATE Classifications" 00113 ." SET QualifierId = ".$NewQualifierIdVal 00114 ." WHERE QualifierId = '".$QualifierId."'"); 00115 } 00116 00117 # return count of rated resources 00118 function GetRatedResourceCount() 00119 { 00120 $RatedResourceCount = $this->DB->Query( 00121 "SELECT COUNT(DISTINCT ResourceId) AS ResourceCount " 00122 ."FROM ResourceRatings", "ResourceCount"); 00123 return $RatedResourceCount; 00124 } 00125 00126 # return count of users who have rated resources 00127 function GetRatedResourceUserCount() 00128 { 00129 $RatedResourceCount = $this->DB->Query( 00130 "SELECT COUNT(DISTINCT UserId) AS UserCount " 00131 ."FROM ResourceRatings", "UserCount"); 00132 return $RatedResourceCount; 00133 } 00134 00135 # return recently released resources 00136 function GetRecentlyReleasedResources($Count = 10, $Offset = 0, $MaxDaysToGoBack = 90) 00137 { 00138 # assume that no resources will be found 00139 $Resources = array(); 00140 00141 # calculate cutoff date for resources 00142 $CutoffDate = date("Y-m-d H:i:s", strtotime($MaxDaysToGoBack." days ago")); 00143 00144 # query for resource IDs 00145 $this->DB->Query("SELECT ResourceId FROM Resources WHERE" 00146 ." DateOfRecordRelease > '".$CutoffDate."'" 00147 ." AND ReleaseFlag = 1" 00148 ." AND ResourceId >= 0" 00149 ." ORDER BY DateOfRecordRelease DESC, DateOfRecordCreation DESC" 00150 ." LIMIT ".intval($Offset).", ".intval($Count)); 00151 $ResourceIds = $this->DB->FetchColumn("ResourceId"); 00152 00153 # for each resource ID found 00154 foreach ($ResourceIds as $ResourceId) 00155 { 00156 # load resource and add to list of found resources 00157 $Resources[$ResourceId] = new Resource($ResourceId); 00158 } 00159 00160 # return found resources to caller 00161 return $Resources; 00162 } 00163 00164 # return resources sorted by specified field 00165 function GetResourceIdsSortedBy($FieldName, $Ascending = TRUE, $Limit = NULL) 00166 { 00167 # assume no resources will be found 00168 $ResourceIds = array(); 00169 00170 # get field 00171 $Schema = new MetadataSchema(); 00172 $Field = $Schema->GetFieldByName($FieldName); 00173 00174 # if field was found 00175 if ($Field != NULL) 00176 { 00177 # construct query based on field type 00178 switch ($Field->Type()) 00179 { 00180 case MetadataSchema::MDFTYPE_TEXT: 00181 case MetadataSchema::MDFTYPE_PARAGRAPH: 00182 case MetadataSchema::MDFTYPE_URL: 00183 $Count = $this->DB->Query("SELECT COUNT(*) AS ResourceCount" 00184 ." FROM Resources WHERE " 00185 .$Field->DBFieldName()." IS NOT NULL" 00186 ." AND LENGTH(LTRIM(RTRIM(".$Field->DBFieldName()."))) > 0", 00187 "ResourceCount"); 00188 if ($Count > 1) 00189 { 00190 $Query = "SELECT ResourceId FROM Resources" 00191 ." ORDER BY ".$Field->DBFieldName() 00192 .($Ascending ? " ASC" : " DESC"); 00193 } 00194 break; 00195 00196 case MetadataSchema::MDFTYPE_NUMBER: 00197 case MetadataSchema::MDFTYPE_TIMESTAMP: 00198 $Count = $this->DB->Query("SELECT COUNT(*) AS ResourceCount" 00199 ." FROM Resources WHERE " 00200 .$Field->DBFieldName()." IS NOT NULL", 00201 "ResourceCount"); 00202 if ($Count > 1) 00203 { 00204 $Query = "SELECT ResourceId FROM Resources" 00205 ." ORDER BY ".$Field->DBFieldName() 00206 .($Ascending ? " ASC" : " DESC"); 00207 } 00208 break; 00209 00210 case MetadataSchema::MDFTYPE_DATE: 00211 $Count = $this->DB->Query("SELECT COUNT(*) AS ResourceCount" 00212 ." FROM Resources WHERE " 00213 .$Field->DBFieldName()."Begin IS NOT NULL", 00214 "ResourceCount"); 00215 if ($Count > 1) 00216 { 00217 $Query = "SELECT ResourceId FROM Resources" 00218 ." ORDER BY ".$Field->DBFieldName()."Begin" 00219 .($Ascending ? " ASC" : " DESC"); 00220 } 00221 break; 00222 } 00223 00224 # if appropriate query was found 00225 if (isset($Query)) 00226 { 00227 # if limited number of results were requested 00228 if ($Limit !== NULL) 00229 { 00230 # add limit to query 00231 $Query .= " LIMIT ".intval($Limit); 00232 } 00233 00234 # perform query and retrieve resource IDs 00235 $this->DB->Query($Query); 00236 $ResourceIds = $this->DB->FetchColumn("ResourceId"); 00237 } 00238 } 00239 00240 # return resource IDs to caller 00241 return $ResourceIds; 00242 } 00243 00244 # get date/time of last resource modification (returned as Unix timestamp) 00245 function GetTimestampOfLastResourceModification($OnlyReleasedResources = TRUE) 00246 { 00247 $LastChangeDate = $this->DB->Query( 00248 "SELECT MAX(DateLastModified) AS LastChangeDate" 00249 ." FROM Resources".($OnlyReleasedResources ? " WHERE ReleaseFlag = 1" : ""), 00250 "LastChangeDate"); 00251 return ($LastChangeDate ? strtotime($LastChangeDate) : NULL); 00252 } 00253 00254 # get list of possible field names for resources 00255 function GetPossibleFieldNames() 00256 { 00257 # retrieve field names from schema 00258 $FieldNames = array(); 00259 $Schema = new MetadataSchema(); 00260 $Fields = $Schema->GetFields(); 00261 foreach ($Fields as $Field) 00262 { 00263 $FieldNames[$Field->Id()] = $Field->Name(); 00264 } 00265 00266 # return field names to caller 00267 return $FieldNames; 00268 } 00269 00270 # find resources with values that match those specified 00271 # (index of $ValuesToMatch is field IDs) 00272 function GetMatchingResources($ValuesToMatch) 00273 { 00274 # start out assuming we won't find any resources 00275 $Resources = array(); 00276 00277 # for each value 00278 $Schema = new MetadataSchema(); 00279 $Fields = $Schema->GetFields( 00280 MetadataSchema::MDFTYPE_TEXT | 00281 MetadataSchema::MDFTYPE_PARAGRAPH | 00282 MetadataSchema::MDFTYPE_NUMBER | MetadataSchema::MDFTYPE_DATE | 00283 MetadataSchema::MDFTYPE_TIMESTAMP | 00284 MetadataSchema::MDFTYPE_FLAG | MetadataSchema::MDFTYPE_URL | 00285 MetadataSchema::MDFTYPE_POINT); 00286 $LinkingTerm = ""; 00287 $Condition = ""; 00288 foreach ($ValuesToMatch as $FieldId => $Value) 00289 { 00290 # if field can be used for comparison 00291 if (isset($Fields[$FieldId])) 00292 { 00293 # add comparison to condition 00294 $Condition .= $LinkingTerm.$Fields[$FieldId]->DBFieldName() 00295 ." = '".addslashes($Value)."'"; 00296 $LinkingTerm = " AND "; 00297 } 00298 } 00299 00300 # if there were valid conditions 00301 if (strlen($Condition)) 00302 { 00303 # build query statment 00304 $Query = "SELECT ResourceId FROM Resources WHERE ".$Condition; 00305 00306 # execute query to retrieve matching resource IDs 00307 $this->DB->Query($Query); 00308 $ResourceIds = $DB->FetchColumn("ResourceId"); 00309 00310 # retrieve resource objects 00311 foreach ($ResourceIds as $Id) 00312 { 00313 $Resources[$Id] = new Resource($Id); 00314 } 00315 } 00316 00317 # return any resources found to caller 00318 return $Resources; 00319 } 00320 00321 # Functions for keeping per-field resource counts updated: 00322 function GetResourceCount($FieldId, $Value, $CountType="All") 00323 { 00324 if ($this->ResourceCount === NULL) 00325 { 00326 $this->DB->Query( 00327 "SELECT FieldId, ClassName, CountType, Count from ResourceCounts"); 00328 00329 while ($Row = $this->DB->FetchRow()) 00330 { 00331 $FieldId = $Row["FieldId"]; 00332 $ClassName = $Row["ClassName"]; 00333 $CountType = $Row["CountType"]; 00334 $Count = $Row["Count"]; 00335 00336 $this->ResourceCount[$FieldId][$ClassName][$CountType] = $Count; 00337 } 00338 } 00339 00340 if (time() - $this->ResourceCount[-1]["__LAST_UPDATED__"][""] > 1800 && 00341 $this->ResourceCountTaskQueued === FALSE) 00342 { 00343 $this->QueueResourceCountUpdate(); 00344 } 00345 00346 $Schema = new MetadataSchema(); 00347 $Field = $Schema->GetField($FieldId); 00348 00349 if ($Field->Status() === MetadataSchema::MDFSTAT_OK && 00350 ( $Field->Type() === MetadataSchema::MDFTYPE_OPTION || 00351 $Field->Type() === MetadataSchema::MDFTYPE_CONTROLLEDNAME ) ) 00352 { 00353 return isset($this->ResourceCount[$FieldId][$Value][$CountType]) ? 00354 $this->ResourceCount[$FieldId][$Value][$CountType] : 00355 0 ; 00356 } 00357 else 00358 { 00359 return NULL; 00360 } 00361 } 00362 00363 function QueueResourceCountUpdate() 00364 { 00365 global $AF; 00366 00367 # be sure that we're not a gigantic object when the task is queued 00368 $TmpResourceCount = $this->ResourceCount; 00369 $this->ResourceCount = NULL; 00370 00371 $AF->QueueUniqueTask( 00372 array($this,"UpdateResourceCountCallback"), array()); 00373 $this->ResourceCountTaskQueued = TRUE; 00374 $this->ResourceCount = $TmpResourceCount; 00375 } 00376 00377 function UpdateResourceCountCallback() 00378 { 00379 $DB = new Database(); 00380 $DB->Query( 00381 "CREATE TABLE ResourceCountsNew (FieldId INT, ClassName TEXT, CountType TEXT, Count INT);"); 00382 00383 $Start = microtime(TRUE); 00384 00385 foreach ($this->ResourceCountConditions as $CountType => $CountCondition) 00386 { 00387 $DB->Query( 00388 "INSERT INTO ResourceCountsNew " 00389 ."SELECT FieldId, ControlledName AS ClassName," 00390 . "'".$CountType."' AS CountType, Count(ResourceId) AS Count " 00391 . "FROM (SELECT * FROM ResourceNameInts WHERE ResourceId IN " 00392 . "(SELECT ResourceId FROM Resources " 00393 . (($CountCondition!==NULL)?"WHERE ".$CountCondition:"").")) AS T0 " 00394 . "JOIN ControlledNames USING(ControlledNameId) GROUP BY ControlledNameId;" ); 00395 } 00396 00397 $Stop = microtime(TRUE); 00398 00399 $DB->Query( 00400 "INSERT INTO ResourceCountsNew VALUES (-1, '__LAST_UPDATED__', '', UNIX_TIMESTAMP()); "); 00401 $DB->Query( 00402 "INSERT INTO ResourceCountsNew VALUES (-2, '__UPDATE_RUNTIME__','',".($Stop-$Start).");"); 00403 $DB->Query( 00404 "RENAME TABLE ResourceCounts TO ResourceCountsOld, ResourceCountsNew TO ResourceCounts; "); 00405 $DB->Query( 00406 "DROP TABLE ResourceCountsOld; "); 00407 } 00408 00409 # ---- PRIVATE INTERFACE ------------------------------------------------- 00410 00411 private $ResourceCount = NULL; 00412 private $ResourceCountTaskQueued = FALSE; 00413 private $ResourceCountConditions = array("All" => NULL, "Released" => "ReleaseFlag=1"); 00414 }