CWIS Developer Documentation
SPTOAIServer.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # FILE: SPTOAIServer.php
4 #
5 # Copyright 2002-2010 Internet Scout
6 # http://scout.wisc.edu
7 #
8 
9 class SPTOAIServer extends OAIServer {
10 
11  # ---- PUBLIC INTERFACE --------------------------------------------------
12 
13  function SPTOAIServer($RetrievalSearchParameters = NULL)
14  {
15  global $SysConfig;
16 
17  # grab our own database handle
18  $this->DB = new Database();
19  $DB = $this->DB;
20 
21  # set up repository description
22  $DB->Query("SELECT * FROM SystemConfiguration");
23  $Record = $DB->FetchRow();
24  $RepDescr["Name"] = $SysConfig->PortalName();
25  $Protocol = isset($_SERVER["HTTPS"]) ? "https://" : "http://";
26  $ServerName = ($_SERVER["SERVER_NAME"] != "127.0.0.1")
27  ? $_SERVER["SERVER_NAME"]
28  : $_SERVER["HTTP_HOST"];
29  $RepDescr["BaseURL"] = $Protocol.$ServerName.$_SERVER["SCRIPT_NAME"];
30  $RepDescr["DateGranularity"] = "DATE";
31  $RepDescr["EarliestDate"] = strlen(trim($Record["OaiEarliestDate"]))
32  ? $Record["OaiEarliestDate"] : "1990-01-01";
33  $RepDescr["AdminEmail"][] = $SysConfig->AdminEmail();
34  $RepDescr["IDDomain"] = strlen(trim($Record["OaiIdDomain"]))
35  ? $Record["OaiIdDomain"] : $ServerName;
36  $RepDescr["IDPrefix"] = strlen(trim($Record["OaiIdPrefix"]))
37  ? $Record["OaiIdPrefix"] : $ServerName;
38 
39  # create item factory object for retrieving items from DB
40  $this->SPTItemFactory = new SPTOAIItemFactory($RetrievalSearchParameters);
41 
42  # call parent's constructor
43  $this->OAIServer($DB, $RepDescr, $this->SPTItemFactory, TRUE, $SysConfig->OAISQEnabled());
44 
45  # set up description of nsdl_dc format
46  $NsdldcNamespaceList = array(
47  "nsdl_dc" => "http://ns.nsdl.org/nsdl_dc_v1.01",
48  "dc" => "http://purl.org/dc/elements/1.1/",
49  "dct" => "http://purl.org/dc/terms/",
50  "ieee" => "http://www.ieee.org/xsd/LOMv1p0",
51  );
52  $NsdldcElements = array(
53  "dc:title",
54  "dc:creator",
55  "dc:subject",
56  "dc:description",
57  "dc:publisher",
58  "dc:contributor",
59  "dc:date",
60  "dc:type",
61  "dc:format",
62  "dc:identifier",
63  "dc:source",
64  "dc:language",
65  "dc:relation",
66  "dc:coverage",
67  "dc:rights",
68  "dct:audience",
69  "dct:alternative",
70  "dct:tableOfContents",
71  "dct:abstract",
72  "dct:created",
73  "dct:valid",
74  "dct:available",
75  "dct:issued",
76  "dct:modified",
77  "dct:extent",
78  "dct:medium",
79  "dct:isVersionOf",
80  "dct:hasVersion",
81  "dct:isReplacedBy",
82  "dct:replaces",
83  "dct:isRequiredBy",
84  "dct:requires",
85  "dct:isPartOf",
86  "dct:hasPart",
87  "dct:isReferencedBy",
88  "dct:references",
89  "dct:isFormatOf",
90  "dct:hasFormat",
91  "dct:conformsTo",
92  "dct:spatial",
93  "dct:temporal",
94  "dct:mediator",
95  "dct:dateAccepted",
96  "dct:dateCopyrighted",
97  "dct:dateSubmitted",
98  "dct:educationLevel",
99  "dct:accessRights",
100  "dct:bibliographicCitation",
101  "ieee:interactivityType",
102  "ieee:interactivityLevel",
103  "ieee:typicalLearningTime",
104  );
105  $NsdldcQualifiers = array(
106  "dct:LCSH",
107  "dct:MESH",
108  "dct:DDC",
109  "dct:LCC",
110  "dct:UDC",
111  "dct:DCMIType",
112  "dct:IMT",
113  "dct:ISO639-2",
114  "dct:RFC1766",
115  "dct:URI",
116  "dct:Point",
117  "dct:ISO3166",
118  "dct:Box",
119  "dct:TGN",
120  "dct:Period",
121  "dct:W3CDTF",
122  "dct:RFC3066",
123  );
124  $this->AddFormat("nsdl_dc", "nsdl_dc:nsdl_dc",
125  "http://ns.nsdl.org/nsdl_dc_v1.01"
126  ." http://ns.nsdl.org/schemas/nsdl_dc/nsdl_dc_v1.01.xsd",
127  "1.01.001",
128  $NsdldcNamespaceList, $NsdldcElements, $NsdldcQualifiers);
129 
130  # load field mappings from database and set in parent
131  $Schema = new MetadataSchema();
132  $DB->Query("SELECT * FROM OAIFieldMappings");
133  while ($Record = $DB->FetchRow())
134  {
135  if ($Record["OAIFieldName"] != "Unmapped")
136  {
137  parent::SetFieldMapping($Record["FormatName"],
138  $Record["SPTFieldId"],
139  $Record["OAIFieldName"]);
140  }
141  }
142 
143  # load qualifier mappings from database and set in parent
144  $DB->Query("SELECT * FROM OAIQualifierMappings");
145  while ($Record = $DB->FetchRow())
146  {
147  if ($Record["OAIQualifierName"] != "Unmapped")
148  {
149  $LocalQualifier = new Qualifier($Record["SPTQualifierId"]);
150  $LocalQualifierName = $LocalQualifier->Name();
151  parent::SetQualifierMapping($Record["FormatName"],
152  $LocalQualifierName,
153  $Record["OAIQualifierName"]);
154  }
155  }
156  }
157 
158  # add SQL conditional for selecting resources
159  function AddSQLConditionalForResources($Conditional)
160  {
161  # pass conditional on to item factory
162  $this->SPTItemFactory->AddSQLConditionalForResources($Conditional);
163  }
164 
165  # get/set mapping of local field to OAI field (overloads parent method)
166  function GetFieldMapping($FormatName, $LocalFieldName)
167  {
168  # retrieve ID for local field
169  $Schema = new MetadataSchema();
170  $LocalField = $Schema->GetFieldByName($LocalFieldName);
171  $LocalFieldId = $LocalField->Id();
172 
173  # return stored value
174  return parent::GetFieldMapping($FormatName, $LocalFieldId);
175  }
176  function SetFieldMapping($FormatName, $LocalFieldName, $OAIFieldName)
177  {
178  # retrieve ID for local field
179  $Schema = new MetadataSchema();
180  $LocalField = $Schema->GetFieldByName($LocalFieldName);
181  $LocalFieldId = $LocalField->Id();
182 
183  # check whether mapping is already in database
184  $DB =& $this->DB;
185  $MapCount = $DB->Query("SELECT COUNT(*) AS MapCount FROM OAIFieldMappings"
186  ." WHERE FormatName = '".$FormatName."'"
187  ." AND SPTFieldId = '".$LocalFieldId."'",
188  "MapCount");
189 
190  # if mapping is already in database
191  if ($MapCount > 0)
192  {
193  # change mapping in database
194  $DB->Query("UPDATE OAIFieldMappings"
195  ." SET OAIFieldName = '".addslashes($OAIFieldName)."'"
196  ." WHERE FormatName = '".addslashes($FormatName)."'"
197  ." AND SPTFieldId = '".$LocalFieldId."'");
198  }
199  else
200  {
201  # add new mapping to database
202  $DB->Query("INSERT INTO OAIFieldMappings"
203  ." (FormatName, SPTFieldId, OAIFieldName) VALUES"
204  ." ('".addslashes($FormatName)."', '".$LocalFieldId
205  ."', '".addslashes($OAIFieldName)."')");
206  }
207 
208  # call parent method
209  parent::SetFieldMapping($FormatName, $LocalFieldId, $OAIFieldName);
210  }
211 
212  # set mapping of local qualifier to OAI qualifier (overloads parent method)
213  function SetQualifierMapping($FormatName, $LocalQualifierName, $OAIQualifierName)
214  {
215  # retrieve ID for local qualifier
216  $QFactory = new QualifierFactory();
217  $LocalQualifier = $QFactory->GetQualifierByName($LocalQualifierName);
218  $LocalQualifierId = $LocalQualifier->Id();
219 
220  # check whether mapping is already in database
221  $DB =& $this->DB;
222  $MapCount = $DB->Query("SELECT COUNT(*) AS MapCount FROM OAIQualifierMappings"
223  ." WHERE FormatName = '".addslashes($FormatName)."'"
224  ." AND SPTQualifierId = '".$LocalQualifierId."'",
225  "MapCount");
226 
227  # if mapping is already in database
228  if ($MapCount > 0)
229  {
230  # change mapping in database
231  $DB->Query("UPDATE OAIQualifierMappings"
232  ." SET OAIQualifierName = '".addslashes($OAIQualifierName)."'"
233  ." WHERE FormatName = '".addslashes($FormatName)."'"
234  ." AND SPTQualifierId = '".$LocalQualifierId."'");
235  }
236  else
237  {
238  # add new mapping to database
239  $DB->Query("INSERT INTO OAIQualifierMappings"
240  ." (FormatName, SPTQualifierId, OAIQualifierName) VALUES"
241  ." ('".addslashes($FormatName)."', '".$LocalQualifierId
242  ."', '".addslashes($OAIQualifierName)."')");
243  }
244 
245  # call parent method
246  parent::SetQualifierMapping($FormatName, $LocalQualifierName, $OAIQualifierName);
247  }
248 
249 
250  # ---- PRIVATE INTERFACE -------------------------------------------------
251 
252  var $DB;
254 
255 }
256 
258 
259  # ---- PUBLIC INTERFACE --------------------------------------------------
260 
261  # object constructor
263  {
264  # save any supplied retrieval parameters
265  $this->RetrievalSearchParameters = $RetrievalSearchParameters;
266  }
267 
268  function GetItem($ItemId)
269  {
270  # add link to full record page for item
271  $ServerName = ($_SERVER["SERVER_NAME"] != "127.0.0.1")
272  ? $_SERVER["SERVER_NAME"]
273  : $_SERVER["HTTP_HOST"];
274  $Protocol = isset($_SERVER["HTTPS"]) ? "https://" : "http://";
275  $SearchInfo["fullRecordLink"] = $Protocol.$ServerName.dirname($_SERVER["SCRIPT_NAME"])."/index.php?P=FullRecord&ID=".$ItemId;
276 
277  # if a search score is available for the item
278  if (isset($this->SearchScores) && isset($this->SearchScores[$ItemId]))
279  {
280  # add search info for item
281  $SearchInfo["searchScore"] = $this->SearchScores[$ItemId];
282  $SearchInfo["searchScoreScale"] = $this->SearchScoreScale;
283  }
284 
285  # attempt to create item
286  $Item = new SPTOAIItem($ItemId, $SearchInfo);
287 
288  # if item creation failed
289  if ($Item->Status() == -1)
290  {
291  # return NULL to indicate that no item was found with that ID
292  return NULL;
293  }
294  else
295  {
296  # return item to caller
297  return $Item;
298  }
299  }
300 
301  function GetItems($StartingDate = NULL, $EndingDate = NULL)
302  {
303  return $this->GetItemsInSet(NULL, $StartingDate, $EndingDate);
304  }
305 
306  function GetItemsInSet($Set, $StartingDate = NULL, $EndingDate = NULL)
307  {
308  # initialize search parameters with release flag requirement
309  $SearchStrings["Release Flag"] = "=1";
310 
311  # if both begin and end date supplied
312  if (($StartingDate != NULL) && ($EndingDate != NULL))
313  {
314  # select resources created between starting and ending dates
315  $SearchStrings["Date Of Record Creation"] =
316  array(">=".$StartingDate, "<=".$EndingDate);
317  }
318  # else if begin date specified
319  elseif ($StartingDate != NULL)
320  {
321  # select resources created after begin date
322  $SearchStrings["Date Of Record Creation"] = ">=".$StartingDate;
323  }
324  # else if end date specified
325  elseif ($EndingDate != NULL)
326  {
327  # select resources created after begin date
328  $SearchStrings["Date Of Record Creation"] = "<=".$EndingDate;
329  }
330 
331  # if set specified
332  if ($Set != NULL)
333  {
334  # load set mappings
335  $this->LoadSetNameInfo();
336 
337  # if set is valid
338  if (isset($this->SetFields[$Set]))
339  {
340  # add field spec to search strings
341  $SearchStrings[$this->SetFields[$Set]] = "= ".$this->SetValues[$Set];
342  }
343  else
344  {
345  # set will not match anything so return empty array to caller
346  return array();
347  }
348  }
349 
350  # perform search for desired items
351  $Engine = new SPTSearchEngine();
352  if ($this->RetrievalSearchParameters)
353  {
354  $SearchStrings = array_merge($SearchStrings,
355  $this->RetrievalSearchParameters);
356  }
357  $SearchResults = $Engine->FieldedSearch($SearchStrings, 0, 1000000);
358 
359  # extract resource IDs from search results
360  $ItemIds = array_keys($SearchResults);
361 
362  # return array of resource IDs to caller
363  return $ItemIds;
364  }
365 
366  # return array containing all set specs (with human-readable set names as keys)
367  function GetListOfSets()
368  {
369  # make sure set name info is loaded
370  $this->LoadSetNameInfo();
371 
372  # return list of sets to caller
373  return $this->SetSpecs;
374  }
375 
376  # retrieve IDs of items that match search parameters (only needed if OAI-SQ supported)
377  function SearchForItems($SearchParams, $StartingDate = NULL, $EndingDate = NULL)
378  {
379  # translate field IDs into field names for search parameters
380  $Schema = new MetadataSchema;
381  foreach ($SearchParams as $FieldId => $Value)
382  {
383  if ($FieldId == "X-KEYWORD-X")
384  {
385  $SearchStrings["XXXKeywordXXX"] = $Value;
386  }
387  else
388  {
389  $Field = $Schema->GetField($FieldId);
390  $SearchStrings[$Field->Name()] = $Value;
391  }
392  }
393 
394  # add release flag requirement to search parameters
395  $SearchStrings["Release Flag"] = "=1";
396 
397  # if both begin and end date supplied
398  if (($StartingDate != NULL) && ($EndingDate != NULL))
399  {
400  # select resources created between starting and ending dates
401  $SearchStrings["Date Of Record Creation"] =
402  array(">=".$StartingDate, "<=".$EndingDate);
403  }
404  # else if begin date specified
405  elseif ($StartingDate != NULL)
406  {
407  # select resources created after begin date
408  $SearchStrings["Date Of Record Creation"] = ">=".$StartingDate;
409  }
410  # else if end date specified
411  elseif ($EndingDate != NULL)
412  {
413  # select resources created after begin date
414  $SearchStrings["Date Of Record Creation"] = "<=".$EndingDate;
415  }
416 
417  # perform search for desired items
418  $Engine = new SPTSearchEngine();
419  if ($this->RetrievalSearchParameters)
420  {
421  $SearchStrings = array_merge($SearchStrings,
422  $this->RetrievalSearchParameters);
423  }
424  $SearchResults = $Engine->FieldedSearch($SearchStrings, 0, 1000000);
425 
426  # save search scores
427  $this->SearchScores = $SearchResults;
428  $this->SearchScoreScale = $Engine->FieldedSearchWeightScale($SearchStrings);
429 
430  # extract resource IDs from search results
431  $ItemIds = array_keys($SearchResults);
432 
433  # return array of resource IDs to caller
434  return $ItemIds;
435  }
436 
437 
438  # ---- PRIVATE INTERFACE -------------------------------------------------
439 
446 
447  # normalize value for use as an OAI set spec
448  function NormalizeForSetSpec($Name)
449  {
450  return preg_replace("/[^a-zA-Z0-9\-_.!~*'()]/", "", $Name);
451  }
452 
453  # load normalized set names and name mappings
454  function LoadSetNameInfo()
455  {
456  # if set names have not already been loaded
457  if (!isset($this->SetSpecs))
458  {
459  # start with empty list of sets
460  $this->SetSpecs = array();
461  $this->SetFields = array();
462  $this->SetValues = array();
463 
464  # for each metadata field that is a type that can be used for sets
465  $Schema = new MetadataSchema();
467  foreach ($Fields as $Field)
468  {
469  # if field is flagged as being used for OAI sets
470  if ($Field->UseForOaiSets())
471  {
472  # retrieve all possible values for field
473  $FieldValues = $Field->GetPossibleValues();
474 
475  # prepend field name to each value and add to list of sets
476  $FieldName = $Field->Name();
477  $NormalizedFieldName = $this->NormalizeForSetSpec($FieldName);
478  foreach ($FieldValues as $Value)
479  {
480  $SetSpec = $NormalizedFieldName.":"
481  .$this->NormalizeForSetSpec($Value);
482  $this->SetSpecs[$FieldName.": ".$Value] = $SetSpec;
483  $this->SetFields[$SetSpec] = $FieldName;
484  $this->SetValues[$SetSpec] = $Value;
485  }
486  }
487  }
488  }
489  }
490 }
491 
492 class SPTOAIItem extends OAIItem {
493 
494  # ---- PUBLIC INTERFACE --------------------------------------------------
495 
496  # object constructor
497  function SPTOAIItem($ItemId, $SearchInfo = NULL)
498  {
499  # save ID for later use
500  $this->Id = $ItemId;
501 
502  # save any search info supplied
503  $this->SearchInfo = $SearchInfo;
504 
505  # attempt to create resource object
506  $this->Resource = new Resource($ItemId);
507 
508  # if resource object creation failed
509  if ($this->Resource->Status() == -1)
510  {
511  # set status to -1 to indicate constructor failure
512  $this->LastStatus = -1;
513  }
514  else
515  {
516  # set status to 1 to indicate constructor success
517  $this->LastStatus = 1;
518 
519  # if cumulative rating data is available for this resource
520  global $SysConfig;
521  if ($SysConfig->ResourceRatingsEnabled()
522  && $this->Resource->CumulativeRating())
523  {
524  # add cumulative rating data to search info
525  $this->SearchInfo["cumulativeRating"] =
526  $this->Resource->CumulativeRating();
527  $this->SearchInfo["cumulativeRatingScale"] = 100;
528  }
529  }
530  }
531 
532  function GetId() { return $this->Id; }
533 
534  function GetDatestamp()
535  {
536  $DateString = $this->Resource->Get("Date Of Record Creation");
537  if ($DateString == "0000-00-00 00:00:00") { $DateString = date("Y-m-d"); }
538  $Date = new Date($DateString);
539  return $Date->FormattedISO8601();
540  }
541 
542  function GetValue($ElementName)
543  {
544  # retrieve value
545  $ReturnValue = $this->Resource->GetByFieldId($ElementName);
546 
547  # strip out any HTML tags if text value
548  if (is_string($ReturnValue))
549  {
550  $ReturnValue = strip_tags($ReturnValue);
551  }
552 
553  # format correctly if standardized date
554  if ($this->GetQualifier($ElementName) == "W3C-DTF")
555  {
556  $Timestamp = strtotime($ReturnValue);
557  $ReturnValue = date('Y-m-d\TH:i:s', $Timestamp)
558  .substr_replace(date('O', $Timestamp), ':', 3, 0);
559  }
560 
561  # return value to caller
562  return $ReturnValue;
563  }
564 
565  function GetQualifier($ElementName)
566  {
567  $ReturnValue = NULL;
568  $Qualifier = $this->Resource->GetQualifierByFieldId($ElementName, TRUE);
569  if (is_array($Qualifier))
570  {
571  foreach ($Qualifier as $ItemId => $QualObj)
572  {
573  if (is_object($QualObj))
574  {
575  $ReturnValue[$ItemId] = $QualObj->Name();
576  }
577  }
578  }
579  else
580  {
581  if (isset($Qualifier) && is_object($Qualifier))
582  {
583  $ReturnValue = $Qualifier->Name();
584  }
585  }
586  return $ReturnValue;
587  }
588 
589  function GetSets()
590  {
591  # start out with empty list
592  $Sets = array();
593 
594  # for each possible metadata field
595  $Schema = new MetadataSchema();
597  foreach ($Fields as $Field)
598  {
599  # if field is flagged for use for OAI sets
600  if ($Field->UseForOaiSets())
601  {
602  # retrieve values for resource for this field and add to set list
603  $FieldName = $Field->Name();
604  $Values = $this->Resource->Get($FieldName);
605  if (isset($Values) && ($Values != NULL))
606  {
607  $NormalizedFieldName = $this->NormalizeForSetSpec($FieldName);
608  if (is_array($Values) && count($Values))
609  {
610  foreach ($Values as $Value)
611  {
612  $Sets[] = $NormalizedFieldName.":"
613  .$this->NormalizeForSetSpec($Value);
614  }
615  }
616  else
617  {
618  $Sets[] = $NormalizedFieldName.":"
619  .$this->NormalizeForSetSpec($Values);
620  }
621  }
622  }
623  }
624 
625  # return list of sets to caller
626  return $Sets;
627  }
628 
629  function GetSearchInfo()
630  {
631  return $this->SearchInfo;
632  }
633 
634  function Status()
635  {
636  return $this->LastStatus;
637  }
638 
639 
640  # ---- PRIVATE INTERFACE -------------------------------------------------
641 
642  var $Id;
646 
647  # normalize value for use as an OAI set spec
648  function NormalizeForSetSpec($Name)
649  {
650  return preg_replace("/[^a-zA-Z0-9\-_.!~*'()]/", "", $Name);
651  }
652 }