Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 58
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
ExportTranslatableBundleMaintenanceScript
0.00% covered (danger)
0.00%
0 / 58
0.00% covered (danger)
0.00%
0 / 6
90
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 28
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
2
 setupServices
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getBundleToExport
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
 getExportFilename
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 exportPageCallback
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\MessageGroupProcessing;
5
6use MediaWiki\Extension\Translate\Services;
7use MediaWiki\Extension\Translate\Utilities\BaseMaintenanceScript;
8use MediaWiki\MediaWikiServices;
9use MediaWiki\Title\TitleFactory;
10
11/**
12 * Script to export a translatable bundle into XML.
13 * @since 2023.05
14 * @license GPL-2.0-or-later
15 * @author Abijeet Patro
16 */
17class ExportTranslatableBundleMaintenanceScript extends BaseMaintenanceScript {
18    private TitleFactory $titleFactory;
19    private TranslatableBundleExporter $translatableBundleExporter;
20    private TranslatableBundleFactory $translatableBundleFactory;
21
22    public function __construct() {
23        parent::__construct();
24        $this->addDescription(
25            'Export a translatable bundle into a file that can then be imported ' .
26            'into another wiki using the importTranslatableBundle.php script'
27        );
28        $this->addOption(
29            'translatable-bundle',
30            'Name of the translatable bundle to be exported',
31            self::REQUIRED,
32            self::HAS_ARG
33        );
34        $this->addOption(
35            'filename',
36            'Path to save the export file including the file name',
37            self::REQUIRED,
38            self::HAS_ARG
39        );
40        $this->addOption(
41            'include-subpages',
42            'Include subpages in the export file',
43            self::OPTIONAL
44        );
45        $this->addOption(
46            'include-talk-pages',
47            'Include talk pages in the export file',
48            self::OPTIONAL
49        );
50
51        $this->requireExtension( 'Translate' );
52    }
53
54    /** @inheritDoc */
55    public function execute() {
56        $this->setupServices();
57
58        $bundle = $this->getBundleToExport();
59        $includeTalkPages = $this->hasOption( 'include-talk-pages' );
60        $includeSubPages = $this->hasOption( 'include-subpages' );
61        $exportFilename = $this->getExportFilename();
62
63        $this->translatableBundleExporter->setExportPageCallback( [ $this, 'exportPageCallback' ] );
64        $output = $this->translatableBundleExporter->export(
65            $bundle,
66            $includeTalkPages,
67            $includeSubPages
68        );
69
70        file_put_contents( $exportFilename, $output );
71        $this->output( "Done! Exported bundle '{$bundle->getTitle()->getPrefixedText()}' to '$exportFilename'.\n" );
72    }
73
74    private function setupServices(): void {
75        $serviceInstance = Services::getInstance();
76
77        $this->titleFactory = MediaWikiServices::getInstance()->getTitleFactory();
78        $this->translatableBundleExporter = $serviceInstance->getTranslatableBundleExporter();
79        $this->translatableBundleFactory = $serviceInstance->getTranslatableBundleFactory();
80    }
81
82    private function getBundleToExport(): TranslatableBundle {
83        $titleString = $this->getOption( 'translatable-bundle' );
84        $translatableBundleTitle = $this->titleFactory->newFromText( $titleString );
85        if ( !$translatableBundleTitle ) {
86            $this->fatalError( "'$titleString' is not a valid title" );
87        }
88
89        $bundle = $this->translatableBundleFactory->getBundle( $translatableBundleTitle );
90        if ( !$bundle ) {
91            $this->fatalError( "Page $titleString is not a translatable bundle" );
92        }
93
94        return $bundle;
95    }
96
97    private function getExportFilename(): string {
98        $filename = $this->getOption( 'filename' );
99        if ( !is_writable( dirname( $filename ) ) ) {
100            $this->fatalError( "Unable to create file '$filename'" );
101        }
102
103        return $filename;
104    }
105
106    public function exportPageCallback( array $pages, string $pageType ): void {
107        $this->output( 'Exporting ' . count( $pages ) . " page(s) of type $pageType.\n" );
108    }
109}