/**
  * Filters a list of element IDs by a given search query.
  *
  * @param array $elementIds   The list of element IDs to filter by the search query.
  * @param mixed $query        The search query (either a string or a SearchQuery instance)
  * @param bool  $scoreResults Whether to order the results based on how closely they match the query.
  * @param mixed $localeId     The locale to filter by.
  * @param bool  $returnScores Whether the search scores should be included in the results. If true, results will be returned as `element ID => score`.
  *
  * @return array The filtered list of element IDs.
  */
 public function filterElementIdsByQuery($elementIds, $query, $scoreResults = true, $localeId = null, $returnScores = false)
 {
     if (is_string($query)) {
         $query = new SearchQuery($query, craft()->config->get('defaultSearchTermOptions'));
     } else {
         if (is_array($query)) {
             $options = $query;
             $query = $options['query'];
             unset($options['query']);
             $query = new SearchQuery($query, $options);
         }
     }
     // Get tokens for query
     $this->_tokens = $query->getTokens();
     $this->_terms = array();
     $this->_groups = array();
     // Set Terms and Groups based on tokens
     foreach ($this->_tokens as $obj) {
         if ($obj instanceof SearchQueryTermGroup) {
             $this->_groups[] = $obj->terms;
         } else {
             $this->_terms[] = $obj;
         }
     }
     // Get where clause from tokens, bail out if no valid query is there
     $where = $this->_getWhereClause();
     if (!$where) {
         return array();
     }
     // Add any locale restrictions
     if ($localeId) {
         $where .= sprintf(' AND %s = %s', craft()->db->quoteColumnName('locale'), craft()->db->quoteValue($localeId));
     }
     // Begin creating SQL
     $sql = sprintf('SELECT * FROM %s WHERE %s', craft()->db->quoteTableName(craft()->db->addTablePrefix('searchindex')), $where);
     // Append elementIds to QSL
     if ($elementIds) {
         $sql .= sprintf(' AND %s IN (%s)', craft()->db->quoteColumnName('elementId'), implode(',', $elementIds));
     }
     // Execute the sql
     $results = craft()->db->createCommand()->setText($sql)->queryAll();
     // Are we scoring the results?
     if ($scoreResults) {
         $scoresByElementId = array();
         // Loop through results and calculate score per element
         foreach ($results as $row) {
             $elementId = $row['elementId'];
             $score = $this->_scoreRow($row);
             if (!isset($scoresByElementId[$elementId])) {
                 $scoresByElementId[$elementId] = $score;
             } else {
                 $scoresByElementId[$elementId] += $score;
             }
         }
         // Sort found elementIds by score
         arsort($scoresByElementId);
         if ($returnScores) {
             return $scoresByElementId;
         } else {
             // Just return the ordered element IDs
             return array_keys($scoresByElementId);
         }
     } else {
         // Don't apply score, just return the IDs
         $elementIds = array();
         foreach ($results as $row) {
             $elementIds[] = $row['elementId'];
         }
         return array_unique($elementIds);
     }
 }
예제 #2
0
 /**
  * Filters a list of element IDs by a given search query.
  *
  * @param array  $elementIds The list of element IDs to filter by the search query.
  * @param mixed  $query      The search query (either a string or a SearchQuery instance)
  * @param bool   $scoreResults Whether to order the results based on how closely they match the query.
  * @return array The filtered list of element IDs.
  */
 public function filterElementIdsByQuery($elementIds, $query, $scoreResults = true)
 {
     if (is_string($query)) {
         $query = new SearchQuery($query);
     }
     // Get tokens for query
     $this->_tokens = $query->getTokens();
     $this->_terms = array();
     $this->_groups = array();
     $this->_results = array();
     // Set Terms and Groups based on tokens
     foreach ($this->_tokens as $obj) {
         if ($obj instanceof SearchQueryTermGroup) {
             $this->_groups[] = $obj->terms;
         } else {
             $this->_terms[] = $obj;
         }
     }
     // Get where clause from tokens, bail out if no valid query is there
     $where = $this->_getWhereClause();
     if (!$where) {
         return array();
     }
     // Begin creating SQL
     $sql = sprintf('SELECT * FROM %s WHERE %s', craft()->db->quoteTableName(DbHelper::addTablePrefix('searchindex')), $where);
     // Append elementIds to QSL
     if ($elementIds) {
         $sql .= sprintf(' AND %s IN (%s)', craft()->db->quoteColumnName('elementId'), implode(',', $elementIds));
     }
     // Execute the sql
     $results = craft()->db->createCommand()->setText($sql)->queryAll();
     // Are we scoring the results?
     if ($scoreResults) {
         // Loop through results and calculate score per element
         foreach ($results as $row) {
             $eId = $row['elementId'];
             $score = $this->_scoreRow($row);
             if (!isset($this->_results[$eId])) {
                 $this->_results[$eId] = $score;
             } else {
                 $this->_results[$eId] += $score;
             }
         }
         // Sort found elementIds by score
         asort($this->_results);
         // Store entry ids in return value
         $elementIds = array_keys($this->_results);
     } else {
         // Don't apply score, just return the IDs
         $elementIds = array();
         foreach ($results as $row) {
             $elementIds[] = $row['elementId'];
         }
         $elementIds = array_unique($elementIds);
     }
     // Return elementIds
     return $elementIds;
 }