API平台自定义操作为数据参数提供价值

时间:2018-10-15 10:52:00

标签: php symfony

下午好。 我正在使用Symfony 4.1.1和APIPlatorm创建一个API。 我正在尝试创建一个定制的Post操作,以在数据库中使用加密的密码创建用户。

我已按照https://api-platform.com/docs/core/operations中所述的过程进行操作 但是我必须遵循以下错误:

  

Controller \“ App \ Controller \ UtilisateurSpecial \”要求您   提供\“ $ data \”参数的值。要么是   可为空,没有提供空值,没有默认值   被提供或因为此之后有非可选参数   一个。

这是我的配置。您能帮我解决这个问题吗?

src \ Entity \ Utilisateur.php

JSONObject jsnobject = new JSONObject(content);

JSONArray jsonArray = jsnobject.getJSONArray("key1");
for (int i = 0; i < jsonArray.length(); i++) {
    JSONObject explrObject = jsonArray.getJSONObject(i);
}

src / controller / UtilisateurSpecial

 <?php

   namespace App\Entity;

   use ApiPlatform\Core\Annotation\ApiResource;
   use Doctrine\ORM\Mapping as ORM;
   use Symfony\Component\Security\Core\User\UserInterface;
   use Symfony\Component\Validator\Constraints as Assert;
   use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;

   /**
    * @ApiResource(
    *     collectionOperations={
    *     "post",
    *     "special"={
    *         "method"="POST",
    *         "path"="/utilisateurs/special.{_format}",
    *          "requirements"={
    *              "_format": "\s+"
    *           },
    *         "controller"=App\Controller\UtilisateurSpecial::class,
    *         "defaults"={"_api_receive"=false}
    *     }
    * })
    * @ORM\Entity(repositoryClass="App\Repository\UtilisateurRepository")
    * @UniqueEntity(fields="email", message="Cet email est déjà enregistré en base.")
    * @UniqueEntity(fields="username", message="Cet identifiant est déjà enregistré en base")
    * 
    */
   class Utilisateur implements UserInterface, \Serializable
   {
       /**
        * @ORM\Column(type="integer")
        * @ORM\Id
        * @ORM\GeneratedValue(strategy="AUTO")
        */
       private $id;

       /**
        * @ORM\Column(type="string", length=25, unique=true)
        * @Assert\NotBlank()
        * @Assert\Length(max=25)
        */
       private $username;

       /**
        * @ORM\Column(type="string")
        */
       private $password;

       /**
        * @ORM\Column(type="string", length=60, unique=true)
        * @Assert\NotBlank()
        * @Assert\Length(max=60)
        * @Assert\Email()
        */
       private $email;

       /**
        * @ORM\Column(name="is_active", type="boolean")
        */
       private $isActive;

        /**
        * @var array
        * @ORM\Column(type="array")
        */
       private $roles;

       public function __construct()
       {
           $this->isActive = true;
           $this->roles = ['ROLE_USER'];
       }

       /*
        * Get id
        */
       public function getId()
       {
           return $this->id;
       }

       public function getUsername()
       {
           return $this->username;
       }

       public function setUsername($username)
       {
           $this->username = $username;
           return $this;
       }


       public function getPassword()
       {
           return $this->password;
       }

       public function setPassword($password)
       {
           $this->password = $password;
           return $this;
       }

       /*
        * Get email
        */
       public function getEmail()
       {
           return $this->email;
       }

       /*
        * Set email
        */
       public function setEmail($email)
       {
           $this->email = $email;
           return $this;
       }

       /*
        * Get isActive
        */
       public function getIsActive()
       {
           return $this->isActive;
       }

       /*
        * Set isActive
        */
       public function setIsActive($isActive)
       {
           $this->isActive = $isActive;
           return $this;
       }

        // modifier la méthode getRoles
        public function getRoles()
        {
            return $this->roles; 
        }

        public function setRoles(array $roles)
        {
            if (!in_array('ROLE_USER', $roles))
            {
                $roles[] = 'ROLE_USER';
            }
            foreach ($roles as $role)
            {
                if(substr($role, 0, 5) !== 'ROLE_') {
                    throw new InvalidArgumentException("Chaque rôle doit commencer par 'ROLE_'");
                }
            }
            $this->roles = $roles;
            return $this;
        }

       public function getSalt()
       {
           // pas besoin de salt puisque nous allons utiliser bcrypt
           // attention si vous utilisez une méthode d'encodage différente !
           // il faudra décommenter les lignes concernant le salt, créer la propriété correspondante, et renvoyer sa valeur dans cette méthode
           return null;
       }

       public function eraseCredentials()
       {
       }

       /** @see \Serializable::serialize() */
       public function serialize()
       {
           return serialize(array(
               $this->id,
               $this->username,
               $this->password,
               $this->isActive,
               // voir remarques sur salt plus haut
               // $this->salt,
           ));
       }

       /** @see \Serializable::unserialize() */
       public function unserialize($serialized)
       {
           list (
               $this->id,
               $this->username,
               $this->password,
               $this->isActive,
               // voir remarques sur salt plus haut
               // $this->salt
           ) = unserialize($serialized);
       }


   }

您能帮我解决我的问题吗?

2 个答案:

答案 0 :(得分:1)

让我们看一下您的配置:

  /**
    * @ApiResource(
    *     collectionOperations={
    *     "post",
    *     "special"={
    *         "method"="POST",
    *         "path"="/utilisateurs/special.{_format}",
    *          "requirements"={
    *              "_format": "\s+"
    *           },
    *         "controller"=App\Controller\UtilisateurSpecial::class,
    *         "defaults"={"_api_receive"=false}
    *     }
    * })
    * @ORM\Entity(repositoryClass="App\Repository\UtilisateurRepository")
    * @UniqueEntity(fields="email", message="Cet email est déjà enregistré en base.")
    * @UniqueEntity(fields="username", message="Cet identifiant est déjà enregistré en base")
    * 
    */

默认情况下,API平台会将资源传递给您的自定义操作,在这种情况下,您将使用Utilisateur类的对象。由于是POST操作,因此它将是一个Utilisateur实例,它根据您在请求正文中的输入创建。

查看有关此内容的API平台文档:

  

如果要绕过实体的自动检索,则可以   将参数_api_receive设置为false。这样,它将跳过   ReadDeserializeValidate侦听器(请参阅事件   系统以获取更多信息。

如果设置_api_receive = true,则API平台无法传递给自定义操作。您已禁用自动反序列化。因此,在这种情况下,您根本不需要在__invoke()上使用$ data参数。

相反,您应该将__invoke()定义为:

public function __invoke(Request $request) { 
}

通过这种方式,您可以访问当前需要的Request对象。

答案 1 :(得分:0)

如果$ data是用户对象...您应该做三件事。

首先,在实体上导入类控制器(使用)。

第二,删除

"defaults"={"_api_receive"=false}

来自用户实体中的api资源注释。

第三,$ data应该是:

public function __invoke(User $data): Utilisateur { 
}