Getting error: `Maximum execution time` when send Mail Queue in Laravel - php

I using Laravel Mail Queue to send quick mail.
I have an error like:
Maximum execution time of 60 seconds exceeded in SendWelcomeEmail.php
(line 38)
Difficult to describe my error because I don't have experience with Laravel. So, I tried to record step by step what I did.
My problem is: when user click Send information, Send Mail is activated and it using too much time to complete this work. This affect to the user experience.
I expect an answer or another method to resolve my problem.
My demo was make with step by step:
Step 1:
c:\xampp\htdocs\laravel-test>php artisan queue:table
Migration created successfully!
c:\xampp\htdocs\laravel-test>php artisan queue:failed-table
Migration created successfully!
c:\xampp\htdocs\laravel-test>php artisan migrate
Migrated: 2017_04_03_144759_create_jobs_table
Migrated: 2017_04_03_150557_create_failed_jobs_table
Step 2: update my .env file and setting email:
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:beQGwYyUPOTMtkbzDhft7swh68UJW7RqwAGwhELUfLI=
APP_DEBUG=true
APP_LOG_LEVEL=debug
APP_URL=http://localhost:8000
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=dongxanh
DB_USERNAME=admin
DB_PASSWORD=euEW12il
BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=database
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=myemail#gmail.com
MAIL_PASSWORD=yxpszfarmxoperew
MAIL_ENCRYPTION=tls
Step 3:
php artisan make:mail EmailCustomer
At function __contruct():
protected $content;
public function __construct($content)
{
$this->content = $content;
}
Function build():
public function build()
{
return $this->view('emails.contact')
->with('content',$this->content);
}
Step 4: In views/emails/contact.blade.php is:
Name: {{ $content['name'] }} <br>
Title: {{ $content['title'] }} <br>
Email: {{ $content['email'] }} <br>
Phone number: {{ $content['phonenumber'] }} <br>
Body:
{{ $content['body'] }}
Step 5: Create Job SendWelcomeEmail:
php artisan make:job SendWelcomeEmail
It will create SendWelcomeEmail.php look like this:
use Mail;
use App\Mail\EmailCustomer;
class SendWelcomeEmail implements ShouldQueue
{
protected $content;
public function __construct($content)
{
$this->content = $content;
}
public function handle()
{
sleep(60);
$receiverAddress = 'myemail#gmail.com';
$email = new EmailCustomer($content);
Mail::to($receiverAddress)->queue($email);
}
}
Finally: Send Job to Queue when user click submits form in app\Http\Controllers\RegisterForm.php:
public function storeCustomer(Request $request) {
Customer::create($request->all());
$content = [
'name'=> $request->input('name'),
'title'=> $request->input('title'),
'email'=> $request->input('email'),
'phonenumber' => $request->input('phonenumber'),
'body' => $request->input('body')
];
dispatch(new SendWelcomeEmail($content));
return view('partials.success-mail');
}
I run two commands:
php artisan serve
php artisan queue:work
And tested. It's show error like the question.

You should not use sleep here , Remove this to make queue work .
If need it try like this to increase time limit
php artisan queue:work --timeout=0
Or you can use Task Schedule : https://laravel.com/docs/5.4/scheduling
Also Use $this->content not $content.
$email = new EmailCustomer($content);

You missing this :
QUEUE_CONNECTION=database

Related

Slow Sending Mail On Laravel 6

I have setting on .env mail like this :
MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=******#gmail.com
MAIL_PASSWORD=******
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"
Then, i have class Sendemail extends mailables like this :
class Sendemail extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
public function build()
{
return
$this->from('*****#gmail.com')->subject('Penugasan')->view('Email/mail')->with('data',
$this->data);
}
}
Here is the view Email/mail :
Dengan Hormat,
Nama : {{ $data['nama'] }}
NIP : {{ $data['nip'] }}
Pangkat/Golongan : {{ $data['pangkat'] }}
The controller is like this :
foreach($rekantugas as $val)
{
$data = array(
'nama' =>$val->nama,
'nip' =>$val->nip,
'pangkat' =>$val->pangkat.' / '.$val->golongan,
);
Mail::to($val->email)->queue(new Sendemail($data));
}
My question is, when i executed the function to sending email, it's so slow about 10-15 seconds. Im still develop it in my localhost and im using Laravel 6 and postgresql.
How can i solve this ?
Note : All email has been success to delivered, but it just take a long time (slow) to sending email. I want to send an email by an form action.

Laravel Dusk loginAs not working, when using DatabaseMigration trait

