1<?php 2/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 3 4/** 5 * Contains the Translation2_Container_mdb2 class 6 * 7 * PHP versions 4 and 5 8 * 9 * LICENSE: Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * @category Internationalization 31 * @package Translation2 32 * @author Lorenzo Alberton <l.alberton@quipo.it> 33 * @copyright 2004-2008 Lorenzo Alberton 34 * @license http://www.debian.org/misc/bsd.license BSD License (3 Clause) 35 * @version CVS: $Id: mdb2.php 305985 2010-12-05 22:55:33Z clockwerx $ 36 * @link http://pear.php.net/package/Translation2 37 */ 38 39/** 40 * require Translation2_Container class 41 */ 42require_once 'Translation2/Container.php'; 43 44/** 45 * Storage driver for fetching data from a database 46 * 47 * This storage driver can use all databases which are supported 48 * by the PEAR::MDB2 abstraction layer to fetch data. 49 * 50 * @category Internationalization 51 * @package Translation2 52 * @author Lorenzo Alberton <l.alberton@quipo.it> 53 * @copyright 2004-2008 Lorenzo Alberton 54 * @license http://www.debian.org/misc/bsd.license BSD License (3 Clause) 55 * @version CVS: $Id: mdb2.php 305985 2010-12-05 22:55:33Z clockwerx $ 56 * @link http://pear.php.net/package/Translation2 57 */ 58class Translation2_Container_mdb2 extends Translation2_Container 59{ 60 // {{{ class vars 61 62 /** 63 * MDB2 object 64 * @var object 65 */ 66 var $db = null; 67 68 /** 69 * query counter 70 * @var integer 71 * @access private 72 */ 73 var $_queries = 0; 74 75 // }}} 76 // {{{ init 77 78 /** 79 * Initialize the container 80 * 81 * @param string &$db Connection data or MDB2 object 82 * 83 * @return boolean|PEAR_Error object if something went wrong 84 */ 85 function init(&$db) 86 { 87 $this->_setDefaultOptions(); 88 if (PEAR::isError($err = $this->_connect($db))) { 89 return $err; 90 } 91 return true; 92 } 93 94 // }}} 95 // {{{ _connect() 96 97 /** 98 * Connect to database by using the given DSN string 99 * 100 * @param mixed &$db DSN string | array | MDB2 object 101 * 102 * @return boolean|PEAR_Error on error 103 * @access private 104 */ 105 function _connect(&$db) 106 { 107 if (is_object($db) && is_a($db, 'MDB2_Driver_Common')) { 108 $this->db = &$db; 109 } elseif (is_string($db) || is_array($db)) { 110 include_once 'MDB2.php'; 111 $this->db =& MDB2::connect($db); 112 } elseif (is_object($db) && MDB2::isError($db)) { 113 return PEAR::raiseError($db->getMessage(), $db->code); 114 } else { 115 return PEAR::raiseError('The given dsn was not valid in file ' 116 . __FILE__ . ' at line ' . __LINE__, 117 TRANSLATION2_ERROR_CANNOT_CONNECT, 118 PEAR_ERROR_RETURN); 119 } 120 121 if (PEAR::isError($this->db)) { 122 return $this->db; 123 } 124 return true; 125 } 126 127 // }}} 128 // {{{ _setDefaultOptions() 129 130 /** 131 * Set some default options 132 * 133 * @return void 134 * @access private 135 */ 136 function _setDefaultOptions() 137 { 138 $this->options['langs_avail_table'] = 'langs'; 139 $this->options['lang_id_col'] = 'id'; 140 $this->options['lang_name_col'] = 'name'; 141 $this->options['lang_meta_col'] = 'meta'; 142 $this->options['lang_errmsg_col'] = 'error_text'; 143 $this->options['lang_encoding_col'] = 'encoding'; 144 145 $this->options['strings_default_table'] = 'i18n'; 146 $this->options['strings_tables'] = array(); // 'lang_id' => 'table_name' 147 $this->options['string_id_col'] = 'id'; 148 $this->options['string_page_id_col'] = 'page_id'; 149 $this->options['string_page_id_col_length'] = 50; 150 $this->options['string_text_col'] = '%s'; // col_name if one table per lang is used, 151 // or a pattern (i.e. "tr_%s" => "tr_EN_US") 152 } 153 154 // }}} 155 // {{{ setCharset() 156 157 /** 158 * Set charset used to read/store the translations 159 * 160 * @param string $charset character set (encoding) 161 * 162 * @return PEAR_Error on error 163 */ 164 function setCharset($charset) 165 { 166 return $this->db->setCharset($charset); 167 } 168 169 // }}} 170 // {{{ fetchLangs() 171 172 /** 173 * Fetch the available langs if they're not cached yet. 174 * 175 * @return PEAR_Error on error 176 */ 177 function fetchLangs() 178 { 179 $query = sprintf('SELECT %s AS id, %s AS name, %s AS meta, %s AS error_text, %s AS encoding FROM %s', 180 $this->db->quoteIdentifier($this->options['lang_id_col'], true), 181 $this->db->quoteIdentifier($this->options['lang_name_col'], true), 182 $this->db->quoteIdentifier($this->options['lang_meta_col'], true), 183 $this->db->quoteIdentifier($this->options['lang_errmsg_col'], true), 184 $this->db->quoteIdentifier($this->options['lang_encoding_col'], true), 185 $this->db->quoteIdentifier($this->options['langs_avail_table'], true) 186 ); 187 188 ++$this->_queries; 189 $res = $this->db->queryAll($query, null, MDB2_FETCHMODE_ASSOC); 190 if (PEAR::isError($res)) { 191 return $res; 192 } 193 foreach ($res as $row) { 194 $row = array_change_key_case($row, CASE_LOWER); 195 $this->langs[$row['id']] = $row; 196 } 197 } 198 199 // }}} 200 // {{{ getPage() 201 202 /** 203 * Returns an array of the strings in the selected page 204 * 205 * @param string $pageID page/group ID 206 * @param string $langID language ID 207 * 208 * @return array 209 */ 210 function getPage($pageID = null, $langID = null) 211 { 212 $langID = $this->_getLangID($langID); 213 if (PEAR::isError($langID)) { 214 return $langID; 215 } 216 $lang_col = $this->_getLangCol($langID); 217 $table = $this->_getLangTable($langID); 218 219 $query = sprintf('SELECT %s, %s FROM %s WHERE %s ', 220 $this->db->quoteIdentifier($this->options['string_id_col'], true), 221 $this->db->quoteIdentifier($lang_col, true), 222 $this->db->quoteIdentifier($table, true), 223 $this->db->quoteIdentifier($this->options['string_page_id_col'], true) 224 ); 225 226 if (is_null($pageID)) { 227 $query .= 'IS NULL'; 228 } else { 229 $query .= ' = ' . $this->db->quote($pageID, 'text'); 230 } 231 232 ++$this->_queries; 233 $res = $this->db->query($query); 234 if (PEAR::isError($res)) { 235 return $res; 236 } 237 238 $strings = array(); 239 while (list($key, $value) = $res->fetchRow(MDB2_FETCHMODE_ORDERED)) { 240 $strings[$key] = $value; 241 } 242 $res->free(); 243 return $strings; 244 } 245 246 // }}} 247 // {{{ getOne() 248 249 /** 250 * Get a single item from the container 251 * 252 * @param string $stringID string ID 253 * @param string $pageID page/group ID 254 * @param string $langID language ID 255 * 256 * @return string 257 */ 258 function getOne($stringID, $pageID = null, $langID = null) 259 { 260 $langID = $this->_getLangID($langID); 261 if (PEAR::isError($langID)) { 262 return $langID; 263 } 264 $lang_col = $this->_getLangCol($langID); 265 $table = $this->_getLangTable($langID); 266 267 $query = sprintf('SELECT %s FROM %s WHERE %s = %s AND %s', 268 $this->db->quoteIdentifier($lang_col, true), 269 $this->db->quoteIdentifier($table, true), 270 $this->db->quoteIdentifier($this->options['string_id_col'], true), 271 $this->db->quote($stringID, 'text'), 272 $this->db->quoteIdentifier($this->options['string_page_id_col'], true) 273 ); 274 275 if (is_null($pageID)) { 276 $query .= ' IS NULL'; 277 } else { 278 $query .= ' = ' . $this->db->quote($pageID, 'text'); 279 } 280 281 ++$this->_queries; 282 return $this->db->queryOne($query); 283 } 284 285 // }}} 286 // {{{ getStringID() 287 288 /** 289 * Get the stringID for the given string 290 * 291 * @param string $string string 292 * @param string $pageID page/group ID 293 * 294 * @return string 295 */ 296 function getStringID($string, $pageID = null) 297 { 298 $lang_col = $this->_getLangCol($this->currentLang['id']); 299 $table = $this->_getLangTable($this->currentLang['id']); 300 $query = sprintf('SELECT %s FROM %s WHERE %s = %s AND %s', 301 $this->db->quoteIdentifier($this->options['string_id_col'], true), 302 $this->db->quoteIdentifier($table, true), 303 $this->db->quoteIdentifier($lang_col, true), 304 $this->db->quote($string, 'text'), 305 $this->db->quoteIdentifier($this->options['string_page_id_col'], true) 306 ); 307 if (is_null($pageID)) { 308 $query .= ' IS NULL'; 309 } else { 310 $query .= ' = ' . $this->db->quote($pageID, 'text'); 311 } 312 ++$this->_queries; 313 return $this->db->queryOne($query); 314 } 315 316 // }}} 317 // {{{ _getLangTable() 318 319 /** 320 * Get the table a language is stored in 321 * 322 * @param string $langID language ID 323 * 324 * @return string table $langID is stored in 325 * @access private 326 */ 327 function _getLangTable($langID) 328 { 329 if (isset($this->options['strings_tables'][$langID])) { 330 return $this->options['strings_tables'][$langID]; 331 } 332 return str_replace('%s', $langID, $this->options['strings_default_table']); 333 } 334 335 // }}} 336 // {{{ _getLangCol() 337 338 /** 339 * Get the column a language's string is stored in 340 * 341 * @param string $langID language ID 342 * 343 * @return string column $langID is stored in 344 * @access private 345 */ 346 function _getLangCol($langID) 347 { 348 static $cols; 349 if (!isset($cols[$langID])) { 350 if (isset($this->options['string_text_col']) && 351 !empty($this->options['string_text_col'])) { 352 $cols[$langID] = str_replace('%s', $langID, $this->options['string_text_col']); 353 } else { 354 $cols[$langID] = $langID; 355 } 356 } 357 return $cols[$langID]; 358 } 359 360 // }}} 361} 362?>