Overview

Packages

  • application
    • commands
    • components
      • actions
      • filters
      • leftWidget
      • permissions
      • sortableWidget
      • util
      • webupdater
      • x2flow
        • actions
        • triggers
      • X2GridView
      • X2Settings
    • controllers
    • models
      • embedded
    • modules
      • accounts
        • controllers
        • models
      • actions
        • controllers
        • models
      • calendar
        • controllers
        • models
      • charts
        • models
      • contacts
        • controllers
        • models
      • docs
        • components
        • controllers
        • models
      • groups
        • controllers
        • models
      • marketing
        • components
        • controllers
        • models
      • media
        • controllers
        • models
      • mobile
        • components
      • opportunities
        • controllers
        • models
      • products
        • controllers
        • models
      • quotes
        • controllers
        • models
      • services
        • controllers
        • models
      • template
        • models
      • users
        • controllers
        • models
      • workflow
        • controllers
        • models
      • x2Leads
        • controllers
        • models
  • Net
  • None
  • PHP
  • system
    • base
    • caching
      • dependencies
    • collections
    • console
    • db
      • ar
      • schema
        • cubrid
        • mssql
        • mysql
        • oci
        • pgsql
        • sqlite
    • i18n
      • gettext
    • logging
    • test
    • utils
    • validators
    • web
      • actions
      • auth
      • filters
      • form
      • helpers
      • renderers
      • services
      • widgets
        • captcha
        • pagers
  • Text
    • Highlighter
  • zii
    • behaviors
    • widgets
      • grid
      • jui

