diff options
author | Reedy <reedy@wikimedia.org> | 2020-04-27 13:44:55 +0100 |
---|---|---|
committer | Krinkle <krinklemail@gmail.com> | 2020-04-30 04:29:17 +0000 |
commit | eeb8cb1342760ff75112b679a7aa425d3ea669ca (patch) | |
tree | abba024babe3695d6ffc4f2fa3ca33a04fb4841c | |
parent | 6870c216e33d709eda74db8e1220ae84f0856a40 (diff) | |
download | mediawikicore-eeb8cb1342760ff75112b679a7aa425d3ea669ca.tar.gz mediawikicore-eeb8cb1342760ff75112b679a7aa425d3ea669ca.zip |
search: Add 'SearchMappings' attribute to map canonical name to PHP class
This allows indirection between the values in $wgSearchType and
$wgSearchTypeAlternatives where the underlying class name
doesn't match the actual class name that subclasses
SearchEngine.
Bug: T250977
Change-Id: Ib9634128f07d428276e80a6f2f492b850eef17e8
-rw-r--r-- | docs/extension.schema.v1.json | 4 | ||||
-rw-r--r-- | docs/extension.schema.v2.json | 4 | ||||
-rw-r--r-- | includes/DefaultSettings.php | 10 | ||||
-rw-r--r-- | includes/ServiceWiring.php | 7 | ||||
-rw-r--r-- | includes/registration/ExtensionProcessor.php | 1 | ||||
-rw-r--r-- | includes/search/SearchEngineConfig.php | 37 | ||||
-rw-r--r-- | includes/search/SearchEngineFactory.php | 19 | ||||
-rw-r--r-- | tests/phpunit/unit/includes/Rest/Handler/SearchHandlerTest.php | 2 |
8 files changed, 77 insertions, 7 deletions
diff --git a/docs/extension.schema.v1.json b/docs/extension.schema.v1.json index e23f0ac7bc08..6730e6da6162 100644 --- a/docs/extension.schema.v1.json +++ b/docs/extension.schema.v1.json @@ -843,6 +843,10 @@ "type": "array", "description": "DEPRECATED: Parser test suite files to be run by parserTests.php when no specific filename is passed to it" }, + "SearchMappings": { + "type": "object", + "description": "Mapping of search canonical names (used in $wgSearchType and $wgSearchTypeAlternatives) using the Object Factory specification" + }, "ServiceWiringFiles": { "type": "array", "description": "List of service wiring files to be loaded by the default instance of MediaWikiServices" diff --git a/docs/extension.schema.v2.json b/docs/extension.schema.v2.json index a1163c3bc232..78e1fabb3572 100644 --- a/docs/extension.schema.v2.json +++ b/docs/extension.schema.v2.json @@ -972,6 +972,10 @@ "type": "array", "description": "DEPRECATED: Parser test suite files to be run by parserTests.php when no specific filename is passed to it" }, + "SearchMappings": { + "type": "object", + "description": "Mapping of search canonical names (used in $wgSearchType and $wgSearchTypeAlternatives) using the Object Factory specification" + }, "ServiceWiringFiles": { "type": "array", "description": "List of service wiring files to be loaded by the default instance of MediaWikiServices" diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index b16280948022..6cc56dad76d1 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -2030,18 +2030,28 @@ $wgDBadminpassword = null; /** * Search type. + * * Leave as null to select the default search engine for the * selected database type (eg SearchMySQL), or set to a class * name to override to a custom search engine. + * + * If the canonical name for the search engine doesn't match the class name + * (because it's namespaced for example), you can add a mapping for this in + * SearchMappings in extension.json. */ $wgSearchType = null; /** * Alternative search types + * * Sometimes you want to support multiple search engines for testing. This * allows users to select their search engine of choice via url parameters * to Special:Search and the action=search API. If using this, there's no * need to add $wgSearchType to it, that is handled automatically. + * + * If the canonical name for the search engine doesn't match the class name + * (because it's namespaced for example), you can add a mapping for this in + * SearchMappings in extension.json. */ $wgSearchTypeAlternatives = null; diff --git a/includes/ServiceWiring.php b/includes/ServiceWiring.php index 9071418e1817..62998d395c5c 100644 --- a/includes/ServiceWiring.php +++ b/includes/ServiceWiring.php @@ -969,8 +969,11 @@ return [ 'SearchEngineConfig' => function ( MediaWikiServices $services ) : SearchEngineConfig { // @todo This should not take a Config object, but it's not so easy to remove because it // exposes it in a getter, which is actually used. - return new SearchEngineConfig( $services->getMainConfig(), - $services->getContentLanguage() ); + return new SearchEngineConfig( + $services->getMainConfig(), + $services->getContentLanguage(), + ExtensionRegistry::getInstance()->getAttribute( 'SearchMappings' ) + ); }, 'SearchEngineFactory' => function ( MediaWikiServices $services ) : SearchEngineFactory { diff --git a/includes/registration/ExtensionProcessor.php b/includes/registration/ExtensionProcessor.php index ea8ea216fef2..36dc32806084 100644 --- a/includes/registration/ExtensionProcessor.php +++ b/includes/registration/ExtensionProcessor.php @@ -131,6 +131,7 @@ class ExtensionProcessor implements Processor { 'type', 'config', 'config_prefix', + 'SearchMappings', 'ServiceWiringFiles', 'ParserTestFiles', 'AutoloadClasses', diff --git a/includes/search/SearchEngineConfig.php b/includes/search/SearchEngineConfig.php index d79028c7b997..507006288a81 100644 --- a/includes/search/SearchEngineConfig.php +++ b/includes/search/SearchEngineConfig.php @@ -20,9 +20,20 @@ class SearchEngineConfig { */ private $language; - public function __construct( Config $config, Language $lang ) { + /** + * Search Engine Mappings + * + * Key is the canonical name (used in $wgSearchType and $wgSearchTypeAlternatives). + * Value is a specification for ObjectFactory. + * + * @var array + */ + private $engineMappings; + + public function __construct( Config $config, Language $lang, array $mappings ) { $this->config = $config; $this->language = $lang; + $this->engineMappings = $mappings; } /** @@ -100,6 +111,30 @@ class SearchEngineConfig { } /** + * Returns the mappings between canonical search name and underlying PHP class + * + * Key is the canonical name (used in $wgSearchType and $wgSearchTypeAlternatives). + * Value is a specification for ObjectFactory. + * + * For example to be able to use 'foobarsearch' in $wgSearchType and + * $wgSearchTypeAlternatives but the PHP class for 'foobarsearch' + * is 'MediaWiki\Extensions\FoobarSearch\FoobarSearch' set: + * + * @par extension.json Example: + * @code + * 'SearchMappings': { + * 'foobarsearch': { 'class': 'MediaWiki\\Extensions\\FoobarSearch\\FoobarSearch' } + * } + * @endcode + * + * @since 1.35 + * @return array + */ + public function getSearchMappings() { + return $this->engineMappings; + } + + /** * Get a list of namespace names useful for showing in tooltips * and preferences. * diff --git a/includes/search/SearchEngineFactory.php b/includes/search/SearchEngineFactory.php index bd53fc6b1e21..2e3223809313 100644 --- a/includes/search/SearchEngineFactory.php +++ b/includes/search/SearchEngineFactory.php @@ -1,6 +1,7 @@ <?php use MediaWiki\MediaWikiServices; +use Wikimedia\ObjectFactory; use Wikimedia\Rdbms\IDatabase; use Wikimedia\Rdbms\ILoadBalancer; @@ -21,6 +22,7 @@ class SearchEngineFactory { /** * Create SearchEngine of the given type. + * * @param string|null $type * @return SearchEngine */ @@ -37,11 +39,22 @@ class SearchEngineFactory { $class = self::getSearchEngineClass( $lb ); } - if ( is_subclass_of( $class, SearchDatabase::class ) ) { - return new $class( $lb ); + $mappings = $this->config->getSearchMappings(); + + if ( isset( $mappings[$class] ) ) { + $spec = $mappings[$class]; } else { - return new $class(); + // Convert non mapped classes to ObjectFactory spec + $spec = [ 'class' => $class ]; } + + $args = []; + + if ( isset( $spec['class'] ) && is_subclass_of( $spec['class'], SearchDatabase::class ) ) { + $args['extraArgs'][] = $lb; + } + + return ObjectFactory::getObjectFromSpec( $spec, $args ); } /** diff --git a/tests/phpunit/unit/includes/Rest/Handler/SearchHandlerTest.php b/tests/phpunit/unit/includes/Rest/Handler/SearchHandlerTest.php index cc690e6ef810..865e7b63bda5 100644 --- a/tests/phpunit/unit/includes/Rest/Handler/SearchHandlerTest.php +++ b/tests/phpunit/unit/includes/Rest/Handler/SearchHandlerTest.php @@ -56,7 +56,7 @@ class SearchHandlerTest extends \MediaWikiUnitTestCase { /** @var Language|MockObject $language */ $language = $this->createNoOpMock( Language::class ); - $searchEngineConfig = new \SearchEngineConfig( $config, $language ); + $searchEngineConfig = new \SearchEngineConfig( $config, $language, [] ); /** @var PermissionManager|MockObject $permissionManager */ $permissionManager = $this->createNoOpMock( |