Spatie Laravel 9: send email notification to Users with roles - php

I got everything working in terms of sending emails and templating. Now I want to replace the static to: email#test.com with users' email with specific roles.
I have this code written:
public function envelope()
{
return new Envelope(
from: 'amushref#hsse.co',
to: [
User::with("roles")->whereHas("roles", function($q) {
$q->whereIn("id", [
1, // Super Admin
6, // Admin
2, // Security Supervisor
5, // Security Manager
]);
})->get('email')
],
subject: 'New Incident: ' . str_pad($this->record->ir_number, 4, '0', STR_PAD_LEFT) .
' - ' .
$this->record->caseTypeRelationship->name .
' - ' . $this->record->locationRelationship->name,
);
}
I've made to: as an array to include emails of the provided roles (id). I get an error saying that the address are not correct/doesn't exist. What is the proper way to fetch emails of users of the selected roles?

First of all, you do not need to include roles if you don't need them. It's introducing an additional query which you should avoid.
Secondly, your ->get('email') is returning a Collection of users with only the email field. You probably want to convert that to an array to pass it on to the Envelope.
Thirdly, you have wrapped the output of your ->get('email') which in itself is already a collection in an array of its own, making your email sit a level too deep.
Something like this should do the trick:
to: User::whereHas("roles", function($q) {
$q->whereIn("id", [1, 6, 2, 5]);
})->pluck('email')->toArray(),

You can get the list of emails with the following and assign it to an array:
$emails = User::role(['Super Admin', 'Admin', 'Security Supervisor', 'Security Manager'])
->pluck('email')->toArray();
then change your to: $emails

Related

What is the best option to send emails in laravel with different email template

We are currently using laravel Event listener to send emails for laravel. Basically this is a slot booking option, so sometimes we have to send emails to sender and sometimes we have to send to receiver and sometimes we have to send emails other partners of the slots. In the current case we are using a single Event Listner to send different emails fir the different actions users taking on the slot like cancel meeting, add one more member etc. But generally in the case the email templates would be different only the dunamic variables we need to change.
But in the new case we have to send 4 or 5 emails to different users with different email templates and different contents on a single action. If we plan this in a single event listner, how we can handle this?
$event_id=$event->user['XXXXX'];//event id
$slot_type=$event->user['XXXXX'];//slot type
$notification_type=$event->user['XXXXX']; //slot type
$scheduler_slot_info_ids=$event->user['XXXX'];
$data = $schedulerHelper->getOnetoOneNotificationContents($scheduler_slot_info_ids,$event_id,$slot_type);
$action_trigger_by=$event->user['XXXXX'];
//$data['subject'] = 'CARVRE SEVEN|MEETING CONFIRMED';
$data['subject'] = $event->user['XXXX'];
// $data['template'] = 'emailtemplates.scheduler.oneToOneMeetingConfirmed';
$data['template'] = $event->user['XXXX'];
$invitee_id=Crypt::encryptString($data['XXXX']);
$crypt_event_id=Crypt::encryptString($event_id);
$data['link'] = url('XXXX');
$data['email_admin'] = env('FROM_EMAIL');
$data['mail_from_name'] = env('MAIL_FROM_NAME');
// $data['receiver_email'] = 'XXXXXXX';//$invitee['email'];
//Calling mail helper function
MailHelper::sendMail($data);
Make either a table or hardcoded array with template renderers, then have those renderers render a twig/blade/php template based upon the variables you're supplying and all other variables you'd need for feeding into the mailer.
Then just loop through all your receiving candidates and render the appropriate emails with the correct renderer.
You'll have to make a few utility classes and all to accomplish this, but once you get it up and sorted it will be easy to manage and expand with more templates.
Just a rough outline of what I'd use
protected $renderers = [
'templateA' => '\Foo\Bar\BazEmailRender',
'templateB' => '\Foo\Bar\BbyEmailRender',
'templateC' => '\Foo\Bar\BcxEmailRender',
];
public function getTemplate($name)
{
if(array_key_exists($name, $this->renderers)) {
$clazz = $this->renderers[$name];
return new $clazz();
}
return null;
}
public function handleEmails($list, $action)
{
$mailer = $this->getMailer();
foreach($list as $receiver) {
if(($template = $this->getTemplate($receiver->getFormat()))) {
$template->setVars([
'action' => $action,
'action_name' => $action->getName(),
'action_time' => $action->created_at,
// etc...
]);
$mailer->send($receiver->email, $template->getSubject(), $template->getEmailBody());
}
}
}

can we fetch email from inbox and sentbox in one call (gmail API PHP)