I wrote tests with Laravel Dusk and no need to clear previous tests data in database, so everything was OK.
My problem starts when add use DatabaseMigrations; in DuskTestCase.php file to make sure all previous tests data is purged.
But the problem is the loginAs not working. so lots of my tests is fail, because my tests are redirected to application login page!
Any help will be appreciated.
This is my test code:
<?php
namespace Tests\Browser;
use App\Models\Brand;
use App\Models\User;
use Laravel\Dusk\Browser;
use Tests\Browser\Components\DashboardCategoryForm;
use Tests\DuskTestCase;
class DashboardBrandsTest extends DuskTestCase
{
/**
* A Dusk test example.
*
* #return void
* #throws \Exception
* #throws \Throwable
*/
public function testBrandList()
{
$user = factory(User::class)->create();
$this->browse(function (Browser $browser) use ($user) {
$browser->loginAs($user)
->visitRoute('dashboard.brands.index')
->assertSee('‌Brands')
->assertSee('id')
->assertSee('name')
->assertSee('image')
->assertSee('updated_at')
->assertSee('operations');
});
}
/**
* #throws \Exception
* #throws \Throwable
*/
public function testCreateUpdateDeleteBrand()
{
$user = factory(User::class)->create();
$this->browse(function (Browser $browser) use ($user) {
$expectedName = 'Brand ' . $user->id;
$expectedNameEdited = $expectedName . ' Edited';
$expectedShortDesc = 'This is a little desc for test.';
$expectedShortDescEdited = 'Edited desc';
$expectedImage = __DIR__ . '/photos/test.jpg';
$browser->loginAs($user)
->visitRoute('dashboard.brands.index')
->click('#new-category')
->assertRouteIs('dashboard.brands.create')
->within(new DashboardCategoryForm, function ($browser)
use ($expectedName, $expectedShortDesc, $expectedImage) {
$browser->fillCategory(
$expectedName,
$expectedShortDesc,
$expectedImage
);
})
->click('#submit')
->assertRouteIs('dashboard.brands.index')
->assertSee($expectedName);
$latestRecord = Brand::orderBy('updated_at', 'desc')->first();
$browser
->click('#edit-category' . $latestRecord->id)
->within(new DashboardCategoryForm, function ($browser)
use ($expectedName, $expectedShortDesc) {
$browser->checkCategory(
$expectedName,
$expectedShortDesc
);
})
->within(new DashboardCategoryForm, function ($browser)
use ($expectedNameEdited, $expectedShortDescEdited, $expectedImage) {
$browser->fillCategory(
$expectedNameEdited,
$expectedShortDescEdited,
$expectedImage
);
})
->click('#submit')
->assertRouteIs('dashboard.brands.index')
->assertSee($expectedNameEdited)
->click('#edit-category' . $latestRecord->id)
->within(new DashboardCategoryForm, function ($browser)
use ($expectedNameEdited, $expectedShortDescEdited) {
$browser->checkCategory(
$expectedNameEdited,
$expectedShortDescEdited
);
})
->click('#submit')
->assertRouteIs('dashboard.brands.index')
->click('#delete-category' . $latestRecord->id)
->acceptDialog()
->pause(500)
->assertDontSee($expectedNameEdited);
});
}
}
This is my env.dusk.local:
APP_NAME=Laravel
APP_ENV=testing
APP_KEY=base64:EOMuHiEoMcS0YvJQq+b/bSVm0kXfJwNnNFJ7WOQwWwQ=
APP_DEBUG=true
APP_LOG_LEVEL=debug
APP_URL=http://site.local
DB_CONNECTION=mysql
DB_HOST=10.5.0.7
DB_PORT=3306
DB_DATABASE=db_test
DB_USERNAME=root
DB_PASSWORD=secret
BROADCAST_DRIVER=log
CACHE_DRIVER=database
SESSION_DRIVER=database
SESSION_LIFETIME=120
QUEUE_DRIVER=sync
REDIS_HOST=10.5.0.9
REDIS_PASSWORD=secret
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
As you're starting off by editing a category, that implies that you're expecting there to already be data in your database. DatabaseMigrations creates your database structure, but it doesn't seed your database, so if you're trying to login there may not be a user in your database for you to loginAs.
I found that the best way to resolve this is to add seeding at the start of each test, though this does make them pretty slow. I tried a number of ways and this was the only one I could get to work.
public function setUp()
{
parent::setUp();
$this->artisan('db:seed');
}

Sending mail with lumen | Timeout

