13 private $extensionDir;
17 private $excludedMsgs;
21 private $coreDataCache;
24 parent::__construct();
25 $this->
addArg(
'extension',
'The extension name' );
27 'The output directory, default MW_INSTALL_PATH/languages/i18n',
false,
true );
33 $this->outDir = $this->
getOption(
'outdir', MW_INSTALL_PATH .
'/languages/i18n' );
34 if ( !file_exists( $this->outDir ) ) {
35 mkdir( $this->outDir, 0777,
true );
38 $this->extName = $this->
getArg();
39 $extJsonPath = $this->extensionDir .
"/{$this->extName}/extension.json";
40 $extJson = file_get_contents( $extJsonPath );
41 if ( $extJson ===
false ) {
42 $this->
fatalError(
"Unable to open \"$extJsonPath\"" );
44 $extData = json_decode( $extJson,
true, flags: JSON_THROW_ON_ERROR );
45 if ( !is_array( $extData ) || array_is_list( $extData ) ) {
46 $this->
fatalError(
"\"$extJsonPath\" contains unexpected data, expected a JSON object" );
49 $this->excludedMsgs = [];
50 foreach ( [
'namemsg',
'descriptionmsg' ] as $key ) {
51 if ( isset( $extData[$key] ) ) {
53 $this->excludedMsgs[] = $extData[$key];
57 foreach ( $this->getMessagesDirs( $extData ) as $dir ) {
58 $this->processDir( $dir );
62 private function init() {
64 $config = $services->getMainConfig();
65 $this->extensionDir = $config->get( MainConfigNames::ExtensionDirectory );
68 private function getMessagesDirs( array $extData ): array {
69 if ( isset( $extData[
'MessagesDirs'] ) ) {
71 foreach ( $extData[
'MessagesDirs'] as $dirs ) {
72 if ( is_array( $dirs ) ) {
73 foreach ( $dirs as $dir ) {
74 $messagesDirs[] = $dir;
77 $messagesDirs[] = $dirs;
81 $messagesDirs = [
'i18n' ];
86 private function processDir(
string $dir ) {
87 $path = $this->extensionDir .
"/{$this->extName}/$dir";
89 foreach (
new DirectoryIterator(
$path ) as $file ) {
90 if ( !$file->isDot() && str_ends_with( $file->getFilename(),
'.json' ) ) {
92 substr( $file->getFilename(), 0, -5 ),
99 private function processFile(
string $lang,
string $extI18nPath ) {
100 $extJson = file_get_contents( $extI18nPath );
101 if ( $extJson ===
false ) {
102 $this->error(
"Unable to read i18n file \"$extI18nPath\"" );
105 $extData = json_decode( $extJson,
true, flags: JSON_THROW_ON_ERROR );
106 $coreData = $this->getCoreData( $lang );
108 if ( isset( $extData[
'@metadata'][
'authors'] ) ) {
109 $authors = array_unique( array_merge(
110 $coreData[
'@metadata'][
'authors'] ?? [],
111 $extData[
'@metadata'][
'authors']
114 foreach ( $authors as &$author ) {
115 $author = (string)$author;
118 $coreData[
'@metadata'][
'authors'] = $authors;
121 foreach ( $extData as $name => $value ) {
122 if ( str_starts_with( $name,
'@' ) ) {
125 if ( in_array( $name, $this->excludedMsgs ) ) {
128 $coreData[$name] = $value;
131 $this->setCoreData( $lang, $coreData );
135 private function getCoreData(
string $lang ) {
136 if ( !isset( $this->coreDataCache[$lang] ) ) {
137 $corePath = MW_INSTALL_PATH .
"/languages/i18n/$lang.json";
139 $coreJson = @file_get_contents( $corePath );
140 if ( $coreJson ===
false ) {
141 $this->error(
"Warning: discarding extension localisation " .
142 "for language \"$lang\" not present in core" );
146 $this->coreDataCache[$lang] = json_decode( $coreJson,
true, flags: JSON_THROW_ON_ERROR );
148 return $this->coreDataCache[$lang];
155 private function setCoreData(
string $lang, $data ) {
156 if ( !isset( $this->coreDataCache[$lang] ) ) {
161 $this->coreDataCache[$lang] = $data;
162 $outPath =
"{$this->outDir}/$lang.json";
163 if ( !file_put_contents(
165 FormatJson::encode( $data,
"\t", FormatJson::ALL_OK ) .
"\n"
167 $this->error(
"Unable to write core i18n file \"$outPath\"" );
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.