其实是我自己解决的,想在这里回复一下,以防以后其他人也想解决和我一样的问题。
解决方案
我在App\Exceptions\Handler 类中添加了一个invalidJson 方法,只要抛出ValidationException 并且$request->wantsJson() 为真,Laravel 就会自动调用该方法。
在该方法中,我只是检查了我的自定义标头 (X-WITH-UNTRANSLATED-VALIDATION) 是否存在于请求中,值为“yes”。
如果是这种情况,我会从异常中获取验证器实例,并获取所有规则。
然而,laravel 在内部以“studly caps case”(StartsWith)表示这些规则,我们希望以蛇形案例格式(“starts_with”)获得它们。为了解决这个问题,我使用 laravel 集合助手映射嵌套数组并将规则键转换为蛇形大小写。
代码
这是来自app\Exceptions\Handler.php的代码。
/**
* Convert a validation exception into a JSON response.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Validation\ValidationException $exception
* @return \Illuminate\Http\Response
*/
protected function invalidJson($request, ValidationException $exception)
{
//If the header is not present in the request 'no' wil be provided as the fallback value, thus not being equal with "yes"
if($request->header('X-WITH-UNTRANSLATED-VALIDATION', 'no') === "yes") {
$failed = $this->makeUntranslatedMessagesIntoSnakeCase($exception);
return response([
// Get the original exception message
'message' => $exception->getMessage(),
'errors' => $failed,
// Add the original translated error messages under a diffrent key to help with debugging
'translated_errors' => $exception->errors(),
], $exception->status);
}
//If the header is not present (with the right value) we return the default JSON response instead
return parent::invalidJson($request, $exception);
}
/**
* Convert the untranslated rule names of a validation exception into snake case.
*
* @param \Illuminate\Validation\ValidationException $exception
* @return array
*/
protected function makeUntranslatedMessagesIntoSnakeCase(ValidationException $exception) : array
{
return collect($exception->validator->failed())->map(function ($item) {
return collect($item)->mapWithKeys(function ($values, $rule) {
return [Str::snake($rule) => $values];
});
})->toArray();
}
进一步改进
如果您需要为正常的“非 json”请求禁用翻译,您也可以覆盖 Handler.php 中的 invalid 方法并执行类似的操作,但只需将消息添加到会话中即可。同样,您也可以在未翻译的消息旁边添加已翻译的消息。
编辑
我还在回复中添加了'translated_errors' => $exception->errors(),以帮助调试