没有不值得去解决的问题,也没有不值得去学习的技术!

Localizing the Exists Rule When Using the @rules Directive in Laravel 6, LightHouse 5, and Modules

When the locale is zh_CN and the validated parameter does not exist, the response is: 所选的theme id无效。 The expected response is: 所选的主题ID无效。

1. When the locale is en and the validated parameter does not exist, the response is: The selected theme id is invalid. See Figure 1.

When the locale is en and the validated parameter does not exist, the response is: The selected theme id is invalid.
Figure 1
JSON

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

2. When the locale is zh_CN and the validated parameter does not exist, the response is: 所选的theme id无效。 The expected response is: 所选的主题ID无效。 See Figure 2.

When the locale is zh_CN and the validated parameter does not exist, the response is: 所选的theme id无效。 The expected response is: 所选的主题ID无效。
Figure 2
JSON
{
  "errors": [
    {
      "message": "Validation failed for the field [onlineStoreThemeEditorSessionCreate].",
      "extensions": {
        "validation": {
          "themeId": [
            "所选的theme id无效。"
          ]
        },
        "category": "validation"
      },
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "onlineStoreThemeEditorSessionCreate"
      ],
      "trace": ...
    }
  ],
  "data": {
    "onlineStoreThemeEditorSessionCreate": null
  }
}

3. Review the GraphQL code implementation: /Modules/ThemeStore/Resources/graphql/theme_editor.graphql

GraphQL

extend type Mutation {
    "创建主题编辑会话"
    onlineStoreThemeEditorSessionCreate(themeId: ID! @rules(apply: ["exists:theme_asset,theme_id"])): ThemeEditorSessionCreatePayload @field(resolver: "Modules\\ThemeStore\\Resolver\\ThemeEditor\\CreateThemeEditorSessionResolver")
}

type ThemeEditorSessionCreatePayload
{
    "会话"
    session: Session!
}



4. Check the language file /Modules/ThemeStore/Resources/lang/zh_CN/validation.php. A custom attribute name for theme_id has been specified, but it does not take effect.

PHP
<?php
 
return [
 
    'attributes' => [
        'theme_id' => '主题ID',
    ],
];
 

5. Even if this configuration is placed in the language file /resources/lang/zh_CN/validation.php, it still does not take effect. The response is: 所选的theme_id无效。 However, this language file’s configuration is used by default. When the validation rule message is placed in the attributes key of validation.php for any language, the :attribute portion of the validation message is not translated (in the module context).

PHP
<?php
 
return [
 
    'exists' => '所选的:attribute无效。',
 
    'attributes' => [
        'theme_id' => '主题ID',
    ],
];

6. In Laravel v8.7.90 and nwidart/laravel-modules 8.2.0, editing /resources/lang/zh_CN/validation.php makes the attributes take effect.

PHP

    /**
     * 显示创建博客文章的表单
     *
     * @return Response
     */
    public function create(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'theme_id' => 'required|exists:users,id',
        ]);

        if ($validator->fails()) {
            dd($validator->errors());
        }

        // 保存博客文章…

        return view('blog::post.create');
    }

PHP
<?php
return [
    'exists' => '所选的:attribute无效。resources',
 
    'attributes' => [
        'theme_id' => '主题ID',
    ],
];
Plaintext
Illuminate\Support\MessageBag {#361 ▼
  #messages: array:1 [▼
    "theme_id" => array:1 [▼
      0 => "所选的主题ID无效。resources"
    ]
  ]
  #format: ":message"
}

7. I decided to replicate the implementation from step 6 in the current versions: Laravel v6.20.43 and nwidart/laravel-modules 7.3.0. This was to determine whether the issue of attributes not taking effect in the application’s root directory was related to the framework or module package versions. I confirmed that they are unrelated. Therefore, the cause lies in LightHouse 5.

PHP
<?php
return [
    'array' => ':attribute必须是一个数组。',
 
    'attributes' => [
        'filter' => '过滤器'
    ],
];
JSON

{
  "message": "The given data was invalid.",
  "errors": {
    "filter": [
      "过滤器必须是一个数组。"
    ]
  },
  "status_code": 422,
  "debug": {
    "line": 385,
    "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Validation\\Validator.php",
    "class": "Illuminate\\Validation\\ValidationException",
    "trace": ...
  }
}

8. Reference: https://github.com/nuwave/lighthouse/issues/1773 . Although translation functionality has been implemented for the @rules directive, the implementation is not thorough. Specifically, validation attributes are not supported. The developer recommends: https://lighthouse-php.com/master/security/validation.html#validator-classes . This supports defining rules via arbitrary PHP code.

9. I am not going to write a custom rule for now. I have decided to temporarily accept that attribute names are not translated into the corresponding language in non-English environments. Additionally, the language file remains in the root directory rather than in the corresponding module directory.

关于作者 · 持续学习与技术实践

我是一名拥有 15 年以上开发经验的技术从业者,自 2013 年起持续运营个人技术博客,记录工作与个人项目中遇到的真实问题,以及解决问题过程中的探索、实践和思考。

除了技术写作,我也在持续开发和维护自己的独立项目,探索新技术和新工具在实际场景中的应用。我始终相信,没有不值得去解决的问题,也没有不值得去学习的技术。

如果这篇文章对你有所帮助,欢迎浏览博客中的其他文章,也欢迎交流技术经验与想法。

关于我  ·  GitHub  ·  邮件联系