feature(Popups): Conditional User Defaults Implementation

Implement conditional defaults for user preferences in the Popups
component.
This patch aims to simplify the preference management system by
leveraging conditional logic directly within the component rather
than relying on multiple hooks

Changes:
- Updated `extension.json` to reflect the removal of outdated hooks.
- Updated `extension.json` to reflect the conditional user defaults.
- Removed unused user option `popupsreferencepreviews` from
 `extension.json`
- Modified `PopupsHooks` to streamline the preferences management,
 and depend on conditional user defaults, and removing `onUserGetDefaultOptions` and `onLocalUserCreated` hooks.
- Removed unneeded test cases in `PopupsHooksTest`.

Bug: T364347
Change-Id: Iae454e4b4704a0289ca0a2b0794730562fda0dd1
This commit is contained in:
Moh'd Khier Abualruz 2024-05-22 14:17:55 +02:00 committed by Mabualruz
parent f3f397e252
commit a75ddc4173
3 changed files with 35 additions and 111 deletions

View file

@ -22,9 +22,7 @@
"BeforePageDisplay": "PopupsHooks", "BeforePageDisplay": "PopupsHooks",
"ResourceLoaderGetConfigVars": "PopupsHooks", "ResourceLoaderGetConfigVars": "PopupsHooks",
"GetPreferences": "PopupsHooks", "GetPreferences": "PopupsHooks",
"UserGetDefaultOptions": "PopupsHooks", "MakeGlobalVariablesScript": "PopupsHooks"
"MakeGlobalVariablesScript": "PopupsHooks",
"LocalUserCreated": "PopupsHooks"
}, },
"HookHandlers": { "HookHandlers": {
"PopupsHooks": { "PopupsHooks": {
@ -63,10 +61,6 @@
"description": "@var string:['1'|'0'] Default Page Previews visibility for old accounts. Has to be a string as a compatibility with beta feature settings. For more info see @T191888", "description": "@var string:['1'|'0'] Default Page Previews visibility for old accounts. Has to be a string as a compatibility with beta feature settings. For more info see @T191888",
"value": "1" "value": "1"
}, },
"PopupsOptInStateForNewAccounts": {
"description": "@var string:['1'|'0'] Default Page Previews visibility for newly created accounts (from Q2 2018). For more info see @T191888",
"value": "1"
},
"PopupsConflictingNavPopupsGadgetName": { "PopupsConflictingNavPopupsGadgetName": {
"description": "@var string: Navigation popups gadget name", "description": "@var string: Navigation popups gadget name",
"value": "Navigation_popups" "value": "Navigation_popups"
@ -214,8 +208,41 @@
"includes/ServiceWiring.php" "includes/ServiceWiring.php"
], ],
"DefaultUserOptions": { "DefaultUserOptions": {
"popups": 1,
"popupsreferencepreviews": 0, "popupsreferencepreviews": 0,
"popups-reference-previews": 0 "popups-reference-previews": 0
}, },
"ConditionalUserOptions": {
"popups": [
[
1,
[
"registered-after",
"20170816000000"
]
],
[
0,
[
"named-user"
]
]
],
"popups-reference-previews": [
[
1,
[
"registered-after",
"20170816000000"
]
],
[
0,
[
"named-user"
]
]
]
},
"manifest_version": 2 "manifest_version": 2
} }

View file

