/** * getInstance() * * Connect to the backend engine and store for later use * * @static * @return SugarSearchEngineInterface */ public static function getInstance($name = '', $config = array(), $useDefaultWhenFTSDown = false) { require_once 'include/SugarSearchEngine/SugarSearchEngineAbstractBase.php'; if ($useDefaultWhenFTSDown && SugarSearchEngineAbstractBase::isSearchEngineDown()) { $name = 'SugarSearchEngine'; } if (!isset(self::$_instance[$name])) { self::$_instance[$name] = self::setupEngine($name, $config); } return self::$_instance[$name]; }
public function __construct($params = array()) { // Setup Elastica Client object $this->_config = $params; // this timeout can be overriden at $sugar_config['full_text_engine']['Elastic']['timeout'] if (empty($this->_config['timeout'])) { $this->_config['timeout'] = 15; } $this->setClient(new \Elastica\Client($this->_config)); // Setup index strategy $this->indexStrategy = SugarSearchEngineElasticIndexStrategyFactory::getinstance(); // Asynchronous indexing through fts_queue table $this->forceAsyncIndex = SugarConfig::getInstance()->get('search_engine.force_async_index', false); // Elastic mapping $mappingClass = SugarAutoLoader::customClass('SugarSearchEngineElasticMapping'); $this->mapper = new $mappingClass($this); // Facet handler $this->facetHandler = new FacetHandler(); parent::__construct(); }
/** * This function is used to hand off the global search to the FTS Search Emgine * @param $api ServiceBase The API class of the request * @param $args array The arguments array passed in from the API * @param $searchEngine SugarSearchEngine The SugarSpot search engine created using the Factory in the caller * @param $options array An array of options to pass through to the search engine, they get translated to the $searchOptions array so you can see exactly what gets passed through * @return array Two elements, 'records' the list of returned records formatted through FormatBean, and 'next_offset' which will indicate to the user if there are additional records to be returned. */ protected function globalSearchFullText(ServiceBase $api, array $args, SugarSearchEngineAbstractBase $searchEngine, array $options) { $options['append_wildcard'] = 1; if (empty($options['moduleList'])) { require_once 'modules/ACL/ACLController.php'; $moduleList = SugarSearchEngineMetadataHelper::getSystemEnabledFTSModules(); // filter based on User Access if Blank $ACL = new ACLController(); // moduleList is passed by reference $ACL->filterModuleList($moduleList); $options['moduleList'] = $moduleList; } if (!empty($options['searchFields'])) { $customWhere = array(); foreach ($options['moduleList'] as $module) { $seed = BeanFactory::getBean($module); $fields = array_keys($seed->field_defs); $existingfields = array_intersect($fields, $options['searchFields']); if (!empty($existingfields)) { foreach ($existingfields as $field) { if (empty($seed->field_defs[$field]['full_text_search'])) { continue; } $prefix = $seed->module_name; if (!isset($seed->field_defs[$field]['source']) || $seed->field_defs[$field]['source'] != 'non-db') { $customWhere[] = "{$prefix}.{$field}"; } } } } $options['searchFields'] = $customWhere; } $options['moduleFilter'] = $options['moduleList']; $results = $searchEngine->search($options['query'], $options['offset'], $options['limit'], $options); $returnedRecords = array(); $total = 0; $api->action = 'list'; if (is_object($results)) { foreach ($results as $result) { $record = BeanFactory::retrieveBean($result->getModule(), $result->getId()); // if we can't get the bean skip it if (!$record) { continue; } $module = $record->module_dir; // Need to override the filter arg so that it looks like something formatBean expects if (!empty($options['fieldFilters'][$module])) { $moduleFields = $options['fieldFilters'][$module]; } else { if (!empty($options['fieldFilters']['_default'])) { $moduleFields = $options['fieldFilters']['_default']; } else { $moduleFields = array(); } } if (!empty($moduleFields) && !in_array('id', $moduleFields)) { $moduleFields[] = 'id'; } $moduleArgs['fields'] = implode(',', $moduleFields); $formattedRecord = $this->formatBean($api, $moduleArgs, $record); $formattedRecord['_module'] = $module; // The SQL based search engine doesn't know how to score records, so set it to 1 $formattedRecord['_search']['score'] = $result->getScore(); //Add highlighted text $formattedRecord['_search']['highlighted'] = $result->getHighlightedHitText(); $returnedRecords[] = $formattedRecord; } $total = $results->getTotalHits(); } if ($total > $options['limit'] + $options['offset']) { $nextOffset = $options['offset'] + $options['limit']; } else { $nextOffset = -1; } return array('next_offset' => $nextOffset, 'records' => $returnedRecords); }
sugar_die("silentFTSIndex.php is CLI only.\n"); } if (empty($current_language)) { $current_language = $sugar_config['default_language']; } $app_list_strings = return_app_list_strings_language($current_language); $app_strings = return_application_language($current_language); global $current_user; $current_user = BeanFactory::getBean('Users'); $current_user->getSystemUser(); // Pop off the filename array_shift($argv); // Don't wipe the index if we're just doing individual modules $clearData = empty($argv); // Allows for php -f silentFTSIndex.php Bugs Cases $modules = $argv; require_once 'include/SugarSearchEngine/SugarSearchEngineFullIndexer.php'; require_once 'include/SugarSearchEngine/SugarSearchEngineAbstractBase.php'; try { SugarSearchEngineAbstractBase::markSearchEngineStatus(false); // set search engine to "up" $indexer = new SugarSearchEngineFullIndexer(); if (!$indexer->performFullSystemIndex($modules, $clearData)) { echo "FTS index failed. Please check the sugarcrm.log for more details.\n"; exit(1); } } catch (Exception $e) { echo "Exception: " . $e->getMessage() . "\n"; exit(1); } exit(0);
/** * This method sets the full text search to available when a scheduled FTS Index occurs. * An indexing can only occur with a valid connection * * TODO: XXX Fix this to use admin settings not config options * @return bool */ protected function setFTSUp() { $cfg = new Configurator(); $cfg->config['fts_disable_notification'] = false; $cfg->handleOverride(); // set it up SugarSearchEngineAbstractBase::markSearchEngineStatus(false); $admin = BeanFactory::newBean('Administration'); $admin->retrieveSettings(FALSE, TRUE); return TRUE; }
/** * Check FTS server status and update cache file and notification. * * @return boolean */ protected function updateFTSServerStatus() { $GLOBALS['log']->debug('Going to check and update FTS Server status.'); // check FTS server status $result = $this->SSEngine->getServerStatus(); if ($result['valid']) { $GLOBALS['log']->debug('FTS Server is OK.'); // server is ok if (SugarSearchEngineAbstractBase::isSearchEngineDown()) { $GLOBALS['log']->debug('Restoring FTS Server status.'); // mark fts server as up SugarSearchEngineAbstractBase::markSearchEngineStatus(false); // remove notification $cfg = new Configurator(); $cfg->config['fts_disable_notification'] = false; $cfg->handleOverride(); } return true; } else { $GLOBALS['log']->info('FTS Server is down?'); // server is down if (!SugarSearchEngineAbstractBase::isSearchEngineDown()) { $GLOBALS['log']->fatal('Marking FTS Server as down.'); // fts is not marked as down, so mark it as down SugarSearchEngineAbstractBase::markSearchEngineStatus(true); } return false; } }