deprecated. There are no known callers.
* File::getStreamHeaders() was deprecated.
* MediaHandler::getStreamHeaders() was deprecated.
+* The ExtractThumbParameters hook (deprecated in 1.21) was removed.
+* The OutputPage::addParserOutputNoText and ::getHeadLinks methods (both
+ deprecated in 1.24) were removed.
== Compatibility ==
MediaWiki 1.30 requires PHP 5.5.9 or later. There is experimental support for
"$schema": "http://json-schema.org/schema#",
"description": "MediaWiki extension.json schema",
"type": "object",
+ "additionalProperties": false,
"properties": {
"manifest_version": {
"type": "integer",
"type": "array",
"description": "List of service wiring files to be loaded by the default instance of MediaWikiServices"
},
+ "attributes": {
+ "description":"Registration information for other extensions",
+ "type": "object",
+ "patternProperties": {
+ ".*": {
+ "type": "object",
+ "patternProperties": {
+ ".*": {
+ "type": ["array", "object"]
+ }
+ }
+ }
+ }
+ },
"load_composer_autoloader": {
"type": "boolean",
"description": "Load the composer autoloader for this extension, if one is present"
change the tables headers.
&$extTypes: associative array of extensions types
-'ExtractThumbParameters': DEPRECATED! Media handler should override
-MediaHandler::parseParamString instead.
-Called when extracting thumbnail parameters from a thumbnail file name.
-$thumbname: the base name of the thumbnail file
-&$params: the currently extracted params (has source name, temp or archived
-zone)
-
'FetchChangesList': When fetching the ChangesList derivative for a particular
user.
$user: User the list is being fetched for
$wgOut->addHTML( Html::hidden( 'format', $this->contentFormat ) );
$wgOut->addHTML( Html::hidden( 'model', $this->contentModel ) );
+ // Preserve &ooui=1 / &ooui=0 from URL parameters after submitting the page for preview
+ $wgOut->addHTML( Html::hidden( 'ooui', $this->oouiEnabled ? '1' : '0' ) );
+
// following functions will need OOUI, enable it only once; here.
if ( $this->oouiEnabled ) {
$wgOut->enableOOUI();
$this->addParserOutput( $parserOutput );
}
- /**
- * Add a ParserOutput object, but without Html.
- *
- * @deprecated since 1.24, use addParserOutputMetadata() instead.
- * @param ParserOutput $parserOutput
- */
- public function addParserOutputNoText( $parserOutput ) {
- wfDeprecated( __METHOD__, '1.24' );
- $this->addParserOutputMetadata( $parserOutput );
- }
-
/**
* Add all metadata associated with a ParserOutput object, but without the actual HTML. This
* includes categories, language links, ResourceLoader modules, effects of certain magic words,
return $tags;
}
- /**
- * @return string HTML tag links to be put in the header.
- * @deprecated since 1.24 Use OutputPage::headElement or if you have to,
- * OutputPage::getHeadLinksArray directly.
- */
- public function getHeadLinks() {
- wfDeprecated( __METHOD__, '1.24' );
- return implode( "\n", $this->getHeadLinksArray() );
- }
-
/**
* Generate a "<link rel/>" for a feed.
*
* @return string|bool
*/
public function getWrapOutputClass() {
+ $this->optionUsed( 'wrapclass' );
return $this->wrapOutputClass;
}
$confstr .= '!printable=1';
}
+ if ( $this->wrapOutputClass !== 'mw-parser-output' && in_array( 'wrapclass', $forOptions ) ) {
+ $confstr .= '!wrapclass=' . $this->wrapOutputClass;
+ }
+
if ( $this->mExtraKey != '' ) {
$confstr .= $this->mExtraKey;
}
'ValidSkinNames',
];
+ /**
+ * Top-level attributes that come from MW core
+ *
+ * @var string[]
+ */
+ protected static $coreAttributes = [
+ 'SkinOOUIThemes',
+ 'TrackingCategories',
+ ];
+
/**
* Mapping of global settings to their specific merge strategies.
*
*/
protected $attributes = [];
+ /**
+ * Extension attributes, keyed by name =>
+ * settings.
+ *
+ * @var array
+ */
+ protected $extAttributes = [];
+
/**
* @param string $path
* @param array $info
$this->callbacks[$name] = $info['callback'];
}
+ if ( $version === 2 ) {
+ $this->extractAttributes( $path, $info );
+ }
+
foreach ( $info as $key => $val ) {
+ // If it's a global setting,
if ( in_array( $key, self::$globalSettings ) ) {
$this->storeToArray( $path, "wg$key", $val, $this->globals );
+ continue;
+ }
// Ignore anything that starts with a @
- } elseif ( $key[0] !== '@' && !in_array( $key, self::$notAttributes )
- && !in_array( $key, self::$creditsAttributes )
- ) {
- $this->storeToArray( $path, $key, $val, $this->attributes );
+ if ( $key[0] === '@' ) {
+ continue;
+ }
+
+ if ( $version === 2 ) {
+ // Only whitelisted attributes are set
+ if ( in_array( $key, self::$coreAttributes ) ) {
+ $this->storeToArray( $path, $key, $val, $this->attributes );
+ }
+ } else {
+ // version === 1
+ if ( !in_array( $key, self::$notAttributes )
+ && !in_array( $key, self::$creditsAttributes )
+ ) {
+ // If it's not blacklisted, it's an attribute
+ $this->storeToArray( $path, $key, $val, $this->attributes );
+ }
+ }
+
+ }
+ }
+
+ /**
+ * @param string $path
+ * @param array $info
+ */
+ protected function extractAttributes( $path, array $info ) {
+ if ( isset( $info['attributes'] ) ) {
+ foreach ( $info['attributes'] as $extName => $value ) {
+ $this->storeToArray( $path, $extName, $value, $this->extAttributes );
}
}
}
}
}
+ // Merge $this->extAttributes into $this->attributes depending on what is loaded
+ foreach ( $this->extAttributes as $extName => $value ) {
+ // Only set the attribute if $extName is loaded (and hence present in credits)
+ if ( isset( $this->credits[$extName] ) ) {
+ foreach ( $value as $attrName => $attrValue ) {
+ $this->storeToArray(
+ '', // Don't provide a path since it's impossible to generate an error here
+ $extName . $attrName,
+ $attrValue,
+ $this->attributes
+ );
+ }
+ unset( $this->extAttributes[$extName] );
+ }
+ }
+
return [
'globals' => $this->globals,
'defines' => $this->defines,
/**
* Bump whenever the registration cache needs resetting
*/
- const CACHE_VERSION = 5;
+ const CACHE_VERSION = 6;
/**
* Special key that defines the merge strategy
* be loaded then).
*/
public function loadFromQueue() {
- global $wgVersion;
+ global $wgVersion, $wgDevelopmentWarnings;
if ( !$this->queued ) {
return;
}
// did that, but it should be cached
$data['globals']['wgAutoloadClasses'] += $data['autoload'];
unset( $data['autoload'] );
- $cache->set( $key, $data, 60 * 60 * 24 );
+ if ( !( $data['warnings'] && $wgDevelopmentWarnings ) ) {
+ // If there were no warnings that were shown, cache it
+ $cache->set( $key, $data, 60 * 60 * 24 );
+ }
}
$this->queued = [];
}
$versionChecker = new VersionChecker( $wgVersion );
$extDependencies = [];
$incompatible = [];
+ $warnings = false;
foreach ( $queue as $path => $mtime ) {
$json = file_get_contents( $path );
if ( $json === false ) {
}
if ( !isset( $info['manifest_version'] ) ) {
+ wfDeprecated(
+ "{$info['name']}'s extension.json or skin.json does not have manifest_version",
+ '1.29'
+ );
+ $warnings = true;
// For backwards-compatability, assume a version of 1
$info['manifest_version'] = 1;
}
$processor->extractInfo( $path, $info, $version );
}
$data = $processor->getExtractedInfo();
+ $data['warnings'] = $warnings;
// check for incompatible extensions
$incompatible = array_merge(
this.clearItems();
$.each( savedQueries.queries || {}, function ( id, obj ) {
var normalizedData = $.extend( true, {}, baseState, obj.data );
+
+ // Backwards-compat fix: We stored the 'highlight' state with
+ // "1" and "0" instead of true/false; for already-stored states,
+ // we need to fix that.
+ // NOTE: Since this feature is only available in beta, we should
+ // not need this line when we release this to the general wikis.
+ // This method will automatically fix all saved queries anyways
+ // for existing users, who are only betalabs users at the moment.
+ normalizedData.highlights.highlight = !!Number( normalizedData.highlight );
+
items.push(
new mw.rcfilters.dm.SavedQueryItemModel(
id,
highlightedItems[ item.getName() ] = highlightEnabled ?
item.getHighlightColor() : null;
} );
- // Stored as a string '0' or '1'
- highlightedItems.highlight = String( Number( this.filtersModel.isHighlightEnabled() ) );
+ // These are filter states; highlight is stored as boolean
+ highlightedItems.highlight = this.filtersModel.isHighlightEnabled();
// Add item
this.savedQueriesModel.addNewQuery(
this.filtersModel.toggleFiltersSelected( data.filters );
// Update highlight state
- this.filtersModel.toggleHighlight( !!highlights.highlight );
+ this.filtersModel.toggleHighlight( !!Number( highlights.highlight ) );
this.filtersModel.getItems().forEach( function ( filterItem ) {
var color = highlights[ filterItem.getName() ];
if ( color ) {
);
// Update highlight state
- this.filtersModel.toggleHighlight( !!parameters.highlight );
+ this.filtersModel.toggleHighlight( !!Number( parameters.highlight ) );
this.filtersModel.getItems().forEach( function ( filterItem ) {
var color = parameters[ filterItem.getName() + '_color' ];
if ( color ) {
savedParams = this.filtersModel.getParametersFromFilters( data.filters || {} );
// Translate highlights to parameters
- savedHighlights.highlight = queryHighlights.highlight;
+ savedHighlights.highlight = String( Number( queryHighlights.highlight ) );
$.each( queryHighlights, function ( filterName, color ) {
if ( filterName !== 'highlights' ) {
savedHighlights[ filterName + '_color' ] = color;
];
}
+ /**
+ * Attributes under manifest_version 2
+ *
+ * @covers ExtensionProcessor::extractAttributes
+ * @covers ExtensionProcessor::getExtractedInfo
+ */
+ public function testExtractAttributes() {
+ $processor = new ExtensionProcessor();
+ // Load FooBar extension
+ $processor->extractInfo( $this->dir, [ 'name' => 'FooBar' ], 2 );
+ $processor->extractInfo(
+ $this->dir,
+ [
+ 'name' => 'Baz',
+ 'attributes' => [
+ // Loaded
+ 'FooBar' => [
+ 'Plugins' => [
+ 'ext.baz.foobar',
+ ],
+ ],
+ // Not loaded
+ 'FizzBuzz' => [
+ 'MorePlugins' => [
+ 'ext.baz.fizzbuzz',
+ ],
+ ],
+ ],
+ ],
+ 2
+ );
+
+ $info = $processor->getExtractedInfo();
+ $this->assertArrayHasKey( 'FooBarPlugins', $info['attributes'] );
+ $this->assertSame( [ 'ext.baz.foobar' ], $info['attributes']['FooBarPlugins'] );
+ $this->assertArrayNotHasKey( 'FizzBuzzMorePlugins', $info['attributes'] );
+ }
+
+ /**
+ * Attributes under manifest_version 1
+ *
+ * @covers ExtensionProcessor::extractInfo
+ */
+ public function testAttributes1() {
+ $processor = new ExtensionProcessor();
+ $processor->extractInfo(
+ $this->dir,
+ [
+ 'name' => 'FooBar',
+ 'FooBarPlugins' => [
+ 'ext.baz.foobar',
+ ],
+ 'FizzBuzzMorePlugins' => [
+ 'ext.baz.fizzbuzz',
+ ],
+ ],
+ 1
+ );
+
+ $info = $processor->getExtractedInfo();
+ $this->assertArrayHasKey( 'FooBarPlugins', $info['attributes'] );
+ $this->assertSame( [ 'ext.baz.foobar' ], $info['attributes']['FooBarPlugins'] );
+ $this->assertArrayHasKey( 'FizzBuzzMorePlugins', $info['attributes'] );
+ $this->assertSame( [ 'ext.baz.fizzbuzz' ], $info['attributes']['FizzBuzzMorePlugins'] );
+ }
+
public function testGlobalSettingsDocumentedInSchema() {
global $IP;
$globalSettings = TestingAccessWrapper::newFromClass(
$thumbname = $params['thumbName'];
unset( $params['thumbName'] );
- // Do the hook first for older extensions that rely on it.
- if ( !Hooks::run( 'ExtractThumbParameters', [ $thumbname, &$params ] ) ) {
- // Check hooks if parameters can be extracted
- // Hooks return false if they manage to *resolve* the parameters
- // This hook should be considered deprecated
- wfDeprecated( 'ExtractThumbParameters', '1.22' );
- return $params; // valid thumbnail URL (via extension or config)
- }
-
// FIXME: Files in the temp zone don't set a MIME type, which means
// they don't have a handler. Which means we can't parse the param
// string. However, not a big issue as what good is a param string