/** * 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); } }
/** * 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; }