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

CWIS logo doxygen
Copyright 2010 Internet Scout