Laravel Mail not passing variables to blade template - php

I have two functions, the first one is working fine but the second one is not, in the second ones the variables appearing in the mail are {{$variableName}} unrendered.
I have checked as much other posts on SO as possible but no solution.
In the example below, in the first one the $userName correctly loads in the mail, whereas in the second one all variables show up as the variable name with the dollar sign.
I can confirm the $data variable is correct, and mails are even correctly sending using data from that variable.
public function workingMail($emailAddress,$userName) {
$message = '';
\Mail::send('workingtemplate', [
'userName' => $userName
], function ($message) use ($emailAddress) {
$message->from($this->fromAddress, $this->$this->fromAddressName);
$message->to($emailAddress);
$message->subject('Sample Subject');
});
}
public function notWorkingMail($data) {
$message = '';
foreach($data['namesAndAddress'] as $person) {
\Mail::send('notworkingtemplate', [
'name' => $person['name'],
'link' => $data['link'],
'fileName' => $data['fileName'],
'timeStamp' => $data['timeStamp'],
'action' => $data['action'],
'placeAddress' => $data['placeAddress']
], function ($message) use ($person,$data) {
$message->from($this->fromAddress, $this->fromAddressName);
$message->to($person['email']);
$message->subject($data['placeAddress'].' files have been updated.');
});
}
}
Thank you.

I had forgotten to add .blade to the name of the php file. It worked perfectly as soon as I did.

Related

Laravel assert multiple recipients of email during PHPUnit test

I want to test that an email has been sent to a number of addresses during a PHPUnit test. How can I achieve this?
Although the Laravel documentation does indicate that a hasTo() function exists within the Mail object:
// Assert a message was sent to the given users...
Mail::assertSent(OrderShipped::class, function ($mail) use ($user) {
return $mail->hasTo($user->email) &&
$mail->hasCc('...') &&
$mail->hasBcc('...');
});
It does not make clear that it is possible to assert that multiple address have been sent the mail. The hasTo function accepts the following structure as expected assertions:
[
[
'email' => 'johnny#appleseed.com',
'name' => 'Johnny Appleseed'
],
[
'email' => 'jane#appleseed.com',
'name' => 'Jane Appleseed'
],
]
As the name key is optional, the simplest way to test that specific users have received an email would look something like this:
Mail::fake();
$admins = User::where('administrator', true)->get()->map(function ($admin) {
return ['email' => $admin->email];
})->toArray();
Mail::assertSent(MyMailable::class, function ($mail) use ($admins) {
return $mail->hasTo($admins);
});
If you have used the default Laravel User model, or your user model has both name and email properties, you can pass your users in as a collection
Mail::fake();
$admins = User::where('administrator', true)->get();
Mail::assertSent(MyMailable::class, function ($mail) use ($admins) {
return $mail->hasTo($admins);
});

Using blade data value into another one within layout

I want to use a variable value into another one (both are in the same table as keys) and display in a blade layout the container variable value. Both variables are passed using the with method from the controller. Is that possible?
Here a quick demo of what I'm loooking for :
# controller method
public function build()
{
return $this
->view('emails.registration_following')
->with( ['name' => 'Nick', 'text' => 'Hello {{ $name }}'] ) # Here goes the thing
;
}
And the blade.php looks like :
<html>
<body>
<p> {{ $text }} </p>
</body>
</html>
The expect output by me is Hello Nickbut I got Hello {{Nick}}. I know that brackets here, are treated like String but how to circumvine that?
How about defining the variable in the function first:
# controller method
public function build()
{
$name = 'Nick';
return $this
->view('emails.registration_following')
->with( ['name' => $name, 'text' => "Hello $name"] ) # Here goes the thing
;
}
In this way, you have both $name and $text accessible in the view.
In fact, I did not need to pass two variables but just one and put in its value all needed other variables to form my expected text.
It was a bad idea to do what I was asking for. Thank you.
Have u tried like this below?
public function build()
{
$name = 'Nick';
return $this
->view('emails.registration_following')
->with( ['name' => $name , 'text' => 'Hello '.$name] ) # Here goes the thing
;
}
with( ['name' => 'Nick', 'text' => "Hello $name"] ) Please use double quote

Redirect Loop in Laravel 5

