Home > Software engineering >  How to call Mailable function from Controller?
How to call Mailable function from Controller?

Time:10-04

I am new to laravel and worked through the laravel mailable doc which ended me with a mailable that looks like this:

ContactMail.php:

<?php

namespace App\Mail;

use http\Env\Request;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;


class ContactMail extends Mailable implements ShouldQueue
{
  use Queueable, SerializesModels;

  public function __construct()
  {
    //
  }

  public function build()
  {

    return $this->markdown('emails.contact');
  }

  public function store(Request $request)
  {

    $contactVar = 'hello world!';

    Mail::to($request->user())->send(new contact($contactVar));

  }
}

I want the store function of this mailable to be called from my ContactController.php:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;


class ContactController extends Controller
{
  public function submit(Request $request) {
    $this->validate($request, [
      'name' => 'required',
      'email' => 'required | email',
      'message' => 'required'
    ]);
    
    // store(...)
    
    return response()->json(null, 200);
  }
}

How would I call the function and is this good practice? Sorry if it's obvious, I'm trying to get the hang of Laravel/PHP.

This is the corresponding email template file (contact.blade.php):

@component('mail::message')
# Introduction

The body of your message.

@component('mail::button', ['url' => ''])
Button Text
@endcomponent

Thanks,<br>
{{ config('app.name') }}
@endcomponent

CodePudding user response:

If you want to use view, your mailable should return view in the store method. You can read about it here.

So your mailable should look more like this:

class ContactMail extends Mailable implements ShouldQueue
{
  // the rest of the code

  public function store(Request $request)
  {
    return $this->view('contact');
  }
}

And then you can send mail to user in your Controller like this:

Mail::to($request->user())->send(new ContactMail());

What you can read here.


Also, if you want to use variables in your view, you can use with method, and there you can pass associative array with named variables:

public function store(Request $request)
{
  return $this->view('contact')
              ->with(['contactVariable' => 'hello world!']);
}

And to use this variable you just type $contactVariable in your view template.

CodePudding user response:

My opinion is to create a job and dispatch the mail load to this job. The job structure is shown below:

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class SendMail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

   
    protected $email;
    public function __construct($email)
    {
        $this->email = $email;
    }

    
    public function handle()
    {
        Mail::to($this->email)->send(new ContactMail());
    }
}

And dispatch the job from your controllers submit method like this.

class ContactController extends Controller
{
  public function submit(Request $request) {
    $this->validate($request, [
      'name' => 'required',
      'email' => 'required | email',
      'message' => 'required'
    ]);
    SendMail::dispatch($request->email)->onQueue('send_mail');
    // store(...)
    return response()->json(null, 200);
  }

}

Remove the store method from the ContactMail.php file

CodePudding user response:

public $mailData;

public function __construct($mailData)
{
    $this->mailData = $mailData;
}

public function build()
{
    // Array for Blade
    $input = array(
                      'action'     => $this->mailData['action'],
                      'object'     => $this->mailData['object'],
                  );

    return $this->view('emails.notification')
                ->with([
                    'inputs' => $input,
                  ]);
}

Link

Docs

Same Question And Answer


  • Related