diff options
Diffstat (limited to 'framework')
| -rw-r--r-- | framework/Exceptions/messages/messages.txt | 5 | ||||
| -rw-r--r-- | framework/I18N/TGlobalization.php | 8 | ||||
| -rw-r--r-- | framework/I18N/core/MessageSource.php | 20 | ||||
| -rw-r--r-- | framework/I18N/core/MessageSource_Database.php | 322 | 
4 files changed, 342 insertions, 13 deletions
diff --git a/framework/Exceptions/messages/messages.txt b/framework/Exceptions/messages/messages.txt index 36a23701..3edd5d49 100644 --- a/framework/Exceptions/messages/messages.txt +++ b/framework/Exceptions/messages/messages.txt @@ -349,6 +349,9 @@ clientscript_invalid_package_path		= Invalid PackagePath '{0}' for TClientScript  tdatepicker_autopostback_unsupported	= '{0}' does not support AutoPostBack.  globalization_cache_path_failed			= Unable to create translation message cache path '{0}'. Make sure the parent directory exists and is writable by the Web process.  globalization_source_path_failed		= Unable to create translation message path '{0}'. Make sure the parent directory exists and is writable by the Web process. +messagesource_connectionid_invalid      = MessageSource_Database.source '{0}' does not point to a valid TDataSourceConfig module. +messagesource_connectionid_required     = ConnectionID in MessageSource_Database.source is required. +  callback_not_support_no_priority_state_update	= Callback request does not support unprioritized pagestate update.  callback_invalid_callback_options		= '{1}' is not a valid TCallbackOptions control for Callback control '{0}'.  callback_invalid_clientside_options		= Callback ClientSide property must be either a string that is the ID of a TCallbackOptions control or an instance of TCallbackClientSideOptions.======= @@ -462,4 +465,4 @@ ar_delete_invalid						= The {0} instance cannot be deleted because it is either  datasource_dbconnection_invalid			= TDataSourceConfig.DbConnection '{0}' is invalid. Please make sure it points to a valid application module.  response_status_reason_missing			= HTTP 1.1 need reason for extended status-codes -response_status_reason_badchars			= For HTTP 1.1 header, the token status-reason must not contain token CR or LF
\ No newline at end of file +response_status_reason_badchars			= For HTTP 1.1 header, the token status-reason must not contain token CR or LF diff --git a/framework/I18N/TGlobalization.php b/framework/I18N/TGlobalization.php index 471869c7..a30c8423 100644 --- a/framework/I18N/TGlobalization.php +++ b/framework/I18N/TGlobalization.php @@ -155,8 +155,10 @@ class TGlobalization extends TModule  	/**
  	 * Sets the translation configuration. Example configuration:
  	 * <code>
 -	 * $config['type'] = 'XLIFF'; //XLIFF, gettext, mysql or sqlite
 -	 * $config['source'] = 'Path.to.directory'; //or database connection string
 +	 * $config['type'] = 'XLIFF'; //XLIFF, gettext, Database or MySQL (deprecated)
 +	 * $config['source'] = 'Path.to.directory'; // for types XLIFF and gettext
 +	 * $config['source'] = 'connectionId'; // for type Database
 +	 * $config['source'] = 'mysql://user:pw@host/db'; // for type MySQL (deprecated)
  	 * $config['catalogue'] = 'messages'; //default catalog
  	 * $config['autosave'] = 'true'; //save untranslated message
  	 * $config['cache'] = 'true'; //cache translated message
 @@ -266,4 +268,4 @@ class TGlobalization extends TModule  }
 -?>
\ No newline at end of file +?>
 diff --git a/framework/I18N/core/MessageSource.php b/framework/I18N/core/MessageSource.php index 6563f8c9..68fcd903 100644 --- a/framework/I18N/core/MessageSource.php +++ b/framework/I18N/core/MessageSource.php @@ -108,26 +108,28 @@ abstract class MessageSource implements IMessageSource  	/**
  	 * Factory method to instantiate a new MessageSource depending on the
 -	 * source type. The allowed source types are 'XLIFF', 'SQLite', 
 -	 * 'MySQL', and 'gettext'. The source parameter is dependent on the 
 -	 * source type. For 'gettext' and 'XLIFF', it should point to the directory
 -	 * where the messages are stored. For database types, e.g. 'SQLite' and 
 -	 * 'MySQL', it should be a PEAR DB style DSN string. 
 +	 * source type. The allowed source types are 'XLIFF', 'gettext' and
 +     * 'Database'. The source parameter depends on the source type. 
 +     * For 'gettext' and 'XLIFF', 'source' should point to the directory 
 +     * where the messages are stored. 
 +     * For 'Database', 'source' should be a valid connection id.
 +     * If (deprecated) 'MySQL' is used, 'source' must contain a valid 
 +     * DSN.
  	 *
   	 * Custom message source are possible by supplying the a filename parameter
   	 * in the factory method.
  	 * 
  	 * @param string the message source type.
 -	 * @param string the location of the resource.
 +	 * @param string the location of the resource or the ConnectionID.
  	 * @param string the filename of the custom message source.
  	 * @return MessageSource a new message source of the specified type. 
  	 * @throws InvalidMessageSourceTypeException
  	 */
  	static function &factory($type, $source='.', $filename='')
  	{
 -		$types = array('XLIFF', 'SQLite', 'MySQL', 'gettext');
 +		$types = array('XLIFF', 'MySQL', 'Database', 'gettext');
 -		if(empty($filename) && in_array($type, $types) == false)
 +		if(empty($filename) && !in_array($type, $types))
  			throw new Exception('Invalid type "'.$type.'", valid types are '.
  				implode(', ', $types));
 @@ -330,4 +332,4 @@ class TMessageSourceIOException extends TException  {
  }
 -?>
\ No newline at end of file +?>
 diff --git a/framework/I18N/core/MessageSource_Database.php b/framework/I18N/core/MessageSource_Database.php new file mode 100644 index 00000000..4d756820 --- /dev/null +++ b/framework/I18N/core/MessageSource_Database.php @@ -0,0 +1,322 @@ +<?php
 +/**
 + * MessageSource_MySQL class file.
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the BSD License.
 + *
 + * Copyright(c) 2004 by Qiang Xue. All rights reserved.
 + *
 + * To contact the author write to {@link mailto:qiang.xue@gmail.com Qiang Xue}
 + * The latest version of PRADO can be obtained from:
 + * {@link http://prado.sourceforge.net/}
 + *
 + * @package System.I18N.core
 + */
 +
 +/**
 + * Get the MessageSource class file.
 + */
 +require_once(dirname(__FILE__).'/MessageSource.php');
 +
 +/**
 + * MessageSource_MySQL class.
 + *
 + * Retrive the message translation from a MySQL database.
 + *
 + * See the MessageSource::factory() method to instantiate this class.
 + *
 + * @package System.I18N.core
 + */
 +class MessageSource_Database extends MessageSource
 +{
 +	private $_connID='';
 +	private $_conn;
 +
 +	/**
 +	 * Constructor.
 +	 * Create a new message source using a Database
 +	 * @param string MySQL datasource, in PEAR's DB DSN format.
 +	 * @see MessageSource::factory();
 +	 */
 +	function __construct($source)
 +	{
 +		$this->_connID= (string)$source;
 +	}
 +
 +	/**
 +	 * @return TDbConnection the database connection that may be used to retrieve messages.
 +	 */
 +	public function getDbConnection()
 +	{
 +		if($this->_conn===null)
 +		{
 +			$this->_conn=$this->createDbConnection($this->_connID);
 +			$this->_conn->setActive(true);
 +		}
 +		return $this->_conn;
 +	}
 +
 +	/**
 +	 * Creates the DB connection.
 +	 * @param string the module ID for TDataSourceConfig
 +	 * @return TDbConnection the created DB connection
 +	 * @throws TConfigurationException if module ID is invalid or empty
 +	 */
 +	protected function createDbConnection($connectionID)
 +	{
 +		if($connectionID!=='')
 +		{
 +			$conn=Prado::getApplication()->getModule($connectionID);
 +			if($conn instanceof TDataSourceConfig)
 +				return $conn->getDbConnection();
 +			else
 +				throw new TConfigurationException('messagesource_connectionid_invalid',$connectionID);
 +		}
 +		else
 +			throw new TConfigurationException('messagesource_connectionid_required');
 +	}
 +
 +	/**
 +	 * Get an array of messages for a particular catalogue and cultural
 +	 * variant.
 +	 * @param string the catalogue name + variant
 +	 * @return array translation messages.
 +	 */
 +	protected function &loadData($variant)
 +	{
 +		$command=$this->getDBConnection()->createCommand(
 +			'SELECT t.id, t.source, t.target, t.comments
 +				FROM trans_unit t, catalogue c
 +				WHERE c.cat_id =  t.cat_id
 +					AND c.name = :variant
 +				ORDER BY id ASC');
 +		$command->bindParameter(':variant',$variant,PDO::PARAM_STR);
 +		$dataReader=$command->query();
 +
 +		$result = array();
 +
 +		foreach ($dataReader as $row)
 +			$result[$row['source']] = array($row['target'],$row['id'],$row['comments']);
 +
 +		return $result;
 +	}
 +	
 +	/**
 +	 * Get the last modified unix-time for this particular catalogue+variant.
 +	 * We need to query the database to get the date_modified.
 +	 * @param string catalogue+variant
 +	 * @return int last modified in unix-time format.
 +	 */
 +	protected function getLastModified($source)
 +	{
 +		$command=$this->getDBConnection()->createCommand(
 +			'SELECT date_modified FROM catalogue WHERE name = :source');
 +		$command->bindParameter(':source',$source,PDO::PARAM_STR);
 +		$result=$command->queryScalar();
 +		return $result ? $result : 0;
 +	}
 +
 +
 +	/**
 +	 * Check if a particular catalogue+variant exists in the database.
 +	 * @param string catalogue+variant
 +	 * @return boolean true if the catalogue+variant is in the database,
 +	 * false otherwise.
 +	 */
 +	protected function isValidSource($variant)
 +	{
 +		$command=$this->getDBConnection()->createCommand(
 +			'SELECT COUNT(*) FROM catalogue WHERE name = :variant');
 +		$command->bindParameter(':variant',$variant,PDO::PARAM_STR);
 +		return $command->queryScalar()==1;
 +	}
 +
 +	/**
 +	 * Get all the variants of a particular catalogue.
 +	 * @param string catalogue name
 +	 * @return array list of all variants for this catalogue.
 +	 */
 +	protected function getCatalogueList($catalogue)
 +	{
 +		$variants = explode('_',$this->culture);
 +
 +		$catalogues = array($catalogue);
 +
 +		$variant = null;
 +
 +		for($i = 0, $k = count($variants); $i < $k; ++$i)
 +		{
 +			if(isset($variants[$i]{0}))
 +			{
 +				$variant .= ($variant)?'_'.$variants[$i]:$variants[$i];
 +				$catalogues[] = $catalogue.'.'.$variant;
 +			}
 +		}
 +		return array_reverse($catalogues);
 +	}
 +
 +	/**
 +	 * Retrive catalogue details, array($cat_id, $variant, $count).
 +	 * @param string catalogue
 +	 * @return array catalogue details, array($cat_id, $variant, $count).
 +	 */
 +	private function getCatalogueDetails($catalogue='messages')
 +	{
 +		if(empty($catalogue))
 +			$catalogue = 'messages';
 +
 +		$variant = $catalogue.'.'.$this->culture;
 +
 +		$command=$this->getDBConnection()->createCommand(
 +			'SELECT cat_id FROM catalogue WHERE name = :variant');
 +		$command->bindParameter(':variant',$variant,PDO::PARAM_STR);
 +		$cat_id=$command->queryScalar();
 +
 +		if ($cat_id===null) return false;
 +
 +		$command=$this->getDBConnection()->createCommand(
 +			'SELECT COUNT(msg_id) FROM trans_unit WHERE cat_id = :catid ');
 +		$command->bindParameter(':catid',$cat_id,PDO::PARAM_INT);
 +		$count=$command->queryScalar();
 +
 +		return array($cat_id, $variant, $count);
 +	}
 +
 +	/**
 +	 * Update the catalogue last modified time.
 +	 * @return boolean true if updated, false otherwise.
 +	 */
 +	private function updateCatalogueTime($cat_id, $variant)
 +	{
 +		$time = time();
 +		$command=$this->getDBConnection()->createCommand(
 +			'UPDATE catalogue SET date_modified = :moddate WHERE cat_id = :catid');
 +		$command->bindParameter(':moddate',$time,PDO::PARAM_INT);
 +		$command->bindParameter(':catid',$cat_id,PDO::PARAM_INT);
 +		$command->execute();
 +
 +		if(!empty($this->cache))
 +			$this->cache->clean($variant, $this->culture);
 +
 +		return $result;
 +	}
 +
 +	/**
 +	 * Save the list of untranslated blocks to the translation source.
 +	 * If the translation was not found, you should add those
 +	 * strings to the translation source via the <b>append()</b> method.
 +	 * @param string the catalogue to add to
 +	 * @return boolean true if saved successfuly, false otherwise.
 +	 */
 +	function save($catalogue='messages')
 +	{
 +		$messages = $this->untranslated;
 +
 +		if(count($messages) <= 0) return false;
 +
 +		$details = $this->getCatalogueDetails($catalogue);
 +
 +		if($details)
 +			list($cat_id, $variant, $count) = $details;
 +		else
 +			return false;
 +
 +		if($cat_id <= 0) return false;
 +		$inserted = 0;
 +
 +		$time = time();
 +
 +		$command=$this->getDBConnection()->createCommand(
 +			'INSERT INTO trans_unit (cat_id,id,source,date_added) VALUES (:catid,:id,:source,:dateadded)');
 +		$command->bindParameter(':catid',$cat_id,PDO::PARAM_INT);
 +		$command->bindParameter(':id',$count,PDO::PARAM_INT);
 +		$command->bindParameter(':source',$message,PDO::PARAM_STR);
 +		$command->bindParameter(':dateadded',$time,PDO::PARAM_INT);
 +		foreach($messages as $message)
 +		{
 +			$count++; $inserted++;
 +			$command->execute();
 +		}
 +		if($inserted > 0)
 +			$this->updateCatalogueTime($cat_id, $variant);
 +
 +		return $inserted > 0;
 +	}
 +
 +	/**
 +	 * Delete a particular message from the specified catalogue.
 +	 * @param string the source message to delete.
 +	 * @param string the catalogue to delete from.
 +	 * @return boolean true if deleted, false otherwise.
 +	 */
 +	function delete($message, $catalogue='messages')
 +	{
 +		$details = $this->getCatalogueDetails($catalogue);
 +		if($details)
 +			list($cat_id, $variant, $count) = $details;
 +		else
 +			return false;
 +
 +		$command=$this->getDBConnection()->createCommand(
 +			'DELETE FROM trans_unit WHERE cat_id = :catid AND source = :message');
 +		$command->bindParameter(':catid',$cat_id,PDO::PARAM_INT);
 +		$command->bindParameter(':message',$message,PDO::PARAM_STR);
 +
 +		return ($command->execute()==1) ? $this->updateCatalogueTime($cat_id, $variant) : false;
 +
 +	}
 +
 +	/**
 +	 * Update the translation.
 +	 * @param string the source string.
 +	 * @param string the new translation string.
 +	 * @param string comments
 +	 * @param string the catalogue of the translation.
 +	 * @return boolean true if translation was updated, false otherwise.
 +	 */
 +	function update($text, $target, $comments, $catalogue='messages')
 +	{
 +		$details = $this->getCatalogueDetails($catalogue);
 +		if($details)
 +			list($cat_id, $variant, $count) = $details;
 +		else
 +			return false;
 +
 +		$time = time();
 +		$command=$this->getDBConnection()->createCommand(
 +			'UPDATE trans_unit SET target = :target, comments = :comments, date_modified = :datemod
 +					WHERE cat_id = :catid AND source = :source');
 +		$command->bindParameter(':target',$target,PDO::PARAM_STR);
 +		$command->bindParameter(':comments',$comments,PDO::PARAM_STR);
 +		$command->bindParameter(':datemod',$time,PDO::PARAM_INT);
 +		$command->bindParameter(':catid',$cat_id,PDO::PARAM_INT);
 +		$command->bindParameter(':source',$text,PDO::PARAM_STR);
 +
 +		return ($command->execute()==1) ? $this->updateCatalogueTime($cat_id, $variant) : false;
 +	}
 +
 +	/**
 +	 * Returns a list of catalogue as key and all it variants as value.
 +	 * @return array list of catalogues
 +	 */
 +	function catalogues()
 +	{
 +		$command=$this->getDBConnection()->createCommand( 'SELECT name FROM catalogue ORDER BY name');
 +		$dataReader=$command->query();
 +
 +		$result = array();
 +
 +		foreach ($dataReader as $row)
 +		{
 +			$details = explode('.',$row[0]);
 +			if(!isset($details[1])) $details[1] = null;
 +
 +			$result[] = $details;
 +		}
 +
 +		return $result;
 +	}
 +
 +}
 +?>
  | 