I'm doin the backend of a website while learning Laravel. I have these router below:
Route::get('/update/survivor/flag', 'SurvivorsController#flagSurvivor');
Route::get('/submit/log/flag', 'LogsController#submitFlag');
And in the flagSurvivor function i have:
public function flagSurvivor(Request $request){
$this->validate($request,[
'idFlagged' => 'required',
'idFlagger' => 'required'
]);
//Get the ids
$id = $request->input('idFlagged');
$flaggerid = $request->input('idFlagger');
//Get the flagger name
$survivors = Survivor::all();;
$flaggerSurvivor = $survivors->find($flaggerid);
//Flag a survivor
$survivors = Survivor::all();;
$flaggedSurvivor = $survivors->find($id);
$flaggedSurvivor->flags = $flaggedSurvivor->flags+1;
//Save updates
$flaggedSurvivor->save();
//Redirect
return redirect('submit/log/flag')
->with('nameFlagged', $flaggedSurvivor->name)
->with('idFlagged', $id)
->with('nameFlagger', $flaggerSurvivor->name)
->with('idFlagger' , $flaggerid);
}
which works perfectly except for the redirect part. After inserting the change into the DB it should send data to the submitFlag function, except that it doesn't. It just keeps looping with itself until it crashes from too many redirects. The log submit page also works just fine:
public function submitFlag(Request $request){
$this->validate($request,[
'nameFlagged' => 'required',
'nameFlagger' => 'required',
'idFlagger' => 'required',
'idFlagged' => 'required'
]);
$flaggerid = $request->input('idFlagger');
$flaggedid = $request->input('idFlagged');
$flaggername = $request->input('nameFlagger');
$flaggedname = $request->input('nameFlagged');
//Create a new log
$flag = new Log;
$flag->log = "The survivor $flaggername($flaggerid) reported that the survivor $flaggedname($flaggedid) is contaminated";
//Save log
$flag->save();
echo "Success";
}
if i go to
localhost/submit/log/flag?idFlagger=1&idFlagged=2&nameFlagger=Matheus&nameFlagged=Tauan
It echoes "Success" and inserts the log into the DB. But i just don't get it why it doesn't work by sending the parameters in the flagSurvivor function. I assume I'm doing the withs in the redirects wrong, or maybe something in the routes I have no idea. Any help is appreciated!
Turns out that using
return redirect('submit/log/flag?nameFlagged='.$flaggedSurvivor->name.'&idFlagged='.$id.'&nameFlagger='.$flaggerSurvivor->name.'&idFlagger='.$flaggerid);
Instead of the 'with's that I was using works properly.
Change your redirect to an action and the with's to an associative array:
//Redirect
return redirect()->action('LogsController#submitFlag', [
'nameFlagged' => $flaggedSurvivor->name,
'idFlagged' => $id,
'nameFlagger' => $flaggerSurvivor->name,
'idFlagger' => $flaggerid
]);
Redirecting to a controller action

Laravel 5.1 - Return to edit page

