00001 <?php
00023 require_once 'Zend/Locale.php';
00024
00026 require_once 'Zend/Translate/Adapter.php';
00027
00034 class Zend_Translate_Adapter_Gettext extends Zend_Translate_Adapter {
00035
00036 private $_bigEndian = false;
00037 private $_file = false;
00038 private $_adapterInfo = array();
00039 private $_data = array();
00040
00049 public function __construct($data, $locale = null, array $options = array())
00050 {
00051 parent::__construct($data, $locale, $options);
00052 }
00053
00059 private function _readMOData($bytes)
00060 {
00061 if ($this->_bigEndian === false) {
00062 return unpack('V' . $bytes, fread($this->_file, 4 * $bytes));
00063 } else {
00064 return unpack('N' . $bytes, fread($this->_file, 4 * $bytes));
00065 }
00066 }
00067
00078 protected function _loadTranslationData($filename, $locale, array $options = array())
00079 {
00080 $this->_data = array();
00081 $this->_bigEndian = false;
00082 $this->_file = @fopen($filename, 'rb');
00083 if (!$this->_file) {
00084 require_once 'Zend/Translate/Exception.php';
00085 throw new Zend_Translate_Exception('Error opening translation file \'' . $filename . '\'.');
00086 }
00087 if (@filesize($filename) < 10) {
00088 require_once 'Zend/Translate/Exception.php';
00089 throw new Zend_Translate_Exception('\'' . $filename . '\' is not a gettext file');
00090 }
00091
00092 // get Endian
00093 $input = $this->_readMOData(1);
00094 if (strtolower(substr(dechex($input[1]), -8)) == "950412de") {
00095 $this->_bigEndian = false;
00096 } else if (strtolower(substr(dechex($input[1]), -8)) == "de120495") {
00097 $this->_bigEndian = true;
00098 } else {
00099 require_once 'Zend/Translate/Exception.php';
00100 throw new Zend_Translate_Exception('\'' . $filename . '\' is not a gettext file');
00101 }
00102 // read revision - not supported for now
00103 $input = $this->_readMOData(1);
00104
00105 // number of bytes
00106 $input = $this->_readMOData(1);
00107 $total = $input[1];
00108
00109 // number of original strings
00110 $input = $this->_readMOData(1);
00111 $OOffset = $input[1];
00112
00113 // number of translation strings
00114 $input = $this->_readMOData(1);
00115 $TOffset = $input[1];
00116
00117 // fill the original table
00118 fseek($this->_file, $OOffset);
00119 $origtemp = $this->_readMOData(2 * $total);
00120 fseek($this->_file, $TOffset);
00121 $transtemp = $this->_readMOData(2 * $total);
00122
00123 for($count = 0; $count < $total; ++$count) {
00124 if ($origtemp[$count * 2 + 1] != 0) {
00125 fseek($this->_file, $origtemp[$count * 2 + 2]);
00126 $original = @fread($this->_file, $origtemp[$count * 2 + 1]);
00127 $original = explode(chr(00), $original);
00128 } else {
00129 $original[0] = '';
00130 }
00131
00132 if ($transtemp[$count * 2 + 1] != 0) {
00133 fseek($this->_file, $transtemp[$count * 2 + 2]);
00134 $translate = fread($this->_file, $transtemp[$count * 2 + 1]);
00135 $translate = explode(chr(00), $translate);
00136 if ((count($original) > 1) && (count($translate) > 1)) {
00137 $this->_data[$locale][$original[0]] = $translate;
00138 array_shift($original);
00139 foreach ($original as $orig) {
00140 $this->_data[$locale][$orig] = '';
00141 }
00142 } else {
00143 $this->_data[$locale][$original[0]] = $translate[0];
00144 }
00145 }
00146 }
00147
00148 $this->_data[$locale][''] = trim($this->_data[$locale]['']);
00149 if (empty($this->_data[$locale][''])) {
00150 $this->_adapterInfo[$filename] = 'No adapter information available';
00151 } else {
00152 $this->_adapterInfo[$filename] = $this->_data[$locale][''];
00153 }
00154
00155 unset($this->_data[$locale]['']);
00156 return $this->_data;
00157 }
00158
00164 public function getAdapterInfo()
00165 {
00166 return $this->_adapterInfo;
00167 }
00168
00174 public function toString()
00175 {
00176 return "Gettext";
00177 }
00178 }