Merge "Introduce MultiGadgetRepo to facilitate repo migration"

This commit is contained in:
jenkins-bot 2024-03-02 18:43:01 +00:00 committed by Gerrit Code Review
commit 0b9f7f907d
7 changed files with 173 additions and 2 deletions

View file

@ -58,6 +58,7 @@
"gadgets-validate-invalidrights": "The following {{PLURAL:$2|right does|rights do}} not exist: $1",
"gadgets-validate-invalidtitle": "Page title \"$1\" is invalid",
"gadgets-validate-unknownpages": "Contains one or more pages without .js, .css or .json suffix. They would not be used.",
"gadgets-validate-duplicate": "A second definition of gadget $1 was detected and shall be ignored",
"gadgets-validate-nopage": "Page \"$1\" does not exist.",
"gadgets-supports-urlload": "This gadget supports loading via URL with <code>?withgadget</code> query parameter."
}

View file

@ -73,6 +73,7 @@
"gadgets-validate-invalidrights": "Warning message to indicate that the rights are not recognised. Parameters:\n* $1 - comma-separated list of invalid rights\n* $2 - number of items in list $1",
"gadgets-validate-invalidtitle": "Warning message to indicate that the page title is invalid. Parameters:\n* $1 - page name",
"gadgets-validate-unknownpages": "Warning message to indicate that a gadget contains pages without .js, .css or .json suffix, which are not recognised.",
"gadgets-validate-duplicate": "Warning message to indicate that the second gadget definition with the same name would be ignored. Parameters:\n* $1 -gadget name",
"gadgets-validate-nopage": "Warning message to indicate the script/style/json page does not exist. Parameters:\n* $1 - page name",
"gadgets-supports-urlload": "Used in [[Special:Gadgets]], if the gadget supports ?withgadget query parameter."
}

View file

