How to pass data to mail view using queue? - php

I have my job class ProductPublish method handle() I am trying to send email.
public function handle()
{
//
Mail::to('i******o#gmail.com')->send(new SendEmail());
}
In the ProductController controller I am calling that job class as like below
ProductPublish::dispatch();
In the SendEmail class which is mailable I am trying to pass data to view as like below
public $message;
public function __construct($message)
{
$this->message = 'This is test message';
}
public function build()
{
return $this->view('email.product.product-publish')->with('message' => $this->message);
}
But it does not works. I also tried with no attaching with() method but still does getting result. In the email view I am calling data as like below
{{ $message }}
Can someone kindly guide me what can be issue that it is not working. Also I want to pass data actually from ProductController but since I am failed to pass from sendEmail that's I didn't tried yet from controller.
Kindly guide me how can I fix it.

In laravel,
The arguments passed to the dispatch method will be given to the job's constructor
So when you are calling dispatch, you can pass message :
ProductPublish::dispatch($message);
Then inside your job you can add a property message and a constructor to get it from dispatch and assign it :
private $message;
public function __construct($message)
{
$this->message = $message;
}
public function handle()
{
// Use the message using $this->messge
Mail::to('i******o#gmail.com')->send(new SendEmail($this->message));
}
Also you can directly queue emails. Check documentation

Try this:
public $message;
public function __construct($message)
{
$this->message= $message;
}
public function build()
{
// Array for passing template
$input = array(
'message' => $this->message
);
return $this->view('email.product.product-publish')
->with([
'inputs' => $input,
]);
}
Check Docs

Related

Laravel Validator Not Returning Key

I am creating a new API call for our project.
We have a table with different locales. Ex:
ID Code
1 fr_CA
2 en_CA
However, when we are calling the API to create Invoices, we do not want to send the id but the code.
Here's a sample of the object we are sending:
{
"locale_code": "fr_CA",
"billing_first_name": "David",
"billing_last_name": "Etc"
}
In our controller, we are modifying the locale_code to locale_id using a function with an extension of FormRequest:
// This function is our method in the controller
public function createInvoice(InvoiceCreateRequest $request)
{
$validated = $request->convertLocaleCodeToLocaleId()->validated();
}
// this function is part of ApiRequest which extend FormRequest
// InvoiceCreateRequest extend ApiRequest
// So it goes FormRequest -> ApiRequest -> InvoiceCreateRequest
public function convertLocaleCodeToLocaleId()
{
if(!$this->has('locale_code'))
return $this;
$localeCode = $this->input('locale_code');
if(empty($localeCode))
return $this['locale_id'] = NULL;
$locale = Locale::where(Locale::REFERENCE_COLUMN, $localeCode)->firstOrFail();
$this['locale_id'] = $locale['locale_id'];
return $this;
}
If we do a dump of $this->input('locale_id') inside the function, it return the proper ID (1). However, when it goes through validated();, it doesn't return locale_id even if it's part of the rules:
public function rules()
{
return [
'locale_id' => 'sometimes'
];
}
I also tried the function merge, add, set, etc and nothing work.
Any ideas?
The FormRequest will run before it ever gets to the controller. So trying to do this in the controller is not going to work.
The way you can do this is to use the prepareForValidation() method in the FormRequest class.
// InvoiceCreateRequest
protected function prepareForValidation()
{
// logic here
$this->merge([
'locale_id' => $localeId,
]);
}

Unable to access property - Laravel

I'm trying to send emails in Laravel.
I have my Mailable:
public $message;
public function __construct($message)
{
$this->message = $message;
}
public function build()
{
return $this->subject('Message from B&B Vintage Collectibles')->view('mail.direct');
}
Controller:
namespace App\Http\Controllers;
use App\Contact;
use App\Mail\DirectMailable;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Http\Controllers\Controller;
class DirectController extends Controller
{
public function __invoke(Request $request)
{
$user = $request->get('email');
$message = new Contact();
$message->body = $request->get('message');
Mail::to($user)->send(new DirectMailable($message));
return response()->json('Message sent', 200);
}
}
And in direct.blade.php I have this line:
<p>{{ $message->body }}</p>
But when I send the email I get this response:
"Undefined property: Illuminate\Mail\Message::$body..."
I have other email systems setup in almost the exact same way so I can't figure out why this isn't working.
I've tried without the templates and the email sends just fine.
When I dd($message->body) before Mail::to... I get the correct string.
What's happening on the way to my blade file that won't let me access this property?
As discussed on this thread
https://laracasts.com/discuss/channels/laravel/laravel-mailable-not-working?page=1
don't use $message variable, it cause errors in email send in larvel framework.
You can follow this thread for more info.
I have used in the same way and it works. But I do something like this... Passing the actual data to the view
public function build()
{
return $this->subject('Message from B&B Vintage Collectibles')->view('mail.direct',[ 'message' => $this->message ]);
}

