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