在 Laravel 6、LightHouse 5、Module 中使用 @rules 指令时,应用 exists 规则时的本地化实现

1、当语言区域为 en 时,当验证的参数不存在时,响应:The selected theme id is invalid.。如图1

图1

{
  "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、当语言区域为 zh_CN 时,当验证的参数不存在时,响应:所选的theme id无效。预期为:所选的主题ID无效。如图2

图2

{
  "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、查看 GraphQL 代码实现,/Modules/ThemeStore/Resources/graphql/theme_editor.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、查看 语言文件 ,/Modules/ThemeStore/Resources/lang/zh_CN/validation.php,已经指定了 theme_id 的自定义属性名称,但是,并未生效

<?php

return [

    'attributes' => [
        'theme_id' => '主题ID',
    ],
];

5、即使将此配置放至语言文件 /resources/lang/zh_CN/validation.php 中,仍然未生效,响应:所选的theme_id无效。但是,其默认是使用的此语言文件的配置。将验证规则消息放在任何语言的 validation.php 中名为 attributes 的键中,验证消息的 :attribute 部分不会被翻译(模块上下文)。

<?php

return [

 'exists' => '所选的:attribute无效。',

    'attributes' => [
        'theme_id' => '主题ID',
    ],
];

6、在 Laravel v8.7.90、nwidart/laravel-modules 8.2.0 中,编辑 /resources/lang/zh_CN/validation.php ,attributes 会生效。

    /**
     * 显示创建博客文章的表单
     *
     * @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
return [
    'exists' => '所选的:attribute无效。resources',

    'attributes' => [
        'theme_id' => '主题ID',
    ],
];

Illuminate\Support\MessageBag {#361 ▼
  #messages: array:1 [▼
    "theme_id" => array:1 [▼
      0 => "所选的主题ID无效。resources"
    ]
  ]
  #format: ":message"
}

7、决定在当前版本:Laravel v6.20.43、nwidart/laravel-modules 7.3.0 中,模拟步骤6的实现。以确定是否与框架、模块包的版本有关,进而导致在应用的根目录中,attributes 不生效的问题。确定是无关的。那么原因在于 LightHouse 5。

<?php
return [
    'array' => ':attribute必须是一个数组。',

    'attributes' => [
        'filter' => '过滤器'
    ],
];

{
  "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、参考:https://github.com/nuwave/lighthouse/issues/1773 ,虽然已经在 @rules 指令上实现了翻译功能,但是实现得不够彻底。即验证属性未支持。开发者建议:https://lighthouse-php.com/master/security/validation.html#validator-classes 。支持通过任意 PHP 代码定义规则。

9、暂时不准备编写一个自定义规则。决定在非英语环境下,属性名未翻译为对应的语言,暂且接受。且语言文件在根目录下,不在对应的模块目录下。

 

永夜