From 2fbf13812ad87d9bc061d6bd889f13177db95936 Mon Sep 17 00:00:00 2001 From: Alexander Vorwerk Date: Thu, 22 Jul 2021 01:49:49 +0200 Subject: [PATCH] WikiExporter: inject services This patch injects services into WikiExporter. It also adds a WikiExporterFactory service for creating WikiExporter instances. Change-Id: Ib1547defea54c309865c116bc83d617c21568843 --- autoload.php | 1 + includes/MediaWikiServices.php | 9 ++ includes/ServiceWiring.php | 9 ++ includes/api/ApiQuery.php | 4 +- includes/export/WikiExporter.php | 17 ++-- includes/export/WikiExporterFactory.php | 84 +++++++++++++++++++ includes/specialpage/SpecialPageFactory.php | 1 + includes/specials/SpecialExport.php | 11 ++- maintenance/includes/BackupDumper.php | 8 +- tests/phpunit/includes/ExportTest.php | 13 ++- .../includes/import/ImportExportTest.php | 4 +- .../export/WikiExporterFactoryTest.php | 39 +++++++++ 12 files changed, 182 insertions(+), 18 deletions(-) create mode 100644 includes/export/WikiExporterFactory.php create mode 100644 tests/phpunit/integration/includes/export/WikiExporterFactoryTest.php diff --git a/autoload.php b/autoload.php index eef6f2618ea..d1df9a5684c 100644 --- a/autoload.php +++ b/autoload.php @@ -859,6 +859,7 @@ $wgAutoloadLocalClasses = [ 'MediaWiki\\DAO\\WikiAwareEntity' => __DIR__ . '/includes/dao/WikiAwareEntity.php', 'MediaWiki\\DAO\\WikiAwareEntityTrait' => __DIR__ . '/includes/dao/WikiAwareEntityTrait.php', 'MediaWiki\\Debug\\DeprecatablePropertyArray' => __DIR__ . '/includes/debug/DeprecatablePropertyArray.php', + 'MediaWiki\\Export\\WikiExporterFactory' => __DIR__ . '/includes/export/WikiExporterFactory.php', 'MediaWiki\\FileBackend\\FSFile\\TempFSFileFactory' => __DIR__ . '/includes/libs/filebackend/fsfile/TempFSFileFactory.php', 'MediaWiki\\Hook\\AbortEmailNotificationHook' => __DIR__ . '/includes/changes/Hook/AbortEmailNotificationHook.php', 'MediaWiki\\Hook\\AbortTalkPageEmailNotificationHook' => __DIR__ . '/includes/mail/Hook/AbortTalkPageEmailNotificationHook.php', diff --git a/includes/MediaWikiServices.php b/includes/MediaWikiServices.php index e04dfc30475..d36f21175d6 100644 --- a/includes/MediaWikiServices.php +++ b/includes/MediaWikiServices.php @@ -41,6 +41,7 @@ use MediaWiki\Cache\LinkBatchFactory; use MediaWiki\Config\ConfigRepository; use MediaWiki\Content\IContentHandlerFactory; use MediaWiki\EditPage\SpamChecker; +use MediaWiki\Export\WikiExporterFactory; use MediaWiki\FileBackend\FSFile\TempFSFileFactory; use MediaWiki\FileBackend\LockManager\LockManagerGroupFactory; use MediaWiki\HookContainer\HookContainer; @@ -1692,6 +1693,14 @@ class MediaWikiServices extends ServiceContainer { return $this->getService( 'WatchlistManager' ); } + /** + * @since 1.37 + * @return WikiExporterFactory + */ + public function getWikiExporterFactory(): WikiExporterFactory { + return $this->getService( 'WikiExporterFactory' ); + } + /** * @since 1.37 * @return WikiImporterFactory diff --git a/includes/ServiceWiring.php b/includes/ServiceWiring.php index e1a54248c03..664fdff1cc6 100644 --- a/includes/ServiceWiring.php +++ b/includes/ServiceWiring.php @@ -64,6 +64,7 @@ use MediaWiki\Content\ContentHandlerFactory; use MediaWiki\Content\IContentHandlerFactory; use MediaWiki\EditPage\Constraint\EditConstraintFactory; use MediaWiki\EditPage\SpamChecker; +use MediaWiki\Export\WikiExporterFactory; use MediaWiki\FileBackend\FSFile\TempFSFileFactory; use MediaWiki\FileBackend\LockManager\LockManagerGroupFactory; use MediaWiki\HookContainer\DeprecatedHooks; @@ -1746,6 +1747,14 @@ return [ ); }, + 'WikiExporterFactory' => static function ( MediaWikiServices $services ): WikiExporterFactory { + return new WikiExporterFactory( + $services->getHookContainer(), + $services->getRevisionStore(), + $services->getTitleParser() + ); + }, + 'WikiImporterFactory' => static function ( MediaWikiServices $services ): WikiImporterFactory { return new WikiImporterFactory( $services->getMainConfig(), diff --git a/includes/api/ApiQuery.php b/includes/api/ApiQuery.php index c05f7367846..9caa2c1a8d4 100644 --- a/includes/api/ApiQuery.php +++ b/includes/api/ApiQuery.php @@ -736,7 +736,9 @@ class ApiQuery extends ApiBase { } } - $exporter = new WikiExporter( $this->getDB() ); + $exporter = MediaWikiServices::getInstance() + ->getWikiExporterFactory() + ->getWikiExporter( $this->getDB() ); $sink = new DumpStringOutput; $exporter->setOutputSink( $sink ); $exporter->setSchemaVersion( $this->mParams['exportschema'] ); diff --git a/includes/export/WikiExporter.php b/includes/export/WikiExporter.php index bd9d98f1444..ce4e1beb514 100644 --- a/includes/export/WikiExporter.php +++ b/includes/export/WikiExporter.php @@ -27,8 +27,8 @@ * @defgroup Dump Dump */ +use MediaWiki\HookContainer\HookContainer; use MediaWiki\HookContainer\HookRunner; -use MediaWiki\MediaWikiServices; use MediaWiki\Page\PageIdentity; use MediaWiki\Revision\RevisionAccessException; use MediaWiki\Revision\RevisionRecord; @@ -101,6 +101,9 @@ class WikiExporter { /** * @param IDatabase $db + * @param HookContainer $hookContainer + * @param RevisionStore $revisionStore + * @param TitleParser $titleParser * @param int|array $history One of WikiExporter::FULL, WikiExporter::CURRENT, * WikiExporter::RANGE or WikiExporter::STABLE, or an associative array: * - offset: non-inclusive offset at which to start the query @@ -112,20 +115,24 @@ class WikiExporter { */ public function __construct( $db, + HookContainer $hookContainer, + RevisionStore $revisionStore, + TitleParser $titleParser, $history = self::CURRENT, $text = self::TEXT, $limitNamespaces = null ) { $this->db = $db; $this->history = $history; + // TODO: add a $hookContainer parameter to XmlDumpWriter so that we can inject + // and then be able to convert the factory test to a unit test $this->writer = new XmlDumpWriter( $text, self::schemaVersion() ); $this->sink = new DumpOutput(); $this->text = $text; $this->limitNamespaces = $limitNamespaces; - $services = MediaWikiServices::getInstance(); - $this->hookRunner = new HookRunner( $services->getHookContainer() ); - $this->revisionStore = $services->getRevisionStore(); - $this->titleParser = $services->getTitleParser(); + $this->hookRunner = new HookRunner( $hookContainer ); + $this->revisionStore = $revisionStore; + $this->titleParser = $titleParser; } /** diff --git a/includes/export/WikiExporterFactory.php b/includes/export/WikiExporterFactory.php new file mode 100644 index 00000000000..2f4b68c5a10 --- /dev/null +++ b/includes/export/WikiExporterFactory.php @@ -0,0 +1,84 @@ +hookContainer = $hookContainer; + $this->revisionStore = $revisionStore; + $this->titleParser = $titleParser; + } + + /** + * @param IDatabase $db + * @param int|array $history + * @param int $text + * @param null|array $limitNamespaces + * + * @return WikiExporter + */ + public function getWikiExporter( + IDatabase $db, + $history = WikiExporter::CURRENT, + $text = WikiExporter::TEXT, + $limitNamespaces = null + ): WikiExporter { + return new WikiExporter( + $db, + $this->hookContainer, + $this->revisionStore, + $this->titleParser, + $history, + $text, + $limitNamespaces + ); + } +} diff --git a/includes/specialpage/SpecialPageFactory.php b/includes/specialpage/SpecialPageFactory.php index 627a29cdd2b..abd3088e46b 100644 --- a/includes/specialpage/SpecialPageFactory.php +++ b/includes/specialpage/SpecialPageFactory.php @@ -754,6 +754,7 @@ class SpecialPageFactory { 'class' => \SpecialExport::class, 'services' => [ 'DBLoadBalancer', + 'WikiExporterFactory', ] ], 'Import' => [ diff --git a/includes/specials/SpecialExport.php b/includes/specials/SpecialExport.php index 7ba6cf3407c..199debc4722 100644 --- a/includes/specials/SpecialExport.php +++ b/includes/specials/SpecialExport.php @@ -23,6 +23,7 @@ * @ingroup SpecialPage */ +use MediaWiki\Export\WikiExporterFactory; use MediaWiki\Logger\LoggerFactory; use Wikimedia\Rdbms\ILoadBalancer; @@ -37,14 +38,20 @@ class SpecialExport extends SpecialPage { /** @var ILoadBalancer */ private $loadBalancer; + /** @var WikiExporterFactory */ + private $wikiExporterFactory; + /** * @param ILoadBalancer $loadBalancer + * @param WikiExporterFactory $wikiExporterFactory */ public function __construct( - ILoadBalancer $loadBalancer + ILoadBalancer $loadBalancer, + WikiExporterFactory $wikiExporterFactory ) { parent::__construct( 'Export' ); $this->loadBalancer = $loadBalancer; + $this->wikiExporterFactory = $wikiExporterFactory; } public function execute( $par ) { @@ -390,7 +397,7 @@ class SpecialExport extends SpecialPage { /* Ok, let's get to it... */ $db = $this->loadBalancer->getConnectionRef( ILoadBalancer::DB_REPLICA ); - $exporter = new WikiExporter( $db, $history ); + $exporter = $this->wikiExporterFactory->getWikiExporter( $db, $history ); $exporter->list_authors = $list_authors; $exporter->openStream(); diff --git a/maintenance/includes/BackupDumper.php b/maintenance/includes/BackupDumper.php index e6c0d7f4b87..0cc3c94b052 100644 --- a/maintenance/includes/BackupDumper.php +++ b/maintenance/includes/BackupDumper.php @@ -292,7 +292,13 @@ abstract class BackupDumper extends Maintenance { $this->initProgress( $history ); $db = $this->backupDb(); - $exporter = new WikiExporter( $db, $history, $text, $this->limitNamespaces ); + $services = MediaWikiServices::getInstance(); + $exporter = $services->getWikiExporterFactory()->getWikiExporter( + $db, + $history, + $text, + $this->limitNamespaces + ); $exporter->setSchemaVersion( $this->schemaVersion ); $exporter->dumpUploads = $this->dumpUploads; $exporter->dumpUploadFileContents = $this->dumpUploadFileContents; diff --git a/tests/phpunit/includes/ExportTest.php b/tests/phpunit/includes/ExportTest.php index ca4c434432b..a3254a95b73 100644 --- a/tests/phpunit/includes/ExportTest.php +++ b/tests/phpunit/includes/ExportTest.php @@ -1,7 +1,5 @@ db, - WikiExporter::FULL - ); + $services = $this->getServiceContainer(); + $exporter = $services + ->getWikiExporterFactory() + ->getWikiExporter( $this->db, WikiExporter::FULL ); $title = Title::newFromText( $pageTitle ); @@ -53,8 +51,7 @@ class ExportTest extends MediaWikiLangTestCase { } $xmlNamespaces = str_replace( ' ', '_', $xmlNamespaces ); - $actualNamespaces = (array)MediaWikiServices::getInstance()->getContentLanguage()-> - getNamespaces(); + $actualNamespaces = (array)$services->getContentLanguage()->getNamespaces(); $actualNamespaces = array_values( $actualNamespaces ); $this->assertEquals( $actualNamespaces, $xmlNamespaces ); diff --git a/tests/phpunit/includes/import/ImportExportTest.php b/tests/phpunit/includes/import/ImportExportTest.php index 350a2400bf2..6cd95b07fa2 100644 --- a/tests/phpunit/includes/import/ImportExportTest.php +++ b/tests/phpunit/includes/import/ImportExportTest.php @@ -29,7 +29,9 @@ class ImportExportTest extends MediaWikiLangTestCase { * @return WikiExporter */ private function getExporter( string $schemaVersion ) { - $exporter = new WikiExporter( $this->db, WikiExporter::FULL ); + $exporter = $this->getServiceContainer() + ->getWikiExporterFactory() + ->getWikiExporter( $this->db, WikiExporter::FULL ); $exporter->setSchemaVersion( $schemaVersion ); return $exporter; } diff --git a/tests/phpunit/integration/includes/export/WikiExporterFactoryTest.php b/tests/phpunit/integration/includes/export/WikiExporterFactoryTest.php new file mode 100644 index 00000000000..8f9db6fcdd3 --- /dev/null +++ b/tests/phpunit/integration/includes/export/WikiExporterFactoryTest.php @@ -0,0 +1,39 @@ +setMwGlobals( [ + 'XmlDumpSchemaVersion' => XmlDumpWriter::$supportedSchemas[0], + ] ); + } + + protected static function getFactoryClass() { + return WikiExporterFactory::class; + } + + protected static function getInstanceClass() { + return WikiExporter::class; + } + + protected static function getExtraClassArgCount() { + return 4; + } + + protected function getFactoryMethodName() { + return 'getWikiExporter'; + } +}