使用自定义操作时,Symfony 验证不适用于 Api 平台 class
Symfony validation doesnt' work with Api Platform when using custom action class
我正在使用 symfony 4 和 Api 平台 2.5。我创建了一个自定义操作来更改用户密码。
问题是,当我发送 一个空的旧密码 或任何其他必需的属性时,验证不起作用。如您所见,我使用了一个名为 "change_password".
的验证组
这是实体用户的一部分:
/**
* @ApiResource(
* itemOperations={
* "user_change_password"={
* "method"="PUT",
* "path"="/users/change-password/{id}",
* "controller"=UserChangePassword::class,
* "formats"={"json"},
* "denormalization_context"={"groups"={"user:change-password"}},
* "normalization_context"={"groups"={"user:read"}},
* "validation_groups"={"change_password"},
* "access_control"="is_granted('EDIT', object)",
* "access_control_message"="access denied"
* },
* },
* )
*
*/
class User implements UserInterface, \Serializable, EquatableInterface
{
/**
* @Assert\NotBlank(
* message=Tthis value should not be blank",
* groups={"change_password"}
* )
* @SecurityAssert\UserPassword(
* message = "Wrong value for your current password",
* groups={"change_password"}
* )
* @Groups({"user:change-password"})
*/
private $oldPassword;
/**
* @Assert\NotBlank(
* message="This value should not be blank",
* groups={"registration", "change_password"}
* )
* @Assert\Length(
* min="6",
* max="32",
* minMessage="Password must be at least ({{ limit }}) characters.",
* maxMessage="Password must have a maximum of ({{ limit }}) characters.",
* groups={"registration", "change_password"}
* )
* @Groups({"user:write", "user:change-password"})
*/
private $plainPassword;
/**
* @Assert\NotBlank(
* message="This value should not be blank",
* groups={"registration", "change_password"}
* )
* @Assert\Expression(
* "this.getPlainPassword() == this.getRetypedPlainPassword()",
* groups={"registration", "change_password"}
* )
* @Groups({"user:write", "user:change-password"})
*/
private $retypedPlainPassword;
}
这是自定义操作class:
class UserChangePassword
{
public function __invoke(User $data)
{
$errors = $this->validator->validate($data);
if (count($errors) > 0) {
throw new ValidationException($errors);
}
dd($errors) ;
$oldPassword = $data->getOldPassword();
if ($this->passwordEncoder->isPasswordValid($data, $oldPassword)) {
// do changes
}
return $data;
}
}
旧密码为空时dd($erros)的输出:
和没有 dd($erros) 我得到这个错误:
第一
对于 v2.5+,将 access_control
替换为 security
。并将 access_control_message
替换为 security_message
.
第二
如果您不使用自定义控制器,请尝试在 validation_groups
中添加 Default
组:
"validation_groups"={"Default", "change_password"},
或在约束中添加Default
组:
//src/Entity/User.php
@Assert\NotBlank(groups={"Default", "change_password"})
并调用验证:
<?php
// src/Controller/Api/CustomClass.php
declare(strict_types=1);
namespace App\Controller\Api;
use ApiPlatform\Core\Validator\ValidatorInterface;
use App\Entity\User;
class CustomClass extends AbstractController
{
/**
* @var ValidatorInterface
*/
private $validator;
public function __construct(ValidatorInterface $validator) {
$this->validator = $validator;
}
public function __invoke(User $data): User
{
$this->validator->validate($data);
//other code ...
}
}
你也可以查看这个Url
https://symfony.com/doc/current/validation/groups.html
所以不加"Default"可以这样解:
$errors = $this->validator->validate($data, null, ['change_password']);
if (count($errors) > 0) {
throw new ValidationException($errors);
}
在我的例子中,我使用 symfony 4.4,api-平台版本 2.5 使用以下代码
$this->validator->validate($data,['groups'=>'register']);
而验证器是 instanceof ApiPlatform\Core\Validator\ValidatorInterface
.
我正在使用 symfony 4 和 Api 平台 2.5。我创建了一个自定义操作来更改用户密码。
问题是,当我发送 一个空的旧密码 或任何其他必需的属性时,验证不起作用。如您所见,我使用了一个名为 "change_password".
的验证组这是实体用户的一部分:
/**
* @ApiResource(
* itemOperations={
* "user_change_password"={
* "method"="PUT",
* "path"="/users/change-password/{id}",
* "controller"=UserChangePassword::class,
* "formats"={"json"},
* "denormalization_context"={"groups"={"user:change-password"}},
* "normalization_context"={"groups"={"user:read"}},
* "validation_groups"={"change_password"},
* "access_control"="is_granted('EDIT', object)",
* "access_control_message"="access denied"
* },
* },
* )
*
*/
class User implements UserInterface, \Serializable, EquatableInterface
{
/**
* @Assert\NotBlank(
* message=Tthis value should not be blank",
* groups={"change_password"}
* )
* @SecurityAssert\UserPassword(
* message = "Wrong value for your current password",
* groups={"change_password"}
* )
* @Groups({"user:change-password"})
*/
private $oldPassword;
/**
* @Assert\NotBlank(
* message="This value should not be blank",
* groups={"registration", "change_password"}
* )
* @Assert\Length(
* min="6",
* max="32",
* minMessage="Password must be at least ({{ limit }}) characters.",
* maxMessage="Password must have a maximum of ({{ limit }}) characters.",
* groups={"registration", "change_password"}
* )
* @Groups({"user:write", "user:change-password"})
*/
private $plainPassword;
/**
* @Assert\NotBlank(
* message="This value should not be blank",
* groups={"registration", "change_password"}
* )
* @Assert\Expression(
* "this.getPlainPassword() == this.getRetypedPlainPassword()",
* groups={"registration", "change_password"}
* )
* @Groups({"user:write", "user:change-password"})
*/
private $retypedPlainPassword;
}
这是自定义操作class:
class UserChangePassword
{
public function __invoke(User $data)
{
$errors = $this->validator->validate($data);
if (count($errors) > 0) {
throw new ValidationException($errors);
}
dd($errors) ;
$oldPassword = $data->getOldPassword();
if ($this->passwordEncoder->isPasswordValid($data, $oldPassword)) {
// do changes
}
return $data;
}
}
旧密码为空时dd($erros)的输出:
和没有 dd($erros) 我得到这个错误:
第一
对于 v2.5+,将 access_control
替换为 security
。并将 access_control_message
替换为 security_message
.
第二
如果您不使用自定义控制器,请尝试在 validation_groups
中添加 Default
组:
"validation_groups"={"Default", "change_password"},
或在约束中添加Default
组:
//src/Entity/User.php
@Assert\NotBlank(groups={"Default", "change_password"})
并调用验证:
<?php
// src/Controller/Api/CustomClass.php
declare(strict_types=1);
namespace App\Controller\Api;
use ApiPlatform\Core\Validator\ValidatorInterface;
use App\Entity\User;
class CustomClass extends AbstractController
{
/**
* @var ValidatorInterface
*/
private $validator;
public function __construct(ValidatorInterface $validator) {
$this->validator = $validator;
}
public function __invoke(User $data): User
{
$this->validator->validate($data);
//other code ...
}
}
你也可以查看这个Url
https://symfony.com/doc/current/validation/groups.html
所以不加"Default"可以这样解:
$errors = $this->validator->validate($data, null, ['change_password']);
if (count($errors) > 0) {
throw new ValidationException($errors);
}
在我的例子中,我使用 symfony 4.4,api-平台版本 2.5 使用以下代码
$this->validator->validate($data,['groups'=>'register']);
而验证器是 instanceof ApiPlatform\Core\Validator\ValidatorInterface
.