Classes

  • CGettextFile
  • CGettextMoFile
  • CGettextPoFile
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * CGettextMoFile class file.
  4:  *
  5:  * @author Qiang Xue <qiang.xue@gmail.com>
  6:  * @link http://www.yiiframework.com/
  7:  * @copyright 2008-2013 Yii Software LLC
  8:  * @license http://www.yiiframework.com/license/
  9:  */
 10: 
 11: /**
 12:  * CGettextMoFile represents an MO Gettext message file.
 13:  *
 14:  * This class is written by adapting Michael's Gettext_MO class in PEAR.
 15:  * Please refer to the following license terms.
 16:  *
 17:  * Copyright (c) 2004-2005, Michael Wallner <mike@iworks.at>.
 18:  * All rights reserved.
 19:  *
 20:  * Redistribution and use in source and binary forms, with or without
 21:  * modification, are permitted provided that the following conditions are met:
 22:  *
 23:  *     * Redistributions of source code must retain the above copyright notice,
 24:  *       this list of conditions and the following disclaimer.
 25:  *     * Redistributions in binary form must reproduce the above copyright
 26:  *       notice, this list of conditions and the following disclaimer in the
 27:  *       documentation and/or other materials provided with the distribution.
 28:  *
 29:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 30:  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 31:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 32:  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 33:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 34:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 35:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 36:  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 37:  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 38:  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 39:  *
 40:  * @author Qiang Xue <qiang.xue@gmail.com>
 41:  * @package system.i18n.gettext
 42:  * @since 1.0
 43:  */
 44: class CGettextMoFile extends CGettextFile
 45: {
 46:     /**
 47:      * @var boolean whether to use Big Endian when reading and writing an integer.
 48:      */
 49:     public $useBigEndian=false;
 50: 
 51:     /**
 52:      * Constructor.
 53:      * @param boolean $useBigEndian whether to use Big Endian when reading and writing an integer.
 54:      */
 55:     public function __construct($useBigEndian=false)
 56:     {
 57:         $this->useBigEndian=$useBigEndian;
 58:     }
 59: 
 60:     /**
 61:      * Loads messages from an MO file.
 62:      * @param string $file file path
 63:      * @param string $context message context
 64:      * @return array message translations (source message => translated message)
 65:      */
 66:     public function load($file,$context)
 67:     {
 68:         if(!($fr=@fopen($file,'rb')))
 69:             throw new CException(Yii::t('yii','Unable to read file "{file}".',
 70:                 array('{file}'=>$file)));
 71: 
 72:         if(!@flock($fr,LOCK_SH))
 73:             throw new CException(Yii::t('yii','Unable to lock file "{file}" for reading.',
 74:                 array('{file}'=>$file)));
 75: 
 76:         $magic=current($array=unpack('c',$this->readByte($fr,4)));
 77:         if($magic==-34)
 78:             $this->useBigEndian=false;
 79:         elseif($magic==-107)
 80:             $this->useBigEndian=true;
 81:         else
 82:             throw new CException(Yii::t('yii','Invalid MO file: {file} (magic: {magic}).',
 83:                 array('{file}'=>$file,'{magic}'=>$magic)));
 84: 
 85:         if(($revision=$this->readInteger($fr))!=0)
 86:             throw new CException(Yii::t('yii','Invalid MO file revision: {revision}.',
 87:                 array('{revision}'=>$revision)));
 88: 
 89:         $count=$this->readInteger($fr);
 90:         $sourceOffset=$this->readInteger($fr);
 91:         $targetOffset=$this->readInteger($fr);
 92: 
 93:         $sourceLengths=array();
 94:         $sourceOffsets=array();
 95:         fseek($fr,$sourceOffset);
 96:         for($i=0;$i<$count;++$i)
 97:         {
 98:             $sourceLengths[]=$this->readInteger($fr);
 99:             $sourceOffsets[]=$this->readInteger($fr);
100:         }
101: 
102:         $targetLengths=array();
103:         $targetOffsets=array();
104:         fseek($fr,$targetOffset);
105:         for($i=0;$i<$count;++$i)
106:         {
107:             $targetLengths[]=$this->readInteger($fr);
108:             $targetOffsets[]=$this->readInteger($fr);
109:         }
110: 
111:         $messages=array();
112:         for($i=0;$i<$count;++$i)
113:         {
114:             $id=$this->readString($fr,$sourceLengths[$i],$sourceOffsets[$i]);
115:             $pos = strpos($id,chr(4));
116: 
117:             if(($context && $pos!==false && substr($id,0,$pos)===$context) || (!$context && $pos===false))
118:             {
119:                 if($pos !== false)
120:                     $id=substr($id,$pos+1);
121: 
122:                 $message=$this->readString($fr,$targetLengths[$i],$targetOffsets[$i]);
123:                 $messages[$id]=$message;
124:             }
125:         }
126: 
127:         @flock($fr,LOCK_UN);
128:         @fclose($fr);
129: 
130:         return $messages;
131:     }
132: 
133:     /**
134:      * Saves messages to an MO file.
135:      * @param string $file file path
136:      * @param array $messages message translations (message id => translated message).
137:      * Note if the message has a context, the message id must be prefixed with
138:      * the context with chr(4) as the separator.
139:      */
140:     public function save($file,$messages)
141:     {
142:         if(!($fw=@fopen($file,'wb')))
143:             throw new CException(Yii::t('yii','Unable to write file "{file}".',
144:                 array('{file}'=>$file)));
145: 
146:         if(!@flock($fw,LOCK_EX))
147:             throw new CException(Yii::t('yii','Unable to lock file "{file}" for writing.',
148:                 array('{file}'=>$file)));
149: 
150:         // magic
151:         if($this->useBigEndian)
152:             $this->writeByte($fw,pack('c*', 0x95, 0x04, 0x12, 0xde));
153:         else
154:             $this->writeByte($fw,pack('c*', 0xde, 0x12, 0x04, 0x95));
155: 
156:         // revision
157:         $this->writeInteger($fw,0);
158: 
159:         // message count
160:         $n=count($messages);
161:         $this->writeInteger($fw,$n);
162: 
163:         // offset of source message table
164:         $offset=28;
165:         $this->writeInteger($fw,$offset);
166:         $offset+=($n*8);
167:         $this->writeInteger($fw,$offset);
168:         // hashtable size, omitted
169:         $this->writeInteger($fw,0);
170:         $offset+=($n*8);
171:         $this->writeInteger($fw,$offset);
172: 
173:         // length and offsets for source messagess
174:         foreach(array_keys($messages) as $id)
175:         {
176:             $len=strlen($id);
177:             $this->writeInteger($fw,$len);
178:             $this->writeInteger($fw,$offset);
179:             $offset+=$len+1;
180:         }
181: 
182:         // length and offsets for target messagess
183:         foreach($messages as $message)
184:         {
185:             $len=strlen($message);
186:             $this->writeInteger($fw,$len);
187:             $this->writeInteger($fw,$offset);
188:             $offset+=$len+1;
189:         }
190: 
191:         // source messages
192:         foreach(array_keys($messages) as $id)
193:             $this->writeString($fw,$id);
194: 
195:         // target messages
196:         foreach($messages as $message)
197:             $this->writeString($fw,$message);
198: 
199:         @flock($fw,LOCK_UN);
200:         @fclose($fw);
201:     }
202: 
203:     /**
204:      * Reads one or several bytes.
205:      * @param resource $fr file handle
206:      * @param integer $n number of bytes to read
207:      * @return string bytes
208:      */
209:     protected function readByte($fr,$n=1)
210:     {
211:         if($n>0)
212:             return fread($fr,$n);
213:     }
214: 
215:     /**
216:      * Writes bytes.
217:      * @param resource $fw file handle
218:      * @param string $data the data
219:      * @return integer how many bytes are written
220:      */
221:     protected function writeByte($fw,$data)
222:     {
223:         return fwrite($fw,$data);
224:     }
225: 
226:     /**
227:      * Reads a 4-byte integer.
228:      * @param resource $fr file handle
229:      * @return integer the result
230:      * @see useBigEndian
231:      */
232:     protected function readInteger($fr)
233:     {
234:         return current($array=unpack($this->useBigEndian ? 'N' : 'V', $this->readByte($fr,4)));
235:     }
236: 
237:     /**
238:      * Writes a 4-byte integer.
239:      * @param resource $fw file handle
240:      * @param integer $data the data
241:      * @return integer how many bytes are written
242:      */
243:     protected function writeInteger($fw,$data)
244:     {
245:         return $this->writeByte($fw,pack($this->useBigEndian ? 'N' : 'V', (int)$data));
246:     }
247: 
248:     /**
249:      * Reads a string.
250:      * @param resource $fr file handle
251:      * @param integer $length string length
252:      * @param integer $offset offset of the string in the file. If null, it reads from the current position.
253:      * @return string the result
254:      */
255:     protected function readString($fr,$length,$offset=null)
256:     {
257:         if($offset!==null)
258:             fseek($fr,$offset);
259:         return $this->readByte($fr,$length);
260:     }
261: 
262:     /**
263:      * Writes a string.
264:      * @param resource $fw file handle
265:      * @param string $data the string
266:      * @return integer how many bytes are written
267:      */
268:     protected function writeString($fw,$data)
269:     {
270:         return $this->writeByte($fw,$data."\0");
271:     }
272: }
273: 
API documentation generated by ApiGen 2.8.0