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