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 __construct()
13  {
14  # pass database handle and config values to real search engine object
15  parent::__construct("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"
158  ." = ResourceNameInts.ControlledNameId "
159  ."AND ControlledNames.FieldId = ".$Field->Id();
160  break;
161 
163  $QueryString = "SELECT DISTINCT ResourceClassInts.ResourceId "
164  ."FROM ResourceClassInts, Classifications "
165  ."WHERE POSITION('".$SearchPhrase
166  ."' IN LOWER(ClassificationName)) "
167  ."AND Classifications.ClassificationId"
168  ." = ResourceClassInts.ClassificationId "
169  ."AND Classifications.FieldId = ".$Field->Id();
170  break;
171 
173  $UserId = $this->DB->Query("SELECT UserId FROM APUsers "
174  ."WHERE POSITION('".$SearchPhrase
175  ."' IN LOWER(UserName)) "
176  ."OR POSITION('".$SearchPhrase
177  ."' IN LOWER(RealName))", "UserId");
178  if ($UserId != NULL)
179  {
180  $QueryString = "SELECT DISTINCT ResourceId FROM Resources "
181  ."WHERE `".$Field->DBFieldName()."` = ".$UserId;
182  }
183  break;
184 
186  if ($SearchPhrase > 0)
187  {
188  $QueryString = "SELECT DISTINCT ResourceId FROM Resources "
189  ."WHERE `".$Field->DBFieldName()
190  ."` = ".(int)$SearchPhrase;
191  }
192  break;
193 
198  # (these types not yet handled by search engine for phrases)
199  break;
200  }
201 
202  # build match list based on results returned from DB
203  if (isset($QueryString))
204  {
205  $this->DMsg(7, "Performing phrase search query (<i>".$QueryString."</i>)");
206  if ($this->DebugLevel > 9) { $StartTime = microtime(TRUE); }
207  $this->DB->Query($QueryString);
208  if ($this->DebugLevel > 9)
209  {
210  $EndTime = microtime(TRUE);
211  if (($StartTime - $EndTime) > 0.1)
212  {
213  printf("SE: Query took %.2f seconds<br>\n",
214  ($EndTime - $StartTime));
215  }
216  }
217  $MatchList = $this->DB->FetchColumn("ResourceId");
218  if (isset($SecondQueryString))
219  {
220  $this->DMsg(7, "Performing second phrase search query"
221  ." (<i>".$SecondQueryString."</i>)");
222  if ($this->DebugLevel > 9) { $StartTime = microtime(TRUE); }
223  $this->DB->Query($SecondQueryString);
224  if ($this->DebugLevel > 9)
225  {
226  $EndTime = microtime(TRUE);
227  if (($StartTime - $EndTime) > 0.1)
228  {
229  printf("SE: query took %.2f seconds<br>\n",
230  ($EndTime - $StartTime));
231  }
232  }
233  $MatchList = $MatchList + $this->DB->FetchColumn("ResourceId");
234  }
235  }
236  else
237  {
238  $MatchList = array();
239  }
240 
241  # return list of matching resources to caller
242  return $MatchList;
243  }
244 
245  # search field for records that meet comparison
246  function SearchFieldsForComparisonMatches($FieldNames, $Operators, $Values)
247  {
248  # use SQL keyword appropriate to current search logic for combining operations
249  $CombineWord = ($this->DefaultSearchLogic == self::LOGIC_AND) ? " AND " : " OR ";
250 
251  # for each comparison
252  foreach ($FieldNames as $Index => $FieldName)
253  {
254  $Operator = $Operators[$Index];
255  $Value = $Values[$Index];
256 
257  # determine query based on field type
258  $Field = $this->Schema->GetFieldByName($FieldName);
259  if ($Field != NULL)
260  {
261  switch ($Field->Type())
262  {
269  if (isset($Queries["Resources"]))
270  {
271  $Queries["Resources"] .= $CombineWord;
272  }
273  else
274  {
275  $Queries["Resources"] = "SELECT DISTINCT ResourceId"
276  ." FROM Resources WHERE ";
277  }
278  if ($Field->Type() == MetadataSchema::MDFTYPE_USER)
279  {
280  $User = new CWUser($Value);
281  $Value = $User->Id();
282  }
283  $Queries["Resources"] .= "`".$Field->DBFieldName()
284  ."` ".$Operator." '".addslashes($Value)."' ";
285  break;
286 
288  $QueryIndex = "ResourceNameInts".$Field->Id();
289  if (!isset($Queries[$QueryIndex]["A"]))
290  {
291  $Queries[$QueryIndex]["A"] =
292  "SELECT DISTINCT ResourceId"
293  ." FROM ResourceNameInts, ControlledNames "
294  ." WHERE ControlledNames.FieldId = ".$Field->Id()
295  ." AND ( ";
296  $CloseQuery[$QueryIndex]["A"] = TRUE;
297  $ComparisonCount[$QueryIndex]["A"] = 1;
298  $ComparisonCountField[$QueryIndex]["A"] = "ControlledName";
299  }
300  else
301  {
302  $Queries[$QueryIndex]["A"] .= " OR ";
303  $ComparisonCount[$QueryIndex]["A"]++;
304  }
305  $Queries[$QueryIndex]["A"] .=
306  "((ResourceNameInts.ControlledNameId"
307  ." = ControlledNames.ControlledNameId"
308  ." AND ControlledName "
309  .$Operator." '".addslashes($Value)."'))";
310  if (!isset($Queries[$QueryIndex]["B"]))
311  {
312  $Queries[$QueryIndex]["B"] =
313  "SELECT DISTINCT ResourceId"
314  . " FROM ResourceNameInts, ControlledNames,"
315  ." VariantNames "
316  ." WHERE ControlledNames.FieldId = ".$Field->Id()
317  ." AND ( ";
318  $CloseQuery[$QueryIndex]["B"] = TRUE;
319  $ComparisonCount[$QueryIndex]["B"] = 1;
320  $ComparisonCountField[$QueryIndex]["B"] = "ControlledName";
321  }
322  else
323  {
324  $Queries[$QueryIndex]["B"] .= " OR ";
325  $ComparisonCount[$QueryIndex]["B"]++;
326  }
327  $Queries[$QueryIndex]["B"] .=
328  "((ResourceNameInts.ControlledNameId"
329  ." = ControlledNames.ControlledNameId"
330  ." AND ResourceNameInts.ControlledNameId"
331  ." = VariantNames.ControlledNameId"
332  ." AND VariantName "
333  .$Operator." '".addslashes($Value)."'))";
334  break;
335 
337  $QueryIndex = "ResourceNameInts".$Field->Id();
338  if (!isset($Queries[$QueryIndex]))
339  {
340  $Queries[$QueryIndex] =
341  "SELECT DISTINCT ResourceId"
342  ." FROM ResourceNameInts, ControlledNames "
343  ." WHERE ControlledNames.FieldId = ".$Field->Id()
344  ." AND ( ";
345  $CloseQuery[$QueryIndex] = TRUE;
346  $ComparisonCount[$QueryIndex] = 1;
347  $ComparisonCountField[$QueryIndex] = "ControlledName";
348  }
349  else
350  {
351  $Queries[$QueryIndex] .= " OR ";
352  $ComparisonCount[$QueryIndex]++;
353  }
354  $Queries[$QueryIndex] .=
355  "(ResourceNameInts.ControlledNameId"
356  ." = ControlledNames.ControlledNameId"
357  ." AND ControlledName ".$Operator
358  ." '".addslashes($Value)."')";
359  break;
360 
362  $QueryIndex = "ResourceClassInts".$Field->Id();
363  if (!isset($Queries[$QueryIndex]))
364  {
365  $Queries[$QueryIndex] = "SELECT DISTINCT ResourceId"
366  ." FROM ResourceClassInts, Classifications"
367  ." WHERE ResourceClassInts.ClassificationId"
368  ." = Classifications.ClassificationId"
369  ." AND Classifications.FieldId"
370  ." = ".$Field->Id()." AND ( ";
371  $CloseQuery[$QueryIndex] = TRUE;
372  $ComparisonCount[$QueryIndex] = 1;
373  $ComparisonCountField[$QueryIndex] = "ClassificationName";
374  }
375  else
376  {
377  $Queries[$QueryIndex] .= " OR ";
378  $ComparisonCount[$QueryIndex]++;
379  }
380  $Queries[$QueryIndex] .= " ClassificationName "
381  .$Operator." '".addslashes($Value)."'";
382  break;
383 
385  # if value appears to have time component or text description
386  if (strpos($Value, ":")
387  || strstr($Value, "day")
388  || strstr($Value, "week")
389  || strstr($Value, "month")
390  || strstr($Value, "year")
391  || strstr($Value, "hour")
392  || strstr($Value, "minute"))
393  {
394  if (isset($Queries["Resources"]))
395  {
396  $Queries["Resources"] .= $CombineWord;
397  }
398  else
399  {
400  $Queries["Resources"] = "SELECT DISTINCT ResourceId"
401  ." FROM Resources WHERE ";
402  }
403 
404  # flip operator if necessary
405  if (strstr($Value, "ago"))
406  {
407  $OperatorFlipMap = array(
408  "<" => ">=",
409  ">" => "<=",
410  "<=" => ">",
411  ">=" => "<",
412  );
413  $Operator = isset($OperatorFlipMap[$Operator])
414  ? $OperatorFlipMap[$Operator] : $Operator;
415  }
416 
417  # use strtotime method to build condition
418  $TimestampValue = strtotime($Value);
419  if (($TimestampValue !== FALSE) && ($TimestampValue != -1))
420  {
421  if ((date("H:i:s", $TimestampValue) == "00:00:00")
422  && (strpos($Value, "00:00") === FALSE)
423  && ($Operator == "<="))
424  {
425  $NormalizedValue =
426  date("Y-m-d", $TimestampValue)." 23:59:59";
427  }
428  else
429  {
430  $NormalizedValue = date(
431  "Y-m-d H:i:s", $TimestampValue);
432  }
433  }
434  else
435  {
436  $NormalizedValue = addslashes($Value);
437  }
438  $Queries["Resources"] .=
439  " ( `".$Field->DBFieldName()."` "
440  .$Operator
441  ." '".$NormalizedValue."' ) ";
442  }
443  else
444  {
445  # use Date object method to build condition
446  $Date = new Date($Value);
447  if ($Date->Precision())
448  {
449  if (isset($Queries["Resources"]))
450  {
451  $Queries["Resources"] .= $CombineWord;
452  }
453  else
454  {
455  $Queries["Resources"] = "SELECT DISTINCT ResourceId"
456  ." FROM Resources WHERE ";
457  }
458  $Queries["Resources"] .= " ( ".$Date->SqlCondition(
459  $Field->DBFieldName(), NULL, $Operator)." ) ";
460  }
461  }
462  break;
463 
465  $Date = new Date($Value);
466  if ($Date->Precision())
467  {
468  if (isset($Queries["Resources"]))
469  {
470  $Queries["Resources"] .= $CombineWord;
471  }
472  else
473  {
474  $Queries["Resources"] = "SELECT DISTINCT ResourceId"
475  ." FROM Resources WHERE ";
476  }
477  $Queries["Resources"] .= " ( ".$Date->SqlCondition(
478  $Field->DBFieldName()."Begin",
479  $Field->DBFieldName()."End", $Operator)." ) ";
480  }
481  break;
482 
484  $QueryIndex = "ReferenceInts".$Field->Id();
485  if (!isset($Queries[$QueryIndex]))
486  {
487  if (!isset($NameField))
488  {
489  $NameField =
490  $this->Schema->GetFieldByMappedName(
491  "Title");
492  }
493  $Queries[$QueryIndex] =
494  "SELECT DISTINCT RI.SrcResourceId AS ResourceId"
495  ." FROM ReferenceInts AS RI, Resources AS R "
496  ." WHERE RI.FieldId = ".$Field->Id()
497  ." AND (";
498  $CloseQuery[$QueryIndex] = TRUE;
499  $ComparisonCount[$QueryIndex] = 1;
500  $ComparisonCountField[$QueryIndex] =
501  "R.`".$NameField->DBFieldName()."`";
502  }
503  else
504  {
505  $Queries[$QueryIndex] .= $CombineWord;
506  $ComparisonCount[$QueryIndex]++;
507  }
508  $Queries[$QueryIndex] .= "(R.`".$NameField->DBFieldName()."` "
509  .$Operator." '".addslashes($Value)."'"
510  ." AND R.ResourceId = RI.DstResourceId)";
511  break;
512 
515  # (these types not yet handled by search engine for comparisons)
516  break;
517  }
518  }
519  }
520 
521  # if queries found
522  if (isset($Queries))
523  {
524  # for each assembled query
525  foreach ($Queries as $QueryIndex => $Query)
526  {
527  # if query has multiple parts
528  if (is_array($Query))
529  {
530  # for each part of query
531  $ResourceIds = array();
532  foreach ($Query as $PartIndex => $PartQuery)
533  {
534  # add closing paren if query was flagged to be closed
535  if (isset($CloseQuery[$QueryIndex][$PartIndex]))
536  {
537  $PartQuery .= ") ";
538  if (($this->DefaultSearchLogic == self::LOGIC_AND)
539  && ($ComparisonCount[$QueryIndex][$PartIndex] > 1))
540  {
541  $PartQuery .= "GROUP BY ResourceId"
542  ." HAVING COUNT(DISTINCT "
543  .$ComparisonCountField[$QueryIndex][$PartIndex]
544  .") = "
545  .$ComparisonCount[$QueryIndex][$PartIndex];
546  }
547  }
548 
549  # perform query and retrieve IDs
550  $this->DMsg(5, "Performing comparison query <i>"
551  .$PartQuery."</i>");
552  $this->DB->Query($PartQuery);
553  $ResourceIds = $ResourceIds
554  + $this->DB->FetchColumn("ResourceId");
555  $this->DMsg(5, "Comparison query produced <i>"
556  .count($ResourceIds)."</i> results");
557  }
558  }
559  else
560  {
561  # add closing paren if query was flagged to be closed
562  if (isset($CloseQuery[$QueryIndex]))
563  {
564  $Query .= ") ";
565  if (($this->DefaultSearchLogic == self::LOGIC_AND)
566  && ($ComparisonCount[$QueryIndex] > 1))
567  {
568  $Query .= "GROUP BY ResourceId"
569  ." HAVING COUNT(DISTINCT "
570  .$ComparisonCountField[$QueryIndex]
571  .") = "
572  .$ComparisonCount[$QueryIndex];
573  }
574  }
575 
576  # perform query and retrieve IDs
577  $this->DMsg(5, "Performing comparison query <i>".$Query."</i>");
578  $this->DB->Query($Query);
579  $ResourceIds = $this->DB->FetchColumn("ResourceId");
580  $this->DMsg(5, "Comparison query produced <i>"
581  .count($ResourceIds)."</i> results");
582  }
583 
584  # if we already have some results
585  if (isset($Results))
586  {
587  # if search logic is set to AND
588  if ($this->DefaultSearchLogic == self::LOGIC_AND)
589  {
590  # remove anything from results that was not returned from query
591  $Results = array_intersect($Results, $ResourceIds);
592  }
593  else
594  {
595  # add values returned from query to results
596  $Results = array_unique(array_merge($Results, $ResourceIds));
597  }
598  }
599  else
600  {
601  # set results to values returned from query
602  $Results = $ResourceIds;
603  }
604  }
605  }
606  else
607  {
608  # initialize results to empty list
609  $Results = array();
610  }
611 
612  # return results to caller
613  return $Results;
614  }
615 
616  static function GetItemIdsSortedByField($FieldName, $SortDescending)
617  {
618  $RFactory = new ResourceFactory();
619  return $RFactory->GetResourceIdsSortedBy($FieldName, !$SortDescending);
620  }
621 
622  static function QueueUpdateForItem($ItemId,
623  $TaskPriority = ApplicationFramework::PRIORITY_LOW)
624  {
625  $Item = new Resource($ItemId);
626  $TaskDescription = "Update search data for"
627  ." <a href=\"r".$ItemId."\"><i>"
628  .$Item->GetMapped("Title")."</i></a>";
629  $GLOBALS["AF"]->QueueUniqueTask(array(__CLASS__, "RunUpdateForItem"),
630  array(intval($ItemId)), $TaskPriority, $TaskDescription);
631  }
632 
633  static function RunUpdateForItem($ItemId)
634  {
635  # bail out if item ID is negative (indicating a temporary record)
636  if ($ItemId < 0) { return; }
637 
638  # check that resource still exists
639  $RFactory = new ResourceFactory();
640  if (!$RFactory->ItemExists($ItemId)) { return; }
641 
642  # retrieve schema ID of item to use for item type
643  $Resource = new Resource($ItemId);
644  $ItemType = $Resource->SchemaId();
645 
646  # update search data for resource
647  $SearchEngine = new SPTSearchEngine();
648  $SearchEngine->UpdateForItem($ItemId, $ItemType);
649  }
650 
659  static function GetResultFacets($SearchResults, $User)
660  {
661  # classifications and names associated with these search results
662  $SearchClasses = array();
663  $SearchNames = array();
664 
665  # disable DB cache for the search suggestions process,
666  # this avoids memory exhaustion.
667  $DB = new Database();
668  $DB->Caching(FALSE);
669 
670  if (count($SearchResults)>0)
671  {
672  foreach (array_chunk($SearchResults, 1000, TRUE) as $Chunk)
673  {
674  # pull out all the Classifications that were associated
675  # with our search results
676  $DB->Query("SELECT ResourceId,ClassificationId FROM ResourceClassInts "
677  ."WHERE ResourceId IN "
678  ."(".implode(",", array_keys($Chunk)).")");
679  foreach ($DB->FetchRows() as $Row)
680  {
681  $SearchClasses[ $Row["ClassificationId"] ] []= $Row["ResourceId"] ;
682  }
683 
684  # similarly with controlled names
685  $DB->Query("SELECT ResourceId,ControlledNameId FROM ResourceNameInts "
686  ."WHERE ResourceId in "
687  ."(".implode(",", array_keys($Chunk)).")");
688  foreach ($DB->FetchRows() as $Row)
689  {
690  $SearchNames[ $Row["ControlledNameId"] ] []= $Row["ResourceId"];
691  }
692  }
693  }
694 
695  # generate a map of FieldId -> Field Names for all of the generated facets:
696  $SuggestionsById = array();
697 
698  # pull relevant Classification names out of the DB
699  if (count($SearchClasses)>0)
700  {
701  foreach (array_chunk($SearchClasses, 1000, TRUE) as $Chunk)
702  {
703  $DB->Query("SELECT FieldId,ClassificationId,ClassificationName"
704  ." FROM Classifications"
705  ." WHERE ClassificationId"
706  ." IN (".implode(",", array_keys($Chunk)).")");
707  foreach ($DB->FetchRows() as $Row)
708  {
709  $SuggestionsById[$Row["FieldId"]] []=
710  array("Id" => $Row["ClassificationId"],
711  "Name" => $Row["ClassificationName"],
712  "Count" => count($SearchClasses[
713  $Row["ClassificationId"]]));
714  }
715  }
716  }
717 
718  # pull relevant ControlledNames out of the DB
719  if (count($SearchNames)>0)
720  {
721  foreach (array_chunk($SearchNames, 1000, TRUE) as $Chunk)
722  {
723  $DB->Query("SELECT FieldId,ControlledNameId,ControlledName"
724  ." FROM ControlledNames"
725  ." WHERE ControlledNameId"
726  ." IN (".implode(",", array_keys($SearchNames)).")");
727  foreach ($DB->FetchRows() as $Row)
728  {
729  $SuggestionsById[$Row["FieldId"]] []=
730  array("Id" => $Row["ControlledNameId"],
731  "Name" => $Row["ControlledName"],
732  "Count" => count(
733  $SearchNames[$Row["ControlledNameId"]]));
734  }
735  }
736  }
737 
738  # translate the suggestions that we have in terms of the
739  # FieldIds to suggestions in terms of the field names
740  $SuggestionsByFieldName = array();
741 
742  # if we have suggestions to offer
743  if (count($SuggestionsById)>0)
744  {
745  $Schema = new MetadataSchema();
746 
747  # gill in an array that maps FieldNames to search links
748  # which would be appropriate for that field
749  foreach ($SuggestionsById as $FieldId => $FieldValues)
750  {
751  $ThisField = $Schema->GetField($FieldId);
752 
753  # bail on fields that didn't exist and on fields that the
754  # current user cannot view, and on fields that are
755  # disabled for advanced searching
756  if (is_object($ThisField) &&
757  $ThisField->Status() == MetadataSchema::MDFSTAT_OK &&
758  $ThisField->IncludeInFacetedSearch() &&
759  $ThisField->Enabled() &&
760  $User->HasPriv($ThisField->ViewingPrivileges()))
761  {
762  $SuggestionsByFieldName[ $ThisField->Name() ] = array();
763 
764  foreach ($FieldValues as $Value)
765  {
766  $SuggestionsByFieldName [ $ThisField->Name() ] [$Value["Id"]] =
767  array("Name" => $Value["Name"], "Count" => $Value["Count"] );
768  }
769  }
770  }
771  }
772 
773  ksort($SuggestionsByFieldName);
774 
775  return $SuggestionsByFieldName;
776  }
777 
778  private $Schema;
779 
780  # functions for backward compatability w/ old SPT code
781  function UpdateForResource($ItemId)
782  {
783  $this->UpdateForItem($ItemId);
784  }
785 }
SearchFieldForPhrases($FieldName, $Phrase)
Metadata schema (in effect a Factory class for MetadataField).
SQL database abstraction object with smart query caching.
AddField($FieldName, $FieldType, $Weight, $UsedInKeywordSearch)
Add field to include in searching.
UpdateForResource($ItemId)
UpdateForItem($ItemId, $ItemType=0)
Update search database for the specified item.
GetFieldContent($ItemId, $FieldName)
Overloaded version of method to retrieve text from DB.
const MDFTYPE_CONTROLLEDNAME
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
static QueueUpdateForItem($ItemId, $TaskPriority=ApplicationFramework::PRIORITY_LOW)