@ -21,14 +21,12 @@
namespace Popups; namespace Popups;
use ExtensionRegistry; use ExtensionRegistry;
use MediaWiki\Auth\Hook\LocalUserCreatedHook;
use MediaWiki\Config\Config; use MediaWiki\Config\Config;
use MediaWiki\Hook\BeforePageDisplayHook; use MediaWiki\Hook\BeforePageDisplayHook;
use MediaWiki\Hook\MakeGlobalVariablesScriptHook; use MediaWiki\Hook\MakeGlobalVariablesScriptHook;
use MediaWiki\Output\OutputPage; use MediaWiki\Output\OutputPage;
use MediaWiki\Preferences\Hook\GetPreferencesHook; use MediaWiki\Preferences\Hook\GetPreferencesHook;
use MediaWiki\ResourceLoader\Hook\ResourceLoaderGetConfigVarsHook; use MediaWiki\ResourceLoader\Hook\ResourceLoaderGetConfigVarsHook;
use MediaWiki\User\Hook\UserGetDefaultOptionsHook;
use MediaWiki\User\Options\UserOptionsManager; use MediaWiki\User\Options\UserOptionsManager;
use MediaWiki\User\User; use MediaWiki\User\User;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
@ -43,9 +41,7 @@ class PopupsHooks implements
GetPreferencesHook, GetPreferencesHook,
BeforePageDisplayHook, BeforePageDisplayHook,
ResourceLoaderGetConfigVarsHook, ResourceLoaderGetConfigVarsHook,
MakeGlobalVariablesScriptHook, MakeGlobalVariablesScriptHook
UserGetDefaultOptionsHook,
LocalUserCreatedHook
{ {
private const PREVIEWS_PREFERENCES_SECTION = 'rendering/reading'; private const PREVIEWS_PREFERENCES_SECTION = 'rendering/reading';
@ -245,41 +241,4 @@ class PopupsHooks implements
public function onMakeGlobalVariablesScript( &$vars, $out ): void { public function onMakeGlobalVariablesScript( &$vars, $out ): void {
$vars['wgPopupsFlags'] = $this->popupsContext->getConfigBitmaskFromUser( $out->getUser() ); $vars['wgPopupsFlags'] = $this->popupsContext->getConfigBitmaskFromUser( $out->getUser() );
} }
/**
* Called whenever a user wants to reset their preferences.
*
* @param array &$defaultOptions
*/
public function onUserGetDefaultOptions( &$defaultOptions ) {
$default = $this->config->get( 'PopupsOptInDefaultState' );
$defaultOptions[PopupsContext::PREVIEWS_OPTIN_PREFERENCE_NAME] = $default;
if ( $this->config->get( 'PopupsReferencePreviews' ) ) {
$defaultOptions[PopupsContext::REFERENCE_PREVIEWS_PREFERENCE_NAME] = '1';
}
}
/**
* Called one time when initializing a users preferences for a newly created account.
*
* @param User $user Newly created user object
* @param bool $isAutoCreated
*/
public function onLocalUserCreated( $user, $isAutoCreated ) {
$default = $this->config->get( 'PopupsOptInStateForNewAccounts' );
$this->userOptionsManager->setOption(
$user,
PopupsContext::PREVIEWS_OPTIN_PREFERENCE_NAME,
$default
);
if ( $this->config->get( 'PopupsReferencePreviews' ) ) {
$this->userOptionsManager->setOption(
$user,
PopupsContext::REFERENCE_PREVIEWS_PREFERENCE_NAME,
$default
);
}
}
} }

View file

@ -22,7 +22,6 @@
use MediaWiki\Config\HashConfig; use MediaWiki\Config\HashConfig;
use MediaWiki\Config\MultiConfig; use MediaWiki\Config\MultiConfig;
use MediaWiki\Output\OutputPage; use MediaWiki\Output\OutputPage;
use MediaWiki\User\Options\UserOptionsManager;
use MediaWiki\User\User; use MediaWiki\User\User;
use Popups\PopupsContext; use Popups\PopupsContext;
use Popups\PopupsHooks; use Popups\PopupsHooks;
@ -316,67 +315,6 @@ class PopupsHooksTest extends MediaWikiIntegrationTestCase {
'The wgPopupsFlags global is present and 0.' ); 'The wgPopupsFlags global is present and 0.' );
} }
/**
* @covers ::onUserGetDefaultOptions
* @dataProvider provideReferencePreviewsFlag
*/
public function testOnUserGetDefaultOptions( bool $enabled ) {
$userOptions = [
'test' => 'not_empty'
];
( new PopupsHooks(
new HashConfig( [
'PopupsOptInDefaultState' => '1',
'PopupsReferencePreviews' => $enabled,
] ),
$this->getServiceContainer()->getService( 'Popups.Context' ),
$this->getServiceContainer()->getService( 'Popups.Logger' ),
$this->getServiceContainer()->getUserOptionsManager()
) )
->onUserGetDefaultOptions( $userOptions );
$this->assertCount( $enabled ? 3 : 2, $userOptions );
$this->assertSame( '1', $userOptions[ PopupsContext::PREVIEWS_OPTIN_PREFERENCE_NAME ] );
if ( $enabled ) {
$this->assertSame( '1', $userOptions[ PopupsContext::REFERENCE_PREVIEWS_PREFERENCE_NAME ] );
}
}
/**
* @covers ::onUserGetDefaultOptions
* @dataProvider provideReferencePreviewsFlag
*/
public function testOnLocalUserCreatedForNewlyCreatedUser( bool $enabled ) {
$expectedState = '1';
$userMock = $this->createMock( User::class );
$userOptionsManagerMock = $this->createMock( UserOptionsManager::class );
$expectedOptions = [
'popups' => $expectedState,
'popups-reference-previews' => $expectedState
];
$userOptionsManagerMock->expects( $this->exactly( $enabled ? 2 : 1 ) )
->method( 'setOption' )
->willReturnCallback( function ( $user, $option, $val ) use ( &$expectedOptions, $userMock ) {
$this->assertSame( $userMock, $user );
$this->assertArrayHasKey( $option, $expectedOptions );
$this->assertSame( $expectedOptions[$option], $val );
unset( $expectedOptions[$option] );
} );
( new PopupsHooks(
new HashConfig( [
'PopupsOptInStateForNewAccounts' => $expectedState,
'PopupsReferencePreviews' => $enabled,
] ),
$this->getServiceContainer()->getService( 'Popups.Context' ),
$this->getServiceContainer()->getService( 'Popups.Logger' ),
$userOptionsManagerMock
) )
->onLocalUserCreated( $userMock, false );
}
public static function provideReferencePreviewsFlag() { public static function provideReferencePreviewsFlag() {
return [ return [
[ false ], [ false ],