There is no problem not worth solving, and no technology not worth learning!

In Laravel 6, Module, the translation of unavailable translations in the message of custom validation rules (caused by delay provider)

在一段时间后,突然发现自定义验证规则的 message 中翻译不可用。验证失败时响应的 message 未被翻译

1. Reference:https://www.shuijingwanwq.com/2022/04/26/6341/

2. After a period of time, I suddenly found that the translation in the message of the custom verification rule is not available. Message that responds when validation fails is not translated. as shown in Figure 1

在一段时间后,突然发现自定义验证规则的 message 中翻译不可用。验证失败时响应的 message 未被翻译
Figure 1

{
  "errors": [
    {
      "message": "Validation failed for the field [onlineStoreThemeEditorSessionDelete].",
      "extensions": {
        "validation": {
          "sessionId": [
            "online_store_theme_graphql::validation.custom.theme_editor_session.theme_editor_session_id_exists_rule"
          ]
        },
        "category": "validation"
      },
      "locations": [
        {
          "line": 3,
          "column": 3
        }
      ],
      "path": [
        "onlineStoreThemeEditorSessionDelete"
      ],
      "trace": ...
    }
  ],
  "data": {
    "onlineStoreThemeEditorSessionDelete": null
  }
}


3. Reference:https://www.shuijingwanwq.com/2022/06/29/6707/, after deleting the Implements DeferrableProvider, then clear the directory: /bootstrap/cache, the translation works normally. as shown in Figure 2

参考:https://www.shuijingwanwq.com/2022/06/29/6707/ ,当删除 implements DeferrableProvider 后,再清空目录:/bootstrap/cache 后,翻译正常工作
Figure 2

{
  "errors": [
    {
      "message": "Validation failed for the field [onlineStoreThemeEditorSessionDelete].",
      "extensions": {
        "validation": {
          "sessionId": [
            "The selected session id is invalid."
          ]
        },
        "category": "validation"
      },
      "locations": [
        {
          "line": 3,
          "column": 3
        }
      ],
      "path": [
        "onlineStoreThemeEditorSessionDelete"
      ],
      "trace": ...
    }
  ],
  "data": {
    "onlineStoreThemeEditorSessionDelete": null
  }
}


4. The existing implementation in the service provider of the module is as follows


class GraphQlResolverServiceProvider extends ServiceProvider implements DeferrableProvider
{
    /**
     * @return void
     */
    public function register()
    {
        $this->registerTranslations();

        // ...
    }
}


5. Reference: /vendor/laravel/framework/src/illuminate/translation/TranslationServiceProvider.php, the code adjustment is as follows


class GraphQlResolverServiceProvider extends ServiceProvider implements DeferrableProvider
{
    /**
     * @return void
     */
    public function register()
    {
        $this->registerLoader();

        $this->app->singleton('translator', function ($app) {
            $loader = $app['translation.loader'];

            // When registering the translator component, we'll need to set the default
            // locale as well as the fallback locale. So, we'll grab the application
            // configuration so we can easily get both of these values from there.
            $locale = $app['config']['app.locale'];

            $trans = new Translator($loader, $locale);

            $trans->setFallback($app['config']['app.fallback_locale']);

            return $trans;
        });

        $this->registerTranslations();

        // ...
    }

    /**
     * Register the translation line loader.
     *
     * @return void
     */
    protected function registerLoader()
    {
        $this->app->singleton('translation.loader', function ($app) {
            return new FileLoader($app['files'], $app['path.lang']);
        });
    }

    /**
     * Register translations.
     *
     * @return void
     */
    public function registerTranslations()
    {
        $langPath = resource_path('lang/modules/' . $this->moduleNameLower);

        if (is_dir($langPath)) {
            $this->loadTranslationsFrom($langPath, $this->moduleNameLower);
        } else {
            $this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', $this->moduleNameLower);
        }
    }

    /**
     * 获取由提供者提供的服务。
     *
     * @return array
     */
    public function provides()
    {
        return ['translator', 'translation.loader'];
    }
}


6. The translation is normal. But in this case, the code is very redundant. Decided to adjust it again, and peeled out a class with a delayed loading service.


class OnlineStoreThemeGraphQLServiceProvider extends ServiceProvider
{
    private $moduleNameLower = 'online_store_theme_graphql';

    /**
     * @return void
     */
    public function register()
    {
        $this->app->register(ResolverServiceProvider::class);

        $this->registerTranslations();
    }

    /**
     * Register translations.
     *
     * @return void
     */
    public function registerTranslations()
    {
        $langPath = resource_path('lang/modules/' . $this->moduleNameLower);

        if (is_dir($langPath)) {
            $this->loadTranslationsFrom($langPath, $this->moduleNameLower);
        } else {
            $this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', $this->moduleNameLower);
        }
    }

    /**
     * 获取由提供者提供的服务。
     *
     * @return array
     */
    public function provides()
    {
        return [];
    }
}



class ResolverServiceProvider extends ServiceProvider implements DeferrableProvider
{
    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton(SettingPersistenceInterface::class, function($app){
            return new DbSettingPersister();
        });

        $this->app->singleton(ThemeAssetRepositoryInterface::class, function($app){
            return new ThemeAssetRepository();
        });
    }

    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {
        return [SettingPersistenceInterface::class, ThemeAssetRepositoryInterface::class];
    }
}


7. The translation is working normally. as shown in Figure 3

翻译正常工作
Figure 3

PHP / Laravel / Yii2 Legacy Project Maintenance & Long-Term Technical Support

If your PHP / Laravel / Yii2 project is already in production but needs bug fixing, API troubleshooting, performance optimization, developer handover support, or long-term maintenance, feel free to contact me for remote technical support.

Ideal For:
✅ PHP legacy systems without active maintenance
✅ Laravel / Yii2 project bug fixes
✅ Admin panel feature iterations
✅ RESTful API troubleshooting
✅ MySQL / Redis / Nginx performance issues
✅ Long-term remote part-time maintenance

We can start with a small task:
✅ Production error troubleshooting
✅ API issue analysis
✅ Slow query and performance bottleneck diagnosis
✅ Initial code structure review
✅ Deployment environment and log inspection

If you would like to discuss your project, please contact me and mention: PHP Maintenance Consultation.

Contact Me:
Telegram: @shuijingwan
WeChat: 13980074657
Email: shuijingwanwq@gmail.com

评论

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.