Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 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: sfMessageSource_gettext.class.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
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
}