日期: 2022年4月29日

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

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

    1、当语言区域为 en 时,当验证的参数不存在时,响应:The selected theme id is invalid.。如图1
    当语言区域为 en 时,当验证的参数不存在时,响应:The selected theme id is invalid.
    图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
    当语言区域为 zh_CN 时,当验证的参数不存在时,响应:所选的theme id无效。预期为:所选的主题ID无效。
    图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 的自定义属性名称,但是,并未生效
    <pre class="wp-block-syntaxhighlighter-code">
    
    <?php
    
    return [
    
        'attributes' => [
            'theme_id' => '主题ID',
        ],
    ];
    
    
    </pre>
    
    5、即使将此配置放至语言文件 /resources/lang/zh_CN/validation.php 中,仍然未生效,响应:所选的theme_id无效。但是,其默认是使用的此语言文件的配置。将验证规则消息放在任何语言的 validation.php 中名为 attributes 的键中,验证消息的 :attribute 部分不会被翻译(模块上下文)。
    <pre class="wp-block-syntaxhighlighter-code">
    
    <?php
    
    return [
    
    	'exists' => '所选的:attribute无效。',
    
        'attributes' => [
            'theme_id' => '主题ID',
        ],
    ];
    
    
    </pre>
    
    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');
        }
    
    
    
    <pre class="wp-block-syntaxhighlighter-code">
    
    <?php
    return [
        'exists' => '所选的:attribute无效。resources',
    
        'attributes' => [
            'theme_id' => '主题ID',
        ],
    ];
    
    
    </pre>
    
    
    
    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。
    <pre class="wp-block-syntaxhighlighter-code">
    
    <?php
    return [
        'array' => ':attribute必须是一个数组。',
    
        'attributes' => [
            'filter' => '过滤器'
        ],
    ];
    
    
    </pre>
    
    
    
    {
      "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、暂时不准备编写一个自定义规则。决定在非英语环境下,属性名未翻译为对应的语言,暂且接受。且语言文件在根目录下,不在对应的模块目录下。