Development

/branches/1.4/lib/i18n/sfMessageSource_gettext.class.php

You must first sign up to be able to contribute.

root/branches/1.4/lib/i18n/sfMessageSource_gettext.class.php

Revision 23810, 8.2 kB (checked in by Kris.Wallsmith, 5 years ago)

[1.3] set svn:eol-style property to native and svn:keywords property to Id on all .php files

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1 <?php
2
3 /**
4  * sfMessageSource_gettext class file.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the BSD License.
8  *
9  * Copyright(c) 2004 by Qiang Xue. All rights reserved.
10  *
11  * To contact the author write to {@link mailto:qiang.xue@gmail.com Qiang Xue}
12  * The latest version of PRADO can be obtained from:
13  * {@link http://prado.sourceforge.net/}
14  *
15  * @author     Wei Zhuo <weizhuo[at]gmail[dot]com>
16  * @version    $Id$
17  * @package    symfony
18  * @subpackage i18n
19  */
20
21 /**
22  * sfMessageSource_gettext class.
23  *
24  * Using Gettext MO format as the message source for translation.
25  * The gettext classes are based on PEAR's gettext MO and PO classes.
26  *
27  * See the MessageSource::factory() method to instantiate this class.
28  *
29  * @author Xiang Wei Zhuo <weizhuo[at]gmail[dot]com>
30  * @version v1.0, last update on Fri Dec 24 16:18:44 EST 2004
31  * @package    symfony
32  * @subpackage i18n
33  */
34 class sfMessageSource_gettext extends sfMessageSource_File
35 {
36   /**
37    * Message data filename extension.
38    * @var string
39    */
40   protected $dataExt = '.mo';
41
42   /**
43    * PO data filename extension
44    * @var string
45    */
46   protected $poExt = '.po';
47
48   /**
49    * Loads the messages from a MO file.
50    *
51    * @param string $filename MO file.
52    * @return array of messages.
53    */
54   public function &loadData($filename)
55   {
56     $mo = TGettext::factory('MO',$filename);
57     $mo->load();
58     $result = $mo->toArray();
59
60     $results = array();
61     $count = 0;
62     foreach ($result['strings'] as $source => $target)
63     {
64       $results[$source][] = $target//target
65       $results[$source][] = $count++; //id
66       $results[$source][] = '';       //comments
67     }
68
69     return $results;
70   }
71
72   /**
73    * Gets the variant for a catalogue depending on the current culture.
74    *
75    * @param string $catalogue catalogue
76    * @return string the variant.
77    * @see save()
78    * @see update()
79    * @see delete()
80    */
81   protected function getVariants($catalogue = 'messages')
82   {
83     if (empty($catalogue))
84     {
85       $catalogue = 'messages';
86     }
87
88     foreach ($this->getCatalogueList($catalogue) as $variant)
89     {
90       $file = $this->getSource($variant);
91       $po = $this->getPOFile($file);
92       if (is_file($file) || is_file($po))
93       {
94         return array($variant, $file, $po);
95       }
96     }
97
98     return false;
99   }
100
101   protected function getPOFile($MOFile)
102   {
103     return substr($MOFile, 0, strlen($MOFile) - strlen($this->dataExt)).$this->poExt;
104   }
105
106   /**
107    * Saves the list of untranslated blocks to the translation source.
108    * If the translation was not found, you should add those
109    * strings to the translation source via the <b>append()</b> method.
110    *
111    * @param string $catalogue the catalogue to add to
112    * @return boolean true if saved successfuly, false otherwise.   
113    */
114   function save($catalogue = 'messages')
115   {
116     $messages = $this->untranslated;
117
118     if (count($messages) <= 0)
119     {
120       return false;
121     }
122
123     $variants = $this->getVariants($catalogue);
124
125     if ($variants)
126     {
127       list($variant, $MOFile, $POFile) = $variants;
128     }
129     else
130     {
131       list($variant, $MOFile, $POFile) = $this->createMessageTemplate($catalogue);
132     }
133
134     if (is_writable($MOFile) == false)
135     {
136       throw new sfException(sprintf("Unable to save to file %s, file must be writable.", $MOFile));
137     }
138     if (is_writable($POFile) == false)
139     {
140       throw new sfException(sprintf("Unable to save to file %s, file must be writable.", $POFile));
141     }
142
143     // set the strings as untranslated.
144     $strings = array();
145     foreach ($messages as $message)
146     {
147       $strings[$message] = '';
148     }
149
150     // load the PO
151     $po = TGettext::factory('PO',$POFile);
152     $po->load();
153     $result = $po->toArray();
154
155     $existing = count($result['strings']);
156
157     // add to strings to the existing message list
158     $result['strings'] = array_merge($result['strings'],$strings);
159
160     $new = count($result['strings']);
161
162     if ($new > $existing)
163     {
164       // change the date 2004-12-25 12:26
165       $result['meta']['PO-Revision-Date'] = @date('Y-m-d H:i:s');
166
167       $po->fromArray($result);
168       $mo = $po->toMO();
169       if ($po->save() && $mo->save($MOFile))
170       {
171         if ($this->cache)
172         {
173           $this->cache->remove($variant.':'.$this->culture);
174         }
175
176         return true;
177       }
178       else
179       {
180         return false;
181       }
182     }
183
184     return false;
185   }
186
187   /**
188    * Deletes a particular message from the specified catalogue.
189    *
190    * @param string $message   the source message to delete.
191    * @param string $catalogue the catalogue to delete from.
192    * @return boolean true if deleted, false otherwise.
193    */
194   function delete($message, $catalogue = 'messages')
195   {
196     $variants = $this->getVariants($catalogue);
197     if ($variants)
198     {
199       list($variant, $MOFile, $POFile) = $variants;
200     }
201     else
202     {
203       return false;
204     }
205
206     if (is_writable($MOFile) == false)
207     {
208       throw new sfException(sprintf("Unable to modify file %s, file must be writable.", $MOFile));
209     }
210
211     if (is_writable($POFile) == false)
212     {
213       throw new sfException(sprintf("Unable to modify file %s, file must be writable.", $POFile));
214     }
215
216     $po = TGettext::factory('PO', $POFile);
217     $po->load();
218     $result = $po->toArray();
219
220     foreach ($result['strings'] as $string => $value)
221     {
222       if ($string == $message)
223       {
224         $result['meta']['PO-Revision-Date'] = @date('Y-m-d H:i:s');
225         unset($result['strings'][$string]);
226
227         $po->fromArray($result);
228         $mo = $po->toMO();
229         if ($po->save() && $mo->save($MOFile))
230         {
231           if ($this->cache)
232           {
233             $this->cache->remove($variant.':'.$this->culture);
234           }
235
236           return true;
237         }
238         else
239         {
240           return false;
241         }
242       }
243     }
244
245     return false;
246   }
247
248   /**
249    * Updates the translation.
250    *
251    * @param string $text      the source string.
252    * @param string $target    the new translation string.
253    * @param string $comments  comments
254    * @param string $catalogue the catalogue of the translation.
255    * @return boolean true if translation was updated, false otherwise.
256    */
257   function update($text, $target, $comments, $catalogue = 'messages')
258   {
259     $variants = $this->getVariants($catalogue);
260     if ($variants)
261     {
262       list($variant, $MOFile, $POFile) = $variants;
263     }
264     else
265     {
266       return false;
267     }
268
269     if (is_writable($MOFile) == false)
270     {
271       throw new sfException(sprintf("Unable to update file %s, file must be writable.", $MOFile));
272     }
273
274     if (is_writable($POFile) == false)
275     {
276       throw new sfException(sprintf("Unable to update file %s, file must be writable.", $POFile));
277     }
278
279     $po = TGettext::factory('PO',$POFile);
280     $po->load();
281     $result = $po->toArray();
282
283     foreach ($result['strings'] as $string => $value)
284     {
285       if ($string == $text)
286       {
287         $result['strings'][$string] = $target;
288         $result['meta']['PO-Revision-Date'] = @date('Y-m-d H:i:s');
289
290         $po->fromArray($result);
291         $mo = $po->toMO();
292
293         if ($po->save() && $mo->save($MOFile))
294         {
295           if ($this->cache)
296           {
297             $this->cache->remove($variant.':'.$this->culture);
298           }
299
300           return true;
301         }
302         else
303         {
304           return false;
305         }
306       }
307     }
308
309     return false;
310   }
311
312   protected function createMessageTemplate($catalogue)
313   {
314     if (null === $catalogue)
315     {
316       $catalogue = 'messages';
317     }
318
319     $variants = $this->getCatalogueList($catalogue);
320     $variant = array_shift($variants);
321     $mo_file = $this->getSource($variant);
322     $po_file = $this->getPOFile($mo_file);
323
324     $dir = dirname($mo_file);
325     if (!is_dir($dir))
326     {
327       @mkdir($dir);
328       @chmod($dir, 0777);
329     }
330
331     if (!is_dir($dir))
332     {
333       throw new sfException(sprintf("Unable to create directory %s.", $dir));
334     }
335
336     $po = TGettext::factory('PO', $po_file);
337     $result['meta']['PO-Revision-Date'] = date('Y-m-d H:i:s');
338     $result['strings'] = array();
339
340     $po->fromArray($result);
341     $mo = $po->toMO();
342     if ($po->save() && $mo->save($mo_file))
343     {
344       return array($variant, $mo_file, $po_file);
345     }
346     else
347     {
348       throw new sfException(sprintf("Unable to create file %s and %s.", $po_file, $mo_file));
349     }
350   }
351 }
352
Note: See TracBrowser for help on using the browser.