yidashi 2016-07-25 18:32:29 5649次浏览 2条评论 1 1 0

原文链接:http://www.51siyuan.cn/94.html

参考源码:http://www.51siyuan.cn/code.html

如果翻译的消息在消息源文件里找不到,Yii 将直接显示该消息内容。这样一来当你的原始消息是一个有效的冗长的文字时会很方便。 然而,有时它是不能实现我们的需求。你可能需要执行一些自定义处理的情况, 这时请求的翻译可能在消息翻译源文件找不到。 这可通过使用

yii\i18n\MessageSource::EVENT_MISSING_TRANSLATION - yii\i18n\MessageSource 的事件来完成。

例如,你可能想要将所有缺失的翻译做一个明显的标记,这样它们就可以很容易地在页面中找到。 为此,你需要先设置一个事件处理程序。这可以在应用程序配置中进行:

'components' => [
    // ...
    'i18n' => [
        'translations' => [
            'app*' => [
                'class' => 'yii\i18n\PhpMessageSource',
                'fileMap' => [
                    'app' => 'app.php',
                    'app/error' => 'error.php',
                ],
                'on missingTranslation' => ['app\components\TranslationEventHandler', 'handleMissingTranslation']
            ],
        ],
    ],
],

现在,你需要实现自己的事件处理程序,以下代码通过调用百度翻译api实现没命中的情况下先翻译并保存数据库再返回翻译结果:

<?php

namespace app\components;

use app\models\I18nMessage;
use app\models\I18nSourceMessage;

class TranslationEventHandler
{
    /**
     * @param \yii\i18n\MissingTranslationEvent $event
     */
    public static function missingTranslation($event)
    {
        //http://fanyi.baidu.com/v2transapi?from=zh&query=世界&to=en
        // 当语言没命中的时候用百度翻译并保存到数据库
        $model = I18nSourceMessage::find()->where(['category' => $event->category, 'message' => $event->message])->one();
        if ($model == null) {
            $model = new I18nSourceMessage();
            $model->category = $event->category;
            $model->message = $event->message;
            $model->save();
        }
        $messageModel = I18nMessage::find()->where(['id' => $model->id, 'language' => $event->language])->one();
        if ($messageModel == null) {
            $messageModel = new I18nMessage();
            $messageModel->language = $event->language;
            $messageModel->id = $model->id;
            $messageModel->translation = self::translate($event->message, 'en', self::parseLanguage($event->language));
            $messageModel->save();
        }
        $event->translatedMessage = $messageModel->translation;
    }

    public static function parseLanguage($language)
    {
        // 参考百度翻译api自己添加其他语言的map(yii - baidu)
        $languageMap = [
            'zh-CN' => 'zh'
        ];
        return $languageMap[$language];
    }
    //百度翻译
    public static function translate($text, $from , $to)
    {
        $url = "http://fanyi.baidu.com/v2transapi";
        $data = array (
            'from' => $from,
            'to' => $to,
            'query' => $text
        );
        $data = http_build_query($data);
        $ch = curl_init ();
        curl_setopt ($ch, CURLOPT_URL, $url );
        curl_setopt ($ch, CURLOPT_REFERER, "http://fanyi.baidu.com" );
        curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; rv:37.0) Gecko/20100101 Firefox/37.0' );
        curl_setopt ($ch, CURLOPT_HEADER, 0 );
        curl_setopt ($ch, CURLOPT_POST, 1 );
        curl_setopt ($ch, CURLOPT_POSTFIELDS, $data );
        curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1 );
        curl_setopt ($ch, CURLOPT_TIMEOUT, 10 );
        $result = curl_exec($ch);
        curl_close($ch);

        $result = json_decode($result, true);

        if (!isset($result['trans_result']['data']['0']['dst'])){
            return false;
        }
        return $result['trans_result']['data']['0']['dst'];
    }
}

yii\i18n\MissingTranslationEvent::translatedMessage 是由事件处理程序设置,它将显示翻译结果。

当然你可以直接设置所有国际化语言都用 DB 来管理,一开始通过这种方法收集所有消息源,而不用那么麻烦自己去文件里定义。翻译结果不可能完全符合你意,自己做个 crud 界面改翻译结果~

觉得很赞
您需要登录后才可以评论。登录 | 立即注册