CWIS Developer Documentation

- Home
- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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 {
33 case MetadataSchema::MDFTYPE_TEXT:
34 case MetadataSchema::MDFTYPE_PARAGRAPH:
35 case MetadataSchema::MDFTYPE_USER:
36 case MetadataSchema::MDFTYPE_URL:
37 $FieldInfo[$FieldName]["FieldType"] =
38 Recommender::CONTENTFIELDTYPE_TEXT;
39 break;
40
41 case MetadataSchema::MDFTYPE_TREE:
42 case MetadataSchema::MDFTYPE_CONTROLLEDNAME:
43 case MetadataSchema::MDFTYPE_OPTION:
44 $FieldInfo[$FieldName]["FieldType"] =
45 Recommender::CONTENTFIELDTYPE_TEXT;
46 break;
47
48 case MetadataSchema::MDFTYPE_NUMBER:
49 case MetadataSchema::MDFTYPE_FLAG:
50 $FieldInfo[$FieldName]["FieldType"] =
51 Recommender::CONTENTFIELDTYPE_NUMERIC;
52 break;
53
54 case MetadataSchema::MDFTYPE_DATE:
55 $FieldInfo[$FieldName]["FieldType"] =
56 Recommender::CONTENTFIELDTYPE_DATERANGE;
57 break;
58
59 case MetadataSchema::MDFTYPE_TIMESTAMP:
60 $FieldInfo[$FieldName]["FieldType"] =
61 Recommender::CONTENTFIELDTYPE_DATE;
62 break;
63
64 case MetadataSchema::MDFTYPE_IMAGE:
65 # (for images we use their alt text)
66 $FieldInfo[$FieldName]["FieldType"] =
67 Recommender::CONTENTFIELDTYPE_TEXT;
68 break;
69
70 case MetadataSchema::MDFTYPE_FILE:
71 # (for files we use the file name)
72 $FieldInfo[$FieldName]["FieldType"] =
73 Recommender::CONTENTFIELDTYPE_TEXT;
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
87 $this->Recommender($DB, $ItemTableName, $RatingTableName,
88 $ItemIdFieldName, $UserIdFieldName, $RatingFieldName,
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,
119 $Priority = ApplicationFramework::PRIORITY_LOW)
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 }