@ -86,9 +86,10 @@ abstract class GadgetRepo {
* to `MediaWiki:Gadget-example.json`.
*
* @param string $titleText
* @param string $gadgetId
* @return string
*/
public function titleWithoutPrefix( string $titleText ): string {
public function titleWithoutPrefix( string $titleText, string $gadgetId ): string {
$numReplaces = 1; // there will only one occurrence of the prefix
return str_replace( self::RESOURCE_TITLE_PREFIX, '', $titleText, $numReplaces );
}

View file

@ -0,0 +1,131 @@
<?php
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
*/
namespace MediaWiki\Extension\Gadgets;
use InvalidArgumentException;
use MediaWiki\Linker\LinkTarget;
use MediaWiki\Title\Title;
/**
* Combine two gadget repos during migrations
*
* @copyright 2017 Kunal Mehta <legoktm@member.fsf.org>
* @copyright 2023 Siddharth VP
*/
class MultiGadgetRepo extends GadgetRepo {
/**
* @var GadgetRepo[]
*/
private array $repos;
/**
* @param GadgetRepo[] $repos
*/
public function __construct( array $repos ) {
$this->repos = $repos;
}
/**
* @inheritDoc
*/
public function getGadget( string $id ): Gadget {
foreach ( $this->repos as $repo ) {
try {
return $repo->getGadget( $id );
} catch ( InvalidArgumentException $e ) {
// Try next repo
}
}
throw new InvalidArgumentException( "No gadget registered for '$id'" );
}
/**
* @inheritDoc
*/
public function getGadgetIds(): array {
$ids = [];
foreach ( $this->repos as $repo ) {
$ids = array_merge( $ids, $repo->getGadgetIds() );
}
return array_values( array_unique( $ids ) );
}
/**
* @inheritDoc
*/
public function handlePageUpdate( LinkTarget $target ): void {
foreach ( $this->repos as $repo ) {
$repo->handlePageUpdate( $target );
}
}
private function getRepoForGadget( string $id ): GadgetRepo {
foreach ( $this->repos as $repo ) {
try {
$repo->getGadget( $id );
// return repo if it didn't throw
return $repo;
} catch ( InvalidArgumentException $e ) {
}
}
throw new InvalidArgumentException( "No repo found for gadget $id" );
}
public function getGadgetDefinitionTitle( string $id ): ?Title {
return $this->getRepoForGadget( $id )->getGadgetDefinitionTitle( $id );
}
public function titleWithoutPrefix( string $titleText, string $gadgetId ): string {
return $this->getRepoForGadget( $gadgetId )->titleWithoutPrefix( $titleText, $gadgetId );
}
public function validationWarnings( Gadget $gadget ): array {
$duplicateWarnings = $this->isDefinedTwice( $gadget->getName() ) ? [
wfMessage( "gadgets-validate-duplicate", $gadget->getName() )
] : [];
return array_merge( $duplicateWarnings, parent::validationWarnings( $gadget ) );
}
/**
* Checks if a gadget is defined with the same name in two different repos.
* @param string $id Gadget name
* @return bool
*/
private function isDefinedTwice( string $id ) {
$found = false;
foreach ( $this->repos as $repo ) {
try {
$repo->getGadget( $id );
if ( $found ) {
// found it a second time
return true;
} else {
$found = true;
}
} catch ( InvalidArgumentException $e ) {
}
}
return false;
}
}

View file

@ -3,6 +3,7 @@
use MediaWiki\Extension\Gadgets\GadgetRepo;
use MediaWiki\Extension\Gadgets\MediaWikiGadgetsDefinitionRepo;
use MediaWiki\Extension\Gadgets\MediaWikiGadgetsJsonRepo;
use MediaWiki\Extension\Gadgets\MultiGadgetRepo;
use MediaWiki\MediaWikiServices;
return [
@ -14,6 +15,11 @@ return [
return new MediaWikiGadgetsDefinitionRepo( $wanCache, $revisionLookup );
case 'json':
return new MediaWikiGadgetsJsonRepo( $wanCache, $revisionLookup );
case 'json+definition':
return new MultiGadgetRepo( [
new MediaWikiGadgetsJsonRepo( $wanCache, $revisionLookup ),
new MediaWikiGadgetsDefinitionRepo( $wanCache, $revisionLookup )
] );
default:
throw new InvalidArgumentException( 'Unexpected value for $wgGadgetsRepo' );
}

View file

@ -223,7 +223,7 @@ class SpecialGadgets extends SpecialPage {
$output->addHTML( '<br />' );
}
$output->addHTML( $this->msg( 'gadgets-packaged',
$this->gadgetRepo->titleWithoutPrefix( $gadget->getScripts()[0] ) ) );
$this->gadgetRepo->titleWithoutPrefix( $gadget->getScripts()[0], $gadget->getName() ) ) );
$needLineBreakAfter = true;
}

View file

@ -0,0 +1,31 @@
<?php
use MediaWiki\Extension\Gadgets\Gadget;
use MediaWiki\Extension\Gadgets\MultiGadgetRepo;
use MediaWiki\Extension\Gadgets\StaticGadgetRepo;
/**
* @covers \MediaWiki\Extension\Gadgets\MultiGadgetRepo
* @group Gadgets
* @group Database
*/
class MultiGadgetRepoTest extends MediaWikiIntegrationTestCase {
public function testMultiGadgetRepo() {
$repo = new MultiGadgetRepo( [
new StaticGadgetRepo( [
'g1' => new Gadget( [ 'name' => 'g1', 'onByDefault' => true ] ),
'g2' => new Gadget( [ 'name' => 'g2', 'onByDefault' => true ] ),
] ),
new StaticGadgetRepo( [
'g1' => new Gadget( [ 'name' => 'g1', 'onByDefault' => false ] ),
'g3' => new Gadget( [ 'name' => 'g3', 'onByDefault' => false ] ),
] )
] );
$this->assertTrue( $repo->getGadget( 'g1' )->isOnByDefault() );
$this->assertTrue( $repo->getGadget( 'g2' )->isOnByDefault() );
$this->assertFalse( $repo->getGadget( 'g3' )->isOnByDefault() );
$this->assertCount( 1, $repo->validationWarnings( $repo->getGadget( 'g1' ) ) );
}
}