88eb1c1afb6cd28fa0446b2e1005b8574418a545
[pear] / File / Gettext / PO.php
1 <?php
2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
4 /**
5  * File::Gettext
6  * 
7  * PHP versions 4 and 5
8  *
9  * @category   FileFormats
10  * @package    File_Gettext
11  * @author     Michael Wallner <mike@php.net>
12  * @copyright  2004-2005 Michael Wallner
13  * @license    BSD, revised
14  * @version    CVS: $Id: PO.php,v 1.6 2006/01/07 09:45:25 mike Exp $
15  * @link       http://pear.php.net/package/File_Gettext
16  */
17
18 /**
19  * Requires File_Gettext
20  */
21 require_once 'File/Gettext.php';
22
23 /** 
24  * File_Gettext_PO
25  *
26  * GNU PO file reader and writer.
27  * 
28  * @author      Michael Wallner <mike@php.net>
29  * @version     $Revision: 1.6 $
30  * @access      public
31  */
32 class File_Gettext_PO extends File_Gettext
33 {
34     /**
35      * Constructor
36      *
37      * @access  public
38      * @return  object      File_Gettext_PO
39      * @param   string      path to GNU PO file
40      */
41     function File_Gettext_PO($file = '')
42     {
43         $this->file = $file;
44     }
45
46     /**
47      * Load PO file
48      *
49      * @access  public
50      * @return  mixed   Returns true on success or PEAR_Error on failure.
51      * @param   string  $file
52      */
53     function load($file = null)
54     {
55         $this->strings = array();
56         
57         if (!isset($file)) {
58             $file = $this->file;
59         }
60         
61         // load file
62         if (!$contents = @file($file)) {
63             return parent::raiseError($php_errormsg . ' ' . $file);
64         }
65         $contents = implode('', $contents);
66         
67         // match all msgid/msgstr entries
68         $matched = preg_match_all(
69             '/(msgid\s+("([^"]|\\\\")*?"\s*)+)\s+' .
70             '(msgstr\s+("([^"]|\\\\")*?"\s*)+)/',
71             $contents, $matches
72         );
73         unset($contents);
74         
75         if (!$matched) {
76             return parent::raiseError('No msgid/msgstr entries found');
77         }
78         
79         // get all msgids and msgtrs
80         for ($i = 0; $i < $matched; $i++) {
81             $msgid = preg_replace(
82                 '/\s*msgid\s*"(.*)"\s*/s', '\\1', $matches[1][$i]);
83             $msgstr= preg_replace(
84                 '/\s*msgstr\s*"(.*)"\s*/s', '\\1', $matches[4][$i]);
85             $this->strings[parent::prepare($msgid)] = parent::prepare($msgstr);
86         }
87         
88         // check for meta info
89         if (isset($this->strings[''])) {
90             $this->meta = parent::meta2array($this->strings['']);
91             unset($this->strings['']);
92         }
93         
94         return true;
95     }
96     
97     /**
98      * Save PO file
99      *
100      * @access  public
101      * @return  mixed   Returns true on success or PEAR_Error on failure.
102      * @param   string  $file
103      */
104     function save($file = null)
105     {
106         if (!isset($file)) {
107             $file = $this->file;
108         }
109         
110         // open PO file
111         if (!is_resource($fh = @fopen($file, 'w'))) {
112             return parent::raiseError($php_errormsg . ' ' . $file);
113         }
114         // lock PO file exclusively
115         if (!@flock($fh, LOCK_EX)) {
116             @fclose($fh);
117             return parent::raiseError($php_errmsg . ' ' . $file);
118         }
119         
120         // write meta info
121         if (count($this->meta)) {
122             $meta = 'msgid ""' . "\nmsgstr " . '""' . "\n";
123             foreach ($this->meta as $k => $v) {
124                 $meta .= '"' . $k . ': ' . $v . '\n"' . "\n";
125             }
126             fwrite($fh, $meta . "\n");
127         }
128         // write strings
129         foreach ($this->strings as $o => $t) {
130             fwrite($fh,
131                 'msgid "'  . parent::prepare($o, true) . '"' . "\n" .
132                 'msgstr "' . parent::prepare($t, true) . '"' . "\n\n"
133             );
134         }
135         
136         //done
137         @flock($fh, LOCK_UN);
138         @fclose($fh);
139         return true;
140     }
141 }
142 ?>