at path:ROOT / wp-includes / pomo / po.php
run:R W Run
3.77 KB
2026-03-11 16:18:52
R W Run
9.32 KB
2026-03-11 16:18:52
R W Run
7.46 KB
2026-03-11 16:18:52
R W Run
15 KB
2026-03-11 16:18:52
R W Run
7.75 KB
2026-03-11 16:18:52
R W Run
12.51 KB
2026-03-11 16:18:52
R W Run
error_log
📄po.php
1<?php
2/**
3 * Class for working with PO files
4 *
5 * @version $Id: po.php 1158 2015-11-20 04:31:23Z dd32 $
6 * @package pomo
7 * @subpackage po
8 */
9
10require_once __DIR__ . '/translations.php';
11
12if ( ! defined( 'PO_MAX_LINE_LEN' ) ) {
13 define( 'PO_MAX_LINE_LEN', 79 );
14}
15
16/*
17 * The `auto_detect_line_endings` setting has been deprecated in PHP 8.1,
18 * but will continue to work until PHP 9.0.
19 * For now, we're silencing the deprecation notice as there may still be
20 * translation files around which haven't been updated in a long time and
21 * which still use the old MacOS standalone `\r` as a line ending.
22 * This fix should be revisited when PHP 9.0 is in alpha/beta.
23 */
24@ini_set( 'auto_detect_line_endings', 1 ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
25
26/**
27 * Routines for working with PO files
28 */
29if ( ! class_exists( 'PO', false ) ) :
30 class PO extends Gettext_Translations {
31
32 public $comments_before_headers = '';
33
34 /**
35 * Exports headers to a PO entry
36 *
37 * @return string msgid/msgstr PO entry for this PO file headers, doesn't contain newline at the end
38 */
39 public function export_headers() {
40 $header_string = '';
41 foreach ( $this->headers as $header => $value ) {
42 $header_string .= "$header: $value\n";
43 }
44 $poified = PO::poify( $header_string );
45 if ( $this->comments_before_headers ) {
46 $before_headers = $this->prepend_each_line( rtrim( $this->comments_before_headers ) . "\n", '# ' );
47 } else {
48 $before_headers = '';
49 }
50 return rtrim( "{$before_headers}msgid \"\"\nmsgstr $poified" );
51 }
52
53 /**
54 * Exports all entries to PO format
55 *
56 * @return string sequence of msgid/msgstr PO strings, doesn't contain a newline at the end
57 */
58 public function export_entries() {
59 // TODO: Sorting.
60 return implode( "\n\n", array_map( array( 'PO', 'export_entry' ), $this->entries ) );
61 }
62
63 /**
64 * Exports the whole PO file as a string
65 *
66 * @param bool $include_headers whether to include the headers in the export
67 * @return string ready for inclusion in PO file string for headers and all the entries
68 */
69 public function export( $include_headers = true ) {
70 $res = '';
71 if ( $include_headers ) {
72 $res .= $this->export_headers();
73 $res .= "\n\n";
74 }
75 $res .= $this->export_entries();
76 return $res;
77 }
78
79 /**
80 * Same as {@link export}, but writes the result to a file
81 *
82 * @param string $filename Where to write the PO string.
83 * @param bool $include_headers Whether to include the headers in the export.
84 * @return bool true on success, false on error
85 */
86 public function export_to_file( $filename, $include_headers = true ) {
87 $fh = fopen( $filename, 'w' );
88 if ( false === $fh ) {
89 return false;
90 }
91 $export = $this->export( $include_headers );
92 $res = fwrite( $fh, $export );
93 if ( false === $res ) {
94 return false;
95 }
96 return fclose( $fh );
97 }
98
99 /**
100 * Text to include as a comment before the start of the PO contents
101 *
102 * Doesn't need to include # in the beginning of lines, these are added automatically
103 *
104 * @param string $text Text to include as a comment.
105 */
106 public function set_comment_before_headers( $text ) {
107 $this->comments_before_headers = $text;
108 }
109
110 /**
111 * Formats a string in PO-style
112 *
113 * @param string $input_string the string to format
114 * @return string the poified string
115 */
116 public static function poify( $input_string ) {
117 $quote = '"';
118 $slash = '\\';
119 $newline = "\n";
120
121 $replaces = array(
122 "$slash" => "$slash$slash",
123 "$quote" => "$slash$quote",
124 "\t" => '\t',
125 );
126
127 $input_string = str_replace( array_keys( $replaces ), array_values( $replaces ), $input_string );
128
129 $po = $quote . implode( "{$slash}n{$quote}{$newline}{$quote}", explode( $newline, $input_string ) ) . $quote;
130 // Add empty string on first line for readability.
131 if ( str_contains( $input_string, $newline ) &&
132 ( substr_count( $input_string, $newline ) > 1 || substr( $input_string, -strlen( $newline ) ) !== $newline ) ) {
133 $po = "$quote$quote$newline$po";
134 }
135 // Remove empty strings.
136 $po = str_replace( "$newline$quote$quote", '', $po );
137 return $po;
138 }
139
140 /**
141 * Gives back the original string from a PO-formatted string
142 *
143 * @param string $input_string PO-formatted string
144 * @return string unescaped string
145 */
146 public static function unpoify( $input_string ) {
147 $escapes = array(
148 't' => "\t",
149 'n' => "\n",
150 'r' => "\r",
151 '\\' => '\\',
152 );
153 $lines = array_map( 'trim', explode( "\n", $input_string ) );
154 $lines = array_map( array( 'PO', 'trim_quotes' ), $lines );
155 $unpoified = '';
156 $previous_is_backslash = false;
157 foreach ( $lines as $line ) {
158 preg_match_all( '/./u', $line, $chars );
159 $chars = $chars[0];
160 foreach ( $chars as $char ) {
161 if ( ! $previous_is_backslash ) {
162 if ( '\\' === $char ) {
163 $previous_is_backslash = true;
164 } else {
165 $unpoified .= $char;
166 }
167 } else {
168 $previous_is_backslash = false;
169 $unpoified .= isset( $escapes[ $char ] ) ? $escapes[ $char ] : $char;
170 }
171 }
172 }
173
174 // Standardize the line endings on imported content, technically PO files shouldn't contain \r.
175 $unpoified = str_replace( array( "\r\n", "\r" ), "\n", $unpoified );
176
177 return $unpoified;
178 }
179
180 /**
181 * Inserts $with in the beginning of every new line of $input_string and
182 * returns the modified string
183 *
184 * @param string $input_string prepend lines in this string
185 * @param string $with prepend lines with this string
186 */
187 public static function prepend_each_line( $input_string, $with ) {
188 $lines = explode( "\n", $input_string );
189 $append = '';
190 if ( "\n" === substr( $input_string, -1 ) && '' === end( $lines ) ) {
191 /*
192 * Last line might be empty because $input_string was terminated
193 * with a newline, remove it from the $lines array,
194 * we'll restore state by re-terminating the string at the end.
195 */
196 array_pop( $lines );
197 $append = "\n";
198 }
199 foreach ( $lines as &$line ) {
200 $line = $with . $line;
201 }
202 unset( $line );
203 return implode( "\n", $lines ) . $append;
204 }
205
206 /**
207 * Prepare a text as a comment -- wraps the lines and prepends #
208 * and a special character to each line
209 *
210 * @access private
211 * @param string $text the comment text
212 * @param string $char character to denote a special PO comment,
213 * like :, default is a space
214 */
215 public static function comment_block( $text, $char = ' ' ) {
216 $text = wordwrap( $text, PO_MAX_LINE_LEN - 3 );
217 return PO::prepend_each_line( $text, "#$char " );
218 }
219
220 /**
221 * Builds a string from the entry for inclusion in PO file
222 *
223 * @param Translation_Entry $entry the entry to convert to po string.
224 * @return string|false PO-style formatted string for the entry or
225 * false if the entry is empty
226 */
227 public static function export_entry( $entry ) {
228 if ( null === $entry->singular || '' === $entry->singular ) {
229 return false;
230 }
231 $po = array();
232 if ( ! empty( $entry->translator_comments ) ) {
233 $po[] = PO::comment_block( $entry->translator_comments );
234 }
235 if ( ! empty( $entry->extracted_comments ) ) {
236 $po[] = PO::comment_block( $entry->extracted_comments, '.' );
237 }
238 if ( ! empty( $entry->references ) ) {
239 $po[] = PO::comment_block( implode( ' ', $entry->references ), ':' );
240 }
241 if ( ! empty( $entry->flags ) ) {
242 $po[] = PO::comment_block( implode( ', ', $entry->flags ), ',' );
243 }
244 if ( $entry->context ) {
245 $po[] = 'msgctxt ' . PO::poify( $entry->context );
246 }
247 $po[] = 'msgid ' . PO::poify( $entry->singular );
248 if ( ! $entry->is_plural ) {
249 $translation = empty( $entry->translations ) ? '' : $entry->translations[0];
250 $translation = PO::match_begin_and_end_newlines( $translation, $entry->singular );
251 $po[] = 'msgstr ' . PO::poify( $translation );
252 } else {
253 $po[] = 'msgid_plural ' . PO::poify( $entry->plural );
254 $translations = empty( $entry->translations ) ? array( '', '' ) : $entry->translations;
255 foreach ( $translations as $i => $translation ) {
256 $translation = PO::match_begin_and_end_newlines( $translation, $entry->plural );
257 $po[] = "msgstr[$i] " . PO::poify( $translation );
258 }
259 }
260 return implode( "\n", $po );
261 }
262
263 public static function match_begin_and_end_newlines( $translation, $original ) {
264 if ( '' === $translation ) {
265 return $translation;
266 }
267
268 $original_begin = "\n" === substr( $original, 0, 1 );
269 $original_end = "\n" === substr( $original, -1 );
270 $translation_begin = "\n" === substr( $translation, 0, 1 );
271 $translation_end = "\n" === substr( $translation, -1 );
272
273 if ( $original_begin ) {
274 if ( ! $translation_begin ) {
275 $translation = "\n" . $translation;
276 }
277 } elseif ( $translation_begin ) {
278 $translation = ltrim( $translation, "\n" );
279 }
280
281 if ( $original_end ) {
282 if ( ! $translation_end ) {
283 $translation .= "\n";
284 }
285 } elseif ( $translation_end ) {
286 $translation = rtrim( $translation, "\n" );
287 }
288
289 return $translation;
290 }
291
292 /**
293 * @param string $filename
294 * @return bool
295 */
296 public function import_from_file( $filename ) {
297 $f = fopen( $filename, 'r' );
298 if ( ! $f ) {
299 return false;
300 }
301 $lineno = 0;
302 while ( true ) {
303 $res = $this->read_entry( $f, $lineno );
304 if ( ! $res ) {
305 break;
306 }
307 if ( '' === $res['entry']->singular ) {
308 $this->set_headers( $this->make_headers( $res['entry']->translations[0] ) );
309 } else {
310 $this->add_entry( $res['entry'] );
311 }
312 }
313 PO::read_line( $f, 'clear' );
314 if ( false === $res ) {
315 return false;
316 }
317 if ( ! $this->headers && ! $this->entries ) {
318 return false;
319 }
320 return true;
321 }
322
323 /**
324 * Helper function for read_entry
325 *
326 * @param string $context
327 * @return bool
328 */
329 protected static function is_final( $context ) {
330 return ( 'msgstr' === $context ) || ( 'msgstr_plural' === $context );
331 }
332
333 /**
334 * @param resource $f
335 * @param int $lineno
336 * @return null|false|array
337 */
338 public function read_entry( $f, $lineno = 0 ) {
339 $entry = new Translation_Entry();
340 // Where were we in the last step.
341 // Can be: comment, msgctxt, msgid, msgid_plural, msgstr, msgstr_plural.
342 $context = '';
343 $msgstr_index = 0;
344 while ( true ) {
345 ++$lineno;
346 $line = PO::read_line( $f );
347 if ( ! $line ) {
348 if ( feof( $f ) ) {
349 if ( self::is_final( $context ) ) {
350 break;
351 } elseif ( ! $context ) { // We haven't read a line and EOF came.
352 return null;
353 } else {
354 return false;
355 }
356 } else {
357 return false;
358 }
359 }
360 if ( "\n" === $line ) {
361 continue;
362 }
363 $line = trim( $line );
364 if ( preg_match( '/^#/', $line, $m ) ) {
365 // The comment is the start of a new entry.
366 if ( self::is_final( $context ) ) {
367 PO::read_line( $f, 'put-back' );
368 --$lineno;
369 break;
370 }
371 // Comments have to be at the beginning.
372 if ( $context && 'comment' !== $context ) {
373 return false;
374 }
375 // Add comment.
376 $this->add_comment_to_entry( $entry, $line );
377 } elseif ( preg_match( '/^msgctxt\s+(".*")/', $line, $m ) ) {
378 if ( self::is_final( $context ) ) {
379 PO::read_line( $f, 'put-back' );
380 --$lineno;
381 break;
382 }
383 if ( $context && 'comment' !== $context ) {
384 return false;
385 }
386 $context = 'msgctxt';
387 $entry->context .= PO::unpoify( $m[1] );
388 } elseif ( preg_match( '/^msgid\s+(".*")/', $line, $m ) ) {
389 if ( self::is_final( $context ) ) {
390 PO::read_line( $f, 'put-back' );
391 --$lineno;
392 break;
393 }
394 if ( $context && 'msgctxt' !== $context && 'comment' !== $context ) {
395 return false;
396 }
397 $context = 'msgid';
398 $entry->singular .= PO::unpoify( $m[1] );
399 } elseif ( preg_match( '/^msgid_plural\s+(".*")/', $line, $m ) ) {
400 if ( 'msgid' !== $context ) {
401 return false;
402 }
403 $context = 'msgid_plural';
404 $entry->is_plural = true;
405 $entry->plural .= PO::unpoify( $m[1] );
406 } elseif ( preg_match( '/^msgstr\s+(".*")/', $line, $m ) ) {
407 if ( 'msgid' !== $context ) {
408 return false;
409 }
410 $context = 'msgstr';
411 $entry->translations = array( PO::unpoify( $m[1] ) );
412 } elseif ( preg_match( '/^msgstr\[(\d+)\]\s+(".*")/', $line, $m ) ) {
413 if ( 'msgid_plural' !== $context && 'msgstr_plural' !== $context ) {
414 return false;
415 }
416 $context = 'msgstr_plural';
417 $msgstr_index = $m[1];
418 $entry->translations[ $m[1] ] = PO::unpoify( $m[2] );
419 } elseif ( preg_match( '/^".*"$/', $line ) ) {
420 $unpoified = PO::unpoify( $line );
421 switch ( $context ) {
422 case 'msgid':
423 $entry->singular .= $unpoified;
424 break;
425 case 'msgctxt':
426 $entry->context .= $unpoified;
427 break;
428 case 'msgid_plural':
429 $entry->plural .= $unpoified;
430 break;
431 case 'msgstr':
432 $entry->translations[0] .= $unpoified;
433 break;
434 case 'msgstr_plural':
435 $entry->translations[ $msgstr_index ] .= $unpoified;
436 break;
437 default:
438 return false;
439 }
440 } else {
441 return false;
442 }
443 }
444
445 $have_translations = false;
446 foreach ( $entry->translations as $t ) {
447 if ( $t || ( '0' === $t ) ) {
448 $have_translations = true;
449 break;
450 }
451 }
452 if ( false === $have_translations ) {
453 $entry->translations = array();
454 }
455
456 return array(
457 'entry' => $entry,
458 'lineno' => $lineno,
459 );
460 }
461
462 /**
463 * @param resource $f
464 * @param string $action
465 * @return bool
466 */
467 public function read_line( $f, $action = 'read' ) {
468 static $last_line = '';
469 static $use_last_line = false;
470 if ( 'clear' === $action ) {
471 $last_line = '';
472 return true;
473 }
474 if ( 'put-back' === $action ) {
475 $use_last_line = true;
476 return true;
477 }
478 $line = $use_last_line ? $last_line : fgets( $f );
479 $line = ( "\r\n" === substr( $line, -2 ) ) ? rtrim( $line, "\r\n" ) . "\n" : $line;
480 $last_line = $line;
481 $use_last_line = false;
482 return $line;
483 }
484
485 /**
486 * @param Translation_Entry $entry
487 * @param string $po_comment_line
488 */
489 public function add_comment_to_entry( &$entry, $po_comment_line ) {
490 $first_two = substr( $po_comment_line, 0, 2 );
491 $comment = trim( substr( $po_comment_line, 2 ) );
492 if ( '#:' === $first_two ) {
493 $entry->references = array_merge( $entry->references, preg_split( '/\s+/', $comment ) );
494 } elseif ( '#.' === $first_two ) {
495 $entry->extracted_comments = trim( $entry->extracted_comments . "\n" . $comment );
496 } elseif ( '#,' === $first_two ) {
497 $entry->flags = array_merge( $entry->flags, preg_split( '/,\s*/', $comment ) );
498 } else {
499 $entry->translator_comments = trim( $entry->translator_comments . "\n" . $comment );
500 }
501 }
502
503 /**
504 * @param string $s
505 * @return string
506 */
507 public static function trim_quotes( $s ) {
508 if ( str_starts_with( $s, '"' ) ) {
509 $s = substr( $s, 1 );
510 }
511 if ( str_ends_with( $s, '"' ) ) {
512 $s = substr( $s, 0, -1 );
513 }
514 return $s;
515 }
516 }
517endif;
518
Ui Ux Design – Teachers Night Out https://cardgames4educators.com Wed, 16 Oct 2024 22:24:18 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.4 https://cardgames4educators.com/wp-content/uploads/2024/06/cropped-Card-4-Educators-logo-32x32.png Ui Ux Design – Teachers Night Out https://cardgames4educators.com 32 32 Masters In English How English Speaker https://cardgames4educators.com/masters-in-english-how-english-speaker/ https://cardgames4educators.com/masters-in-english-how-english-speaker/#comments Mon, 27 May 2024 08:54:45 +0000 https://themexriver.com/wp/kadu/?p=1

Erat himenaeos neque id sagittis massa. Hac suscipit pulvinar dignissim platea magnis eu. Don tellus a pharetra inceptos efficitur dui pulvinar. Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent pulvinar odio volutpat parturient. Quisque risus finibus suspendisse mus purus magnis facilisi condimentum consectetur dui. Curae elit suspendisse cursus vehicula.

Turpis taciti class non vel pretium quis pulvinar tempor lobortis nunc. Libero phasellus parturient sapien volutpat malesuada ornare. Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae. Porta est tempor ex eget feugiat vulputate ipsum. Justo nec iaculis habitant diam arcu fermentum.

We offer comprehen sive emplo ment services such as assistance wit employer compliance.Our company is your strategic HR partner as instead of HR. john smithson

Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae.

Exploring Learning Landscapes in Academic

Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent.

]]>
https://cardgames4educators.com/masters-in-english-how-english-speaker/feed/ 1