18 protected $idPrefix =
'ext-';
30 protected $definitionFile;
41 $this->definitionFile = $def;
42 $this->path = rtrim( $path,
'/' );
60 if ( $this->
namespace ===
null ) {
63 return $this->namespace;
73 $this->idPrefix = $value;
83 $this->
namespace = $value;
92 public function register( array &$list, array &$deps ) {
93 $groups = $this->parseFile();
94 $groups = $this->processGroups( $groups );
95 foreach ( $groups as $id => $g ) {
99 $deps[] =
new FileDependency( $this->definitionFile );
112 $conf[
'BASIC'][
'class'] = MediaWikiExtensionMessageGroup::class;
113 $conf[
'BASIC'][
'id'] = $id;
115 $conf[
'BASIC'][
'label'] = $info[
'name'];
117 if ( isset( $info[
'desc'] ) ) {
118 $conf[
'BASIC'][
'description'] = $info[
'desc'];
120 $conf[
'BASIC'][
'descriptionmsg'] = $info[
'descmsg'];
123 $conf[
'FILES'][
'class'] = JsonFFS::class;
124 $conf[
'FILES'][
'sourcePattern'] = $this->path .
'/' . $info[
'file'];
127 if ( isset( $info[
'aliasfile'] ) ) {
128 $conf[
'FILES'][
'aliasFileSource'] = $this->path .
'/' . $info[
'aliasfile'];
129 $conf[
'FILES'][
'aliasFile'] = $info[
'aliasfile'];
131 if ( isset( $info[
'magicfile'] ) ) {
132 $conf[
'FILES'][
'magicFileSource'] = $this->path .
'/' . $info[
'magicfile'];
133 $conf[
'FILES'][
'magicFile'] = $info[
'magicfile'];
136 if ( isset( $info[
'prefix'] ) ) {
137 $conf[
'MANGLER'][
'class'] = StringMatcher::class;
138 $conf[
'MANGLER'][
'prefix'] = $info[
'prefix'];
139 $conf[
'MANGLER'][
'patterns'] = $info[
'mangle'];
141 $mangler =
new StringMatcher( $info[
'prefix'], $info[
'mangle'] );
142 if ( isset( $info[
'ignored'] ) ) {
143 $info[
'ignored'] = $mangler->mangleList( $info[
'ignored'] );
145 if ( isset( $info[
'optional'] ) ) {
146 $info[
'optional'] = $mangler->mangleList( $info[
'optional'] );
150 $conf[
'VALIDATORS'] = [
151 [
'id' =>
'BraceBalance' ],
152 [
'id' =>
'MediaWikiLink' ],
153 [
'id' =>
'MediaWikiPageName' ],
154 [
'id' =>
'MediaWikiParameter' ],
155 [
'id' =>
'MediaWikiPlural' ],
158 $conf[
'INSERTABLES'] = [
159 [
'class' => MediaWikiInsertablesSuggester::class ]
162 if ( isset( $info[
'optional'] ) ) {
163 $conf[
'TAGS'][
'optional'] = $info[
'optional'];
165 if ( isset( $info[
'ignored'] ) ) {
166 $conf[
'TAGS'][
'ignored'] = $info[
'ignored'];
169 if ( isset( $info[
'languages'] ) ) {
170 $conf[
'LANGUAGES'] = [
175 foreach ( $info[
'languages'] as $tagSpec ) {
176 if ( preg_match(
'/^([+-])?(.+)$/', $tagSpec, $m ) ) {
177 list( , $sign, $tag ) = $m;
178 if ( $sign ===
'+' ) {
179 $conf[
'LANGUAGES'][
'include'][] = $tag;
180 } elseif ( $sign ===
'-' ) {
181 $conf[
'LANGUAGES'][
'exclude'][] = $tag;
183 $conf[
'LANGUAGES'][
'exclude'] =
'*';
184 $conf[
'LANGUAGES'][
'include'][] = $tag;
191 return MessageGroupBase::factory( $conf );
194 protected function parseFile() {
195 $defines = file_get_contents( $this->definitionFile );
196 $linefeed =
'(\r\n|\n)';
197 $sections = array_map(
199 preg_split(
"/$linefeed{2,}/", $defines, -1, PREG_SPLIT_NO_EMPTY )
203 foreach ( $sections as $section ) {
204 $lines = array_map(
'trim', preg_split(
"/$linefeed/", $section ) );
207 foreach ( $lines as $line ) {
208 if ( $line ===
'' || $line[0] ===
'#' ) {
212 if ( strpos( $line,
'=' ) ===
false ) {
213 if ( empty( $newgroup[
'name'] ) ) {
214 $newgroup[
'name'] = $line;
216 throw new MWException(
'Trying to define name twice: ' . $line );
219 list( $key, $value ) = array_map(
'trim', explode(
'=', $line, 2 ) );
228 $newgroup[$key] = $value;
233 $values = array_map(
'trim', explode(
',', $value ) );
234 if ( !isset( $newgroup[$key] ) ) {
235 $newgroup[$key] = [];
237 $newgroup[$key] = array_merge( $newgroup[$key], $values );
240 list( $prefix, $messages ) = array_map(
242 explode(
'|', $value, 2 )
244 if ( isset( $newgroup[
'prefix'] ) && $newgroup[
'prefix'] !== $prefix ) {
245 throw new MWException(
246 "Only one prefix supported: {$newgroup['prefix']} !== $prefix"
249 $newgroup[
'prefix'] = $prefix;
251 if ( !isset( $newgroup[
'mangle'] ) ) {
252 $newgroup[
'mangle'] = [];
255 $messages = array_map(
'trim', explode(
',', $messages ) );
256 $newgroup[
'mangle'] = array_merge( $newgroup[
'mangle'], $messages );
259 throw new MWException(
'Unknown key:' . $key );
264 if ( count( $newgroup ) ) {
265 if ( empty( $newgroup[
'name'] ) ) {
266 throw new MWException(
"Name missing\n" . print_r( $newgroup,
true ) );
268 $groups[] = $newgroup;
275 protected function processGroups( $groups ) {
277 foreach ( $groups as $g ) {
280 $id = $g[
'id'] ?? $this->idPrefix . preg_replace(
'/\s+/',
'', strtolower( $name ) );
282 if ( !isset( $g[
'file'] ) ) {
283 $file = preg_replace(
'/\s+/',
'',
"$name/i18n/%CODE%.json" );
288 $descmsg = $g[
'descmsg'] ?? str_replace( $this->idPrefix,
'', $id ) .
'-desc';
293 'descmsg' => $descmsg,
308 foreach ( $copyvars as $var ) {
309 if ( isset( $g[$var] ) ) {
310 $newgroup[$var] = $g[$var];
315 if ( !isset( $newgroup[
'optional' ] ) ) {
316 $newgroup[
'optional'] = [];
320 $newgroup[
'optional'][] =
'*-extensionname';
321 $newgroup[
'optional'][] =
'skinname-*';
323 $fixedGroups[$id] = $newgroup;