There has been a major roadblock in the progress of CiviLingua. I'll quote the question I asked on civicrm-dev:
---- Msg #1 ----
I've asked a few people about this individually lately, but now I'll throw a
wider net ...
I'm working on the CiviLingua i18n/l10n component, and have basic multilingual
contact creation and deletion working via the DB_DataObject save(), find(),
delete() and insert() methods. Unfortunately, a good many BAO entities pass
queries directly to the database via query(), and there's just no happy way
to parse arbitrary SQL statement to add a l10n constraint.
We had been hoping to not intervene in the BAO layers to make this work, but I
wonder if that's just impossible. I can see adding localization code to a key
BAO object such as CRM_Contact_BAO_Query, but seeking out all the entities
that issue direct queries and writing in CiviLingua code sounds almost as
laborious as adding DAO layer code to do something like force in a first JOIN
to restrict the entity id by locale.
Is there a way around this? Ideas?
---- Msg #2 ----
> 1. What type query rewrite do you need to do? can u give an example
> and a bit more background
As things stand, any localizable table needs to be constrained against our
l10n table, something like: "INNER JOIN civicrm_l10n ON
$tablename.id=civicrm_l10n.entity_id WHERE
civicrm_l10n.entity_table='$tablename.' AND civicrm_l10n.locale='$locale'".
For reference, my CRM_Core_DAO::fetch() looks like this:
function find( $autoFetch = false ) {
if ( $this->isLocalizable() ) {
require_once(str_replace('_',DIRECTORY_SEPARATOR, 'CRM_Lingua_Utils') . '.php');
$lingua =& CRM_Lingua_Utils::singleton();
$locale = $lingua->get_locale();
$table = $this->tablename();
// set up the l10n object
require_once(str_replace('_',DIRECTORY_SEPARATOR, 'CRM_Lingua_DAO_L10n') . '.php');
$l10n =& new CRM_Lingua_DAO_L10n( );
$l10n->entity_table = $table;
$l10n->locale = $locale;
$l10n->selectAdd( 'entity_id' );
// add the join
$this->set_link( 'id', 'civicrm_l10n:entity_id');
$this->joinAdd( $l10n );
}
return parent::find( $autoFetch );
}
(Where set_link() manipulates $GLOBALS['_DB_DATAOBJECT']['LINKS'].)
> 2. What tables are affected with this component?
Almost all of them. Not all contain information that can be translated,
strictly speaking, but the many requirements for unique foreign keys mean
that just about everything winds up subject to localization.
> basically, if we can get a bit more background material, that might
> help us think of potentially easier solutions
All of this assumes the approach to i18n described here
(
http://wiki.civicrm.org/confluence/display/CRM/CiviLingua+-+support+for+multi-lingual+sites),
which follows the design of Drupal's i18n node translation approach, more or
less.
An alternative would be to do something with localization on output instead,
where individual strings are matched against a translation table. Which would
be truly enormous, and maybe even more trouble than the current
duplicate-everything approach.
----
I'm still looking for a solution.
At the moment, for the immediate purposes of our clients, I'm investigating using CCK and some custom code to expose CiviCRM data as nodes in Drupal that can then be managed by Drupal's i18n/locale system. But I'd really like to get i18n written into CiviCRM itself. Unfortunately it will likely require significant changes to BAO objects.