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 ?>