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
+
0
-

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)