Search:

CWIS Developers Documentation

  • Main Page
  • Classes
  • Files
  • File List
  • File Members

SPTRecommender.php

Go to the documentation of this file.
00001 <?PHP
00002 #
00003 #   FILE:  SPTRecommender.php
00004 #
00005 #   Copyright 2002-2010 Internet Scout and Edward Almasy
00006 #   http://scout.wisc.edu
00007 #
00008 
00009 class SPTRecommender extends Recommender {
00010 
00011     function SPTRecommender()
00012     {
00013         # set up recommender configuration values for SPT
00014         $ItemTableName = "Resources";
00015         $ItemIdFieldName = "ResourceId";
00016         $RatingTableName = "ResourceRatings";
00017         $UserIdFieldName = "UserId";
00018         $RatingFieldName = "Rating";
00019 
00020         # build field info from SPT metadata schema
00021         $this->Schema = new MetadataSchema();
00022         $Fields = $this->Schema->GetFields();
00023         foreach ($Fields as $Field)
00024         {
00025             if ($Field->Enabled() && $Field->IncludeInKeywordSearch())
00026             {
00027                 $FieldName = $Field->Name();
00028                 $FieldInfo[$FieldName]["DBFieldName"] = $Field->DBFieldName();
00029                 $FieldInfo[$FieldName]["Weight"] = $Field->SearchWeight();
00030                 switch ($Field->Type())
00031                 {
00032                 case MetadataSchema::MDFTYPE_TEXT:
00033                 case MetadataSchema::MDFTYPE_PARAGRAPH:
00034                 case MetadataSchema::MDFTYPE_USER:
00035                 case MetadataSchema::MDFTYPE_URL:
00036                     $FieldInfo[$FieldName]["FieldType"] =
00037                         Recommender::CONTENTFIELDTYPE_TEXT;
00038                     break;
00039 
00040                 case MetadataSchema::MDFTYPE_TREE:
00041                 case MetadataSchema::MDFTYPE_CONTROLLEDNAME:
00042                 case MetadataSchema::MDFTYPE_OPTION:
00043                     $FieldInfo[$FieldName]["FieldType"] =
00044                         Recommender::CONTENTFIELDTYPE_TEXT;
00045                     break;
00046 
00047                 case MetadataSchema::MDFTYPE_NUMBER:
00048                 case MetadataSchema::MDFTYPE_FLAG:
00049                         $FieldInfo[$FieldName]["FieldType"] =
00050                             Recommender::CONTENTFIELDTYPE_NUMERIC;
00051                         break;
00052 
00053                 case MetadataSchema::MDFTYPE_DATE:
00054                     $FieldInfo[$FieldName]["FieldType"] =
00055                         Recommender::CONTENTFIELDTYPE_DATERANGE;
00056                     break;
00057 
00058                 case MetadataSchema::MDFTYPE_TIMESTAMP:
00059                     $FieldInfo[$FieldName]["FieldType"] =
00060                         Recommender::CONTENTFIELDTYPE_DATE;
00061                     break;
00062 
00063                 case MetadataSchema::MDFTYPE_IMAGE:
00064                     # (for images we use their alt text)
00065                     $FieldInfo[$FieldName]["FieldType"] =
00066                         Recommender::CONTENTFIELDTYPE_TEXT;
00067                     break;
00068 
00069                 case MetadataSchema::MDFTYPE_FILE:
00070                     # (for files we use the file name)
00071                     $FieldInfo[$FieldName]["FieldType"] =
00072                         Recommender::CONTENTFIELDTYPE_TEXT;
00073                     break;
00074                 }
00075             }
00076         }
00077 
00078         # create our own schema object and tell it to cache values
00079         $this->Schema = new MetadataSchema();
00080         $this->Schema->CacheData(TRUE);
00081 
00082         # create a database connection for recommender to use
00083         $DB = new SPTDatabase();
00084 
00085         # pass configuration info to real recommender object
00086         $this->Recommender($DB, $ItemTableName, $RatingTableName,
00087                 $ItemIdFieldName, $UserIdFieldName, $RatingFieldName,
00088                 $FieldInfo);
00089     }
00090 
00091     # overloaded version of method to retrieve field values from DB
00092     function GetFieldValue($ItemId, $FieldName)
00093     {
00094         static $Resources;
00095 
00096         # if resource not already loaded
00097         if (!isset($Resources[$ItemId]))
00098         {
00099             # get resource object
00100             $Resources[$ItemId] = new Resource($ItemId);
00101 
00102             # if cached resource limit exceeded
00103             if (count($Resources) > 100)
00104             {
00105                 # dump oldest resource
00106                 reset($Resources);
00107                 list($DumpedItemId, $DumpedResources) = each($Resources);
00108                 unset($Resources[$DumpedItemId]);
00109             }
00110         }
00111 
00112         # retrieve field value from resource object and return to caller
00113         $FieldValue = $Resources[$ItemId]->Get($FieldName);
00114         return $FieldValue;
00115     }
00116 
00117     function QueueUpdateForItem($ItemId,
00118             $Priority = ApplicationFramework::PRIORITY_LOW)
00119     {
00120         global $AF;
00121         $AF->QueueUniqueTask(array(__CLASS__, "RunUpdateForItem"),
00122                 array(intval($ItemId), 0), $Priority);
00123     }
00124 
00125     static function RunUpdateForItem($SourceItemId, $StartingIndex)
00126     {
00127         # check that resource still exists
00128         $RFactory = new ResourceFactory();
00129         if (!$RFactory->ItemExists($SourceItemId)) {  return;  }
00130 
00131         # load recommender engine
00132         static $Recommender;
00133         if (!isset($Recommender)) {  $Recommender = new SPTRecommender();  }
00134 
00135         # if starting update for source item
00136         if ($StartingIndex == 0)
00137         {
00138             # clear data for item
00139             $Recommender->DropItem($SourceItemId);
00140         }
00141 
00142         # load array of item IDs
00143         $TargetItemIds = $Recommender->GetItemIds();
00144         $TargetCount = count($TargetItemIds);
00145 
00146         # while not last item ID and not out of time
00147         global $AF;
00148         for ($Index = $StartingIndex;  ($Index < $TargetCount)
00149                 && ($AF->GetSecondsBeforeTimeout() > 5);  $Index++)
00150         {
00151             # if target ID points to non-temporary entry
00152             if ($TargetItemIds[$Index] >= 0)
00153             {
00154                 # update correlation for source item and current item
00155                 $Recommender->UpdateContentCorrelation(
00156                         $SourceItemId, $TargetItemIds[$Index]);
00157             }
00158         }
00159 
00160         # if all correlations completed for source item
00161         if ($Index >= $TargetCount)
00162         {
00163             # periodically prune correlations if enough time remaining
00164             if (($AF->GetSecondsBeforeTimeout() > 10) && (rand(1, 10) == 1))
00165             {
00166                 $Recommender->PruneCorrelations();
00167             }
00168         }
00169         else
00170         {
00171             # requeue updates for remaining items
00172             $AF->QueueUniqueTask(array(__CLASS__, "RunUpdateForItem"),
00173                     array($SourceItemId, $Index), ApplicationFramework::PRIORITY_MEDIUM);
00174         }
00175     }
00176 
00177 
00178     # ---- PRIVATE INTERFACE -------------------------------------------------
00179 
00180     private $Schema;
00181 
00182 };
00183 
00184 
00185 ?>

CWIS logo doxygen
Copyright 2010 Internet Scout