i'm using Gmail API to fetch messages. if i do like this
$labelIds = ['INBOX'];
$opt_params=[
'labelIds' => $labelIds,
];
$list = $gmail->users_messages->listUsersMessages('me',$opt_params);
it will work fine. and return messages. but if i mention SENT label with INBOX then it return nothing. what am i doing wrong?
$labelIds = ['INBOX', 'SENT'];
i want to fetch emails from both inbox and sentbox in one call.
Your code lists messages that has both the INBOX and SENT labels. You can list messages that has either one with the OR operator:
$opt_params=[
'maxResults' => 50,
'q' => 'in:inbox OR in:sent',
];
$list = $gmail->users_messages->listUsersMessages('me', $opt_params);

how to replace text with another similar to mail merge?

I am working in Magento, and i have developed a module to send text messages to customers. In the settings of the module, the admin can set the message that will be sent to the customer. I'm trying to add a features that will allow the replacement of texts with data from my database.
for example, i currently have the following code that fetches the saved settings for the body of the text message:
$body = $settings['sms_notification_message'];
The message that is fetched looks like this:
Dear {{firstname}},
your order ({{ordernumber}}) has been shipped.
tracking#: {(trackingnumber}}
Thanks for your business!
{{storename}}
The goal is to have the module replace the variables in "{{ }}" with the customer and store information.
Unfortunately, i'm unable to figure out how to make it replace the information before sending the message. It is currently being send as is.
The easiest way to do it would be to use str_replace, like so:
// Set up the message
$message = <<< MESSAGE
Dear {{firstname}},
your order ({{ordernumber}}) has been shipped.
tracking#: {{trackingnumber}}
Thanks for your business!
{{storename}}
MESSAGE;
// Assign the values in an associative array
$values = [
'firstname' => 'firstnamevalue',
'ordernumber' => 'ordernumbervalue',
'trackingnumber' => 'trackingnumbervalue',
'storename' => 'storenamevalue'
];
// Create arrays $target indicating the value to change
$targets = [];
foreach ($values as $k => $v) {
$targets[] = '{{'.$k.'}}';
}
// Use str_replace to perform the substitution
echo str_replace($targets,$values,$message);

Wordpress Gravity Form Plugin [HELP]

I have a form at my website where the user can request for information, but there's a catch. Inside the form I have a checkbox and when the user selects it, the email must to be sent to another place. (See the screenshots)
What's happening is: Gravity form sends both emails when both rules match, but I only wanna send one email based on the priority.
How can I do that?
I don't believe the routing will take into account AND conditions for the individual rules.
You can however, use the following filter to do further modifications to the e-mail before it is being sent:
add_filter("gform_notification", "my_custom_function", 10, 3);
Or, for a specific form (i.e. id = 42):
add_filter("gform_notification_42", "my_custom_function", 10, 3);
Source: http://www.gravityhelp.com/documentation/page/Gform_notification
Update
An example of accessing the fields would look like this:
add_filter('gform_notification_42', 'updateNotificationForForm42', 10, 3);
function updateNotificationForForm42( $notification, $form, $entry ) {
$fields = $form['fields'];
foreach( $fields as $field ) {
// Here you need to provide the field with some kind of identifying mark (e.g., Admin Label).
// Below assumes the field you're interested in has an admin label of 'Test Me'
if( $field['adminLabel'] == 'Test Me' ) {
$fieldValue = rgpost("input_{$field['id']}");
}
}
}
The Gravity Forms developer docs have a lot of examples of how to customize via actions/filters.
See Also: http://www.gravityhelp.com/documentation/page/Fields

How to query two more input in laravel 3's validation?

For example, the user pass the userName, email to me, and I would like to have a custom validation for check the DB's user table have a column with the both userName equal and email equal and status equal 1 or not? How the customised validation implements?
For example:
User input:
userName: Peter
email: peter#email.com
In case 1, in the DB's user table:
Success: userName: Peter , email: peter#email.com, status: 1
Fail: userName: Peter , email: peter#email.com, status: 0
Fail: userName: Mary , email: peter#email.com, status: 1
Fail: userName: Peter , email: mary#email.com, status: 1
You can create a custom validation method as a catch all. The major problem here is that the validation extension will only ever pass the single attribute to the method rather than the values of all three. This will require you to hack up the validation. This method will be very bespoke to your particular application due to the hard coded nature of the table, column names and input. It also does not give you any way of telling which field the issue is with and would require some additional rule. Another suggestion would be to actually extend the validator class as a library to provide you with a much finer tuned validation engine for this circumstance.
Validator::register('usercheck', function($attribute, $value, $parameters)
{
$count = DB::table('user')
->where('userName', '=', Input::get('userName'))
->where('email', '=', Input::get('email'))
->where('status', '=', Input::get('status'))
->count();
return $count > 0;
});
To use it just add it as a rule... bear in mind this feels a bit hacky and there ARE better ways of doing this, most notably the method I suggested in the opening paragraph.
$rules = array(
'userName' => 'usercheck'
);
You can use this validation.
'userName' => 'unique:user,username',
'email' => 'unique:user,email'
See the docs about this http://laravel.com/docs/validation#rule-unique (Laravel 3) or the Laravel 4 docs at http://four.laravel.com/docs/validation#rule-unique

Categories