Mail::send() not working in Laravel 5 - php

I am continuously getting this error 'Class 'App\Http\Controllers\Mail' not found' error in my UserController.php
public function store(CreateUserRequest $request)
{
$result = DB::table('clients')->select('client_code','name','email')
->where('client_code','=',$request->code)
->where('email','=',$request->email)
->first();
if($result){
$tmp_pass = str_random(10);
$user = User::create([
'username' => $result->name,
'email' => $request->email,
'password' => $tmp_pass,
'tmp_pass' => '',
'active' => 0,
'client_code' => $request->code
]);
if($user){
Mail::send('emails.verify',array('username' => $result->name, 'tmp_pass' => $tmp_pass), function($message) use ($user){
$message->to($user->email, $user->username)
->subject('Verify your Account');
});
return Redirect::to('/')
->with('message', 'Thanks for signing up! Please check your email.');
}
else{
return Redirect::to('/')
->with('message', 'Something went wrong');
}
}
else{
Session::flash('message', "Invalid code or email.");
return redirect('/');
}
}
Mail function used to work in Laravel 4 but I am getting errors in Laravel 5. Any help would be appreciated.

Mail is an alias inside the global namespace. When you want to reference it from inside a namespace (like App\Http\Controllers in your case) you have to either:
Prepend a backslash:
\Mail::send(...)
Or add a use statement before your class declaration:
namespace App\Http\Controllers;
use Mail; // <<<<
class MyController extends Controller {
The same goes for the other facades you use. Like Session and Redirect.

Another way is to use Mail facade
use Illuminate\Support\Facades\Mail;
In your controller

In Laravel 5.8 I solved it by also adding this in the controller :
THIS:
use App\Mail\<<THE_NAME_OF_YOUR_MAIL_CLASS>>;
use Illuminate\Support\Facades\Mail;
INSTEAD OF:
use Mail;

setup your app/config/mail.php
return array(
'driver' => 'smtp',
'host' => 'smtp.gmail.com',
'port' => 465,
'from' => array('address' => 'your#gmail.com', 'name' => 'Welcome'),
'encryption' => 'ssl',
'username' => 'your#gmail.com',
'password' => 'passowrd',
'sendmail' => '/usr/sbin/sendmail -bs',
'pretend' => false,
);
than setup in controller:
use Mail;
\Mail::send('tickets.emails.tickets',array('ticketsCurrentNewId'=>
$ticketsCurrentNewId->id,'ticketsCurrentSubjectId'=>$ticketsCurrentNewId->subject,'ticketsCurrentLocationsObj'=>$ticketsCurrentLocationsObjname), function($message)
{
//$message->from('your#gmail.com');
$message->to('your#gmail.com', 'Amaresh')->subject(`Welcome!`);
});
after this setup mail are send emails if any permission error have showing then click this url and checked this radio button
https://www.google.com/settings/security/lesssecureapps
after configuration it is working fine in #laravel,#symfony and any php framework
thank you

Related

test if user is logged in laravel 5.7

I am making a test but it fails when it tries to check if a user is logged in:
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Auth;
use App\User;
class RegisterTest extends TestCase
{
use RefreshDatabase;
/*.....
more test about registering
....*/
/** #test */
function redirect_to_home_page_and_logged_in_after_login()
{
$user = factory(User::class)->create([
'name' => 'Test',
'email' => 'test#hotmail.com',
'password' => '123456'
]);
$response = $this->post('login', [
'email' => 'test#hotmail.com',
'password' => '123456'
]);
//this works
$response->assertRedirect('/');
//this fails
$this->assertTrue(Auth::check());
}
}
And this is my controller HomeController:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class HomeController extends Controller
{
public function index()
{
if (Auth::check()){
return view('home');
}
return view('welcome');
}
}
And this is my routes/web.php
Route::get('/', 'HomeController#index');
Auth::routes();
I am not sure what I am doing wrong. What can I do?. I am using laravel 5.7 and phpunit 5.7.1
Also in my app/Htpp/Auth/LoginController.php I did this:
protected $redirectTo = '/';
Thank you.
In addition to hashing your password you could also just post to the register route and create a new account.
/** #test */
function redirect_to_home_page_and_logged_in_after_register()
{
$response = $this->post('register', [
'name' => 'Test',
'email' => 'test#hotmail.com',
'password' => '123456'
]);
//this works
$response->assertRedirect('/');
//this fails
$this->assertTrue(Auth::check());
}
I guess you may also have a requirement to do it both ways:
/** #test */
function redirect_to_home_page_and_logged_in_after_login()
{
$user = factory(User::class)->create([
'name' => 'Test',
'email' => 'test#hotmail.com',
// note you need to use the bcrypt function here to hash your password
'password' => bcrypt('123456')
]);
$response = $this->post('login', [
'name' => 'Test',
'email' => 'test#hotmail.com',
'password' => '123456'
]);
//this works
$response->assertRedirect('/');
//this fails
$this->assertTrue(Auth::check());
}
Creating a user requires you to take care of the hashing of the password.
You can simply do it by using php's password_hash function. And use Auth::login($user); to login.
Like so:
$user = User::create(['email' => 'r#o.b', 'password' => password_hash('123456', 1)]);
Auth::login($user); //You should be logged in :)

How to Use Mail::Queue in Laravel

I want to send emails to 100 users. Mail::send() is taking too much load time and isn't able to cover all emails of users. I'm trying to use Mail::queue() in my application, but I'm getting the error below while running
php artisan queue:listen.
[ErrorExcepton] Undefined Property :
SuperClosure\SerializableClosure::$binding.
Updated .env file with QUEUE_DRIVER = database.
Please help me find the solution to resolve this. Also, I am using the same code to run background jobs, using Laravel 5.3.
Here is my code
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\DB;
class ProbationCronJobEmail extends Command
{
protected $signature = 'hrm:notify';
protected $description = "";
public function __construct()
{
parent::__construct();
}
public function handle()
{
$email = 'abc#gmail.com';
\Mail::queue('emails.probation',
['empname'=>'abc','id'=>'123'],function($msg) use($email){
$msg->from('abc#gmail.com');
$msg->to($email);
$msg->subject('Probation List as on '.date('Y-M-d'));
});
}
}
abc#gmail is a dummy email, i am using my corporate email instead.
if i simple type php artisan hrm:notify, getting no error.
I have a little example. I hope this will help.
<?php
public function mails_meeting($meeting, $group, $place, $date, $message, $user)
{
$subject = "meeting " . $group;
$cargos = Cargo::where('comision_id', '=', $meeting->comision_id)->where('active', '=', '1')->get();
foreach ($cargos as $cargo) {
$mail_reciever = $cargo->asambleista->user->email;
Mail::queue('correos.comision_mail', ['group' => $group, 'place' => $place,
'date' => $date, 'message' => $message, 'user' => $user],
function ($mail) use ($subject, $mail_reciever) {
$mail->from('siarcaf#gmail.com', 'Automatic mail system');
$mail->to($mail_reciever);
$mail->subject($subject);
});
}
return 0;
}
In your_app/config/mail.php .
'sendmail' => '/usr/sbin/sendmail -bs',
'stream' => [
'ssl' => [
'allow_self_signed' => true,
'verify_peer' => false,
'verify_peer_name' => false,
],
],
.env file
MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=your_username
MAIL_PASSWORD=your_password
MAIL_ENCRYPTION=your_conf

Auth::attempt() always returns false for default brand new installation

I tried lot to search about the problem. I couldn't find any solution. Please help me to understand what i am doing wrong.
I am attaching the code:
UserController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
use Illuminate\Support\Facades\Auth;
class UserController extends Controller
{
public function signup(Request $request){
$this->validate($request,[
'name' => 'required',
'email' => 'required|unique:users',
'password' => 'required'
]);
$user = new User([
'name' => $request->input('name'),
'email' => $request->input('email'),
'password' => bcrypt($request->input('password ')),
]);
$user->save();
return response()->json([
'state' => 'success',
'message' => 'User created.'
],201);
}
public function signin(Request $request){
$credentials = $request->only('email', 'password');
dd(Auth::attempt($credentials));
if (!$token = $this->guard()->attempt($credentials)) {
return response()->json(['error' => 'Unauthorized'], 401);
}
return $this->respondWithToken($token);
}
}
And i have routes in api.php
Route::prefix('user')->group(function () {
Route::post('signup', 'UserController#signup');
Route::post('signin', 'UserController#signin');
});
I have
I have this in database
I sent the below json to signup first, but then when i sent to signin i am getting failed.
{
"name":"ironman",
"email":"ironman#yahoo.com",
"password":"avengers"
}
This is a brand new installation of laravel 5.4 (same with 5.5), Using detailt User migration and model came with it.
When i tried to diagnose the problem myself, i found that the password_very is returning false all the time in Auth package.
I am using default password field, hashing it while creating users as other similar questions answered.
I am using php artisan serv.
I am using postman to send this request.
Please help,
This is pulling null from the request:
$request->input('password '); // notice the space
'password' => bcrypt($request->input('password ')),
You probably did not intend to put a space at the end of the input name:
$request->input('password'); // no space
'password' => bcrypt($request->input('password')),

Dynamic mail configuration with values from database [Laravel]

I have created a service provider in my Laravel Application SettingsServiceProvider. This caches the settings table from the database.
$settings = $cache->remember('settings', 60, function() use ($settings)
{
return $settings->pluck('value', 'name')->all();
});
config()->set('settings', $settings);
settings table:
I am able to echo the value from the table like this:
{{ config('settings.sitename') }} //returns Awesome Images
This works fine on any blade files or controllers in App\Http\Controllers
Problem:
I am trying to echo the value to App\config\mail.php like this:
'driver' => config('settings.maildriver'),
'host' => config('settings.mailhost'),
But I'm getting this error:
Missing argument 1 for Illuminate\Support\Manager::createDriver()
Update:
I have created a new service provider MailServiceProvider to override the settings in Mail.php like this:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Config;
class MailServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
Config::set('mail.driver', config('settings.maildriver'));
Config::set('mail.host', config('settings.mailhost'));
Config::set('mail.port', config('settings.mailport'));
Config::set('mail.encryption', config('settings.mailencryption'));
Config::set('mail.username', config('settings.mailusername'));
Config::set('mail.password', config('settings.mailpassword'));
}
}
But still I am getting the same error!!
Is there any way to override default mail configuration (in app/config/mail.php) on-the-fly (e.g. configuration is stored in database) before swiftmailer transport is created?
Struggled for 3 days with this issue finally I figured out a way to solve it.
First I created a table mails and populated it with my values.
Then I created a provider MailConfigServiceProvider.php
<?php
namespace App\Providers;
use Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;
class MailConfigServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
if (\Schema::hasTable('mails')) {
$mail = DB::table('mails')->first();
if ($mail) //checking if table is not empty
{
$config = array(
'driver' => $mail->driver,
'host' => $mail->host,
'port' => $mail->port,
'from' => array('address' => $mail->from_address, 'name' => $mail->from_name),
'encryption' => $mail->encryption,
'username' => $mail->username,
'password' => $mail->password,
'sendmail' => '/usr/sbin/sendmail -bs',
'pretend' => false,
);
Config::set('mail', $config);
}
}
}
}
And then registered it in the config\app.php
App\Providers\MailConfigServiceProvider::class,
Maybe its usefull to somebody, but I solved it as following;
In a ServiceProvider under the boot-method;
$settings = Cache::remember('settings', 60, function () {
return Setting::pluck('value', 'name')->all();
});
config()->set('settings', $settings); // optional
config()->set('mail', array_merge(config('mail'), [
'driver' => 'mailgun',
'from' => [
'address' => $settings['mail_from_address'],
'name' => $settings['mail_from_name']
]
]));
config()->set('services', array_merge(config('services'), [
'mailgun' => [
'domain' => $settings['mailgun_domain'],
'secret' => $settings['mailgun_secret']
]
]));
I used array_merge with the original config, so we only override the values we need to. Also we can use the Cache-facade in the boot-method.
Following the instructions here is the proper solution to the problem, in case if you're sending multiple emails per request over different SMTP configurations, Config::set() won't work right, the first email will use the correct settings, while all upcoming emails within the same request will use the same configuration of the first one, because the Mail service is provided as a singleton thus only the initial configurations will be used.
This also might affect emails sent over Laravel queue workers due to the same reason.
After research a lot, finally I found the best possible way to dynamic mail configuration.
I am saving my mail configuration data in the settings table, please have a look at the table structure.
Helpers/AaapHelper.php
<?php
namespace App\Helpers;
use App\Setting;
class AppHelper
{
public static function setMailConfig(){
//Get the data from settings table
$settings = Setting::pluck('description', 'label');
//Set the data in an array variable from settings table
$mailConfig = [
'transport' => 'smtp',
'host' => $settings['smtp_host'],
'port' => $settings['smtp_port'],
'encryption' => $settings['smtp_security'],
'username' => $settings['smtp_username'],
'password' => $settings['smtp_password'],
'timeout' => null
];
//To set configuration values at runtime, pass an array to the config helper
config(['mail.mailers.smtp' => $mailConfig]);
}
}
app\Http\Controllers\SettingController.php
<?php
namespace App\Http\Controllers;
use App\Helpers\AppHelper;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
class SettingController extends Controller
{
public function sendMail()
{
try
{
//Set mail configuration
AppHelper::setMailConfig();
$data = ['name' => "Virat Gandhi"];
Mail::send(['text' => 'mail'], $data, function ($message)
{
$message->to('abc#gmail.com', 'Lorem Ipsum')
->subject('Laravel Basic Testing Mail');
$message->from('xyz#gmail.com', $data['name']);
});
return redirect()->back()->with('success', 'Test email sent successfully');
}
catch(\Exception $e)
{
return redirect()->back()->withErrors($e->getMessage());
}
}
}
Explanation
While sending a mail through the sendMail function it will first configure mail through helper.

