CWIS Developer Documentation
SPTRecommender.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # FILE: SPTRecommender.php
4 #
5 # Part of the Collection Workflow Integration System (CWIS)
6 # Copyright 2011 Edward Almasy and Internet Scout Project
7 # http://scout.wisc.edu/
8 #
9 
10 class SPTRecommender extends Recommender {
11 
12  function SPTRecommender()
13  {
14  # set up recommender configuration values for SPT
15  $ItemTableName = "Resources";
16  $ItemIdFieldName = "ResourceId";
17  $RatingTableName = "ResourceRatings";
18  $UserIdFieldName = "UserId";
19  $RatingFieldName = "Rating";
20 
21  # build field info from SPT metadata schema
22  $this->Schema = new MetadataSchema();
23  $Fields = $this->Schema->GetFields();
24  foreach ($Fields as $Field)
25  {
26  if ($Field->Enabled() && $Field->IncludeInKeywordSearch())
27  {
28  $FieldName = $Field->Name();
29  $FieldInfo[$FieldName]["DBFieldName"] = $Field->DBFieldName();
30  $FieldInfo[$FieldName]["Weight"] = $Field->SearchWeight();
31  switch ($Field->Type())
32  {
37  $FieldInfo[$FieldName]["FieldType"] =
39  break;
40 
44  $FieldInfo[$FieldName]["FieldType"] =
46  break;
47 
50  $FieldInfo[$FieldName]["FieldType"] =
52  break;
53 
55  $FieldInfo[$FieldName]["FieldType"] =
56  Recommender::CONTENTFIELDTYPE_DATERANGE;
57  break;
58 
60  $FieldInfo[$FieldName]["FieldType"] =
62  break;
63 
65  # (for images we use their alt text)
66  $FieldInfo[$FieldName]["FieldType"] =
68  break;
69 
71  # (for files we use the file name)
72  $FieldInfo[$FieldName]["FieldType"] =
74  break;
75  }
76  }
77  }
78 
79  # create our own schema object and tell it to cache values
80  $this->Schema = new MetadataSchema();
81  $this->Schema->CacheData(TRUE);
82 
83  # create a database connection for recommender to use
84  $DB = new Database();
85 
86  # pass configuration info to real recommender object
89  $FieldInfo);
90  }
91 
92  # overloaded version of method to retrieve field values from DB
93  function GetFieldValue($ItemId, $FieldName)
94  {
95  static $Resources;
96 
97  # if resource not already loaded
98  if (!isset($Resources[$ItemId]))
99  {
100  # get resource object
101  $Resources[$ItemId] = new Resource($ItemId);
102 
103  # if cached resource limit exceeded
104  if (count($Resources) > 100)
105  {
106  # dump oldest resource
107  reset($Resources);
108  list($DumpedItemId, $DumpedResources) = each($Resources);
109  unset($Resources[$DumpedItemId]);
110  }
111  }
112 
113  # retrieve field value from resource object and return to caller
114  $FieldValue = $Resources[$ItemId]->Get($FieldName);
115  return $FieldValue;
116  }
117 
118  function QueueUpdateForItem($ItemId,
120  {
121  global $AF;
122  $AF->QueueUniqueTask(array(__CLASS__, "RunUpdateForItem"),
123  array(intval($ItemId), 0), $Priority);
124  }
125 
126  static function RunUpdateForItem($SourceItemId, $StartingIndex)
127  {
128  # check that resource still exists
129  $RFactory = new ResourceFactory();
130  if (!$RFactory->ItemExists($SourceItemId)) { return; }
131 
132  # load recommender engine
133  static $Recommender;
134  if (!isset($Recommender)) { $Recommender = new SPTRecommender(); }
135 
136  # if starting update for source item
137  if ($StartingIndex == 0)
138  {
139  # clear data for item
140  $Recommender->DropItem($SourceItemId);
141  }
142 
143  # load array of item IDs
144  $TargetItemIds = $Recommender->GetItemIds();
145  $TargetCount = count($TargetItemIds);
146 
147  # while not last item ID and not out of time
148  global $AF;
149  for ($Index = $StartingIndex; ($Index < $TargetCount)
150  && ($AF->GetSecondsBeforeTimeout() > 5); $Index++)
151  {
152  # if target ID points to non-temporary entry
153  if ($TargetItemIds[$Index] >= 0)
154  {
155  # update correlation for source item and current item
156  $Recommender->UpdateContentCorrelation(
157  $SourceItemId, $TargetItemIds[$Index]);
158  }
159  }
160 
161  # if all correlations completed for source item
162  if ($Index >= $TargetCount)
163  {
164  # periodically prune correlations if enough time remaining
165  if (($AF->GetSecondsBeforeTimeout() > 10) && (rand(1, 10) == 1))
166  {
167  $Recommender->PruneCorrelations();
168  }
169  }
170  else
171  {
172  # requeue updates for remaining items
173  $AF->QueueUniqueTask(array(__CLASS__, "RunUpdateForItem"),
174  array($SourceItemId, $Index), ApplicationFramework::PRIORITY_LOW);
175  }
176  }
177 
178 
179  # ---- PRIVATE INTERFACE -------------------------------------------------
180 
181  private $Schema;
182 
183 }