X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fapi%2FSearchApi.php;h=fb9c4e67d9286ccb5900500e47907b437d049c0f;hb=531ed101ccd14dc7e2cf2858a67b2523ef6a79ff;hp=139793d12b2b6eec9de7f453ca6b8db88c0f1eb3;hpb=e5facc46bc170c302438f60849041b0d6be75e82;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/api/SearchApi.php b/includes/api/SearchApi.php index 139793d12b..fb9c4e67d9 100644 --- a/includes/api/SearchApi.php +++ b/includes/api/SearchApi.php @@ -26,26 +26,90 @@ use MediaWiki\MediaWikiServices; * @ingroup API */ trait SearchApi { + + /** + * When $wgSearchType is null, $wgSearchAlternatives[0] is null. Null isn't + * a valid option for an array for PARAM_TYPE, so we'll use a fake name + * that can't possibly be a class name and describes what the null behavior + * does + */ + private static $BACKEND_NULL_PARAM = 'database-backed'; + /** - * Build the profile api param definitions. + * The set of api parameters that are shared between api calls that + * call the SearchEngine. Primarily this defines parameters that + * are utilized by self::buildSearchEngine(). * - * @param string $profileType type of profile to customize - * @param string $helpMsg i18n message - * @param string|null $backendType SearchEngine backend type or null for default engine - * @return array|null the api param definition or null if profiles are - * not supported by the searchEngine implementation. + * @param bool $isScrollable True if the api offers scrolling + * @return array */ - public function buildProfileApiParam( $profileType, $helpMsg, $backendType = null ) { - $searchEngine = null; - if ( $backendType !== null ) { - $searchEngine = MediaWikiServices::getInstance() - ->getSearchEngineFactory()->create( $backendType ); + public function buildCommonApiParams( $isScrollable = true ) { + $params = [ + 'search' => [ + ApiBase::PARAM_TYPE => 'string', + ApiBase::PARAM_REQUIRED => true, + ], + 'namespace' => [ + ApiBase::PARAM_DFLT => NS_MAIN, + ApiBase::PARAM_TYPE => 'namespace', + ApiBase::PARAM_ISMULTI => true, + ], + 'limit' => [ + ApiBase::PARAM_DFLT => 10, + ApiBase::PARAM_TYPE => 'limit', + ApiBase::PARAM_MIN => 1, + ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1, + ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2, + ], + ]; + if ( $isScrollable ) { + $params['offset'] = [ + ApiBase::PARAM_DFLT => 0, + ApiBase::PARAM_TYPE => 'integer', + ApiBase::PARAM_HELP_MSG => 'api-help-param-continue', + ]; + } + + $searchConfig = MediaWikiServices::getInstance()->getSearchEngineConfig(); + $alternatives = $searchConfig->getSearchTypes(); + if ( count( $alternatives ) > 1 ) { + if ( $alternatives[0] === null ) { + $alternatives[0] = self::$BACKEND_NULL_PARAM; + } + $this->allowedParams['backend'] = [ + ApiBase::PARAM_DFLT => $searchConfig->getSearchType(), + ApiBase::PARAM_TYPE => $alternatives, + ]; + // @todo: support profile selection when multiple + // backends are available. The solution could be to + // merge all possible profiles and let ApiBase + // subclasses do the check. Making ApiHelp and ApiSandbox + // comprehensive might be more difficult. } else { - $searchEngine = MediaWikiServices::getInstance()->newSearchEngine(); + $params += $this->buildProfileApiParam(); } - $profiles = $searchEngine->getProfiles( $profileType ); - if ( $profiles ) { + return $params; + } + + /** + * Build the profile api param definitions. Makes bold assumption only one search + * engine is available, ensure that is true before calling. + * + * @return array array containing available additional api param definitions. + * Empty if profiles are not supported by the searchEngine implementation. + */ + private function buildProfileApiParam() { + $configs = $this->getSearchProfileParams(); + $searchEngine = MediaWikiServices::getInstance()->newSearchEngine(); + $params = []; + foreach ( $configs as $paramName => $paramConfig ) { + $profiles = $searchEngine->getProfiles( $paramConfig['profile-type'], + $this->getContext()->getUser() ); + if ( !$profiles ) { + continue; + } + $types = []; $helpMessages = []; $defaultProfile = null; @@ -58,20 +122,23 @@ trait SearchApi { $defaultProfile = $profile['name']; } } - return [ + + $params[$paramName] = [ ApiBase::PARAM_TYPE => $types, - ApiBase::PARAM_HELP_MSG => $helpMsg, + ApiBase::PARAM_HELP_MSG => $paramConfig['help-message'], ApiBase::PARAM_HELP_MSG_PER_VALUE => $helpMessages, ApiBase::PARAM_DFLT => $defaultProfile, ]; } - return null; + + return $params; } /** * Build the search engine to use. * If $params is provided then the following searchEngine options * will be set: + * - backend: which search backend to use * - limit: mandatory * - offset: optional, if set limit will be incremented by * one ( to support the continue parameter ) @@ -84,6 +151,9 @@ trait SearchApi { public function buildSearchEngine( array $params = null ) { if ( $params != null ) { $type = isset( $params['backend'] ) ? $params['backend'] : null; + if ( $type === self::$BACKEND_NULL_PARAM ) { + $type = null; + } $searchEngine = MediaWikiServices::getInstance()->getSearchEngineFactory()->create( $type ); $limit = $params['limit']; $searchEngine->setNamespaces( $params['namespace'] ); @@ -97,9 +167,15 @@ trait SearchApi { $limit += 1; } $searchEngine->setLimitOffset( $limit, $offset ); - foreach ( $this->getSearchProfileParams() as $type => $param ) { - if ( isset( $params[$param] ) ) { - $searchEngine->setFeatureData( $type, $params[$param] ); + + // Initialize requested search profiles. + $configs = $this->getSearchProfileParams(); + foreach ( $configs as $paramName => $paramConfig ) { + if ( isset( $params[$paramName] ) ) { + $searchEngine->setFeatureData( + $paramConfig['profile-type'], + $params[$paramName] + ); } } } else { @@ -109,8 +185,13 @@ trait SearchApi { } /** - * @return string[] the list of supported search profile types. Key is - * the profile type and its associated value is the request param. + * @return array[] array of arrays mapping from parameter name to a two value map + * containing 'help-message' and 'profile-type' keys. */ abstract public function getSearchProfileParams(); + + /** + * @return IContextSource + */ + abstract public function getContext(); }