diff --git a/includes/service.inc b/includes/service.inc index 4455235..20e57b8 100644 --- a/includes/service.inc +++ b/includes/service.inc @@ -27,28 +27,6 @@ class SearchApiSolrService extends SearchApiAbstractService { protected $solr; /** - * An array of all recognized types. - * - * Maps the type names to the prefixes used for identifying them in the Solr - * schema. - * - * @var array - */ - protected static $type_prefixes = array( - 'text' => 'tm', - 'tokens' => 'tm', - 'string' => 's', - 'integer' => 'i', - 'decimal' => 'f', - 'date' => 'd', - 'duration' => 'i', - 'boolean' => 'b', - 'uri' => 's', - 'location' => 'loc', - 'geohash' => 'geo', - ); - - /** * Static cache for getFieldNames(). * * @var array @@ -290,7 +268,8 @@ class SearchApiSolrService extends SearchApiAbstractService { * Overrides SearchApiAbstractService::supportsFeature(). */ public function supportsFeature($feature) { - $supported = drupal_map_assoc(array( + // Search API features. + $supported = array( 'search_api_autocomplete', 'search_api_facets', 'search_api_facets_operator_or', @@ -300,7 +279,14 @@ class SearchApiSolrService extends SearchApiAbstractService { 'search_api_spellcheck', 'search_api_data_type_location', 'search_api_data_type_geohash', - )); + ); + + // Custom data types. + foreach (search_api_solr_get_dynamic_field_info() as $type => $info) { + $supported[] = 'search_api_data_type_' . $type; + } + + $supported = drupal_map_assoc($supported); return isset($supported[$feature]); } @@ -495,8 +481,9 @@ class SearchApiSolrService extends SearchApiAbstractService { } $inner_type = search_api_extract_inner_type($type); - $pref = isset(self::$type_prefixes[$inner_type]) ? self::$type_prefixes[$inner_type] : ''; - if ($pref != 'tm') { + $type_info = search_api_solr_get_dynamic_field_info($inner_type); + $pref = isset($type_info['prefix']) ? $type_info['prefix']: ''; + if (empty($type_info['always multiValued'])) { $pref .= $type == $inner_type ? 's' : 'm'; } if (!empty($this->options['clean_ids'])) { diff --git a/search_api_solr.api.php b/search_api_solr.api.php index a64c477..cc9b208 100644 --- a/search_api_solr.api.php +++ b/search_api_solr.api.php @@ -101,5 +101,45 @@ function hook_search_api_solr_multi_query_alter(array &$call_args, SearchApiMult } /** + * Define how Search API Solr should index different data types. + * + * It is important to make sure that any types you define are also declared to + * Search API using hook_search_api_data_type_info(). + * + * @return array + * An array containing data type definitions, keyed by their type identifier + * and containing the following keys: + * - prefix: The prefix used by the dynamic field type. + * - always multiValued: (optional) Whether the single/multiple prefix should + * be skipped for this data type. Defaults to FALSE. + * + * @see hook_search_api_solr_dynamic_field_info_alter() + * @see search_api_solr_get_dynamic_field_info() + * @see hook_search_api_data_type_info(). + */ +function hook_search_api_solr_dynamic_field_info() { + return array( + 'example_type' => array( + 'prefix' => 'ex', + // Could be omitted, as FALSE is the default. + 'always multiValued' => FALSE, + ), + ); +} + +/** + * Alter the data type indexing info. + * + * @param array $infos + * The item type info array, keyed by type identifier. + * + * @see hook_search_api_solr_dynamic_field_info() + */ +function hook_search_api_solr_dynamic_field_info_alter(array &$infos) { + // Change the prefix used for example_type. + $info['example_type']['prefix'] = 'ex2'; +} + +/** * @} End of "addtogroup hooks". */ diff --git a/search_api_solr.module b/search_api_solr.module index cfab380..52ae956 100644 --- a/search_api_solr.module +++ b/search_api_solr.module @@ -113,6 +113,84 @@ function search_api_solr_search_api_server_update(SearchApiServer $server) { } /** + * Returns either all dynamic field types, or a specific one. + * + * @param $type + * If specified, the type whose definition should be returned. + * + * @return array + * If $type was not given, an array containing all custom dynamic fields, in + * the format specified by hook_search_api_solr_dynamic_field_info(). + * Otherwise, the definition for the given type, or NULL if it is unknown. + * + * @see hook_search_api_solr_dynamic_field_info(). + */ +function search_api_solr_get_dynamic_field_info($type = NULL) { + $types = &drupal_static(__FUNCTION__); + if (!isset($types)) { + $types = module_invoke_all('search_api_solr_dynamic_field_info'); + $types = $types ? $types : array(); + drupal_alter('search_api_solr_dynamic_field_info', $types); + } + if (isset($type)) { + return isset($types[$type]) ? $types[$type] : NULL; + } + return $types; +} + +/** + * Implements hook_search_api_solr_dynamic_field_info(). + */ +function search_api_solr_search_api_solr_dynamic_field_info() { + return array( + 'text' => array( + 'prefix' => 'tm', + 'always multiValued' => TRUE, + ), + 'tokens' => array( + 'prefix' => 'tm', + 'always multiValued' => TRUE, + ), + 'string' => array( + 'prefix' => 's', + 'always multiValued' => FALSE, + ), + 'integer' => array( + 'prefix' => 'i', + 'always multiValued' => FALSE, + ), + 'decimal' => array( + 'prefix' => 'f', + 'always multiValued' => FALSE, + ), + 'date' => array( + 'prefix' => 'd', + 'always multiValued' => FALSE, + ), + 'duration' => array( + 'prefix' => 'i', + 'always multiValued' => FALSE, + ), + 'boolean' => array( + 'prefix' => 'b', + 'always multiValued' => FALSE, + ), + 'uri' => array( + 'prefix' => 's', + 'always multiValued' => FALSE, + ), + 'location' => array( + 'prefix' => 'loc', + 'always multiValued' => FALSE, + ), + 'geohash' => array( + 'prefix' => 'geohash', + 'always multiValued' => FALSE, + ), + ); +} + +/** * Retrieves a list of all config files of a server. * * @param SearchApiServer $server