SQLiteTranslator – SQLite3 – alternativny translator
Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
- banshee
- Člen | 1
Ahojte,
ak by mal niekto zaujem o Translator vyuzivajuci SQLite3, ktory vie plural a doplnanie premennych ako GettextTranslator, doplnanie neexistujucich stringov.
Hlavna vyhoda je, ze pri volani metody translate vo formularoch, alebo v template zozbiera stringy a v destructore ich ulozi pre danu stranku, pri dalsom volani ak nebol pridany na stranku ziadny novy string, vytiahne len stringy pouzite na stranke + formulari.
Do buducnosti:
- Ak by bol zaujem by som mohol urobit napojenie na nette_translator_panel
- Pripadne urobit mergovanie stringov z pluginov, ktore si pridate do aplikacie (napr. CMS), pri odinstalovani ich vymazanie.
- rozsirit moznost na logovanie neprelozenych stringov
Pripadne ine…
Robene pre nette-2.0-alpha a php 5.2 bez prefixov
<?php
class TranslatorInvalidAdapterException extends Exception {}
class KTranslator extends NObject implements ITranslator {
/**
* Adapter
*
* @var TranslatorAdapter
*/
public static $adapter;
/** @var string path to adapter file */
public function __construct($adapter) {
if ($adapter instanceof ITranslatorAdapter) self::$adapter=$adapter;
else throw new TranslatorInvalidAdapterException('Adapter isn\'t based on interface ITranslatorAdapter.');
}
/**
* Translates the given string.
* @param string message
* @param int plural count
* @return string
*/
public function translate($message, $count = NULL,$replacement=NULL) {
return $this->_($message, $count, $replacement);
}
/**
* Translates the given string and replace searched keywords.
* @param string message
* @param int plural count
* @param array replacement
* @return string
*/
public function _($message, $count = NULL, $replacement = NULL) {
return self::$adapter->_($message, $count, $replacement);
}
}
?>
<?php
interface ITranslatorAdapter {
/**
* Translates the given string and replace searched keywords.
* @param string message
* @param int plural count
* @param array replacement
* @return string
*/
function _($message, $count = NULL, $replacement = NULL);
}
?>
<?php
class TranslatorAdapterSqlite implements ITranslatorAdapter {
/**
* Array of string from db
* @var array
*/
private $data=array();
/**
* Database handler
* @var SQLite3
*/
private $handler;
/**
* UniqID generated by REQUEST or from options
* @var string
*/
private $uniqid=false;
/**
* Default settings for translator
* @var array
*/
private $options=array(
'add_string'=>true
);
private $page_strings=array();
private $unknown_string=array();
public function __construct($path, $lang,$options=array()) {
$this->lang=$lang;
$this->path=$path;
$this->handler=new SQLite3($path.'/strings/'.$lang.'/strings.db');
$this->initialize();
$this->uniqid=sha1(isset($options['uniqid'])?$options['uniqid']:$_SERVER['REQUEST_URI'].'|'.$_SERVER['REQUEST_METHOD']);
$this->readPageStrings($this->uniqid);
if (isset($options['add_string'])) $this->options['add_string']=(bool) $options['add_string'];
}
private function initialize() {
$this->handler->exec(
'BEGIN;
CREATE TABLE IF NOT EXISTS strings (content TEXT,string CHAR(100),PRIMARY KEY (string));
CREATE TABLE IF NOT EXISTS strings_page (strings TEXT,uniqid CHAR(100),PRIMARY KEY (uniqid));
COMMIT;'
);
}
/**
* Translates the given string and replace searched keywords.
* @param string message
* @param int plural count
* @param mixed replacement
* @return string
*/
public function _($message, $count = NULL, $replacement = NULL) {
$this->page_strings[]=$message;
if (empty($count)) $count=1;
// If is called in pre-compiled template with not defined data
if (!isset($this->data[$message][$count])) $this->addToUnknownString($message,$count);
if (!empty($this->data[$message][$count])) { // identify string && plural form
$string=$this->data[$message][$count];
if (!empty($replacement)) { // replace variables in string
$replace=array();
if (is_array($replacement)) {
foreach($replacement as $k => $v) $replace['%'.$k]=(string) $v;
} else $replace['%s']=(string) $replacement;
$string=str_replace(array_keys($replace),array_values($replace),$string);
}
} else {
$string=$message; // message not exists or is untranslated
}
return $string;
}
/**
* Load string by tags from sqlite and create data
* @param array $items
* @return array
*/
private function load($items) {
$data=array();
if (!empty($items)) {
if (!is_array($items)) $items=array($items);
$sql='SELECT content,string FROM strings WHERE string IN("'.implode('","',$items).'")';
if ($result=$this->handler->query($sql)) {
while($row=$result->fetchArray(SQLITE3_ASSOC)) {
$data[$row['string']]=json_decode($row['content'],true);
}
}
}
return $data;
}
private function addPageStrings($item) {
if (!empty($item) && !empty($this->uniqid)) {
if ($this->readPageStrings()) {
$data=array_keys($this->data);
} else $data[]=$item;
$this->writePageStrings($data);
$this->readPageStrings();
}
}
/**
* Write strings tags to cacheStorage by $this->uniqid
* @param array $items
* @return bool
*/
private function writePageStrings($items) {
if (!empty($items) && is_array($items) && !empty($this->uniqid)) {
$items=json_encode($items,JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_AMP);
$sql='INSERT OR REPLACE INTO strings_page (uniqid,strings) VALUES(\''.$this->uniqid.'\',\''.$this->handler->escapeString($items).'\')';
return $this->handler->exec($sql);
}
return false;
}
/**
* Delete from cacheStorage by $this->uniqid
* @return bool
*/
private function cleanPageStrings() {
if (!empty($this->uniqid)) {
return $this->handler->exec('DELETE FROM strings_page WHERE uniqid="'.$this->uniqid.'"');
}
return false;
}
/**
* Read from cacheStorage by $this->uniqid
*/
private function readPageStrings() {
if (!empty($this->uniqid)) {
$sql='SELECT strings FROM strings_page WHERE uniqid="'.$this->uniqid.'"';
if ($result=$this->handler->querySingle('SELECT strings FROM strings_page WHERE uniqid="'.$this->uniqid.'"')) {
$result=json_decode($result,true);
return (bool) ($this->data=$this->load($result)+$this->data);
}
}
return false;
}
private function addToUnknownString($message,$count) {
if (!empty($message) && !empty($count)) {
if (isset($this->data[$message]) && !isset($this->data[$message][$count])) {
$content=$this->data[$message]+array($count=>'');
} else {
$content=array($count=>'');
}
$content=json_encode($content,JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_AMP);
$this->unknown_string[]='(\''.$this->handler->escapeString($message).'\',\''.$this->handler->escapeString($content).'\')';
}
}
private function saveUnknownString($items) {
if (!empty($this->unknown_string) && is_array($this->unknown_string)) {
$sql='INSERT OR IGNORE INTO strings (string,content) VALUES'.implode(',',$this->unknown_string);
return $this->handler->exec($sql);
}
return false;
}
public function __destruct() {
if (!empty($this->unknown_string)) {
$this->saveUnknownString($this->unknown_string);
}
if (count(array_diff($this->page_strings,array_keys($this->data)))) {
$this->writepageStrings($this->page_strings);
}
}
}
?>
Editoval banshee (5. 11. 2010 17:41)