Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
MessageGroupConfigurationParser.php
Go to the documentation of this file.
1<?php
9
15 private $baseSchema;
16
17 public function __construct() {
18 // Don't perform validations if library not available
19 if ( class_exists( RomaricDrigon\MetaYaml\MetaYaml::class ) ) {
20 $this->baseSchema = $this->getBaseSchema();
21 }
22 }
23
33 public function getHopefullyValidConfigurations( $data, $callback = null ) {
34 if ( !is_callable( $callback ) ) {
35 $callback = static function ( $unused1, $unused2, $unused3 ) {
36 /*noop*/
37 };
38 }
39
40 $documents = self::getDocumentsFromYaml( $data );
41 $configurations = self::parseDocuments( $documents );
42 $groups = [];
43
44 if ( is_array( $this->baseSchema ) ) {
45 foreach ( $configurations as $index => $config ) {
46 try {
47 $this->validate( $config );
48 $groups[$config['BASIC']['id']] = $config;
49 } catch ( Exception $e ) {
50 $callback( $index, $config, $e->getMessage() );
51 }
52 }
53 } else {
54 foreach ( $configurations as $index => $config ) {
55 if ( isset( $config['BASIC']['id'] ) ) {
56 $groups[$config['BASIC']['id']] = $config;
57 } else {
58 $callback( $index, $config, 'id is missing' );
59 }
60 }
61 }
62
63 return $groups;
64 }
65
72 public function getDocumentsFromYaml( $data ) {
73 return preg_split( "/^---$/m", $data, -1, PREG_SPLIT_NO_EMPTY );
74 }
75
83 public function parseDocuments( array $documents ) {
84 $groups = [];
85 $template = [];
86
87 foreach ( $documents as $document ) {
88 $document = TranslateYaml::loadString( $document );
89
90 if ( isset( $document['TEMPLATE'] ) ) {
91 $template = $document['TEMPLATE'];
92 } else {
93 $groups[] = $document;
94 }
95 }
96
97 if ( $template ) {
98 foreach ( $groups as $i => $group ) {
99 $groups[$i] = self::mergeTemplate( $template, $group );
100 // Little hack to allow aggregate groups to be defined in same file with other groups.
101 if ( $groups[$i]['BASIC']['class'] === AggregateMessageGroup::class ) {
102 unset( $groups[$i]['FILES'] );
103 }
104 }
105 }
106
107 return $groups;
108 }
109
110 public function getBaseSchema() {
111 return TranslateYaml::load( __DIR__ . '/data/group-yaml-schema.yaml' );
112 }
113
120 public function validate( array $config ) {
121 $schema = $this->baseSchema;
122
123 foreach ( $config as $section ) {
124 if ( !isset( $section['class'] ) ) {
125 continue;
126 }
127
128 $class = $section['class'];
129
130 // FIXME: UGLY HACK: StringMatcher is now under a namespace so use the fully prefixed
131 // class to check if it has the getExtraSchema method
132 if ( $class === 'StringMatcher' ) {
133 $class = StringMatcher::class;
134 }
135
136 // There is no sane way to check whether *class* implements interface in PHP
137 if ( !is_callable( [ $class, 'getExtraSchema' ] ) ) {
138 continue;
139 }
140
141 $extra = call_user_func( [ $class, 'getExtraSchema' ] );
142 $schema = array_replace_recursive( $schema, $extra );
143 }
144
145 $schema = new RomaricDrigon\MetaYaml\MetaYaml( $schema );
146 $schema->validate( $config );
147 }
148
155 public static function mergeTemplate( array $base, array $specific ) {
156 foreach ( $specific as $key => $value ) {
157 if ( is_array( $value ) && isset( $base[$key] ) && is_array( $base[$key] ) ) {
158 $base[$key] = self::mergeTemplate( $base[$key], $value );
159 } else {
160 $base[$key] = $value;
161 }
162 }
163
164 return $base;
165 }
166}
The versatile default implementation of StringMangler interface.
Utility class to parse and validate message group configurations.
getDocumentsFromYaml( $data)
Given a Yaml string, returns the non-empty documents as an array.
parseDocuments(array $documents)
Returns group configurations from YAML documents.
getHopefullyValidConfigurations( $data, $callback=null)
Easy to use function to get valid group configurations from YAML.
static mergeTemplate(array $base, array $specific)
Merges a document template (base) to actual definition (specific)
validate(array $config)
Validates group configuration against schema.
static loadString( $text)