Laravel problem passing variables from controller to mailer - laravel

I am having trouble passing variables from the controller to the mail fucntion I have tried to search it up on google but didn't find anything that works my goal is to get the variable from the form to the welcomemail.blade the current issue is that the variable doesnt get to my wlcomemail.php from the controller. the mailing part itself does work.
Controller code:
$email_data = array(
'first_name'=>'John',
'last_name'=>'Doe',
'email'=>'john#doe.com',
'password'=>'temp',
);
//Customer::create($data);
Mail::to($email_data['email'])->send(new welcomemail($email_data));
welcomemail.php code:
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class welcomemail extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*
* #return void
*/
public $email_data;
public $example;
public function __construct()
{
$this->email_data = $email_data;
$this->example = 'example';
}
public function build()
{
return $this->markdown('emails.welcomemail');
}
}
blade code:
# Introduction
Welcome.
{{$email_data['first_name']}}
{{$example}}
#endcomponent

change this:
public function __construct()
{
$this->email_data = $email_data;
$this->example = 'example';
}
to:
public function __construct($email_data)
{
$this->email_data = $email_data;
$this->example = 'example';
}
now you have it in your mail class
it should work

Related

Cannot declare class App\User, because the name is already in use Laravel

I want to add user address in address table and want to update the address_id in user table for that i'm using user model and address model, data is being saved in address table but when i use User model in Address Repository
use App\Models\User;
i get
Cannot declare class App\User, because the name is already in use
Here is my code :
<?php
namespace App\Repositories;
use App\Models\Addresses;
use App\Models\User;
use App\Contracts\AddressContract;
use Illuminate\Database\QueryException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Doctrine\Instantiator\Exception\InvalidArgumentException;
class AddressRepository extends BaseRepository implements AddressContract
{
/**
* AttributeRepository constructor.
* #param Attribute $model
*/
public function __construct(Addresses $model)
{
parent::__construct($model);
$this->model = $model;
}
public function addAddress(array $params)
{
try {
$Addresses = new Addresses($params);
$Addresses->save();
$addressId = $Addresses->id;
$userID=auth()->user()->id;
if($params['is_primary_address']==1)
{
User::where('id',$userID)->update(['address_id'=>$addressId]);
}
return $Addresses;
}
catch (QueryException $exception) {
throw new InvalidArgumentException($exception->getMessage());
}
}
}
ProductController.php
<?php
namespace App\Http\Controllers\Site;
use App\Contracts\AttributeContract;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Contracts\ProductContract;
use App\Contracts\AddressContract;
use Cart;
use Validator;
class ProductController extends Controller
{
protected $productRepository;
protected $attributeRepository;
protected $addressRepository;
public function __construct(ProductContract $productRepository, AttributeContract $attributeRepository, AddressContract $addressRepository)
{
$this->productRepository = $productRepository;
$this->attributeRepository = $attributeRepository;
$this->addressRepository = $addressRepository;
}
public function addUserAddress(Request $request)
{
$customer_name=$request->customer_name;
$customer_address=$request->customer_address;
$country=$request->country;
$city=$request->city;
$zip_code=$request->zip_code;
$state=$request->state;
$address_type=$request->address_type;
$is_primary_address=$request->primary_address;
$userID=auth()->user()->id;
$data=array('name'=>$customer_name,'address'=>$customer_address,'country'=>$country,'state'=>$state,'city'=>$city,'address_type'=>$address_type,'user_id'=>$userID,'is_primary_address'=>$is_primary_address);
$userAddress = $this->addressRepository->addAddress($data);
return redirect()->back()->with('message', 'Address Added');
}
}

Laravel giving invalid view error for mail

