fecshop / yii2_fecshop

yii2 ( PHP ) fecmall(fecshop) core code used for ecommerce shop 多语言多货币多入口的开源电商 B2C 商城,支持移动端vue, app, html5,微信小程序微店,微信小程序商城等
http://www.fecmall.com
BSD 3-Clause "New" or "Revised" License
5.22k stars 1.41k forks source link

The message file for category 'yii' does not exist: /path/to/vendor/yiisoft/yii2/messages/zh_CN/yii.php Fallback file does not exist as well: /path/to/vendor/yiisoft/yii2/messages/zh/yii.php #67

Closed successgo closed 5 years ago

successgo commented 5 years ago

在日常的日志巡检过程中,发现了一个不断出现在日志中的翻译的错误很是让人恼火。

The message file for category 'yii' does not exist: /path/to/vendor/yiisoft/yii2/messages/zh_CN/yii.php Fallback file does not exist as well: /path/to/vendor/yiisoft/yii2/messages/zh/yii.php

复现步骤

在vue 端,编辑地址,点保存时,即会触发上述问题。(added 20190216)

经过一番排查,基本定位到了问题的原因:关于语言定义的规范问题。

原因说明

yii 本身使用多语言的定义时,采取这样的格式:zh-CN。如下图:

image

然而 fecshop 在使用多语言的定义时,采用了格式:zh_CN。如下图:

image

fecshop 代码剖析

关于 fecshoplang service 的配置信息相关代码:

return [
    'fecshoplang' => [
        //'class' => 'fecshop\services\FecshopLang',
        //  mongoSearchLangName 在各个语言下字段参考资料如下:(不支持中文)
        //  https://docs.mongodb.com/manual/reference/text-search-languages/#text-search-languages
        'allLangCode' => [
            // 'en_US' 是标准语言简码  code对应的值en取 “标准语言简码”的前两位字符,
            // 该值设置后,进行了产品分类数据的添加后,不能修改,否则会出现部分翻译语言丢失。
            'zh_CN' => [
                'code'                    => 'zh',
            ],
        ],
        // 默认语言。
        'defaultLangCode' => 'zh',
    ],
];

上述代码位于 @common/config/fecshop_local_services/FecshopLang.php

上述代码,删除了原有的其他语言配置项,仅保留了中文。

关于 Yii i18n 的文档链接:https://www.yiiframework.com/doc/guide/2.0/en/tutorial-i18n 中的说明:

For consistency reasons, all locale IDs used in Yii applications should be canonicalized to the format of ll-CC, where ll is a two- or three-letter lowercase language code according to ISO-639 and CC is a two-letter country code according to ISO-3166.

Yii::$service->page->translate 服务中,有一方法定义如下:

    /**
     * @property $language | String,设置当前的语言。
     * 语言部分使用的是Yii2的语言功能。
     */
    protected function actionSetLanguage($language)
    {
        Yii::$app->language = $language;
    }

同时请注意,Yii::$app->language 属性也被 Yii::t() 所使用。

如下:

    public static function t($category, $message, $params = [], $language = null)
    {
        if (static::$app !== null) {
            return static::$app->getI18n()->translate($category, $message, $params, $language ?: static::$app->language);
        }

        $placeholders = [];
        foreach ((array) $params as $name => $value) {
            $placeholders['{' . $name . '}'] = $value;
        }

        return ($placeholders === []) ? $message : strtr($message, $placeholders);
    }

那么此时来讲,fecshop 的语言是什么时候被设置的呢?

答案是在 fecshop 的 store 初始化的时候。

Yii::$service->store 服务的 actionBootstrap() 方法中有关键代码如下:

Yii::$service->page->translate->setLanguage($store['language']);

而 store 的配置相关如下:


            // store key:域名去掉http部分,作为key,这个必须这样定义。
            'appserver.fecshoptest.com' => [
                'language'         => 'zh_CN',        // 语言简码需要在@common/config/fecshop_local_services/FecshopLang.php 中定义。
                'languageName'     => '中文',    // 语言简码对应的文字名称,将会出现在语言切换列表中显示。
                'currency'         => 'CNY', // 当前store的默认货币,这个货币简码,必须在货币配置中配置
                ...
            ]

至此分析结束。

修复方法

使用与 Yii 一致的语言的定义格式:

zh-CN

所有关于语言的设定的地方均要修改。

fancyecommerce commented 5 years ago

修改一下试试: https://github.com/fecshop/yii2_fecshop/commit/2c51df4c5efefcfb204376a3c6ab58c93a9dba79

successgo commented 5 years ago

@fancyecommerce 添加了复现步骤。