WordPress 4.4
[autoinstalls/wordpress.git] / wp-includes / pomo / po.php
index 6c40c5a4eee44ea7e9c9324ee32a4a2ab79d6a20..65d65ff39eb1640594432d1d7af22d0240e5e336 100644 (file)
@@ -2,22 +2,26 @@
 /**
  * Class for working with PO files
  *
- * @version $Id: po.php 123 2009-05-13 19:35:43Z 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', false ) ):
 class PO extends Gettext_Translations {
-       
+
+       var $comments_before_headers = '';
 
        /**
         * Exports headers to a PO entry
@@ -30,7 +34,11 @@ class PO extends Gettext_Translations {
                        $header_string.= "$header: $value\n";
                }
                $poified = PO::poify($header_string);
-               return rtrim("msgid \"\"\nmsgstr $poified");
+               if ($this->comments_before_headers)
+                       $before_headers = $this->prepend_each_line(rtrim($this->comments_before_headers)."\n", '# ');
+               else
+                       $before_headers = '';
+               return rtrim("{$before_headers}msgid \"\"\nmsgstr $poified");
        }
 
        /**
@@ -75,6 +83,15 @@ class PO extends Gettext_Translations {
                return fclose($fh);
        }
 
+       /**
+        * Text to include as a comment before the start of the PO contents
+        *
+        * Doesn't need to include # in the beginning of lines, these are added automatically
+        */
+       function set_comment_before_headers( $text ) {
+               $this->comments_before_headers = $text;
+       }
+
        /**
         * Formats a string in PO-style
         *
@@ -82,7 +99,7 @@ class PO extends Gettext_Translations {
         * @param string $string the string to format
         * @return string the poified string
         */
-       function poify($string) {
+       public static function poify($string) {
                $quote = '"';
                $slash = '\\';
                $newline = "\n";
@@ -105,16 +122,16 @@ class PO extends Gettext_Translations {
                $po = str_replace("$newline$quote$quote", '', $po);
                return $po;
        }
-       
+
        /**
         * Gives back the original string from a PO-formatted string
-        * 
+        *
         * @static
         * @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 = '';
@@ -134,18 +151,22 @@ class PO extends Gettext_Translations {
                                }
                        }
                }
+
+               // 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;
        }
 
        /**
-        * Inserts $with in the beginning of every new line of $string and 
+        * Inserts $with in the beginning of every new line of $string and
         * returns the modified string
         *
         * @static
         * @param string $string prepend lines in this string
         * @param string $with prepend lines with this string
         */
-       function prepend_each_line($string, $with) {
+       public static function prepend_each_line($string, $with) {
                $php_with = var_export($with, true);
                $lines = explode("\n", $string);
                // do not prepend the string on the last empty line, artefact by explode
@@ -165,7 +186,7 @@ class PO extends Gettext_Translations {
         * @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 ");
        }
@@ -174,32 +195,67 @@ class PO extends Gettext_Translations {
         * Builds a string from the entry for inclusion in PO file
         *
         * @static
-        * @param object &$entry the entry to convert to po string
-        * @return string|bool PO-style formatted string for the entry or
+        * @param Translation_Entry &$entry the entry to convert to po string
+        * @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
+        */
        function import_from_file($filename) {
                $f = fopen($filename, 'r');
                if (!$f) return false;
@@ -214,9 +270,20 @@ class PO extends Gettext_Translations {
                        }
                }
                PO::read_line($f, 'clear');
-               return $res !== false;
+               if ( false === $res ) {
+                       return false;
+               }
+               if ( ! $this->headers && ! $this->entries ) {
+                       return false;
+               }
+               return true;
        }
-       
+
+       /**
+        * @param resource $f
+        * @param int      $lineno
+        * @return null|false|array
+        */
        function read_entry($f, $lineno = 0) {
                $entry = new Translation_Entry();
                // where were we in the last step
@@ -253,7 +320,7 @@ class PO extends Gettext_Translations {
                                        return false;
                                }
                                // add comment
-                               $this->add_comment_to_entry($entry, $line);;
+                               $this->add_comment_to_entry($entry, $line);
                        } elseif (preg_match('/^msgctxt\s+(".*")/', $line, $m)) {
                                if ($is_final($context)) {
                                        PO::read_line($f, 'put-back');
@@ -316,10 +383,20 @@ class PO extends Gettext_Translations {
                                return false;
                        }
                }
-               if (array() == array_filter($entry->translations)) $entry->translations = array();
+               if (array() == array_filter($entry->translations, create_function('$t', 'return $t || "0" === $t;'))) {
+                       $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
+        */
        function read_line($f, $action = 'read') {
                static $last_line = '';
                static $use_last_line = false;
@@ -332,11 +409,16 @@ class PO extends Gettext_Translations {
                        return true;
                }
                $line = $use_last_line? $last_line : fgets($f);
+               $line = ( "\r\n" == substr( $line, -2 ) ) ? rtrim( $line, "\r\n" ) . "\n" : $line;
                $last_line = $line;
                $use_last_line = false;
                return $line;
        }
-       
+
+       /**
+        * @param Translation_Entry $entry
+        * @param string            $po_comment_line
+        */
        function add_comment_to_entry(&$entry, $po_comment_line) {
                $first_two = substr($po_comment_line, 0, 2);
                $comment = trim(substr($po_comment_line, 2));
@@ -350,11 +432,15 @@ class PO extends Gettext_Translations {
                        $entry->translator_comments = trim($entry->translator_comments . "\n" . $comment);
                }
        }
-       
-       function trim_quotes($s) {
+
+       /**
+        * @param string $s
+        * @return sring
+        */
+       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;
        }
 }
-?>
+endif;