I'm new to Laravel. I wanted to send a mail to users for every time they login. I wrote the authentication logic already.
<?php
namespace App\Http\Controllers\Users;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use App\Events\Login;
class LoginController extends Controller
{
public function __construct(){
$this->middleware('guest')->except('logout');
}
public function index(){
return view('users.login');
}
public function login(Request $request){
$credentials = $request->only('username', 'password');
if(Auth::attempt($credentials)){
event(new Login(auth()->user()));
return redirect()->intended(route('homepage'));
}else{
return redirect()->back()->withInput()->with('error', 'Username/Password Combo Wrong!');
}
}
public function logout(){
Auth::logout();
return redirect()->route('login-form');
}
}
I wrote an event for this
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use App\User;
class Login
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $user;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct(User $user)
{
$this->user = $user;
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('channel-name');
}
}
This is the event listener
<?php
namespace App\Listeners;
use App\Events\Login;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Request;
use App\Mail\UserLoggedIn;
class SendLoginNotification
{
/**
* Create the event listener.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* #param Login $event
* #return void
*/
public function handle(Login $event)
{
Mail::send($event)->send(new UserLoggedIn($event));
}
}
I created a mail class
<?php
namespace App\Mail;
use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class UserLoggedIn extends Mailable
{
use Queueable, SerializesModels;
public $user;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct(User $user)
{
$this->user = $user;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->from('test#mail.com')->view('emails.users.loggedin');
}
}
I then created the view for the mail in resources/views/emails/users/loggedin.blade.php
<!Doctype html>
<html>
<head>
<title>User Logged In</title>
</head>
<body>
{{$user->name}} Logged in
</body>
</html>
But when i run try to run the login, i get an error saying invalid view
There are a couple of issues I've noticed. Currently, you're:
calling send twice in your SendLoginNotification (and you're passing the Event instead of a mailable to one of them)
not specifying who to send the mail to
also passing the $event to the mailable rather than the User
Change:
Mail::send($event)->send(new UserLoggedIn($event));
To:
Mail::to($event->user)->send(new UserLoggedIn($event->user)); //notice the "user" property.
you didn't pass any variable containing user info.
public function build()
{
$user=User::find(1);
return $this->from('test#mail.com')->view('emails.users.loggedin',compact('user'));
}

How can I add condition on mail notification laravel?

I use laravel 5.3
My notication laravel like this :
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Notifications\Messages\BroadcastMessage;
class GuestRegistered extends Notification implements ShouldBroadcast, ShouldQueue
{
use Queueable;
private $data;
public function __construct($data)
{
$this->data = $data;
}
public function via($notifiable)
{
return ['mail'];
}
public function toMail($notifiable)
{
return (new MailMessage)
->subject('test')
->greeting('Hi')
->line('Thanks')
->line('Your password : '.$this->data)
->action('Start Shopping', url('/'));
}
}
I want to add condition in toMail method
So if $this->data not exist then ->line('Your password : '.$this->data) not display or not executed
How can I do it?
Add a default value for the $data parameter in the constructor .
public function __construct($data = null)
{
$this->data = $data;
}
Then you can store the instance of MailMessage in a variable and use the if statement to add the line() you want.
public function toMail($notifiable)
{
$mailMessage = new MailMessage();
$mailMessage
->subject('test')
->greetings('Hi')
->line('Thanks');
if($this->data) {
$mailMessage->line('Your password: ' . $this->data);
}
$mailMessage->action('Start Shopping', url('/'));
return $mailMessage;
}

laravel queue not working like it did before

Hello i was working with mailable and using queue but when i used php artisan queue:listen and send a mail it did not work like it was supposed to do, i did get the email on mailtrap, but there was no message in my console. I tried sending the mail first and then use my command but it worked without my command. and it does not take a while because its sending immediately here is my code
controller.php
use Illuminate\Support\Facades\Mail;
use App\Mail\testmail;
class Controller extends Controller{
public function email($email, Request $request){
$emailuser = $request->input('email');
$message = $request->input('bericht');
mail::to($email)->queue(new testmail($emailuser, $message));
}
}
testmail.php
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class testmail extends Mailable
{
use Queueable, SerializesModels;
public $emailuser;
public $message;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($emailuser, $message)
{
$this->emailuser = $emailuser;
$this->message = $message;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->markdown('email.mail');
}
}
mail.blade.php
#component('mail::message')
{{ $emailuser }}
{{ $message }}
Thanks,<br>
{{ config('app.name') }}
#endcomponent
does anyone know how to fixs this because i need it to have a delay for my application
Use a job instead of Maillable and in that job in handle function write down the code to send the email in that job
for i.e-:
$job = (new SendWelcomeEmail($activation->code,$user))->onQueue('default');
and the job file SendwelcomeEmail would like following-:
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use App\Jobs\Job;
use Mail;
class SendWelcomeEmail extends Job implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* #return void
*/
protected $activation_code;
protected $user;
public function __construct($activation_code,$user)
{
$this->activation_code=$activation_code;
$this->user=$user;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
try{
$user=$this->user;
Mail::send('emails.user.register', ['activation_code' => $this->activation_code,'user'=>$this->user], function ($m) use ($user) {
$m->to($user->email,$user->first_name." ".$user->last_name)
->subject(trans('emails.USER_REGISTER_SUBJECT',['project'=>trans('project.project_name')]));
});
\Log::useDailyFiles(storage_path().'/logs/user-registration/success/'.date('Y-m-d').'.log');
\Log::info('Welcome Email Send to-:'.$user->email);
}catch(Exception $ex){
\Log::useDailyFiles(storage_path().'/logs/user-registration/error/'.date('Y-m-d').'.log');
\Log::error($ex->getMessage());
\Log::error("Line Number->".$ex->getLine());
}
}
}

