Better way for extensions to add to ParserOutput.

Extensions sometimes need to stash information in the ParserOutput
for later use. This change provides a clean way to do that.

Change-Id: I8bc571d13c9a70bb71430862c2ab679ff1947126
This commit is contained in:
daniel 2013-01-22 12:59:23 +01:00
parent 58b91e162b
commit 40cb62d558
2 changed files with 108 additions and 6 deletions

View file

@ -51,6 +51,7 @@ class ParserOutput extends CacheTime {
private $mIndexPolicy = ''; # 'index' or 'noindex'? Any other value will result in no change.
private $mAccessedOptions = array(); # List of ParserOptions (stored in the keys)
private $mSecondaryDataUpdates = array(); # List of DataUpdate, used to save info from the page somewhere else.
private $mExtensionData = array(); # extra data used by extensions
const EDITSECTION_REGEX = '#<(?:mw:)?editsection page="(.*?)" section="(.*?)"(?:/>|>(.*?)(</(?:mw:)?editsection>))#';
@ -370,15 +371,31 @@ class ParserOutput extends CacheTime {
* Wikimedia Commons.
* This is not actually implemented, yet but would be pretty cool.
*
* Do not use setProperty() to set a property which is only used in a
* context where the ParserOutput object itself is already available, for
* example a normal page view. There is no need to save such a property
* @note: Do not use setProperty() to set a property which is only used
* in a context where the ParserOutput object itself is already available,
* for example a normal page view. There is no need to save such a property
* in the database since it the text is already parsed. You can just hook
* OutputPageParserOutput and get your data out of the ParserOutput object.
*
* If you are writing an extension where you want to set
* a property in the parser which is used by an OutputPageParserOutput hook,
* just use a custom variable within the ParserOutput object:
* If you are writing an extension where you want to set a property in the
* parser which is used by an OutputPageParserOutput hook, you have to
* associate the extension data directly with the ParserOutput object.
* Since MediaWiki 1.21, you can use setExtensionData() to do this:
*
* @par Example:
* @code
* $parser->getOutput()->setExtensionData( 'my_ext_foo', '...' );
* @endcode
*
* And then later, in OutputPageParserOutput or similar:
*
* @par Example:
* @code
* $output->getExtensionData( 'my_ext_foo' );
* @endcode
*
* In MediaWiki 1.20 and older, you have to use a custom member variable
* within the ParserOutput object:
*
* @par Example:
* @code
@ -460,4 +477,72 @@ class ParserOutput extends CacheTime {
return array_merge( $this->mSecondaryDataUpdates, array( $linksUpdate ) );
}
/**
* Attaches arbitrary data to this ParserObject. This can be used to store some information in
* the ParserOutput object for later use during page output. The data will be cached along with
* the ParserOutput object, but unlike data set using setProperty(), it is not recorded in the
* database.
*
* This method is provided to overcome the unsafe practice of attaching extra information to a
* ParserObject by directly assigning member variables.
*
* To use setExtensionData() to pass extension information from a hook inside the parser to a
* hook in the page output, use this in the parser hook:
*
* @par Example:
* @code
* $parser->getOutput()->setExtensionData( 'my_ext_foo', '...' );
* @endcode
*
* And then later, in OutputPageParserOutput or similar:
*
* @par Example:
* @code
* $output->getExtensionData( 'my_ext_foo' );
* @endcode
*
* In MediaWiki 1.20 and older, you have to use a custom member variable
* within the ParserOutput object:
*
* @par Example:
* @code
* $parser->getOutput()->my_ext_foo = '...';
* @endcode
*
* @since 1.21
*
* @param string $key The key for accessing the data. Extensions should take care to avoid
* conflicts in naming keys. It is suggested to use the extension's name as a
* prefix.
*
* @param mixed $value The value to set. Setting a value to null is equivalent to removing
* the value.
*/
public function setExtensionData( $key, $value ) {
if ( $value === null ) {
unset( $this->mExtensionData[$key] );
} else {
$this->mExtensionData[$key] = $value;
}
}
/**
* Gets extensions data previously attached to this ParserOutput using setExtensionData().
* Typically, such data would be set while parsing the page, e.g. by a parser function.
*
* @since 1.21
*
* @param string $key The key to look up.
*
* @return mixed The value previously set for the given key using setExtensionData( $key ),
* or null if no value was set for this key.
*/
public function getExtensionData( $key ) {
if ( isset( $this->mExtensionData[$key] ) ) {
return $this->mExtensionData[$key];
}
return null;
}
}

View file

@ -35,4 +35,21 @@ class ParserOutputTest extends MediaWikiTestCase {
$this->assertEquals( $shouldMatch, ParserOutput::isLinkInternal( $server, $url ) );
}
public function testExtensionData() {
$po = new ParserOutput();
$po->setExtensionData( "one", "Foo" );
$this->assertEquals( "Foo", $po->getExtensionData( "one" ) );
$this->assertNull( $po->getExtensionData( "spam" ) );
$po->setExtensionData( "two", "Bar" );
$this->assertEquals( "Foo", $po->getExtensionData( "one" ) );
$this->assertEquals( "Bar", $po->getExtensionData( "two" ) );
$po->setExtensionData( "one", null );
$this->assertNull( $po->getExtensionData( "one" ) );
$this->assertEquals( "Bar", $po->getExtensionData( "two" ) );
}
}