mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Gadgets
synced 2024-11-23 23:13:27 +00:00
Merge "Introduce MultiGadgetRepo to facilitate repo migration"
This commit is contained in:
commit
0b9f7f907d
|
@ -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."
|
||||
}
|
||||
|
|
|
@ -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."
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
131
includes/MultiGadgetRepo.php
Normal file
131
includes/MultiGadgetRepo.php
Normal 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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' );
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
31
tests/phpunit/integration/MultiGadgetRepoTest.php
Normal file
31
tests/phpunit/integration/MultiGadgetRepoTest.php
Normal 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' ) ) );
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue