33
33
return ;
34
34
}
35
35
36
- $ generate = realpath ( __DIR__ . "/../.entities.ent " ); // sibling of .manual.xml
36
+ $ filename = __DIR__ . "/../.entities.ent " ; // sibling of .manual.xml
37
+ touch ( $ filename ); // empty file, at minimum, and
38
+ $ filename = realpath ( $ filename ); // realpath() fails if file not exists.
39
+
37
40
$ entities = []; // all entitites, already overriden
38
41
$ expected = []; // entities that are expected to be oversidem (translatins)
39
42
$ override = []; // overrides stattics
48
51
$ langs [] = $ argv [$ idx ];
49
52
50
53
if ( $ detail )
51
- print "Creating file $ generate in verbose detail mode... \n" ;
54
+ print "Creating file $ filename in verbose detail mode... \n" ;
52
55
else
53
- print "Creating file $ generate ... " ;
56
+ print "Creating file $ filename ... " ;
54
57
55
58
for ( $ run = 0 ; $ run < count ( $ langs ) ; $ run ++ )
56
59
parseDir ( $ langs [$ run ] , $ run > 0 );
57
60
58
- dump ( $ entities );
59
-
60
- [$ count , $ untranslated , $ overriden ] = verifyOverrides ( $ detail );
61
+ dump ( $ filename , $ entities );
61
62
62
63
if ( $ detail )
63
64
{
66
67
else
67
68
{
68
69
echo " done " ;
69
- if ( $ untranslated + $ overriden > 0 )
70
- echo ": $ count entities, $ untranslated untranslated, $ overriden orerriden " ;
70
+ [$ all , $ unt , $ over ] = verifyOverrides ( $ detail );
71
+ if ( $ unt + $ over > 0 )
72
+ echo ": $ all entities, $ unt untranslated, $ over orerriden " ;
71
73
echo ". \n" ;
72
74
}
73
75
exit ;
@@ -92,52 +94,59 @@ function parseDir( string $dir , bool $expectedOverride )
92
94
continue ;
93
95
94
96
$ text = file_get_contents ( $ path );
95
-
96
- if ( validate ( $ path , $ text , false ) )
97
- {
98
- push ( $ path , $ text , $ expectedOverride );
99
- continue ;
100
- }
101
-
102
- $ frag = "<frag> $ text</frag> " ;
103
- if ( validate ( $ path , $ frag , true ) )
104
- {
105
- push ( $ path , $ text , $ expectedOverride );
106
- continue ;
107
- }
97
+ validateStore ( $ path , $ text , $ expectedOverride );
108
98
}
109
99
}
110
100
111
- function validate ( string $ path , string $ text , bool $ warn ) : bool
101
+ function validateStore ( string $ path , string $ text , bool $ expectedOverride )
112
102
{
103
+ $ trim = trim ( $ text );
104
+ if ( strlen ( $ trim ) == 0 )
105
+ {
106
+ // Yes, there is empty entities, and they are valid entity, but not valid XML.
107
+ // see: en/language-snippets.ent mongodb.note.queryable-encryption-preview
108
+ push ( $ path , $ text , $ expectedOverride , true );
109
+ return ;
110
+ }
111
+
112
+ $ frag = "<root> $ text</root> " ;
113
+
113
114
$ dom = new DOMDocument ( '1.0 ' , 'utf8 ' );
114
115
$ dom ->recover = true ;
115
116
$ dom ->resolveExternals = false ;
116
117
libxml_use_internal_errors ( true );
117
118
118
- $ res = $ dom ->loadXML ( $ text );
119
+ $ res = $ dom ->loadXML ( $ frag );
119
120
120
121
$ err = libxml_get_errors ();
121
122
libxml_clear_errors ();
122
123
123
124
foreach ( $ err as $ item )
124
125
{
125
- $ msg = $ item ->message ;
126
+ $ msg = trim ( $ item ->message ) ;
126
127
if ( str_starts_with ( $ msg , "Entity ' " ) && str_ends_with ( $ msg , "' not defined " ) )
127
128
continue ;
128
129
129
- if ( $ warn )
130
- {
131
- fwrite ( STDERR , "\n XML load failed on entity file. " );
132
- fwrite ( STDERR , "\n Path: $ path " );
133
- fwrite ( STDERR , "\n Error: $ msg \n" );
134
- }
135
- return false ;
130
+ fwrite ( STDERR , "\n XML load failed on entity file. " );
131
+ fwrite ( STDERR , "\n Path: $ path " );
132
+ fwrite ( STDERR , "\n Error: $ msg \n" );
133
+ return ;
136
134
}
137
- return true ;
135
+
136
+ $ inline = shouldInline ( $ dom );
137
+ push ( $ path , $ text , $ expectedOverride , $ inline );
138
138
}
139
139
140
- function push ( string $ path , string $ contents , bool $ expectedOverride )
140
+ class EntityData
141
+ {
142
+ public function __construct (
143
+ public string $ path ,
144
+ public string $ name ,
145
+ public string $ text ,
146
+ public bool $ inline ) {}
147
+ }
148
+
149
+ function push ( string $ path , string $ text , bool $ expectedOverride , bool $ inline )
141
150
{
142
151
global $ entities ;
143
152
global $ expected ;
@@ -154,28 +163,56 @@ function push( string $path , string $contents , bool $expectedOverride )
154
163
else
155
164
$ override [$ name ]++;
156
165
157
- $ entities [$ name ] = $ contents ;
166
+ $ entity = new EntityData ( $ path , $ name , $ text , $ inline );
167
+ $ entities [$ name ] = $ entity ;
158
168
}
159
169
160
- function dump ( array $ entities )
170
+ function dump ( string $ filename , array $ entities )
161
171
{
162
- global $ generate ;
163
-
164
172
// In PHP 8.4 may be possible to construct an extended
165
173
// DOMEntity class with writable properties. For now,
166
174
// creating entities files directly as text.
167
175
168
- $ file = fopen ( $ generate , "w " );
176
+ $ file = fopen ( $ filename , "w " );
169
177
fputs ( $ file , "\n<!-- DO NOT COPY - Autogenerated by entities.php --> \n\n" );
170
178
171
- foreach ( $ entities as $ name => $ text )
179
+ foreach ( $ entities as $ name => $ entity )
172
180
{
173
- $ text = str_replace ( "' " , '' ' , $ text );
174
- fputs ( $ file , "<!ENTITY $ name ' $ text'> \n\n" );
181
+ if ( $ entity ->inline )
182
+ {
183
+ $ text = str_replace ( "' " , '' ' , $ entity ->text );
184
+ fputs ( $ file , "<!ENTITY $ name ' $ text'> \n\n" );
185
+ }
186
+ else
187
+ {
188
+ fputs ( $ file , "<!ENTITY $ name SYSTEM ' {$ entity ->path }'> \n\n" );
189
+ }
175
190
}
176
191
fclose ( $ file );
177
192
}
178
193
194
+ function shouldInline ( DOMDocument $ dom ) : bool
195
+ {
196
+ // Pure text entities CANNOT be SYSTEMed (or libxml fails).
197
+ // But entities that CONTAINS elements NEED to be SYSTEMed
198
+ // to avoid quotation madness.
199
+
200
+ // Why libxml/w3c? WHY?
201
+
202
+ $ xpath = new DomXPath ( $ dom );
203
+ $ elems = $ xpath ->query ( "child::* " );
204
+ return ( $ elems ->length == 0 );
205
+ }
206
+
207
+ function shouldInlineRecurse ( DOMNode $ node ) : bool
208
+ {
209
+ if ( $ node ->nodeType == XML_ELEMENT_NODE )
210
+ return true ;
211
+ foreach ( $ node ->childNodes as $ node )
212
+ return shouldInlineRecurse ( $ node );
213
+
214
+ }
215
+
179
216
function verifyOverrides ( bool $ outputDetail )
180
217
{
181
218
global $ entities ;
@@ -211,4 +248,4 @@ function verifyOverrides( bool $outputDetail )
211
248
}
212
249
213
250
return [$ countGenerated , $ countExpectedOverriden , $ countUnexpectedOverriden ];
214
- }
251
+ }
0 commit comments