Follow code from document, the code that both messenger component and dto integration work
<?php
// api/src/Entity/User.php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Dto\ResetPasswordRequest;
/**
* @ApiResource(
* collectionOperations={
* "post"={"status"=202}
* },
* itemOperations={},
* messenger=true,
* input=ResetPasswordRequest::class,
* output=false
* )
*/
final class User
{
}
but this only work for one input action. if I have ResetPasswordRequest,SMSValidationForRegistration,EmailValidationForRegistration...
,so how I can get multiple input for there owner handler?
input and output are supported as operation attributes so it should not be an issue.
@antograssiot it's true, but the email which will be send by messenger handle just is a validation code email.I not hope persist the user object to database, unless after the user received email and validated the code,so, how can I solve this problem?
It'll not be persisted if you don't persist it yourself in the messenger handler. indeed, when using messenger=true it replaces the persister by the MessengerDataPersister.
@soyuka yeah,that's right.now my annotation like this:
* "post"={
* "access_control"="is_granted('user.create',object)",
* "access_control_message"="Sorry, you are not a super admin or anonymous."
* },
* "send_mail_for_registration"={
* "method"="post",
* "path"="/users/register",
* "status"=202,
* "messenger"=true,
* "output"=false,
* "input"="App\Data\TransportObject\Auth\SendRegMailRequest"
* }
and message SendRegMailRequest like this
private $code;
private $key;
private $email;
public function __construct()
{
$this->code = Str::random(6);
$this->key = Str::random(15);
}
public function setEmail($email): self
{
$this->email = $email;
return $this;
}
public function setMessage(Templating $templating): self
{
$this->setTitle("Register for user {$this->email}")
->setFrom('[email protected]')
->setAddress($this->email)
->setBody($templating->render(
'emails/registration.html.twig',
[
'email' => $this->email,
'code' => $this->code
]
));
return $this;
}
but I must type-in a service named @twig to SendRegMailRequest,because email template should be load, in traditional controller it will called like this:
use Twig\Environment as Templating;
public function index(\Swift_Mailer $mailer,Templating $templating)
{
$this->bus->dispatch(
(new SendRegMailRequest())
->setEmail('[email protected]')
->setMessage($templating)
);
}
and in api platform's entity annotation, how to call it?
If you want the SendRegMailRequestto be sent to the messenger handler immediately you can also use messenger="input". The rest looks just fine. I think that you can use a service name instead of the class to use a service but that's out of ApiPlatform's scope.
@soyuka every things is fine, but where I injection the service to the message SendRegMailRequest,or where I called ->setMessage($templating) in api platform like Symfony traditional controller?
in Symfony controller DefaultController,it look likes this:
use Twig\Environment as Templating;
public function index(\Swift_Mailer $mailer,Templating $templating)
{
$this->bus->dispatch(
(new SendRegMailRequest())
->setEmail('[email protected]')
->setMessage($templating)
);
}
but in api platform, how can I call it(->setMessage($templating))?
I call it with a custom controller?or event listener?
Are you using a messenger handler? You could do it in there:
class RegistrationMailMessengerHandler {
__construct(Templating $templating, Mailer $mailer) {
...
}
__invoke(SendRegMailRequest $message) {
$message->setMessage($this->templating) //something like this
}
}
/!\ this is pseudo code !
it may not be a good way.because the method return of getBody is string(not null) from MailerHandleInteface,
/**
* @return string
*/
public function getBody(): string;
so,I want to set them(like body,title...) in message,because handler is used to handle something.like save the validate code to cache and send validate email.
If there is no way, custom a controller maybe is the only way锛宨s right?
@soyuka I test a custom controller,it only get User instance but not SendRegMailRequest,so I have to injection the @twig service to handle to let it work fine,thx again your great work
Most helpful comment
inputandoutputare supported as operation attributes so it should not be an issue.