From 307eee22b6cfc8354e9fb746a3fb9cfe9c9dc041 Mon Sep 17 00:00:00 2001 From: Alexandre Emsenhuber Date: Thu, 1 Nov 2012 22:07:37 +0100 Subject: [PATCH] (bug 41337) Fix fatal error in Special:Preferences The error is Fatal error: Call to a member function msg() on a non-object at includes/Preferences.php on line 1207. The problem is that fields created in Preferences::getPreferences() for validation don't have their parent set and thus an error occurs when the validation fails since they want to use their parent to get a Message object. This commit adds a dummy parent object to these fields to fix the error. bug: 41337 Change-Id: I5826d6e3f1262c8d26af0cfe7074a939f80bcaca --- includes/Preferences.php | 4 ++ .../specials/SpecialPreferencesTest.php | 60 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 tests/phpunit/includes/specials/SpecialPreferencesTest.php diff --git a/includes/Preferences.php b/includes/Preferences.php index bb386f2a4c..d83f43ad89 100644 --- a/includes/Preferences.php +++ b/includes/Preferences.php @@ -90,10 +90,14 @@ class Preferences { } } + ## Make sure that form fields have their parent set. See bug 41337. + $dummyForm = new HTMLForm( array(), $context ); + ## Prod in defaults from the user foreach ( $defaultPreferences as $name => &$info ) { $prefFromUser = self::getOptionFromUser( $name, $info, $user ); $field = HTMLForm::loadInputFromParameters( $name, $info ); // For validation + $field->mParent = $dummyForm; $defaultOptions = User::getDefaultOptions(); $globalDefault = isset( $defaultOptions[$name] ) ? $defaultOptions[$name] diff --git a/tests/phpunit/includes/specials/SpecialPreferencesTest.php b/tests/phpunit/includes/specials/SpecialPreferencesTest.php new file mode 100644 index 0000000000..d4bba61599 --- /dev/null +++ b/tests/phpunit/includes/specials/SpecialPreferencesTest.php @@ -0,0 +1,60 @@ +setMwGlobals( 'wgMaxSigChars', 2 ); + + $user = $this->getMock( 'User' ); + $user->expects( $this->any() ) + ->method('isAnon') + ->will( $this->returnValue(false) ); + + # Yeah foreach requires an array, not NULL =( + $user->expects( $this->any() ) + ->method('getEffectiveGroups') + ->will( $this->returnValue( array() ) ); + + # The mocked user has a long nickname + $user->expects( $this->any() ) + ->method('getOption') + ->will( $this->returnValueMap( array( + array( 'nickname', null, false, 'superlongnickname' ), + ) + ) ); + + # Validate the mock (FIXME should probably be removed) + $this->assertFalse( $user->isAnon() ); + $this->assertEquals( array(), + $user->getEffectiveGroups() ); + $this->assertEquals( 'superlongnickname', + $user->getOption( 'nickname' ) ); + + # Forge a request to call the special page + $context = new RequestContext(); + $context->setRequest( new FauxRequest() ); + $context->setUser( $user ); + $context->setTitle( Title::newFromText( 'Test' ) ); + + # Do the call, should not spurt a fatal error. + $special = new SpecialPreferences(); + $special->setContext( $context ); + $special->execute( array() ); + } + +} -- 2.20.1