How to test job arguments in Laravel?

How to test job arguments if Exception is thrown after job is dispatched. This test below returns green, but i found no way to test job arguments.
Code:
<?php
namespace Tests\Feature;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Tests\TestCase;
class SomeJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle() {}
}
class NothingTest extends TestCase
{
/** #test */
public function dispatch_test()
{
$this->expectException(\Exception::class);
$this->expectsJobs(SomeJob::class);
// job dispatched and Exception thrown afterwards
dispatch(new SomeJob("argument to test"));
throw new \Exception();
}
}
I actually ran into this earlier today myself. What I did to solve this issue was by using the withoutJobs() method instead. (Internally expectsJobs() calls this as well.) You can then assert against the dispatchedJobs property.
Because you are also 'expecting' and exception in your test you should wrap this in a callback and register it in a beforeApplicationDestroyed()
class SomeJob {
private $argument;
public function __construct($argument)
{
$this->argument = $argument;
}
}
class NothingTest extends TestCase
{
/** #test */
public function dispatch_test()
{
$this->expectException(\Exception::class);
$this->beforeApplicationDestroyed(function () {
// This part depends on how you would like to design this. You could
// use public properties, add a getter method on your job or use
// something like reflection to compare the properties.
$dispatchedJob = $this->dispatchedJobs[0];
$this->assertEquals(
'argument to test',
$this->getValue($dispatchedJob, 'argument')
);
});
// job dispatched and Exception thrown afterwards
dispatch(new SomeJob("argument to test"));
throw new \Exception();
}
protected function getValue($object, $name)
{
$ro = new \ReflectionObject($object);
$property = $ro->getProperty($name);
$property->setAccessible(true);
return $property->getValue($object);
}
}
ok. can test like this code below.
test looks nice, but you must use public properties and assign all arguments to the properties.
<?php
namespace Tests\Examples;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Tests\TestCase;
class SomeJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $arg1;
public $arg2;
public function __construct($arg1, $arg2)
{
$this->arg1 = $arg1;
$this->arg2 = $arg2;
}
public function handle() {}
}
class JobTest extends TestCase
{
/** #test */
public function dispatch_test()
{
$this->expectException(\Exception::class);
$this->expectsJobs(SomeJob::class);
$this->testJobInstance(SomeJob::class, function($job){
$this->assertEquals('arg1', $job->arg1);
$this->assertEquals('arg2', $job->arg2);
});
// job dispatched and Exception thrown afterwards
dispatch(new SomeJob("arg1", "arg2"));
throw new \Exception();
}
// will be pushed up to TestCase
protected function testJobInstance($class, callable $callback)
{
$this->beforeApplicationDestroyed(function () use($class, $callback) {
$job = collect($this->dispatchedJobs)->filter(function($job) use($class) {
return get_class($job) == $class;
})->first();
$callback($job);
});
}
}
Ok, the better way found...
I've made a helper function to dispatch jobs from IOC - it makes a lot easier to test jobs.
/**
* #param string | object $job
* #param array | null $args - associative array of arguments ['agr1' => 'value', 'arg2' => 2]
* #return mixed
*/
function dispatch_from_ioc($job, ? array $args)
{
if (is_string($job)) {
$job = app()->makeWith($job, $args);
}
return app(Dispatcher::class)->dispatch($job);
}
so now i can test job arguments like this:
/** #test */
public function test_jobs_arguments()
{
$this->app->bind(
RealJob::class,
function($app, $args){
// assertions against arguments
$this->assertEquals("argument", $args["arg"]);
$this->assertEquals([], $args["arg2"]);
return new FakeJob;
}
);
// System under test
dispatch_from_ioc(RealJob::class, ["arg" => "argument", "arg2" => []]);
}
Fake Job class
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class FakeJob extends Job
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct() {}
public function handle() {}
}
Does it makes sense? :)

Resources