/** * Получить массив с заголовками страниц для autocomplete * @param string $input * @param string $language * @param integer $site_id * @return array элементы массива: array("label" => "Page Title", "url" => "/path/") */ public function suggest_titles($input, $language, $site_id) { $limit = nc_search::get_setting('NumberOfSuggestions'); $index_search_results = ""; $document_order_by_id = "1"; // поиск в индексе (то есть будут варианты после обработки фильтрами - базовая форма) if (nc_search::should('SearchTitleBaseformsForSuggestions')) { $last_space = strrpos($input, " "); $as_phrase = nc_search::should('SearchTitleAsPhraseForSuggestions'); $b1 = $as_phrase ? '"' : '('; $b2 = $as_phrase ? '"' : ')'; /* @todo сделать проверку на то, что последнее слово является правильным/полным? */ $query_string = "(title:{$b1}{$input}{$b2}" . ($last_space ? " OR title:{$b1}" . trim(substr($input, 0, $last_space)) . $b2 : '') . ")"; $query = new nc_search_query($query_string); $query->set('limit', $limit)->set('options_to_fetch', array('title', 'site_id', 'path'))->set('language', $language)->set('area', "site" . (int) $site_id); // some lower level magic $translator = new nc_search_provider_index_translator($this); $document_ids = $this->get_db()->get_col($query->translate($translator)); if ($document_ids) { $document_ids = join(", ", $document_ids); $index_search_results = "OR `Document_ID` IN ({$document_ids})\n"; $document_order_by_id = "FIELD(`Document_ID`, {$document_ids})"; } } // поиск точного соответствия в таблице с документами $like_expression = '`Title` LIKE "' . nc_search_util::db_escape($input) . '%" '; $query = "SELECT `Catalogue_ID`, `Path`, `Title` FROM `%t%`\n" . "WHERE {$like_expression}\n" . $index_search_results . "ORDER BY {$like_expression}, {$document_order_by_id}\n" . "LIMIT {$limit}"; $documents = new nc_search_result(); $documents->select_from_database($query); $suggestions = array(); // собственно подсказки /** @var $doc nc_search_document */ foreach ($documents as $doc) { $suggestions[] = array("label" => $doc->get('title'), "url" => $doc->get('url')); } return $suggestions; }
/** * @param string $input * @param string $language * @param integer $site_id * @return array */ public function suggest_titles($input, $language, $site_id) { $suggestions = array(); // собственно подсказки $titles = array(); $limit = nc_search::get_setting('NumberOfSuggestions'); // поиск в индексе (то есть будут варианты после обработки фильтрами - базовая форма) if (nc_search::should('SearchTitleBaseformsForSuggestions')) { $last_space = strrpos($input, " "); $as_phrase = nc_search::should('SearchTitleAsPhraseForSuggestions'); $b1 = $as_phrase ? '"' : '('; $b2 = $as_phrase ? '"' : ')'; /* @todo сделать проверку на то, что последнее слово является правильным/полным? */ $query_string = "(title:{$b1}{$input}{$b2}" . ($last_space ? " OR title:{$b1}" . trim(substr($input, 0, $last_space)) . $b2 : '') . ") AND site_id:{$site_id}"; $query = new nc_search_query($query_string); $query->set('limit', $limit)->set('options_to_fetch', array('title', 'site_id', 'path'))->set('language', $language); $documents = $this->find($query, false); foreach ($documents as $doc) { $suggestions[] = array("label" => $doc->get('title'), "url" => $doc->get('url')); $titles[] = '"' . nc_search_util::db_escape($doc->get('title')) . '"'; } $titles = array_unique($titles); } // поиск точного соответствия в таблице с документами // по-хорошему следовало бы сначала сделать запрос к БД, а потом к индексу, однако // в случае запроса к индексу не получится так же просто отфильтровать уже совпавшие запросы $query = "SELECT `Catalogue_ID`, `Path`, `Title` FROM `%t%` " . ' WHERE `Title` LIKE "' . nc_search_util::db_escape($input) . '%" ' . ($titles ? " AND `Title` NOT IN (" . join(", ", $titles) . ") " : "") . " ORDER BY `Title` " . " LIMIT {$limit}"; $documents = new nc_search_result(); $documents->select_from_database($query); foreach ($documents as $doc) { array_unshift($suggestions, array("label" => $doc->get('title'), "url" => $doc->get('url'))); } $suggestions = array_slice($suggestions, 0, $limit); return $suggestions; }