I have required composer require illuminate/mail,
.env looks fine :
MAIL_DRIVER=smtp
MAIL_HOST=smtp-mail.outlook.com
MAIL_PORT=587
MAIL_USERNAME=******#hotmail.com
MAIL_PASSWORD=*****
MAIL_ENCRYPTION=tls
Controller :
use Illuminate\Support\Facades\Mail;
....
....
....
$random = str_random(40);
Mail::send('email.verify', ['user' => $applicant_id, 'random'=>$random], function ($m) use ($findUser) {
$m->to($findUser->user->email)->subject('Account Verification');
});
It always gives me "message": "Maximum execution time of 30 seconds exceeded",, I tried it with zoho mail also.

How to Create Crud Easy Step in Laravel?

Do you guys have a smart and easy way to make crud in laravel framework?
Hot to make crud in laravel easy And fast,i tery step step in official website laravel but i do not understand.
Please let me know the easy steps i understands Thanks.
Do you guys have a smart and easy way to make crud in laravel framework?
Hot to make crud in laravel easy And fast,i tery step step in official website laravel but i do not understand. Please let me know the easy steps i understands Thanks.
I have the small totarial, this can help you !
//////////// FUNDAMENTAL ////////////
Create LARAVEL Project
composer create-project --prefer-dist laravel/laravel Airport
Create Database in PhpMyAdmin
Open project file in cmd / powerShell
Create Table with php artisan
php artisan make:migration create_flight_table
Open your text editor and edit .env
DB_CONNECTION=mysql
DB_HOST=localhost
DB_DATABASE=airport
DB_USERNAME=root
DB_PASSWORD=
Go to folder database>migration , delete user and pasword table ,open flight_table file and edit
public function up()
{
Schema::create('flights', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('airline');
$table->timestamps();
});
}
public function down()
{
Schema::drop('flights');
}
Migrate the table in cmd or powerShell
php artisan migrate
Check your table in PhpMyAdmin
==============================================================================
//////////// MODEL VIEW CONTROLLER ////////////
Create Model in cmd or powerShell
php artisan make:model Tower
protected $table = 'flights';
Create View in folder resources>views
create new folder called hangar
create index.blade.php
create edit.blade.php
create create.blade.php
Create Controller in cmd or powerShell
php artisan make:controller flightController --resource
Open and edit your controller
use App\model;
public function index()
{
$vars = Tower::all();
return view('hangar.index',['var' => $vars]);
}
Go to folder routes, Open and edit web.php
Route::resource('main', 'flightController');
Insert data in PhpMyAdmin
Open and edit your index.blade
VIEW
CREATE
#foreach($var as $var)
<p> {{ $var->name}} </p>
<p> {{ $var->airline}} </p>
{{ date('F d, Y', strtotime($var->created_at))}}<br><br>
<hr>
#endforeach
Run this command in cmd or powerShell
php artisan serve
copy paste this
http://127.0.0.1:8000/main
//////////// CRUD ////////////
//////////// CREATE ////////////
Open and edit your controller
public function create()
{
return view('hangar.create');
}
Open and edit create.blade.php
#if(count($errors)>0)
<ul>
#foreach($errors->all() as $error)
<li>
{{$error}}
</li>
#endforeach
</ul>
#endif
CREATE
Open and edit controller
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required', 'airline' => 'required',
]);
$var = new asd;
$var->name = $request->name;
$var->airline = $request->airline;
$var->save();
return redirect('main');
}
==============================================================================
//////////// UPDATE ////////////
Open and edit controller
public function edit($id)
{
$var = Tower::find($id);
if(!$var){
abort(404);
}
return view('hangar.edit')->with('var', $var);
}
Open and edit edit.blade
#if(count($errors)>0)
<ul>
#foreach($errors->all() as $error)
<li>
{{$error}}
</li>
#endforeach
</ul>
#endif
EDIT
id}}" method="post">
plane}}" placeholder="plane">
airline}}"
placeholder="airline">
Open and edit controller
public function update(Request $request, $id)
{
$this->validate($request, [
'name' => 'required', 'airline' => 'required',
]);
$var = Tower::find($id);
$var ->name = $request->name;
$var ->airline = $request->airline;
$var ->save();
return redirect('main');
}
Open and edit index.blade
id}}/edit"> EDIT
==============================================================================
//////////// DELETE ////////////
Open and edit Controller
public function destroy($id)
{
$var = Tower::find($id);
$var ->delete();
return redirect('main');
}
Open and edit index.blade
id}}" method="post">
//////////// FINISH ////////////

