From: Brad Jorsch Date: Thu, 2 Jul 2015 16:21:58 +0000 (-0400) Subject: Improve serialization of Message, Title X-Git-Tag: 1.31.0-rc.0~10745^2 X-Git-Url: https://git.cyclocoop.org/%7B%7B%20url_for%28%27static%27%2C%20filename=%27css/bootstrap.css%27%29%20%7D%7D?a=commitdiff_plain;h=7782819d647bd23eb9680736806213fe3600833f;p=lhc%2Fweb%2Fwiklou.git Improve serialization of Message, Title This allows them to be stored in the session, for example. Note that properly serializing a Message requires that all its parameters be serializable as well; we don't attempt to account for that here. Change-Id: I3a42a2a883e8eef900eeb02355fc3b064411f642 --- diff --git a/includes/Message.php b/includes/Message.php index 329d97afac..ee41db0097 100644 --- a/includes/Message.php +++ b/includes/Message.php @@ -156,7 +156,7 @@ * * @since 1.17 */ -class Message implements MessageSpecifier { +class Message implements MessageSpecifier, Serializable { /** * In which language to get this message. True, which is the default, @@ -252,6 +252,41 @@ class Message implements MessageSpecifier { $this->language = $language ?: $wgLang; } + /** + * @see Serializable::serialize() + * @since 1.26 + * @return string + */ + public function serialize() { + return serialize( array( + 'interface' => $this->interface, + 'language' => $this->language->getCode(), + 'key' => $this->key, + 'keysToTry' => $this->keysToTry, + 'parameters' => $this->parameters, + 'format' => $this->format, + 'useDatabase' => $this->useDatabase, + 'title' => $this->title, + ) ); + } + + /** + * @see Serializable::unserialize() + * @since 1.26 + * @param string $serialized + */ + public function unserialize( $serialized ) { + $data = unserialize( $serialized ); + $this->interface = $data['interface']; + $this->key = $data['key']; + $this->keysToTry = $data['keysToTry']; + $this->parameters = $data['parameters']; + $this->format = $data['format']; + $this->useDatabase = $data['useDatabase']; + $this->language = Language::factory( $data['language'] ); + $this->title = $data['title']; + } + /** * @since 1.24 * diff --git a/includes/Title.php b/includes/Title.php index 9c8ed477e6..902d58f6b5 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -4759,4 +4759,26 @@ class Title { Hooks::run( 'TitleGetEditNotices', array( $this, $oldid, &$notices ) ); return $notices; } + + /** + * @return array + */ + public function __sleep() { + return array( + 'mNamespace', + 'mDbkeyform', + 'mFragment', + 'mInterwiki', + 'mLocalInterwiki', + 'mUserCaseDBKey', + 'mDefaultNamespace', + ); + } + + public function __wakeup() { + $this->mArticleID = ( $this->mNamespace >= 0 ) ? -1 : 0; + $this->mUrlform = wfUrlencode( $this->mDbkeyform ); + $this->mTextform = strtr( $this->mDbkeyform, '_', ' ' ); + } + } diff --git a/includes/api/ApiMessage.php b/includes/api/ApiMessage.php index 6717c390bb..db826a68a6 100644 --- a/includes/api/ApiMessage.php +++ b/includes/api/ApiMessage.php @@ -132,6 +132,21 @@ class ApiMessage extends Message implements IApiMessage { public function setApiData( array $data ) { $this->apiData = $data; } + + public function serialize() { + return serialize( array( + 'parent' => parent::serialize(), + 'apiCode' => $this->apiCode, + 'apiData' => $this->apiData, + ) ); + } + + public function unserialize( $serialized ) { + $data = unserialize( $serialized ); + parent::unserialize( $data['parent'] ); + $this->apiCode = $data['apiCode']; + $this->apiData = $data['apiData']; + } } /** @@ -188,4 +203,19 @@ class ApiRawMessage extends RawMessage implements IApiMessage { public function setApiData( array $data ) { $this->apiData = $data; } + + public function serialize() { + return serialize( array( + 'parent' => parent::serialize(), + 'apiCode' => $this->apiCode, + 'apiData' => $this->apiData, + ) ); + } + + public function unserialize( $serialized ) { + $data = unserialize( $serialized ); + parent::unserialize( $data['parent'] ); + $this->apiCode = $data['apiCode']; + $this->apiData = $data['apiData']; + } } diff --git a/tests/phpunit/includes/MessageTest.php b/tests/phpunit/includes/MessageTest.php index 99ec2e4255..cf08dbe526 100644 --- a/tests/phpunit/includes/MessageTest.php +++ b/tests/phpunit/includes/MessageTest.php @@ -548,4 +548,26 @@ class MessageTest extends MediaWikiLangTestCase { public function testInLanguageThrows() { wfMessage( 'foo' )->inLanguage( 123 ); } + + /** + * @covers Message::serialize + * @covers Message::unserialize + */ + public function testSerialization() { + $msg = new Message( 'parentheses' ); + $msg->rawParams( 'foo' ); + $msg->title( Title::newFromText( 'Testing' ) ); + $this->assertEquals( '(foo)', $msg->parse(), 'Sanity check' ); + $msg = unserialize( serialize( $msg ) ); + $this->assertEquals( '(foo)', $msg->parse() ); + $title = TestingAccessWrapper::newFromObject( $msg )->title; + $this->assertInstanceOf( 'Title', $title ); + $this->assertEquals( 'Testing', $title->getFullText() ); + + $msg = new Message( 'mainpage' ); + $msg->inLanguage( 'de' ); + $this->assertEquals( 'Hauptseite', $msg->plain(), 'Sanity check' ); + $msg = unserialize( serialize( $msg ) ); + $this->assertEquals( 'Hauptseite', $msg->plain() ); + } } diff --git a/tests/phpunit/includes/api/ApiMessageTest.php b/tests/phpunit/includes/api/ApiMessageTest.php index 6c3ce60d18..08a984eb25 100644 --- a/tests/phpunit/includes/api/ApiMessageTest.php +++ b/tests/phpunit/includes/api/ApiMessageTest.php @@ -14,9 +14,13 @@ class ApiMessageTest extends MediaWikiTestCase { $msg = TestingAccessWrapper::newFromObject( $msg ); $msg2 = TestingAccessWrapper::newFromObject( $msg2 ); - foreach ( array( 'interface', 'useDatabase', 'title' ) as $key ) { - $this->assertSame( $msg->$key, $msg2->$key, $key ); - } + $this->assertSame( $msg->interface, $msg2->interface, 'interface' ); + $this->assertSame( $msg->useDatabase, $msg2->useDatabase, 'useDatabase' ); + $this->assertSame( + $msg->title ? $msg->title->getFullText() : null, + $msg2->title ? $msg2->title->getFullText() : null, + 'title' + ); } /** @@ -30,6 +34,11 @@ class ApiMessageTest extends MediaWikiTestCase { $this->assertEquals( 'code', $msg2->getApiCode() ); $this->assertEquals( array( 'data' ), $msg2->getApiData() ); + $msg2 = unserialize( serialize( $msg2 ) ); + $this->compareMessages( $msg, $msg2 ); + $this->assertEquals( 'code', $msg2->getApiCode() ); + $this->assertEquals( array( 'data' ), $msg2->getApiData() ); + $msg = new Message( array( 'foo', 'bar' ), array( 'baz' ) ); $msg2 = new ApiMessage( array( array( 'foo', 'bar' ), 'baz' ), 'code', array( 'data' ) ); $this->compareMessages( $msg, $msg2 ); @@ -63,6 +72,11 @@ class ApiMessageTest extends MediaWikiTestCase { $this->assertEquals( 'code', $msg2->getApiCode() ); $this->assertEquals( array( 'data' ), $msg2->getApiData() ); + $msg2 = unserialize( serialize( $msg2 ) ); + $this->compareMessages( $msg, $msg2 ); + $this->assertEquals( 'code', $msg2->getApiCode() ); + $this->assertEquals( array( 'data' ), $msg2->getApiData() ); + $msg = new RawMessage( 'foo', array( 'baz' ) ); $msg2 = new ApiRawMessage( array( 'foo', 'baz' ), 'code', array( 'data' ) ); $this->compareMessages( $msg, $msg2 );