i'm writing a resource controller, and i have a problem with edit method.
i inserted a validator form, and if there is a error return to edit page with messages, but RETURN doesnt work good!
public function update(Request $request, $id)
{
$rules = [
'title' => 'required',
'content' => 'required',
'image' => 'required',
];
$messages = [
'title.required' => 'Campo titolo richiesto',
'content.required' => 'Contenuto richiesto',
'image.required' => 'Campo immagine richiesto',
];
$validator = Validator::make($request->all(), $rules, $messages);
if ($validator->fails()){
return redirect('admin/article/edit' , $id)->withErrors($validator);
}else {
$s = new Article;
$visible = (isset($_POST['visible']) == '1' ? '1' : '0');
$data = array(
'title' => $request->get('title'),
'slug' => $request->get('title'),
'content' => $request->get('content'),
'image' => $request->get('image'),
'user_id' => $request->get('user_id'),
'category_id' => $request->get('category_id'),
'visible' => $visible,
);
$s->where('id', '=', $id)->update($data);
return redirect('admin/article')->with('message', 'Articolo aggiornato con successo!');
}
}
It return to:
admin/article/edit/5
NOT to
admin/article/5/edit
How can i fix this issue? thank you for your help!
PS: $id work well, return my id edited
Here is the redirect helper. As you can see below, it takes status as its' second parameter.
function redirect($to = null, $status = 302, $headers = [], $secure = null)
What you do with passing the $id as the second parameter is actually setting the $status.
You need to pass the $to parameter as the full path like below.
return redirect('admin/article/' . $id . '/edit')->withErrors($validator);
I guess that you want to generate the url with route, which can be implemented like below.
return redirect(route('admin.article.edit', compact($id)))->withErrors($validator);
So you're saying the redirect on failure doesn't redirect to the right URL? Have you tried doing return redirect('admin/article/' . $id . '/edit')->withErrors($validator);?
I haven't tested this approach, but perhaps return redirect()->back()->withErrors($validator); could also work.
One way to do this, as others have suggested, is like following:
return redirect("admin/article/{$id}/edit")->withErrors($validator);
Or if you've a "Route Name" defined, like this..
return redirect()->route('route.name',[$id])->withErrors($validator);
it all depends on how you prefer, I prefer the later one, looks clean to me.
Easiest solution:
Laravel 5.1 has a back() helper, that returns to the previous page:
return back()->withErrors($validator);
More thorough explanation:
If you want to be more verbose, a generally more robust way to redirect to a route is to first define it as a named route in your routes.php:
Route::get('admin/article/{article_id}/edit', ['as' => 'articles.edit', 'uses' => 'ArticlesController#edit']);
Route::bind('article_id', function($id, $route) {
return App\Article::whereId($id)->findOrFail();
}
If you are using Route::resource instead, then this is already done automatically for you. To find the name of the route, run the command-line php artisan route:list. Then, in your controller method, you call it like this:
return redirect()->route('articles.edit', ['article_id' => $id])->withErrors($validator);
Using that kind of call, Laravel will automatically build the correct URL for you. This is more robust because if you ever want to change that URL to something else or change what controller method it calls, you only need to change it in one place, the routes.php, and not everywhere in your code (as long as every reference to that route in your code is referring to it by name).
Here you have
return redirect('admin/article/edit' , $id)->withErrors($validator);
means the link/route is admin/article/edit/$id(5 or 2 or ...)
better check
return redirect('admin/article/' . $id . '/edit')->withErrors($validator);
The redirect go to the passed url:
return redirect('admin/article/' . $id . '/edit'); #admin/article/id/edit
return redirect('admin/article/edit', $id); #admin/article/edit/5
And you can use methods to get this url:
return redirect(action('Controller#update', compact($id)));

Laravel 4: Unique(database) not validating

I am creating a basic CMS to teach myself the fundamentals of Laravel and PHP.
I have a 'pages' table and I am storing a url_title. I want this URL title to be unique for obvious reasons. However, whatever I do to validate it, fails. It just saves anyway. I'm sure it is something simple. Can you spot what is wrong with this code?
I am also using Former in the view, that doesn't validate either. I have tried hard-coding a value as the last option in the unique method and it fails also.
http://anahkiasen.github.io/former/
http://laravel.com/docs/validation#rule-unique
States: unique:table,column,except,idColumn
Here is my Controller:
public function store()
{
$validation = Pages::validate(Input::all());
if($validation->fails()) {
Former::withErrors($validation);
return View::make('myview');
} else {
Pages::create(array(
'title' => Input::get('title'),
'url_title' => Input::get('url_title'),
'status' => Input::get('status'),
'body' => Input::get('body'),
'seo_title' => Input::get('seo_title'),
'seo_description' => Input::get('seo_description')
));
//check which submit was clicked on
if(Input::get('save')) {
return Redirect::route('admin_pages')->with('message', 'Woo-hoo! page was created successfully!')->with('message_status', 'success');
}
elseif(Input::get('continue')) {
$id = $page->id;
return Redirect::route('admin_pages_edit', $id)->with('message', 'Woo-hoo! page was created successfully!')->with('message_status', 'success');
}
}
}
Here is my model:
class Pages extends Eloquent {
protected $guarded = array('id');
public static $rules = array(
'id' => 'unique:pages,url_title,{{$id}}'
);
public static function validate($data) {
return Validator::make($data, static::$rules);
}
}
I have tried the following:
public static $rules = array(
// 'id'=> 'unique:pages,url_title,{{$id}}'
// 'id'=> 'unique:pages,url_title,$id'
// 'id'=> 'unique:pages,url_title,:id'
// 'id'=> 'unique:pages,url_title,'. {{$id}}
// 'id'=> 'unique:pages,url_title,'. $id
);
Any ideas? I spoke to the guy who created Former. He can't make head nor tail about it either. He suggested tracking it back to find our what query Laravel uses to check the uniqueness and try running that directly in my DB to see what happens. I can't find the query to do this. Does anyone know where to track it down?
Many thanks
Your rule should be:
public static $rules = array(
'url_title' => 'unique:pages,url_title,{{$id}}'
);
As I guessed from your code Input::get('url_title')
You have to use the field name used in the form.
Thanks peeps. I have been using the Laravel unique solutions and it hasn't been working well. I found this package which solves the issue brilliantly.
https://github.com/cviebrock/eloquent-sluggable#eloquent
Definitely worth a look.
Thanks for your feedback.

Categories