wp/wp-includes/pomo/po.php
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
--- a/wp/wp-includes/pomo/po.php	Tue Jun 09 11:14:17 2015 +0000
+++ b/wp/wp-includes/pomo/po.php	Mon Oct 14 17:39:30 2019 +0200
@@ -2,21 +2,23 @@
 /**
  * Class for working with PO files
  *
- * @version $Id: po.php 718 2012-10-31 00:32:02Z nbachiyski $
+ * @version $Id: po.php 1158 2015-11-20 04:31:23Z dd32 $
  * @package pomo
  * @subpackage po
  */
 
 require_once dirname(__FILE__) . '/translations.php';
 
-define('PO_MAX_LINE_LEN', 79);
+if ( ! defined( 'PO_MAX_LINE_LEN' ) ) {
+	define('PO_MAX_LINE_LEN', 79);
+}
 
 ini_set('auto_detect_line_endings', 1);
 
 /**
  * Routines for working with PO files
  */
-if ( !class_exists( 'PO' ) ):
+if ( ! class_exists( 'PO', false ) ):
 class PO extends Gettext_Translations {
 
 	var $comments_before_headers = '';
@@ -97,7 +99,7 @@
 	 * @param string $string the string to format
 	 * @return string the poified string
 	 */
-	function poify($string) {
+	public static function poify($string) {
 		$quote = '"';
 		$slash = '\\';
 		$newline = "\n";
@@ -128,8 +130,8 @@
 	 * @param string $string PO-formatted string
 	 * @return string enascaped string
 	 */
-	function unpoify($string) {
-		$escapes = array('t' => "\t", 'n' => "\n", '\\' => '\\');
+	public static function unpoify($string) {
+		$escapes = array('t' => "\t", 'n' => "\n", 'r' => "\r", '\\' => '\\');
 		$lines = array_map('trim', explode("\n", $string));
 		$lines = array_map(array('PO', 'trim_quotes'), $lines);
 		$unpoified = '';
@@ -149,6 +151,10 @@
 				}
 			}
 		}
+
+		// Standardise the line endings on imported content, technically PO files shouldn't contain \r
+		$unpoified = str_replace( array( "\r\n", "\r" ), "\n", $unpoified );
+
 		return $unpoified;
 	}
 
@@ -160,15 +166,21 @@
 	 * @param string $string prepend lines in this string
 	 * @param string $with prepend lines with this string
 	 */
-	function prepend_each_line($string, $with) {
-		$php_with = var_export($with, true);
+	public static function prepend_each_line($string, $with) {
 		$lines = explode("\n", $string);
-		// do not prepend the string on the last empty line, artefact by explode
-		if ("\n" == substr($string, -1)) unset($lines[count($lines) - 1]);
-		$res = implode("\n", array_map(create_function('$x', "return $php_with.\$x;"), $lines));
-		// give back the empty line, we ignored above
-		if ("\n" == substr($string, -1)) $res .= "\n";
-		return $res;
+		$append = '';
+		if ("\n" === substr($string, -1) && '' === end($lines)) {
+			// Last line might be empty because $string was terminated
+			// with a newline, remove it from the $lines array,
+			// we'll restore state by re-terminating the string at the end
+			array_pop($lines);
+			$append = "\n";
+		}
+		foreach ($lines as &$line) {
+			$line = $with . $line;
+		}
+		unset($line);
+		return implode("\n", $lines) . $append;
 	}
 
 	/**
@@ -180,7 +192,7 @@
 	 * @param string $char character to denote a special PO comment,
 	 * 	like :, default is a space
 	 */
-	function comment_block($text, $char=' ') {
+	public static function comment_block($text, $char=' ') {
 		$text = wordwrap($text, PO_MAX_LINE_LEN - 3);
 		return PO::prepend_each_line($text, "#$char ");
 	}
@@ -189,32 +201,63 @@
 	 * Builds a string from the entry for inclusion in PO file
 	 *
 	 * @static
-	 * @param Translation_Entry &$entry the entry to convert to po string
+	 * @param Translation_Entry $entry the entry to convert to po string (passed by reference).
 	 * @return false|string PO-style formatted string for the entry or
 	 * 	false if the entry is empty
 	 */
-	function export_entry(&$entry) {
-		if (is_null($entry->singular)) return false;
+	public static function export_entry(&$entry) {
+		if ( null === $entry->singular || '' === $entry->singular ) return false;
 		$po = array();
 		if (!empty($entry->translator_comments)) $po[] = PO::comment_block($entry->translator_comments);
 		if (!empty($entry->extracted_comments)) $po[] = PO::comment_block($entry->extracted_comments, '.');
 		if (!empty($entry->references)) $po[] = PO::comment_block(implode(' ', $entry->references), ':');
 		if (!empty($entry->flags)) $po[] = PO::comment_block(implode(", ", $entry->flags), ',');
-		if (!is_null($entry->context)) $po[] = 'msgctxt '.PO::poify($entry->context);
+		if ($entry->context) $po[] = 'msgctxt '.PO::poify($entry->context);
 		$po[] = 'msgid '.PO::poify($entry->singular);
 		if (!$entry->is_plural) {
 			$translation = empty($entry->translations)? '' : $entry->translations[0];
+			$translation = PO::match_begin_and_end_newlines( $translation, $entry->singular );
 			$po[] = 'msgstr '.PO::poify($translation);
 		} else {
 			$po[] = 'msgid_plural '.PO::poify($entry->plural);
 			$translations = empty($entry->translations)? array('', '') : $entry->translations;
 			foreach($translations as $i => $translation) {
+				$translation = PO::match_begin_and_end_newlines( $translation, $entry->plural );
 				$po[] = "msgstr[$i] ".PO::poify($translation);
 			}
 		}
 		return implode("\n", $po);
 	}
 
+	public static function match_begin_and_end_newlines( $translation, $original ) {
+		if ( '' === $translation ) {
+			return $translation;
+		}
+
+		$original_begin = "\n" === substr( $original, 0, 1 );
+		$original_end = "\n" === substr( $original, -1 );
+		$translation_begin = "\n" === substr( $translation, 0, 1 );
+		$translation_end = "\n" === substr( $translation, -1 );
+
+		if ( $original_begin ) {
+			if ( ! $translation_begin ) {
+				$translation = "\n" . $translation;
+			}
+		} elseif ( $translation_begin ) {
+			$translation = ltrim( $translation, "\n" );
+		}
+
+		if ( $original_end ) {
+			if ( ! $translation_end ) {
+				$translation .= "\n";
+			}
+		} elseif ( $translation_end ) {
+			$translation = rtrim( $translation, "\n" );
+		}
+
+		return $translation;
+	}
+
 	/**
 	 * @param string $filename
 	 * @return boolean
@@ -243,6 +286,15 @@
 	}
 
 	/**
+	 * Helper function for read_entry
+	 * @param string $context
+	 * @return bool
+	 */
+	protected static function is_final($context) {
+		return ($context === 'msgstr') || ($context === 'msgstr_plural');
+	}
+
+	/**
 	 * @param resource $f
 	 * @param int      $lineno
 	 * @return null|false|array
@@ -253,13 +305,12 @@
 		// can be: comment, msgctxt, msgid, msgid_plural, msgstr, msgstr_plural
 		$context = '';
 		$msgstr_index = 0;
-		$is_final = create_function('$context', 'return $context == "msgstr" || $context == "msgstr_plural";');
 		while (true) {
 			$lineno++;
 			$line = PO::read_line($f);
 			if (!$line)  {
 				if (feof($f)) {
-					if ($is_final($context))
+					if (self::is_final($context))
 						break;
 					elseif (!$context) // we haven't read a line and eof came
 						return null;
@@ -273,7 +324,7 @@
 			$line = trim($line);
 			if (preg_match('/^#/', $line, $m)) {
 				// the comment is the start of a new entry
-				if ($is_final($context)) {
+				if (self::is_final($context)) {
 					PO::read_line($f, 'put-back');
 					$lineno--;
 					break;
@@ -285,7 +336,7 @@
 				// add comment
 				$this->add_comment_to_entry($entry, $line);
 			} elseif (preg_match('/^msgctxt\s+(".*")/', $line, $m)) {
-				if ($is_final($context)) {
+				if (self::is_final($context)) {
 					PO::read_line($f, 'put-back');
 					$lineno--;
 					break;
@@ -296,7 +347,7 @@
 				$context = 'msgctxt';
 				$entry->context .= PO::unpoify($m[1]);
 			} elseif (preg_match('/^msgid\s+(".*")/', $line, $m)) {
-				if ($is_final($context)) {
+				if (self::is_final($context)) {
 					PO::read_line($f, 'put-back');
 					$lineno--;
 					break;
@@ -346,15 +397,25 @@
 				return false;
 			}
 		}
-		if (array() == array_filter($entry->translations, create_function('$t', 'return $t || "0" === $t;'))) {
+
+		$have_translations = false;
+		foreach ( $entry->translations as $t ) {
+			if ( $t || ('0' === $t) ) {
+				$have_translations = true;
+				break;
+			}
+		}
+		if ( false === $have_translations ) {
 			$entry->translations = array();
 		}
+
 		return array('entry' => $entry, 'lineno' => $lineno);
 	}
 
 	/**
 	 * @staticvar string   $last_line
 	 * @staticvar boolean  $use_last_line
+	 *
 	 * @param     resource $f
 	 * @param     string   $action
 	 * @return boolean
@@ -399,7 +460,7 @@
 	 * @param string $s
 	 * @return sring
 	 */
-	function trim_quotes($s) {
+	public static function trim_quotes($s) {
 		if ( substr($s, 0, 1) == '"') $s = substr($s, 1);
 		if ( substr($s, -1, 1) == '"') $s = substr($s, 0, -1);
 		return $s;