I want to send two different emails with two different view blade files for submitting a single form.
My Controller
<?php
namespace App\Http\Controllers\Frontend;
use App\Mail\quickQuoteMail;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\sysmaster;
use App\Mail\contactEmail;
use Illuminate\Support\Facades\Mail;
class EmailController extends Controller
{
public function contactEmail(Request $request)
{
$data = array(
'ContactPerson'=> $request->FullName,
'ContactEmail'=> $request->Email,
'ContactNumber'=> $request->Number,
'ContactMessage'=> $request->Enquiry,
);
$token = $request->input('g-recaptcha-response');
if(strlen($token)>0)
{
$quickQuoteemail = sysmaster::where('sysm_val_type', 'Contact_Email')->where('sysm_def_id', 'to')->first();
$quickQuote = sysmaster::where('sysm_val_type', 'Contact_Email')->where('sysm_def_id', 'Cc')->first();
if ($quickQuote->sysm_value!=null) {
Mail::to($quickQuoteemail->sysm_value)->cc([$quickQuote->sysm_value, $request->Email])->send(new contactEmail($data));
} else {
Mail::to($quickQuoteemail->sysm_value)->cc($request->Email)->send(new contactEmail($data));
}
return redirect()->back()->with('message','Thank you for contact us.');
}else{
return redirect()->back()->with('message','Please make sure your not a robot');
}
}
}
Mail Function
<?php
namespace App\Mail;
use App\sysmaster;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class contactEmail extends Mailable
{
use Queueable, SerializesModels;
public $data;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($data)
{
$this->data = $data;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
$quickQuoteemail = sysmaster::where('sysm_val_type','Contact_Email')->where('sysm_def_id','from')->first();
return $this->from($quickQuoteemail->sysm_value,$this->data['ContactPerson'])
->subject('Contact Us Enquiry')->view('email_contact_quote')->with('data',$this->data);
}
}
I have another view blade file there (contact_email_company) How can I include that view with this function and this UI only will send for the company top one have to go for the only client please help how to do this.
You can use dynamic view name You can pass view name in $data Mail class
Change below in your controller function:
if ($quickQuote->sysm_value!=null) {
$data['view_name'] = 'email_contact_quote';
Mail::to($quickQuoteemail->sysm_value)->cc([$quickQuote->sysm_value, $request->Email])->send(new contactEmail($data));
}
else {
$data['view_name'] = 'contact_email_company';
Mail::to($quickQuoteemail->sysm_value)->cc($request->Email)->send(new contactEmail($data));
}
And in mail class change as below: take view name from $data,
return $this->from($quickQuoteemail->sysm_value,$this->data['ContactPerson'])
->subject('Contact Us Enquiry')->view($this->data['view_name'])->with('data',$this->data);
Related
I have a laravel project at hand. However, I did not write this project. They gave me a bug to solve. It shows the problem in this file /app/Http/Controllers/Crons/EmailCronJobController.php but as far as I understand, it shows here because sending mail is used here. I have not used such services of Laravel before, so I do not know much. I'm putting the screenshot of the problem and the content of the file below, but if there is something different I need to share for you to understand better, I can share it with you.
enter image description here
EmailCronJobController.php
namespace App\Http\Controllers\Crons;
use App\Http\Controllers\Controller;
use App\Mail\Listener\FirstContentListen;
use App\Mail\Listener\NothingListenedFor3Days;
use App\RawListeningData;
use App\User;
use App\UserPayment;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
class EmailCronJobController extends Controller
{
public function __invoke()
{
$this->listeners();
}
private function listeners(){
$this->listenersFirstContentListen();
$this->listenersNothingListenedFor3Days();
}
private function listenersNothingListenedFor3Days(){
$users = User::where([
['role_id','=', 4],
['created_at', '>=', Carbon::now()->subDay(7)->toDateTimeString()],
['created_at', '<', Carbon::now()->subDay(3)->toDateTimeString()]
])->get();
$users = $users->filter(function ($user){
return $user->getFirstListenedContent()==null;
});
/*
foreach ($users as $user){
$email_array = explode('#',$user->email);
$email = $email_array[0].'#etrexio.com';
$user->update(['email'=>$email]);
}*/
foreach ($users as $user){
if($user->getCustomField('nothing_listened_3_days_email_send_date')==null){
Mail::to($user)->send(new NothingListenedFor3Days($user));
$user->setCustomField('nothing_listened_3_days_email_send_date',date('Y-m-d H:i:s'));
}
}
}
private function testEmail(){
$active_user_payments = UserPayment::select('user_id')->where('exprire_date', '>=', Carbon::now()->toDateTimeString())->get();
$active_users_ids = $active_user_payments->map(function ($payments){
return $payments->user_id;
});
$users = User::whereIn('id',$active_users_ids)->get();
dd($users);
}
private function listenersFirstContentListen(){
$last_24_h_listening = RawListeningData::select('user_id')->where('created_at', '>=', Carbon::now()->subDay()->toDateTimeString())->get();
$last_24_h_listening_users = $last_24_h_listening->map(function ($listening){
return $listening->user_id;
})->unique();
$before_24_h_listening = RawListeningData::select('user_id')->whereIn('user_id',$last_24_h_listening_users)->where('created_at', '<', Carbon::now()->subDay()->toDateTimeString())->get();
$before_24_h_listening_users = $before_24_h_listening->map(function ($listening){
return $listening->user_id;
})->unique();
$result = collect($last_24_h_listening_users)->diff(collect($before_24_h_listening_users));
$users = User::whereIn('id',$result)->get();
foreach ($users as $user){
if($user->getCustomField('first_content_listen_email_send_date')==null){
$content = $user->getFirstListenedContent();
if($content!=null){
Mail::to($user)->send(new FirstContentListen($user,$content));
$user->setCustomField('first_content_listen_email_send_date',date('Y-m-d H:i:s'));
}
}
}
}
}
NothingListenedFor3Days.php
namespace App\Mail\Listener;
use App\Course;
use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class NothingListenedFor3Days extends Mailable
{
use Queueable, SerializesModels;
public $listener;
public $random_contents;
public $fromEmail = 'listener#omnicourse.io';
public $fromName = 'Omnicourse';
/**
* Create a new message instance.
*
* #return void
*/
public function __construct(User $listener)
{
$this->listener = $listener;
$this->random_contents = Course::all()->random(10);
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->from($this->fromEmail,$this->fromName)
->view('email.listener.nothing_listened_for_3_days')
->text('email.listener.nothing_listened_for_3_days_plain')
->subject("Let's move ahead together");
}
}
I think it's probably this line:
Mail::to($user)>send(newFirstContentListen($user,$content));
$user in your case it's an object not email. Try to debug it or dd() at several points to see where it get stucks.
Also might want to check this out
Address in mailbox given [] does not comply with RFC 2822, 3.6.2. when email is in a variable
I want to send emails to all of the users in my application. I created a separate sample project where the only function is one to add/create new users together with their email and name. I want to email each of my existing users whenever there is a new one who signed up. Like a "Hello, we have a new member!" message.
Controller
public function store()
{
$customer = Customer::create($this->validatedData());
foreach ($customer as $customers) {
Mail::to($customers->email)->send(new WelcomeMail());
}
return redirect('/customers');
}
Here your code is correct but not completely
So I have modified it
Now you need to create one Job file using
php artisan make:job WelcomeMessage and then run
php artisan migrate
to send the mail
use App\Job\WelcomeMessage;
public function store()
{
$customer = Customer::create($this->validatedData());
if ($customer) {
$allUser = Customer::where('id', '!=', $customer->id)->get();
$html = "Your html file with mail content";
$sub = "Welcome Mail";
foreach($allUser as $allUsers){
Mail::to($allUsers->email)->send(new WelcomeMessage($html,$sub));
}
}
return redirect('/customers');
}
If you run this command php artisan make:job WelcomeMessage then it will create the page in the app\Job folder. Then paste the below code on that page.
<?php
namespace App\Emails;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class UserVerificationMail extends Mailable
{
use Queueable, SerializesModels;
public $subject;
public $file;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($file,$subject)
{
$this->subject = $subject;
$this->file = $file;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->from(env('MAIL_FROM_ADDRESS'), env('APP_NAME'))
->subject($this->subject)
->markdown($this->file);
}
}
and then run php artisan queue:listen
This will work
Thank You
So I am trying to implement a command that notifies all users that are subscribes to an event with command that does an check every day. I was reading Laravel mail docs 7.x so there example is about order system where they send the mail with this peace of code
foreach (['taylor#example.com', 'dries#example.com'] as $recipient) {
Mail::to($recipient)->send(new OrderShipped($order));
}
what as it looks takes the email of of the loop and then send an email toward that adress.
So I made a mail class php artisan make:mail NotifyUserOfEvents
and where I made this code
<?php
namespace App\Mail;
use App\Event;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class NotifyUserOfEvents extends Mailable
{
use Queueable, SerializesModels;
protected $event;
public function __construct(Event $event)
{
$this->event = $event;
}
public function build()
{
return $this->view('mails.NotifyUserOfEvents')
->with([
'name' => $this->event->name,
'date' => $this->event->settings->start_date,
]);
}
}
but when I try to call this class with this function
<?php
namespace App\Console\Commands;
use App\Event;
use App\RegistrationEvents;
use App\User;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
class NotifyUsersForEvents extends Command
{
protected $signature = 'NotifyUsersForEvents';
protected $description = 'Notify the user for the event. test run with -> php artisan schedule:run';
public function __construct()
{
parent::__construct();
}
public function handle()
{
Log::debug('this works every minute');
$events = Event::query()
->with('settings')
->has('settings')
->get();
foreach ($events as $event) {
$week = Carbon::now()->addWeek();
$sixDays = $week->copy()->subDay();
if (Carbon::create($event->settings->date_start)->between($week, $sixDays)) {
$subscriptions = RegistrationEvents::query()
->where('event_id', $event->id)
->get();
foreach ($subscriptions as $subscription) {
var_dump($subscription->user_id);
$user = User::findOrFail($subscription->user_id);
Mail::to($user->email)->send($event);
var_dump($user->email);
}
}
}
}
}
it returns this error: Argument 1 passed to Illuminate\Database\Eloquent\Model::__construct() must be of the type array, object given, called in so do I need to change the way I call the mail class or do I need to add something to the Event Model?
also the event.php
use Illuminate\Contracts\Mail\Mailable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Event extends Model implements Mailable
{
use SoftDeletes;
public function settings(){
return $this->hasOne('App\EventSettings', 'event_id');
}
}
You must pass to send function an object of your NotifyUserOfEvents, not an Event object.
Try this:
Mail::to($user->email)->send(new NotifyUserOfEvents($event));
Referring to this line:
Mail::to($user->email)->send(new Event($event));
you are creating a new Event passing to the constructor another Event... you probably never define a constructor that accept as first parameter an Event...
But despite that, what's the sense of doing this? To Mail::send you have to pass a Mailable, not an event, and i'm pretty sure you don't need a new event, so i believe you would want to do something like this:
use App\Mail\NotifyUserOfEvents; // or whatever namespace you have to the mail
Mail::to($user->email)->send(new NotifyUserOfEvents($event));
$user = User::find($id);
$email = $user->email;
if(Helper::isValidEmail($email))
{
Mail::send('emails.applicant_reference',
$emailParameters, function($message) use ($email, $name, $subject){
$message->to($email, $name)
->subject($subject);
});
$applicantName = null;
$subject = " Application received for ".$applicantName;
$emailParameters = ["applicantName" => $applicantName, "proposerName" => $proposerName, "seconderName" => $seconderName];
try
{
Mail::send('emails.application', $emailParameters, function($message) use ($applicantName, $subject){
$message->to(['test#gmail.com','test#gamil.com'], " Test Email Function ")
->subject($subject);
});
} catch (Exception $ex){ Log::error("UserController".$ex->getMessage());
}
I have a controller which mainly has two functions. First function adds the user to the database and sends an email (receipt.blade.php) to the user.The second function allows the user to get all the receipts for a particular email that a user enters.
Right now, if I directly go to the page where the user can enter the email and get all receipts, its working fine. But, if I try to do it through the process of adding a new user I get the error described in the title after I click submit to adding the user. However, it has added the user to the database, but shows the error because its sending the email which is the receipt.blade.php and has the undefined variable. My controller has these:
use App\Donor;
use App\Video;
use Illuminate\Http\Request;
use DB;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Mail;
The first Function is:
public function thankyoupage(Request $data, Mailer $mailer){
$donor = Donor::create([
'first_name'=> $data->first_name,
'last_name' => $data->last_name,
'email' => $data->email,
'video_count' => $video_count,
'amount_donated' => $data->amount_donated,
});
$mailer
->to($data->input('email'))
->send(new \App\Mail\MyMail(($data->input('first_name')),($data->input('last_name')),
($data->input('amount_donated'))));
return redirect()->action('PagesController#thank1');
}
My mailing file(mailable) is:
class MyMail extends Mailable
{
use Queueable, SerializesModels;
public $first_name, $last_name, $amount_donated;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($first_name,$last_name,$amount_donated)
{
$this->first_name = $first_name;
$this->last_name = $last_name;
$this->amount_donated = $amount_donated;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->from('myemailid12341#gmail.com')
->view('emails.receipt');
}
}
The second function is:
public function getUserReceipts(Request $data){
$email = $data->email;
$donor = Donor::where('email', $email)->get();
return view('emails.receipt')->with(compact('donor'));
}
The receipt file simply contains:
#foreach($donor as $value)
{{ $value->first_name }}
{{ $value->last_name }}
{{ $value->amount_donated }}
#endforeach
The error I'm getting seems to be because donor in the receipt file is
undefined and I'm not sure how to fix it as it was passed with compact
in the second function.
Would really appreciate the help.
From your last question i can see the problem. The issue is that you're reusing the same view which takes two different set of data. When used with the method getUserReceipts, it generates receipts for multiple donors. But when you send the mail you're using the view as the mail content. In that case you need to use the properites set in the mailable class. The ideal case would be to create a new view for sending a single email receipt and handle it like so.
Change your mailable class to this. With this you can use all the properties of the donor in your view.
<?php
namespace App\Mail;
use App\Donor;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class MyMail extends Mailable
{
use Queueable, SerializesModels;
public $donor;
public function __construct(Donor $donor)
{
$this->donor = $donor;
}
public function build()
{
return $this->from('myemailid12341#gmail.com')
->view('emails.singlereceipt');
}
}
Change the way you send the email to
\Mail::to($data->input('email'))->send(new \App\Mail\MyMail($donor));
Create a new view singlereceipt.blade.php and use the following code instead.
{{ $donor->first_name }}
{{ $donor->last_name }}
{{ $donor->amount_donated }}
You have an error in sending data to view. If you send data using with() function than syntax should be:
return view('emails.receipt')->with('donor', $donor);
See Passing Data To Views
I would like to know if there is a magic method to use this scenario :
If I call a page via an AJAX request the controller returns a JSON object, otherwise it returns a view, i'm trying to do this on all my controllers without changin each method.
for example i know that i can do this :
if (Request::ajax()) return compact($object1, $object2);
else return view('template', compact($object, $object2));
but I have a lot of controllers/methods, and I prefer to change the basic behavior instead of spending my time to change all of them. any Idea ?
The easiest way would be to make a method that is shared between all of your controllers.
Example:
This is your controller class that all other controllers extend:
<?php namespace App\Http\Controllers;
use Illuminate\Routing\Controller as BaseController;
abstract class Controller extends BaseController
{
protected function makeResponse($template, $objects = [])
{
if (\Request::ajax()) {
return json_encode($objects);
}
return view($template, $objects);
}
}
And this is one of the controllers extending it:
<?php namespace App\Http\Controllers;
class MyController extends Controller
{
public function index()
{
$object = new Object1;
$object2 = new Object2;
return $this->makeResponse($template, compact($object, $object2));
}
}
Update for Laravel 5+
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
protected function makeResponse($request, $template, $data = [])
{
if ($request->ajax()) {
return response()->json($data);
}
return view($template, $data);
}
}
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class MyController extends Controller
{
public function index(Request $request)
{
$object = new Object1;
$object2 = new Object2;
return $this->makeResponse($request, $template, compact($object, $object2));
}
}
There is no magic but you can easily override ViewService in 3 steps:
1.create your view factory (your_project_path/app/MyViewFactory.php)
<?php
/**
* Created by PhpStorm.
* User: panos
* Date: 5/2/15
* Time: 1:35 AM
*/
namespace App;
use Illuminate\View\Factory;
class MyViewFactory extends Factory {
public function make($view, $data = array(), $mergeData = array())
{
if (\Request::ajax()) {
return $data;
}
return parent::make($view, $data, $mergeData);
}
}
2.create your view service provider (your_project_path/app/providers/MyViewProvider.php)
<?php namespace App\Providers;
use App\MyViewFactory;
use Illuminate\View\ViewServiceProvider;
class MyViewProvider extends ViewServiceProvider {
/**
* Register the application services.
*
* #return void
*/
public function register()
{
parent::register();
}
/**
* Overwrite original so we can register MyViewFactory
*
* #return void
*/
public function registerFactory()
{
$this->app->singleton('view', function($app)
{
// Next we need to grab the engine resolver instance that will be used by the
// environment. The resolver will be used by an environment to get each of
// the various engine implementations such as plain PHP or Blade engine.
$resolver = $app['view.engine.resolver'];
$finder = $app['view.finder'];
// IMPORTANT in next line you should use your ViewFactory
$env = new MyViewFactory($resolver, $finder, $app['events']);
// We will also set the container instance on this view environment since the
// view composers may be classes registered in the container, which allows
// for great testable, flexible composers for the application developer.
$env->setContainer($app);
$env->share('app', $app);
return $env;
});
}
}
3.in your_project_path/config/app.php:
change 'Illuminate\View\ViewServiceProvider',
to 'App\Providers\MyViewProvider',
What this do:
it tells your application to use another view provider which will register your view factory
$env = new MyViewFactory($resolver, $finder, $app['events']);
in line 33 of MyViewProvider.php which will check if request is AJAX and return if true or continue with original behavior
return parent::make($view, $data, $mergeData);
in MyViewFactory.php line 19
Hope this help you,
In laravel 5.1, this is the best way:
if (\Illuminate\Support\Facades\Request::ajax())
return response()->json(compact($object1, $object2));
else
return view('template', compact($object, $object2));
The solution suggested by #ryanwinchester is really good. I, however, wanted to use it for the responses from update() and delete(), and there naturally return view() at the end doesn't make a lot of sense as you mostly want to use return redirect()->route('whatever.your.route.is'). I thus came up with that idea:
// App\Controller.php
/**
* Checks whether request is ajax or not and returns accordingly
*
* #param array $data
* #return mixed
*/
protected function forAjax($data = [])
{
if (request()->ajax()) {
return response()->json($data);
}
return false;
}
// any other controller, e.g. PostController.php
public function destroy(Post $post)
{
// all stuff that you need until delete, e.g. permission check
$comment->delete();
$r = ['success' => 'Wohoo! You deleted that post!']; // if necessary
// checks whether AJAX response is required and if not returns a redirect
return $this->forAjax($r) ?: redirect()->route('...')->with($r);
}