How to change mail configuration before sending a mail in the controller using Laravel?

I'm using Laravel 4, I would like to change the mail configuration (like driver/host/port/...) in the controller as I would like to save profiles in databases with different mail configuration. This is the basic send mail using configuration from config/mail.php
Mail::send(
'emails.responsable.password_lost',
array(),
function($message) use ($responsable){
$message->to($responsable->email, $responsable->getName());
$message->subject(Lang::get('email.password_lost'));
});
I've tried to put something like but it didn't work
$message->port('587');
Thanks for your support!
Jean
You can set/change any configuration on the fly using Config::set:
Config::set('key', 'value');
So, to set/change the port in mail.php you may try this:
Config::set('mail.port', 587); // default
Note: Configuration values that are set at run-time are only set for the
current request, and will not be carried over to subsequent requests. Read more.
Update: A hack for saving the config at runtime.
I know is kind of late but an approach could be providing a swift mailer to the laravel mailer.
<?php
$transport = (new \Swift_SmtpTransport('host', 'port'))
->setEncryption(null)
->setUsername('username')
->setPassword('secret');
$mailer = app(\Illuminate\Mail\Mailer::class);
$mailer->setSwiftMailer(new \Swift_Mailer($transport));
$mail = $mailer
->to('user#laravel.com')
->send(new OrderShipped);
The selected answer didn't work for me, I needed to add the following for the changes to be registered.
Config::set('key', 'value');
(new \Illuminate\Mail\MailServiceProvider(app()))->register();
If you want to create a Laravel 7 application where users are allowed to register and sign in on your application and you intend to enable each user with the ability to send emails through your platform, using their own unique email address and password.
THE SOLUTION:
Laravel Model: first you’ll need to create a database table to store the user’s email configuration data. Next, you’ll need an Eloquent Model to retrieve an authenticated user’s id to fetch their email configuration data dynamically.
Laravel ServiceProvider: next, create a service provider that would query the database for the user’s email configurations using a scope method within your Model class and would set it as their default mail configuration. Do not register this service provider within your config/app.php
Laravel MiddleWare: also create a middleware that would run when a user has been authenticated and register the ServiceProvider.
IMPLEMENTING THE MODEL:
Make a migration. Run these from the command line php artisan make:migration create_user_email_configurations_table. Then:
Schema::create('user_email_configurations', function (Blueprint $table) {
$table->id();
$table->string('user_id');
$table->string('name');
$table->string('address');
$table->string('driver');
$table->string('host');
$table->string('port');
$table->string('encryption');
$table->string('username');
$table->string('password');
$table->timestamps();
});
Finalize and create your model. Runphp artisan migrate and
php artisan make:model userEmailConfiguration. Now add a scope method into your model.
<?php
namespace App;
use Illuminate\Support\Facades\Auth;
use Illuminate\Database\Eloquent\Model;
class userEmailConfiguration extends Model
{
protected $hidden = [
'driver',
'host',
'port',
'encryption',
'username',
'password'
];
public function scopeConfiguredEmail($query) {
$user = Auth::user();
return $query->where('user_id', $user->id);
}
}
IMPLEMENTING THE SERVICEPROVIDER
Run this from the command line - php artisan make:provider MailServiceProvider
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\userEmailConfiguration;
use Config;
class MailServiceProvider extends ServiceProvider
{
public function register()
{
$mail = userEmailConfiguration::configuredEmail()->first();
if (isset($mail->id))
{
$config = array(
'driver' => $mail->driver,
'host' => $mail->host,
'port' => $mail->port,
'from' => array('address' => $mail->address, 'name' => $mail->name),
'encryption' => $mail->encryption,
'username' => $mail->username,
'password' => $mail->password
);
Config::set('mail', $config);
}
}
public function boot()
{
}
}
IMPLEMENTING THE MIDDLEWARE
Run the following command - php artisan make:middleware MailService
<?php
namespace App\Http\Middleware;
use Closure;
use App;
class MailService
{
public function handle($request, Closure $next)
{
$app = App::getInstance();
$app->register('App\Providers\MailServiceProvider');
return $next($request);
}
}
Now that we’ve implemented all that, register your middleware within your $routedMiddleware array in your kennel.php as mail. Then call it up within your authenticated routes middleware:
Sample:
Route::group(['middleware' => [ 'auth:api' ]], function () {
Route::post('send/email', 'Controller#test_mail')->middleware('mail');
});
Here's my original post over medium -
Enable Unique And Dynamic SMTP Mail Settings For Each User — Laravel 7

Categories