#!/usr/bin/perl
package RVL::Translation;
##LICENSE##
#use strict;
# Doc:
# http://search.cpan.org/~lbrocard/perl-5.12.4/dist/I18N-LangTags/lib/I18N/LangTags.pm
# RFC 3066, ftp://ftp.isi.edu/in-notes/rfc3066.txt
use warnings;
use Locale::MakePhrase::BackingStore::Directory ;
use Locale::MakePhrase::BackingStore::Database;
use RVL::TranslationDB;
use Encode qw/encode decode/;
use DBI;
use base qw(Locale::MakePhrase);
use Class::Std::Utils;
{
sub new {
my ($class, $opt) = @_;
#my ($this) = bless( {}, $class);
my ($this) = $class->SUPER::new($opt);
$this = bless $this, $class;
if (defined $this->{options}->{fallback_backing_store}) {
$this->{fallback_backing_store} = $this->{options}->{fallback_backing_store};
}
delete $this->{translate_arguments};
return $this;
}
=help
Returns a singleton Registry instance.
=cut
sub singleton {
my ($class) = __PACKAGE__;
if (!defined $RVL::INSTANCE{$class}) {
$RVL::INSTANCE{$class} = $class->new();
}
#$default_language
return $RVL::INSTANCE{$class}
}
=item
Over function
=cut
sub context_translate {
die_from_caller("context_translate() requires at least two parameters") unless @_ > 2;
my ($self,$context,$key) = (shift,shift,shift);
die_from_caller("context_translate() requires a valid key") unless (defined $key and length $key);
$context = ref($context) if (defined $context and ref($context) ne 'SCALAR');
print STDERR "Translation key: $key\n" if $DEBUG;
my $backing_store = $self->{backing_store};
my $languages = $self->{languages};
# Get all possible translations/rules from backing store
my $rule_objs = $backing_store->get_rules($context,$key,$languages);
# Sort the rules according to the linguistic rule algorithms
$rule_objs = $self->_sort_rules($rule_objs,$languages);
# Select the specific rule, based on the linguistic rules for each rule
my $rule_obj = $self->_select_rule($rule_objs, @_);
# at this point we can clean up some resources
$backing_store = undef;
$languages = undef;
$rule_objs = undef;
if (!defined $rule_obj && defined $self->{fallback_backing_store}) {
my ($fallback_backing_store) = $self->{fallback_backing_store};
return $fallback_backing_store->context_translate($context, $key, @_);
} else {
# If no rule found, use input key
$key = ">$key<"
if (defined $self->{options}->{showUntranslated}
&& $self->{options}->{showUntranslated} eq 1);
$rule_obj = new Locale::MakePhrase::LanguageRule(
language => $self->fallback_language,
translation => $key,
) unless (defined $rule_obj);
# Apply arguments to translated text
my $translated_text = $self->_apply_arguments($rule_obj, @_);
# apply encoding
$translated_text = $self->_apply_encoding($translated_text);
print STDERR "Translated text: $translated_text\n" if $DEBUG;
return $translated_text.$\ if $self->{add_newline};
return $translated_text;
}
}
sub getFallbackCharset {
my ($format) = @_;
$format = (defined $format) ? $format : __CONSTANT__::RVL_LANG_ID;
my ($lang) = RVL::Translation::getFallbackLangID($format);
return RVL::Translation::extractCharset($lang, $format);
}
sub extractCharset {
my ($lang, $format) = @_;
my ($devider) = '-';
if ($format eq __CONSTANT__::RVL_LANG_ID_TRANS2) {
$devider = '_';
}
my (@aLang) = split(/$devider/, $lang);
shift(@aLang);
if ($aLang[0] eq 'tw') {
shift(@aLang);
}
return join($devider, @aLang);
}
sub getFallbackLangID {
my ($format) = @_;
$format = (defined $format) ? $format : __CONSTANT__::RVL_LANG_ID_TRANS2;
my ($lang) = RVL::Config::get('translation.fallbackLang');
return RVL::Translation::transformLangID($lang, $format);
}
sub transformLangID {
my ($langID, $format) = @_;
if (defined $format) {
if ($format eq __CONSTANT__::RVL_LANG_ID) {
$langID =~s/_/-/gi;
} else {
$langID =~s/-/_/gi;
}
} else {
if ($langID =~/\-/gi) {
$langID =~s/-/_/gi;
} else {
$langID =~s/_/-/gi;
}
}
return $langID;
}
sub getLangID {
my ($format) = $_[0];
}
sub isAllowedLanguage {
my ($lang) = @_;
$lang = RVL::Translation::transformLangID($lang, __CONSTANT__::RVL_LANG_ID);
return defined ($RVL::GLOBALS{'_RVL'}{'LANGUAGE'}{$lang});
}
sub getTranslations {
my ($module, $defauftModule, $lang) = @_;
my ($container) = RVL::Config::get('translation.container');
if(defined $module && defined $lang && $module ne '' && $lang ne '' && defined $container && $container eq 'directory'){
return RVL::Translation::getGuiTranslationsFromDir($module, $defauftModule, $lang);
}
if (defined $module && defined $lang && $module ne '' && $lang ne '') {
#if($database){}
return RVL::Translation::getGuiTranslationsFromFile($module, $defauftModule, $lang);
#my $translate = RVL::Translation::getGuiTranslationsFromFile($module, $defauftModule, $lang);
#return $translate;
} else {
RVL::raiseError('Incorrect parameter passed to '.__PACKAGE__.'::getTranslations',
__CONSTANT__::RVL_ERROR_INVALIDARGS);
}
}
sub getGuiTranslationsFromFile {
my ($module, $defauftModule, $lang) = @_;
my (@aTranslations);
my (%aLanguages) = %{$RVL::GLOBALS{'_RVL'}{'LANGUAGE'}};
my ($language) = ${$aLanguages{$lang}}[0];
my ($path) = __CONSTANT__::RVL_MOD_DIR . '/' . $module . '/lang';
my ($bs) = new Locale::MakePhrase::BackingStore::Directory(
directory => $path,
);
my ($dbs, $dmp);
my ($showUntranslated) = RVL::Config::get('debug.showUntranslated');
my ($fallbackLang) = RVL::Translation::transformLangID(RVL::Config::get('translation.fallbackLang'));
if ($module ne $defauftModule) {
# Load lang from Default module
my ($defpath) = __CONSTANT__::RVL_MOD_DIR . '/' . $defauftModule . '/lang';
$dbs = new Locale::MakePhrase::BackingStore::Directory(
directory => $defpath,
);
$dmp = new RVL::Translation(
{
language => $lang,
backing_store => $dbs,
fallbackLang => ${$aLanguages{$fallbackLang}}[0],
showUntranslated => $showUntranslated,
});
}
# Load lang form current module
my ($mp) = new RVL::Translation(
{
language => $lang,
backing_store => $bs,
fallbackLang => ${$aLanguages{$fallbackLang}}[0],
fallback_backing_store => $dmp,
showUntranslated => $showUntranslated,
}
);
#TODO Custom Lanaguage
#TODO Custom Lanaguage Form File
if(defined RVL::Session::singleton()->param('aPrefs.customLanguageFormFile') && defined RVL::Session::singleton()->param('aPrefs.customLanguageFilePath')){
my $customLanguage = RVL::Session::singleton()->param('aPrefs.customLanguageFormFile');
my $pathCustomLanguage = RVL::Session::singleton()->param('aPrefs.customLanguageFormFilePath');
my $customTranslate = getGuiCustomTranslationsFromFile($customLanguage,$bs,${$aLanguages{$fallbackLang}}[0],$dmp,$showUntranslated,$mp,$pathCustomLanguage);
if($customTranslate ne 0){
$mp = $customTranslate;
}
}
#TODO Custom Lanaguage Form Database
if(defined RVL::Session::singleton()->param('aPrefs.customLanguageFormDb')){
my $customLanguage = RVL::Session::singleton()->param('aPrefs.customLanguageFormDb');
my $customTranslate = getGuiCustomTranslationsFromDBMySQL($customLanguage,$mp);
if($customTranslate ne 0){
$mp = $customTranslate;
}
}
return $mp;
}
sub getGuiTranslationsFromDir {
my ($module, $defauftModule, $lang) = @_;
my (@aTranslations);
my (%aLanguages) = %{$RVL::GLOBALS{'_RVL'}{'LANGUAGE'}};
my ($showUntranslated) = RVL::Config::get('debug.showUntranslated');
my ($fallbackLang) = RVL::Translation::transformLangID(RVL::Config::get('translation.fallbackLang'));
my ($language) = ${$aLanguages{$fallbackLang}}[0];
#==== Translate default language ====
my $pathLang = __CONSTANT__::RVL_MOD_DIR . '/' . $module . '/lang/' . $language;
my $pathLangFile = $pathLang . '/' . $language . '.mpt';
#my ($dbs, $dmp);
my $bs = {};
my $mp = {};
if(-f $pathLangFile && $language){
$bs = new Locale::MakePhrase::BackingStore::Directory(
directory => $pathLang,
);
$mp = new RVL::Translation(
{
language => $language,
backing_store => $bs,
fallbackLang => ${$aLanguages{$fallbackLang}}[0],
showUntranslated => $showUntranslated,
});
}
#==== Translate current language ====
my ($path) = __CONSTANT__::RVL_MOD_DIR . '/' . $module . '/lang/' . $lang;
my $pathFile = $path . '/' . $lang . '.mpt';;
if(-f $pathFile && $lang){
$bs = new Locale::MakePhrase::BackingStore::Directory(
directory => $path,
);
# Load lang form current module
$mp = new RVL::Translation(
{
language => $lang,
backing_store => $bs,
fallbackLang => $language,
fallback_backing_store => $mp,
showUntranslated => $showUntranslated,
}
);
}
#TODO Custom Lanaguage
#TODO Custom Lanaguage Form File
# if(defined RVL::Session::singleton()->param('aPrefs.customLanguageFormFile') && defined RVL::Session::singleton()->param('aPrefs.customLanguageFilePath')){
# my $customLanguage = RVL::Session::singleton()->param('aPrefs.customLanguageFormFile');
# my $pathCustomLanguage = RVL::Session::singleton()->param('aPrefs.customLanguageFormFilePath');
# my $customTranslate = getGuiCustomTranslationsFromFile($customLanguage,$bs,${$aLanguages{$fallbackLang}}[0],$dmp,$showUntranslated,$mp,$pathCustomLanguage);
# if($customTranslate ne 0){
# $mp = $customTranslate;
# }
# }
#
#TODO Custom Lanaguage Form Database
if(defined RVL::Session::singleton()->param('aPrefs.customLanguageFormDb')){
my $customLanguage = RVL::Session::singleton()->param('aPrefs.customLanguageFormDb');
my $customTranslate = getGuiCustomTranslationsFromDBMySQL($customLanguage,$mp);
if($customTranslate ne 0){
$mp = $customTranslate;
}
}
return $mp;
}
sub getGuiCustomTranslationsFromDBMySQL {
my ($lang,$mp) = @_;
my %connect = (
'table' => 'translation',
'driver' => RVL::Config::get('db.type'),
'db' => RVL::Config::get('db.name'),
'host' => RVL::Config::get('db.host'),
'port' => RVL::Config::get('db.port'),
'user' => RVL::Config::get('db.user'),
'pass' => RVL::Config::get('db.pass'),
);
#valadate owner
if(defined RVL::Session::singleton()->param('aPrefs.owner')){
my $owner = RVL::Session::singleton()->param('aPrefs.owner');
$connect{sqlQuery} = sprintf('SELECT * FROM %s WHERE tran_language = "%s" AND (tran_owner = "%s") ;',$connect{'table'},$lang ,$owner);
}else{
#TODO custom SQL Query
$connect{sqlQuery} = sprintf('SELECT * FROM %s WHERE tran_language = "%s" AND (tran_owner = "rvadmin" OR tran_owner = "admin" OR tran_owner = "root") ;',$connect{'table'},$lang);
}
my $dbiConnect = sprintf('DBI:%s:%s:%s:%s',$connect{'driver'},$connect{'db'},$connect{'host'},$connect{'port'});
my $dbh = DBI->connect($dbiConnect, $connect{'user'}, $connect{'pass'});
$dbh->do('SET NAMES utf8');
$connect{dbh} = $dbh;
my $mpDb = new RVL::TranslationDB(\%connect);
my @langs = ($lang);
my $query_handle = $dbh->prepare($connect{'sqlQuery'});
$query_handle->execute();
my @data = ();
while(my $eachRes = $query_handle->fetchrow_hashref){
my $tranKey = $eachRes->{tran_key};
my $objlang = $mpDb->get_rules('',$tranKey,\@langs);
$mpDb->{rules}->{$lang}->{$tranKey}->{'_'} = $objlang;
}
$query_handle->finish();
$dbh->disconnect();
my ($showUntranslated) = RVL::Config::get('debug.showUntranslated');
my ($fallbackLang) = RVL::Translation::transformLangID(RVL::Config::get('translation.fallbackLang'));
my ($mpDBM) = new RVL::Translation(
{
language => $lang,
backing_store => $mpDb,
fallbackLang => $fallbackLang,
fallback_backing_store => $mp,
showUntranslated => $showUntranslated,
}
);
return $mpDBM;
}
}
1;
Copyright 2K16 - 2K18 Indonesian Hacker Rulez