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 }