CWIS Developer Documentation
SPTSearchEngine.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # FILE: SPTSearchEngine.php
4 #
5 # Part of the Collection Workflow Integration System (CWIS)
6 # Copyright 2011-2013 Edward Almasy and Internet Scout Research Group
7 # http://scout.wisc.edu/cwis/
8 #
9 
11 
12  function SPTSearchEngine()
13  {
14  # pass database handle and config values to real search engine object
15  $this->SearchEngine("Resources", "ResourceId");
16 
17  # for each field defined in schema
18  $this->Schema = new MetadataSchema();
19  $Fields = $this->Schema->GetFields();
20  foreach ($Fields as $Field)
21  {
22  # determine field type for searching
23  switch ($Field->Type())
24  {
35  $FieldType = self::FIELDTYPE_TEXT;
36  break;
37 
40  $FieldType = self::FIELDTYPE_NUMERIC;
41  break;
42 
44  $FieldType = self::FIELDTYPE_DATERANGE;
45  break;
46 
48  $FieldType = self::FIELDTYPE_DATE;
49  break;
50 
52  $FieldType = NULL;
53  break;
54 
55  default:
56  exit("ERROR: unknown field type "
57  .$Field->Type()." in SPTSearchEngine.php");
58  break;
59  }
60 
61  if ($FieldType !== NULL)
62  {
63  # add field to search engine
64  $this->AddField($Field->Name(), $FieldType,
65  $Field->SearchWeight(),
66  $Field->IncludeInKeywordSearch());
67  }
68  }
69  }
70 
78  function GetFieldContent($ItemId, $FieldName)
79  {
80  # get resource object
81  $Resource = new Resource($ItemId);
82 
83  # if this is a reference field
84  $Field = $this->Schema->GetFieldByName($FieldName);
85  if ($Field->Type() == MetadataSchema::MDFTYPE_REFERENCE)
86  {
87  # retrieve IDs of referenced items
88  $ReferredItemIds = $Resource->Get($FieldName);
89 
90  # for each referred item
91  $ReturnValue = array();
92  foreach ($ReferredItemIds as $RefId)
93  {
94  # retrieve title value for item and add to returned values
95  $RefResource = new Resource($RefId);
96  $ReturnValue[] = $RefResource->GetMapped("Title");
97  }
98 
99  # return referred item titles to caller
100  return $ReturnValue;
101  }
102  else
103  {
104  # retrieve text (including variants) from resource object and return to caller
105  return $Resource->Get($FieldName, FALSE, TRUE);
106  }
107  }
108 
109  # overloaded version of method to retrieve resource/phrase match list
110  function SearchFieldForPhrases($FieldName, $Phrase)
111  {
112  # normalize and escape search phrase for use in SQL query
113  $SearchPhrase = strtolower(addslashes($Phrase));
114 
115  # query DB for matching list based on field type
116  $Field = $this->Schema->GetFieldByName($FieldName);
117  switch ($Field->Type())
118  {
123  $QueryString = "SELECT DISTINCT ResourceId FROM Resources "
124  ."WHERE POSITION('".$SearchPhrase."'"
125  ." IN LOWER(`".$Field->DBFieldName()."`)) ";
126  break;
127 
129  $QueryString = "SELECT DISTINCT ResourceId FROM Resources "
130  ."WHERE POSITION('".$SearchPhrase."'"
131  ." IN LOWER(`".$Field->DBFieldName()."AltText`)) ";
132  break;
133 
135  $NameTableSize = $this->DB->Query("SELECT COUNT(*) AS NameCount"
136  ." FROM ControlledNames", "NameCount");
137  $QueryString = "SELECT DISTINCT ResourceNameInts.ResourceId "
138  ."FROM ResourceNameInts, ControlledNames "
139  ."WHERE POSITION('".$SearchPhrase."' IN LOWER(ControlledName)) "
140  ."AND ControlledNames.ControlledNameId"
141  ." = ResourceNameInts.ControlledNameId "
142  ."AND ControlledNames.FieldId = ".$Field->Id();
143  $SecondQueryString = "SELECT DISTINCT ResourceNameInts.ResourceId "
144  ."FROM ResourceNameInts, ControlledNames, VariantNames "
145  ."WHERE POSITION('".$SearchPhrase."' IN LOWER(VariantName)) "
146  ."AND VariantNames.ControlledNameId"
147  ." = ResourceNameInts.ControlledNameId "
148  ."AND ControlledNames.ControlledNameId"
149  ." = ResourceNameInts.ControlledNameId "
150  ."AND ControlledNames.FieldId = ".$Field->Id();
151  break;
152 
154  $QueryString = "SELECT DISTINCT ResourceNameInts.ResourceId "
155  ."FROM ResourceNameInts, ControlledNames "
156  ."WHERE POSITION('".$SearchPhrase."' IN LOWER(ControlledName)) "
157  ."AND ControlledNames.ControlledNameId = ResourceNameInts.ControlledNameId "
158  ."AND ControlledNames.FieldId = ".$Field->Id();
159  break;
160 
162  $QueryString = "SELECT DISTINCT ResourceClassInts.ResourceId "
163  ."FROM ResourceClassInts, Classifications "
164  ."WHERE POSITION('".$SearchPhrase."' IN LOWER(ClassificationName)) "
165  ."AND Classifications.ClassificationId = ResourceClassInts.ClassificationId "
166  ."AND Classifications.FieldId = ".$Field->Id();
167  break;
168 
170  $UserId = $this->DB->Query("SELECT UserId FROM APUsers "
171  ."WHERE POSITION('".$SearchPhrase."' IN LOWER(UserName)) "
172  ."OR POSITION('".$SearchPhrase."' IN LOWER(RealName))", "UserId");
173  if ($UserId != NULL)
174  {
175  $QueryString = "SELECT DISTINCT ResourceId FROM Resources "
176  ."WHERE `".$Field->DBFieldName()."` = ".$UserId;
177  }
178  break;
179 
181  if ($SearchPhrase > 0)
182  {
183  $QueryString = "SELECT DISTINCT ResourceId FROM Resources "
184  ."WHERE `".$Field->DBFieldName()."` = ".(int)$SearchPhrase;
185  }
186  break;
187 
192  # (these types not yet handled by search engine for phrases)
193  break;
194  }
195 
196  # build match list based on results returned from DB
197  if (isset($QueryString))
198  {
199  $this->DMsg(7, "Performing phrase search query (<i>".$QueryString."</i>)");
200  if ($this->DebugLevel > 9) { $StartTime = microtime(TRUE); }
201  $this->DB->Query($QueryString);
202  if ($this->DebugLevel > 9)
203  {
204  $EndTime = microtime(TRUE);
205  if (($StartTime - $EndTime) > 0.1)
206  {
207  printf("SE: Query took %.2f seconds<br>\n",
208  ($EndTime - $StartTime));
209  }
210  }
211  $MatchList = $this->DB->FetchColumn("ResourceId");
212  if (isset($SecondQueryString))
213  {
214  $this->DMsg(7, "Performing second phrase search query"
215  ." (<i>".$SecondQueryString."</i>)");
216  if ($this->DebugLevel > 9) { $StartTime = microtime(TRUE); }
217  $this->DB->Query($SecondQueryString);
218  if ($this->DebugLevel > 9)
219  {
220  $EndTime = microtime(TRUE);
221  if (($StartTime - $EndTime) > 0.1)
222  {
223  printf("SE: query took %.2f seconds<br>\n",
224  ($EndTime - $StartTime));
225  }
226  }
227  $MatchList = $MatchList + $this->DB->FetchColumn("ResourceId");
228  }
229  }
230  else
231  {
232  $MatchList = array();
233  }
234 
235  # return list of matching resources to caller
236  return $MatchList;
237  }
238 
239  # search field for records that meet comparison
240  function SearchFieldsForComparisonMatches($FieldNames, $Operators, $Values)
241  {
242  # use SQL keyword appropriate to current search logic for combining operations
243  $CombineWord = ($this->DefaultSearchLogic == self::LOGIC_AND) ? " AND " : " OR ";
244 
245  # for each comparison
246  foreach ($FieldNames as $Index => $FieldName)
247  {
248  $Operator = $Operators[$Index];
249  $Value = $Values[$Index];
250 
251  # determine query based on field type
252  $Field = $this->Schema->GetFieldByName($FieldName);
253  if ($Field != NULL)
254  {
255  switch ($Field->Type())
256  {
263  if (isset($Queries["Resources"]))
264  {
265  $Queries["Resources"] .= $CombineWord;
266  }
267  else
268  {
269  $Queries["Resources"] = "SELECT DISTINCT ResourceId FROM Resources WHERE ";
270  }
271  if ($Field->Type() == MetadataSchema::MDFTYPE_USER)
272  {
273  $User = new CWUser($Value);
274  $Value = $User->Id();
275  }
276  $Queries["Resources"] .= "`".$Field->DBFieldName()."` ".$Operator." '".addslashes($Value)."' ";
277  break;
278 
280  $QueryIndex = "ResourceNameInts".$Field->Id();
281  if (!isset($Queries[$QueryIndex]["A"]))
282  {
283  $Queries[$QueryIndex]["A"] =
284  "SELECT DISTINCT ResourceId"
285  ." FROM ResourceNameInts, ControlledNames "
286  ." WHERE ControlledNames.FieldId = ".$Field->Id()
287  ." AND ( ";
288  $CloseQuery[$QueryIndex]["A"] = TRUE;
289  $ComparisonCount[$QueryIndex]["A"] = 1;
290  $ComparisonCountField[$QueryIndex]["A"] = "ControlledName";
291  }
292  else
293  {
294  $Queries[$QueryIndex]["A"] .= " OR ";
295  $ComparisonCount[$QueryIndex]["A"]++;
296  }
297  $Queries[$QueryIndex]["A"] .=
298  "((ResourceNameInts.ControlledNameId"
299  ." = ControlledNames.ControlledNameId"
300  ." AND ControlledName "
301  .$Operator." '".addslashes($Value)."'))";
302  if (!isset($Queries[$QueryIndex]["B"]))
303  {
304  $Queries[$QueryIndex]["B"] =
305  "SELECT DISTINCT ResourceId"
306  . " FROM ResourceNameInts, ControlledNames,"
307  ." VariantNames "
308  ." WHERE ControlledNames.FieldId = ".$Field->Id()
309  ." AND ( ";
310  $CloseQuery[$QueryIndex]["B"] = TRUE;
311  $ComparisonCount[$QueryIndex]["B"] = 1;
312  $ComparisonCountField[$QueryIndex]["B"] = "ControlledName";
313  }
314  else
315  {
316  $Queries[$QueryIndex]["B"] .= " OR ";
317  $ComparisonCount[$QueryIndex]["B"]++;
318  }
319  $Queries[$QueryIndex]["B"] .=
320  "((ResourceNameInts.ControlledNameId"
321  ." = ControlledNames.ControlledNameId"
322  ." AND ResourceNameInts.ControlledNameId"
323  ." = VariantNames.ControlledNameId"
324  ." AND VariantName "
325  .$Operator." '".addslashes($Value)."'))";
326  break;
327 
329  $QueryIndex = "ResourceNameInts".$Field->Id();
330  if (!isset($Queries[$QueryIndex]))
331  {
332  $Queries[$QueryIndex] =
333  "SELECT DISTINCT ResourceId FROM ResourceNameInts, ControlledNames "
334  ." WHERE ControlledNames.FieldId = ".$Field->Id()
335  ." AND ( ";
336  $CloseQuery[$QueryIndex] = TRUE;
337  $ComparisonCount[$QueryIndex] = 1;
338  $ComparisonCountField[$QueryIndex] = "ControlledName";
339  }
340  else
341  {
342  $Queries[$QueryIndex] .= " OR ";
343  $ComparisonCount[$QueryIndex]++;
344  }
345  $Queries[$QueryIndex] .= "(ResourceNameInts.ControlledNameId = ControlledNames.ControlledNameId"
346  ." AND ControlledName ".$Operator." '".addslashes($Value)."')";
347  break;
348 
350  $QueryIndex = "ResourceClassInts".$Field->Id();
351  if (!isset($Queries[$QueryIndex]))
352  {
353  $Queries[$QueryIndex] = "SELECT DISTINCT ResourceId FROM ResourceClassInts, Classifications "
354  ." WHERE ResourceClassInts.ClassificationId = Classifications.ClassificationId"
355  ." AND Classifications.FieldId = ".$Field->Id()." AND ( ";
356  $CloseQuery[$QueryIndex] = TRUE;
357  $ComparisonCount[$QueryIndex] = 1;
358  $ComparisonCountField[$QueryIndex] = "ClassificationName";
359  }
360  else
361  {
362  $Queries[$QueryIndex] .= " OR ";
363  $ComparisonCount[$QueryIndex]++;
364  }
365  $Queries[$QueryIndex] .= " ClassificationName ".$Operator." '".addslashes($Value)."'";
366  break;
367 
369  # if value appears to have time component or text description
370  if (strpos($Value, ":")
371  || strstr($Value, "day")
372  || strstr($Value, "week")
373  || strstr($Value, "month")
374  || strstr($Value, "year")
375  || strstr($Value, "hour")
376  || strstr($Value, "minute"))
377  {
378  if (isset($Queries["Resources"]))
379  {
380  $Queries["Resources"] .= $CombineWord;
381  }
382  else
383  {
384  $Queries["Resources"] = "SELECT DISTINCT ResourceId"
385  ." FROM Resources WHERE ";
386  }
387 
388  # flip operator if necessary
389  if (strstr($Value, "ago"))
390  {
391  $OperatorFlipMap = array(
392  "<" => ">=",
393  ">" => "<=",
394  "<=" => ">",
395  ">=" => "<",
396  );
397  $Operator = isset($OperatorFlipMap[$Operator])
398  ? $OperatorFlipMap[$Operator] : $Operator;
399  }
400 
401  # use strtotime method to build condition
402  $TimestampValue = strtotime($Value);
403  if (($TimestampValue !== FALSE) && ($TimestampValue != -1))
404  {
405  if ((date("H:i:s", $TimestampValue) == "00:00:00")
406  && (strpos($Value, "00:00") === FALSE)
407  && ($Operator == "<="))
408  {
409  $NormalizedValue =
410  date("Y-m-d", $TimestampValue)." 23:59:59";
411  }
412  else
413  {
414  $NormalizedValue = date("Y-m-d H:i:s", $TimestampValue);
415  }
416  }
417  else
418  {
419  $NormalizedValue = addslashes($Value);
420  }
421  $Queries["Resources"] .=
422  " ( `".$Field->DBFieldName()."` "
423  .$Operator
424  ." '".$NormalizedValue."' ) ";
425  }
426  else
427  {
428  # use Date object method to build condition
429  $Date = new Date($Value);
430  if ($Date->Precision())
431  {
432  if (isset($Queries["Resources"]))
433  {
434  $Queries["Resources"] .= $CombineWord;
435  }
436  else
437  {
438  $Queries["Resources"] = "SELECT DISTINCT ResourceId"
439  ." FROM Resources WHERE ";
440  }
441  $Queries["Resources"] .= " ( ".$Date->SqlCondition(
442  $Field->DBFieldName(), NULL, $Operator)." ) ";
443  }
444  }
445  break;
446 
448  $Date = new Date($Value);
449  if ($Date->Precision())
450  {
451  if (isset($Queries["Resources"]))
452  {
453  $Queries["Resources"] .= $CombineWord;
454  }
455  else
456  {
457  $Queries["Resources"] = "SELECT DISTINCT ResourceId"
458  ." FROM Resources WHERE ";
459  }
460  $Queries["Resources"] .= " ( ".$Date->SqlCondition(
461  $Field->DBFieldName()."Begin",
462  $Field->DBFieldName()."End", $Operator)." ) ";
463  }
464  break;
465 
467  $QueryIndex = "ReferenceInts".$Field->Id();
468  if (!isset($Queries[$QueryIndex]))
469  {
470  if (!isset($NameField))
471  {
472  $NameField =
473  $this->Schema->GetFieldByMappedName(
474  "Title");
475  }
476  $Queries[$QueryIndex] =
477  "SELECT DISTINCT RI.SrcResourceId AS ResourceId"
478  ." FROM ReferenceInts AS RI, Resources AS R "
479  ." WHERE RI.FieldId = ".$Field->Id()
480  ." AND (";
481  $CloseQuery[$QueryIndex] = TRUE;
482  $ComparisonCount[$QueryIndex] = 1;
483  $ComparisonCountField[$QueryIndex] =
484  "R.`".$NameField->DBFieldName()."`";
485  }
486  else
487  {
488  $Queries[$QueryIndex] .= $CombineWord;
489  $ComparisonCount[$QueryIndex]++;
490  }
491  $Queries[$QueryIndex] .= "(R.`".$NameField->DBFieldName()."` "
492  .$Operator." '".addslashes($Value)."'"
493  ." AND R.ResourceId = RI.DstResourceId)";
494  break;
495 
498  # (these types not yet handled by search engine for comparisons)
499  break;
500  }
501  }
502  }
503 
504  # if queries found
505  if (isset($Queries))
506  {
507  # for each assembled query
508  foreach ($Queries as $QueryIndex => $Query)
509  {
510  # if query has multiple parts
511  if (is_array($Query))
512  {
513  # for each part of query
514  $ResourceIds = array();
515  foreach ($Query as $PartIndex => $PartQuery)
516  {
517  # add closing paren if query was flagged to be closed
518  if (isset($CloseQuery[$QueryIndex][$PartIndex]))
519  {
520  $PartQuery .= ") ";
521  if (($this->DefaultSearchLogic == self::LOGIC_AND)
522  && ($ComparisonCount[$QueryIndex][$PartIndex] > 1))
523  {
524  $PartQuery .= "GROUP BY ResourceId"
525  ." HAVING COUNT(DISTINCT "
526  .$ComparisonCountField[$QueryIndex][$PartIndex]
527  .") = "
528  .$ComparisonCount[$QueryIndex][$PartIndex];
529  }
530  }
531 
532  # perform query and retrieve IDs
533  $this->DMsg(5, "Performing comparison query <i>"
534  .$PartQuery."</i>");
535  $this->DB->Query($PartQuery);
536  $ResourceIds = $ResourceIds
537  + $this->DB->FetchColumn("ResourceId");
538  $this->DMsg(5, "Comparison query produced <i>"
539  .count($ResourceIds)."</i> results");
540  }
541  }
542  else
543  {
544  # add closing paren if query was flagged to be closed
545  if (isset($CloseQuery[$QueryIndex]))
546  {
547  $Query .= ") ";
548  if (($this->DefaultSearchLogic == self::LOGIC_AND)
549  && ($ComparisonCount[$QueryIndex] > 1))
550  {
551  $Query .= "GROUP BY ResourceId"
552  ." HAVING COUNT(DISTINCT "
553  .$ComparisonCountField[$QueryIndex]
554  .") = "
555  .$ComparisonCount[$QueryIndex];
556  }
557  }
558 
559  # perform query and retrieve IDs
560  $this->DMsg(5, "Performing comparison query <i>".$Query."</i>");
561  $this->DB->Query($Query);
562  $ResourceIds = $this->DB->FetchColumn("ResourceId");
563  $this->DMsg(5, "Comparison query produced <i>"
564  .count($ResourceIds)."</i> results");
565  }
566 
567  # if we already have some results
568  if (isset($Results))
569  {
570  # if search logic is set to AND
571  if ($this->DefaultSearchLogic == self::LOGIC_AND)
572  {
573  # remove anything from results that was not returned from query
574  $Results = array_intersect($Results, $ResourceIds);
575  }
576  else
577  {
578  # add values returned from query to results
579  $Results = array_unique(array_merge($Results, $ResourceIds));
580  }
581  }
582  else
583  {
584  # set results to values returned from query
585  $Results = $ResourceIds;
586  }
587  }
588  }
589  else
590  {
591  # initialize results to empty list
592  $Results = array();
593  }
594 
595  # return results to caller
596  return $Results;
597  }
598 
599  static function GetItemIdsSortedByField($FieldName, $SortDescending)
600  {
601  $RFactory = new ResourceFactory();
602  return $RFactory->GetResourceIdsSortedBy($FieldName, !$SortDescending);
603  }
604 
605  static function QueueUpdateForItem($ItemId,
606  $TaskPriority = ApplicationFramework::PRIORITY_LOW)
607  {
608  $Item = new Resource($ItemId);
609  $TaskDescription = "Update search data for"
610  ." <a href=\"r".$ItemId."\"><i>"
611  .$Item->GetMapped("Title")."</i></a>";
612  $GLOBALS["AF"]->QueueUniqueTask(array(__CLASS__, "RunUpdateForItem"),
613  array(intval($ItemId)), $TaskPriority, $TaskDescription);
614  }
615 
616  static function RunUpdateForItem($ItemId)
617  {
618  # check that resource still exists
619  $RFactory = new ResourceFactory();
620  if (!$RFactory->ItemExists($ItemId)) { return; }
621 
622  # update search data for resource
623  $SearchEngine = new SPTSearchEngine();
624  $SearchEngine->UpdateForItem($ItemId);
625  }
626 
634  static function GetResultFacets($SearchResults, $User)
635  {
636  # classifications and names associated with these search results
637  $SearchClasses = array();
638  $SearchNames = array();
639 
640  # disable DB cache for the search suggestions process,
641  # this avoids memory exhaustion.
642  $DB = new Database();
643  $DB->Caching(FALSE);
644 
645  if (count($SearchResults)>0)
646  {
647  foreach (array_chunk($SearchResults, 1000, TRUE) as $Chunk)
648  {
649  # pull out all the Classifications that were associated with our search results
650  $DB->Query("SELECT ResourceId,ClassificationId FROM ResourceClassInts "
651  ."WHERE ResourceId IN "
652  ."(".implode(",", array_keys($Chunk)).")");
653  foreach ($DB->FetchRows() as $Row)
654  {
655  $SearchClasses[ $Row["ClassificationId"] ] []= $Row["ResourceId"] ;
656  }
657 
658  # similarly with controlled names
659  $DB->Query("SELECT ResourceId,ControlledNameId FROM ResourceNameInts "
660  ."WHERE ResourceId in "
661  ."(".implode(",", array_keys($Chunk)).")");
662  foreach ($DB->FetchRows() as $Row)
663  {
664  $SearchNames[ $Row["ControlledNameId"] ] []= $Row["ResourceId"];
665  }
666  }
667  }
668 
669  # generate a map of FieldId -> Field Names for all of the generated facets:
670  $SuggestionsById = array();
671 
672  # pull relevant Classification names out of the DB
673  if (count($SearchClasses)>0)
674  {
675  foreach (array_chunk($SearchClasses, 1000, TRUE) as $Chunk)
676  {
677  $DB->Query("SELECT FieldId,ClassificationId,ClassificationName FROM Classifications "
678  ."WHERE ClassificationId IN (".implode(",", array_keys($Chunk)).")");
679  foreach ($DB->FetchRows() as $Row)
680  {
681  $SuggestionsById[$Row["FieldId"]] []=
682  array("Id" => $Row["ClassificationId"],
683  "Name" => $Row["ClassificationName"],
684  "Count" => count( $SearchClasses[ $Row["ClassificationId"] ] ) );
685  }
686  }
687  }
688 
689  # pull relevant ControlledNames out of the DB
690  if (count($SearchNames)>0)
691  {
692  foreach (array_chunk($SearchNames, 1000, TRUE) as $Chunk)
693  {
694  $DB->Query("SELECT FieldId,ControlledNameId,ControlledName FROM ControlledNames "
695  ."WHERE ControlledNameId IN (".implode(",", array_keys($SearchNames)).")");
696  foreach ($DB->FetchRows() as $Row)
697  {
698  $SuggestionsById[$Row["FieldId"]] []=
699  array("Id" => $Row["ControlledNameId"],
700  "Name" => $Row["ControlledName"],
701  "Count" => count( $SearchNames[ $Row["ControlledNameId"] ] ) );
702  }
703  }
704  }
705 
706  # translate the suggestions that we have in terms of the
707  # FieldIds to suggestions in terms of the field names
708  $SuggestionsByFieldName = array();
709 
710  # if we have suggestions to offer
711  if (count($SuggestionsById)>0)
712  {
713  $Schema = new MetadataSchema();
714 
715  # gill in an array that maps FieldNames to search links
716  # which would be appropriate for that field
717  foreach ($SuggestionsById as $FieldId => $FieldValues)
718  {
719  $ThisField = $Schema->GetField($FieldId);
720 
721  # bail on fields that didn't exist
722  # and on fields that the current user cannot view, and on fields that are disabled
723  # for advanced searching:
724  if (is_object($ThisField) &&
725  $ThisField->Status() == MetadataSchema::MDFSTAT_OK &&
726  $ThisField->IncludeInFacetedSearch() &&
727  $ThisField->Enabled() &&
728  $User->HasPriv($ThisField->ViewingPrivileges()))
729  {
730  $SuggestionsByFieldName[ $ThisField->Name() ] = array();
731 
732  foreach ($FieldValues as $Value)
733  $SuggestionsByFieldName [ $ThisField->Name() ] [$Value["Id"]] =
734  array("Name" => $Value["Name"], "Count" => $Value["Count"] );
735  }
736  }
737  }
738 
739  ksort($SuggestionsByFieldName);
740 
741  return $SuggestionsByFieldName;
742  }
743 
744  private $Schema;
745 
746  # functions for backward compatability w/ old SPT code
747  function UpdateForResource($ItemId) { $this->UpdateForItem($ItemId); }
748 }
SearchFieldForPhrases($FieldName, $Phrase)
Metadata schema (in effect a Factory class for MetadataField).
const PRIORITY_LOW
Lower priority.
SQL database abstraction object with smart query caching.
AddField($FieldName, $FieldType, $Weight, $UsedInKeywordSearch)
Add field to include in searching.
UpdateForResource($ItemId)
SearchEngine($ItemTableName, $ItemIdFieldName)
Object constructor.
GetFieldContent($ItemId, $FieldName)
Overloaded version of method to retrieve text from DB.
const MDFTYPE_CONTROLLEDNAME
PHP
Definition: OAIClient.php:39
static RunUpdateForItem($ItemId)
SearchFieldsForComparisonMatches($FieldNames, $Operators, $Values)
DMsg($Level, $Msg)
Represents a "resource" in CWIS.
Definition: Resource.php:13
static GetResultFacets($SearchResults, $User)
Generate a list of suggested additional search terms that can be used for faceted searching...
static GetItemIdsSortedByField($FieldName, $SortDescending)
Core metadata archive search engine class.
DefaultSearchLogic($NewSetting=NULL)
Get/set default search logic (LOGIC_AND or LOGIC_OR).
DebugLevel($NewValue)
Set debug output level.
Factory for Resource objects.
CWIS-specific user class.
Definition: CWUser.php:13
UpdateForItem($ItemId)
Update search database for the specified item.
static QueueUpdateForItem($ItemId, $TaskPriority=ApplicationFramework::PRIORITY_LOW)