Add preference to control Special:Search thumbnails

Bug: T320337
Change-Id: I828dcd3679a4869b3b58b05d7cdca6c9f8a45d3e
This commit is contained in:
Matthias Mullie 2022-10-14 14:37:35 +02:00
parent ad1a2be374
commit ea6c1ceebb
8 changed files with 69 additions and 7 deletions

View file

@ -53,6 +53,8 @@ For notes on 1.39.x and older releases, see HISTORY.
=== New user-facing features in 1.40 ===
* Ability to show thumbnails (provided via onSearchResultProvideThumbnail
hook) for more than NS_FILE titles in Special:Search results.
* New preference ('search-thumbnail-extra-namespaces') to allow users to
control whether to show more thumbnails (per $wgThumbnailNamespaces)
* …
=== New developer features in 1.40 ===

View file

@ -1485,7 +1485,8 @@ return [
$services->getParser(),
$services->getSkinFactory(),
$services->getUserGroupManager(),
$services->getSignatureValidatorFactory()
$services->getSignatureValidatorFactory(),
$services->getMainConfig()
);
$factory->setLogger( LoggerFactory::getInstance( 'preferences' ) );

View file

@ -20,6 +20,7 @@
namespace MediaWiki\Preferences;
use Config;
use Html;
use HTMLForm;
use HTMLFormField;
@ -113,6 +114,9 @@ class DefaultPreferencesFactory implements PreferencesFactory {
/** @var SignatureValidatorFactory */
private $signatureValidatorFactory;
/** @var Config */
private $config;
/**
* @internal For use by ServiceWiring
*/
@ -163,6 +167,7 @@ class DefaultPreferencesFactory implements PreferencesFactory {
* @param SkinFactory|null $skinFactory
* @param UserGroupManager|null $userGroupManager
* @param SignatureValidatorFactory|null $signatureValidatorFactory
* @param Config|null $config
*/
public function __construct(
ServiceOptions $options,
@ -179,7 +184,8 @@ class DefaultPreferencesFactory implements PreferencesFactory {
Parser $parser = null,
SkinFactory $skinFactory = null,
UserGroupManager $userGroupManager = null,
SignatureValidatorFactory $signatureValidatorFactory = null
SignatureValidatorFactory $signatureValidatorFactory = null,
Config $config = null
) {
$options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
@ -215,6 +221,7 @@ class DefaultPreferencesFactory implements PreferencesFactory {
$this->userGroupManager = $userGroupManager ?? $services()->getUserGroupManager();
$this->signatureValidatorFactory = $signatureValidatorFactory
?? $services()->getSignatureValidatorFactory();
$this->config = $config ?? $services()->getMainConfig();
}
/**
@ -1483,6 +1490,37 @@ class DefaultPreferencesFactory implements PreferencesFactory {
'help-message' => $context->msg( 'searchlimit-help', 500 ),
'filter' => IntvalFilter::class,
];
// show a preference for thumbnails from namespaces other than NS_FILE,
// only when there they're actually configured to be served
$thumbNamespaces = $this->config->get( 'ThumbnailNamespaces' );
$thumbNamespacesFormatted = array_combine(
$thumbNamespaces,
array_map(
static function ( $namespaceId ) use ( $context ) {
return $namespaceId === NS_MAIN
? $context->msg( 'blanknamespace' )->escaped()
: $context->getLanguage()->getFormattedNsText( $namespaceId );
},
$thumbNamespaces
)
);
$defaultThumbNamespacesFormatted = (array)array_intersect_key( $thumbNamespacesFormatted, [ NS_FILE => 1 ] );
$extraThumbNamespacesFormatted = (array)array_diff_key( $thumbNamespacesFormatted, [ NS_FILE => 1 ] );
if ( $extraThumbNamespacesFormatted ) {
$defaultPreferences['search-thumbnail-extra-namespaces'] = [
'type' => 'toggle',
'section' => 'searchoptions/searchmisc',
'label-message' => 'search-thumbnail-extra-namespaces-label',
'help-message' => $context->msg(
'search-thumbnail-extra-namespaces-message',
$context->getLanguage()->listToText( $extraThumbNamespacesFormatted ),
count( $extraThumbNamespacesFormatted ),
$context->getLanguage()->listToText( $defaultThumbNamespacesFormatted ),
count( $defaultThumbNamespacesFormatted )
),
];
}
}
/*
@ -1562,8 +1600,7 @@ class DefaultPreferencesFactory implements PreferencesFactory {
}
}
$preferredSkins = MediaWikiServices::getInstance()->getMainConfig()->get(
MainConfigNames::SkinsPreferred );
$preferredSkins = $this->config->get( MainConfigNames::SkinsPreferred );
// Sort by the internal name, so that the ordering is the same for each display language,
// especially if some skin names are translated to use a different alphabet and some are not.
uksort( $validSkinNames, function ( $a, $b ) use ( $currentUserSkin, $preferredSkins ) {

View file

@ -12,6 +12,7 @@ use MediaWiki\HookContainer\HookRunner;
use MediaWiki\Linker\LinkRenderer;
use MediaWiki\Search\Entity\SearchResultThumbnail;
use MediaWiki\Search\SearchResultThumbnailProvider;
use MediaWiki\User\UserOptionsManager;
use RepoGroup;
use SearchResult;
use SpecialSearch;
@ -40,19 +41,23 @@ class FullSearchResultWidget implements SearchResultWidget {
private $thumbnailProvider;
/** @var string */
private $thumbnailPlaceholderHtml;
/** @var UserOptionsManager */
private $userOptionsManager;
public function __construct(
SpecialSearch $specialPage,
LinkRenderer $linkRenderer,
HookContainer $hookContainer,
RepoGroup $repoGroup,
SearchResultThumbnailProvider $thumbnailProvider
SearchResultThumbnailProvider $thumbnailProvider,
UserOptionsManager $userOptionsManager
) {
$this->specialPage = $specialPage;
$this->linkRenderer = $linkRenderer;
$this->hookRunner = new HookRunner( $hookContainer );
$this->repoGroup = $repoGroup;
$this->thumbnailProvider = $thumbnailProvider;
$this->userOptionsManager = $userOptionsManager;
}
/**
@ -293,6 +298,16 @@ class FullSearchResultWidget implements SearchResultWidget {
);
}
$allowExtraThumbsFromRequest = $this->specialPage->getRequest()->getVal( 'search-thumbnail-extra-namespaces' );
$allowExtraThumbsFromPreference = $this->userOptionsManager->getOption(
$this->specialPage->getUser(),
'search-thumbnail-extra-namespaces'
);
$allowExtraThumbs = (bool)( $allowExtraThumbsFromRequest ?? $allowExtraThumbsFromPreference );
if ( !$allowExtraThumbs && $title->getNamespace() !== NS_FILE ) {
return [ $html, null, null ];
}
$thumbnail = $this->getThumbnail( $result, self::THUMBNAIL_SIZE );
$thumbnailName = $thumbnail ? $thumbnail->getName() : null;
if ( !$thumbnailName ) {

View file

@ -558,7 +558,8 @@ class SpecialSearch extends SpecialPage {
$linkRenderer,
$this->getHookContainer(),
$this->repoGroup,
$this->thumbnailProvider
$this->thumbnailProvider,
$this->userOptionsManager
);
// Default (null) on. Can be explicitly disabled.

View file

@ -4108,6 +4108,8 @@
"searchsuggest-containing": "Search for pages containing",
"search-match-redirect-label": "Redirect to exact matches when searching",
"search-match-redirect-help": "Select to get redirected to a page when that page title matches what you have searched for",
"search-thumbnail-extra-namespaces-label": "Show thumbnails in Special:Search",
"search-thumbnail-extra-namespaces-message": "Also show thumbnails for $1 {{PLURAL:$2|namespace|namespaces}}. Thumbnails for $3 are always shown.",
"searchlimit-label": "Number of search results to show on each page:",
"searchlimit-help": "Maximum number: $1",
"api-clientside-error-noconnect": "Could not connect to the server. Make sure you have a working internet connection and try again.",

View file

@ -4349,6 +4349,8 @@
"searchsuggest-containing": "Label used in the special item of the search suggestions list which gives the user an option to perform a full text search for the term.",
"search-match-redirect-label": "Label for user preference to force redirect to a page during search if the page's title matches a search term",
"search-match-redirect-help": "Help text for user preference to force redirect to a page during search if the page's title matches a search term",
"search-thumbnail-extra-namespaces-label": "Label for user preference to enable thumbnails for additional namespaces",
"search-thumbnail-extra-namespaces-message": "Help text for user preference to enable thumbnails for additional namespaces. Parameters:\n* $1 - formatted list of extra namespaces for which thumbnails can be enabled\n* $2 - number of extra namespaces, used for PLURAL\n* $3 - formatted list of namespaces for which thumbnails are always displayed\n* $4 - number of default namespaces, used for PLURAL",
"searchlimit-label": "Used in [[Special:Preferences]], tab \"Search\".",
"searchlimit-help": "Shown as hint in [[Special:Preferences]], tab \"Search\".\nShown under [[Special:Preferences#mw-prefsection-lqt]]. $1 - The current maximum limit",
"api-clientside-error-noconnect": "Error shown when an API response fails to load due to a connection issue.",

View file

@ -98,6 +98,7 @@ class DefaultPreferencesFactoryTest extends \MediaWikiIntegrationTestCase {
$params[] = $this->createMock( SkinFactory::class );
$params[] = $this->createMock( UserGroupManager::class );
$params[] = $this->createMock( SignatureValidatorFactory::class );
$params[] = $this->createMock( Config::class );
$oldMwServices = MediaWikiServices::forceGlobalInstance(
$this->createNoOpMock( MediaWikiServices::class )
);
@ -166,7 +167,8 @@ class DefaultPreferencesFactoryTest extends \MediaWikiIntegrationTestCase {
$services->getParser(),
$services->getSkinFactory(),
$userGroupManager,
$services->getSignatureValidatorFactory()
$services->getSignatureValidatorFactory(),
$services->getMainConfig()
);
}