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);
});
Related
First of all I love the way that validation is going through, can now easily use
public function authorize(Authenticator $auth)
{
return $auth->user()->hasRole('administrator');
}
hat's not the problem, I bump always into another problem... that is when you update an record, how to do things with the rules? If I need to update an email, I need the following string: 'email' => 'unique:users,email_address,10'. In this case it should look like:
public function rules()
{
return [
'email' => 'required|unique:users,id,?????',
'tags' => 'required'
];
}
It's more simple.
The Laravel documentation says "If your table uses a primary key column name other than id, you may specify it as the fourth parameter":
'email' => 'unique:users,email_address,'.$user->id.',user_id'
If for example, you want to verify if a username exists, but excluding current user ID:
// UpdateUserRequest.php
public function rules() {
//
return [
'username' => 'required|unique:users,username,' . $this->id . ',id',
];
}
I am trying to iterate and send message to mail in array of emails using Laravel Mail::send function
I searched for same problem and found the code below reference from Radmation here https://stackoverflow.com/a/39625789.
$emails = ['tester#blahdomain.com', 'anotheremail#blahdomian.com'];
Mail::send('emails.lead', ['name' => $name, 'email' => $email,
'phone' => $phone], function ($message) use ($request, $emails)
{
$message->from('no-reply#yourdomain.com', 'Joe Smoe');
//$message->to( $request->input('email') );
$message->to( $emails);
//Add a subject
$message->subject("New Email From Your site");
});
I am wondering the second paramater for iteration usage, so i can message each email with dynamic message of their name.
$emails = ['tester#blahdomain.com', 'anotheremail#blahdomian.com'];
foreach($emails as $currentRecipient){
$customtMsg = //create here a custom msg
Mail::send(['text' => 'view'], $customtMsg, function ($message) use ($request, $currentRecipient)
{
$message->from('no-reply#yourdomain.com', 'Joe Smoe');
$message->to($currentRecipient);
//Add a subject
$message->subject("New Email From Your site");
});
}
Please check usage here
You could put emails in associative array, for example:
$emails = [
'tester#blahdomain.com' => 'tester',
'anotheremail#blahdomian.com' => 'anotheremail'
];
And then iterate over key=>value pairs, like:
foreach($emails as $email=>$name){
Mail::send('emails.lead', ['name' => $name, 'email' => $email], function ($message) use ($email, $name){
$message->from('no-reply#yourdomain.com', 'Joe Smoe');
$message->to($email, $name);
$message->subject("New Email From Your site");
});
}
If you want to send same mail to multiple recipients at once, you could also pass an array of email=>name pairs to the to method:
$message->to($emails)
But I don't think it is possible to customize an email content individualy with that approach. Also in that case, all of the email addresses are visible to every recipient.
I'm working on updating a user in Laravel, where I made the following validation rule for updating a users email:
"email" => "required|email|unique:users,email,".$this->route("user")->id,
This is inside of my form request.
However, when I post, it still says that the email is already taken? Is this perhaps a bug in the latest version of Laravel?
Thanks!
No it is not a bug, you are using a null value for the id hence the reason why, change your rule to this:
"email" => "required|email|unique:users,email,".$this->user()->id,
Make sure that you have Request $request in your method, and also you have the auth middleware on your controller.
you set the ignore email column so you should pass email not id
"email" => "required|email|unique:users,email,".$this->route("user")->email,
First you have to add rules in user model
static function rules() {
return [
'email' => 'required|email'
];
}
In user controller
use Illuminate\Validation\Rule; // add this one
function add_update_user(Request $request,$user_id) {
$data = $request->all();
unset($data['_token']);
$rules = User::rules();
$rules['email'] = explode('|', $rules['email']);
if (isset($user_id)) // is old user, your get user_id in route
{
$rules['unique_code'][] = Rule::unique('databse_connection_name.users')->ignore($data['email'], 'email');
} else // is new user
{
$rules['email'][] = 'unique:databse_connection_name.users,email';
}
$validator = Validator::make($data, $rules);
...
...
}
Here i have two inputs field as name and age.
I wanna validate name but not age.
How can i send both value to store.
request()->validate([
'name' => 'required',
]);
//Here i wanna add 'age' along with 'name' in $request
//Then i must store.
Pastor::create($request->all());
The $request->all() already sends whatever is in your request. But if you like you can specifically pass request values to create method like this:
Pastor::create([
'name'=> $request->name,
'age' => $request->age
//any other fields
]);
I assume you have named your inputs like i have passed into create method and it should work.
use the Validator class Laravel has. lets say you have UserController
Use Validator;
Use App\User;
class UserController extends Controller
{
// Your Validator
protected function yourValidatorName(array $data)
{
$rules = ['name'=>'required'];
return Validator::make($data,$rules);;
}
// Your Main Function
public function yourFunctionName(Request $request)
{
$isValid = $this->yourValidatorName($request->all());
if(!isValid->fails())
{
// your code here (validation passed)
}
else
{
// your code here (validation failed)
}
}
}
You simply put a check on name field only
$this->validate($request,[
'name' => 'required|min:3|max:200',
],[
'name.required' => 'name is a required field.', // custom messages you can omit them
'name.min' => ' Name must be at least 3 characters.', // custom message for minimum characters
'name.max' => ' Name should not be greater than 200 characters.', // custom message for maximum characters
]);
Pastor::create($request->all());
Without custom messages
$this->validate($request,[
'name' => 'required|min:3|max:200',
]);
Pastor::create($request->all());
I'm using Validator to validate the input:
$validator = Validator::make($request->all(), [
'short' => 'required',
'name' => 'required|unique:type_event,name'
]);
if ($validator->fails()) {
// fails validation
}
When the unique check is fired, is there a way to receive the id or the record that already exists into the DB? Or I've to call the Model for example with:
$data = TypeEventModel::where('name', '=', $request->input('name'))->firstOrFail();
Thank you.
First you need a custom validation rule. Add the following code to app/Providers/AppServiceProvider.php in boot() method:
Validator::extend('unique_with_id', function ($attribute, $value, $parameters, $validator) {
// First we query for an entity in given table, where given field equals the request value
$found = DB::table($parameters[0])
->where($parameters[1], $value)
->first();
// then we add custom replacer so that it gives the user a verbose error
$validator->addReplacer('unique_with_id', function ($message, $attribute, $rule, $parameters) use ($found) {
// replace :entity placeholder with singularized table name and :id with duplicate entity's id
return str_replace([':entity', ':id'], [str_singular($parameters[0]), $found->id], $message);
});
// finally return wether the entity was not found (the value IS unique)
return !$found;
});
Then add the following validation message to resources/lang/en/validation.php
'unique_with_id'=>'Same :entity exists with ID :id',
Finally you can use
$validator = Validator::make($request->all(), [
'short' => 'required',
'name' => 'required|unique_with_id:type_event,name'
]);