Laravel Mail::send returns zero with no specific error in Mail::failures()

I am using smtp driver and this is my code to send email in laravel 5.2:
public function Sendmail()
{
$data["mail_message"] = "Hello!";
if(Mail::send('Emails.email', $data, function($message)
{
$message->from('webmaster#example.com', Input::get('name'));
$message->to('amirhasan.hesam#gmail.com')->subject('Welcome to My Laravel app!');
}))
{
return "success";
}
else
{
return Mail::failures();
}
}
the Mail::failures() returns ["amirhasan.hesam#gmail.com"] with no specific error!
and this is my config on mail.php :
return [
'driver' => env('MAIL_DRIVER', 'smtp'),
'host' => env('MAIL_HOST', '*******'),
'port' => env('MAIL_PORT', 587),
'from' => ['address' => "****#*****", 'name' => "Diling"],
'encryption' => env('MAIL_ENCRYPTION', ''),
'username' => env('*****#*****'),
'password' => env('*************************'),
'sendmail' => '/usr/sbin/sendmail -bs',
'pretend' => false,
];
and I am using xamp right now to test the email. Any thoughts?
I've had troubles with using variables inside the mail::send .. and im also not sure if mail::send returns boolean or such... I've used something like what I wrote down in the past.
$nameSend = Input::get('name');
Mail::send('Emails.email', $data, function($message) use ($nameSend){
$message->from('webmaster#example.com', $nameSend);
$message->to('amirhasan.hesam#gmail.com')->subject('Welcome to My Laravel app!');
});
.
.
if( count(Mail::failures()) > 0 ) {
$output = "There was one or more failures. They were: \n";
foreach(Mail::failures as $email_address) {
$output = $output. $email_address ."\n";
}
return $output;
}
return "Success!";
you just need to use Mail facade
use Illuminate\Support\Facades\Mail;

Categories