Laravel constructor and method injection

I am having an issue setting up an injection on both the constructor and the method in a controller.
What I need to achieve is to be able to set up a global controller variable without injecting the same on the controller method.
From below route;
Route::group(['prefix' => 'test/{five}'], function(){
Route::get('/index/{admin}', 'TestController#index');
});
I want the five to be received by the constructor while the admin to be available to the method.
Below is my controller;
class TestController extends Controller
{
private $five;
public function __construct(PrimaryFive $five, Request $request)
{
$this->five = $five;
}
public function index(Admin $admin, Request $request)
{
dd($request->segments(), $admin);
return 'We are here: ';
}
...
When I run the above, which I'm looking into using, I get an error on the index method:
Symfony\Component\Debug\Exception\FatalThrowableError thrown with message "Argument 1 passed to App\Http\Controllers\TestController::index() must be an instance of App\Models\Admin, string given"
Below works, but I don't need the PrimaryFive injection at the method.
class TestController extends Controller
{
private $five;
public function __construct(PrimaryFive $five, Request $request)
{
$this->five = $five;
}
public function index(PrimaryFive $five, Admin $admin, Request $request)
{
dd($request->segments(), $five, $admin);
return 'We are here: ';
}
...
Is there a way I can set the constructor injection with a model (which works) and set the method injection as well without having to inject the model set in the constructor?
One way you could do this is to use controller middleware:
public function __construct()
{
$this->middleware(function (Request $request, $next) {
$this->five = PrimaryFive::findOrFail($request->route('five'));
$request->route()->forgetParameter('five');
return $next($request);
});
}
The above is assuming that PrimaryFive is an Eloquent model.
This will mean that $this->five is set for the controller, however, since we're using forgetParameter() it will no longer be passed to your controller methods.
If you've specific used Route::model() or Route::bind() to resolve your five segment then you can retrieve the instance straight from $request->route('five') i.e.:
$this->five = $request->route('five');
The error is because of you cannot pass a model through the route. it should be somethiing like /index/abc or /index/123.
you can use your index function as below
public function index($admin,Request $request){}
This will surely help you.
Route::group(['prefix' => 'test/{five}'], function () {
Route::get('/index/{admin}', function ($five, $admin) {
$app = app();
$ctr = $app->make('\App\Http\Controllers\TestController');
return $ctr->callAction("index", [$admin]);
});
});
Another way to call controller from the route. You can control what do you want to pass from route to controller

Sending value from controller to Mail to view

In my controller, I am trying send mail like this
$activationLink = $activation->GetActivationCode->ActivationLink;
\Mail::to($company)->send(new MLink);
I have a variable called activationlink, which I need to send it to the email
Mlink Mail class
public function build()
{
return $this->view('emails.mindbody')->with($activationLink);
}
View file
<h2>Your activation link is : {{ $activationlink }} </h2>
It's not working this way, I get the activationlink is not defined error.
How can I pass the $activationLink from my controller, to the view file (the email that is sent)?
You can add it in the constructor of MLink class like this :
private $activationLink;
public function __construct($activationLink)
{
$this->activationLink = $activationLink;
}
public function build()
{
return $this->view('emails.mindbody')->with($this->activationLink);
}
And in the controller
$activationLink = $activation->GetActivationCode->ActivationLink;
\Mail::to($company)->send(new MLink($activationLink));
Or as mentioned by #Camilo you can set the visibility of $activationLink to public and remove ->with keyword because you will have access to this variable in the view :)

how to create a model without tabel

I want to send mails to users for which Iam creating a model with name 'Common'. Common model has the function 'test' to send mails. But the model is giving error:
Fatal error: Call to undefined method Common::model()
here is my model code:
<?php
class Common extends CFormModel
{
public $from;
public $to;
public function rules()
{
return array(
array('from, to', 'required'),
);
}
public function attributeLabels()
{
return array(
'from' => 'From',
'to' => 'To',
);
}
public function test($id)
{
print_r($id); die("sfbvjzsb");
------------------------------------------
sending mail code
--------------------------------------------
}
}
?>
Iam calling the model in controller as below:
Common::model()->test($group_id);
Where Iam doing wrong?
Well, you don't have a static method named model().
You can do this:
$c = new Common();
$c->test($group_id);
Or , if you change the declaration of the test function to:
public static function test($id)
then you will be able to call it statically like this:
Common::test($group_id);

Categories