I'm trying to create job to register users and tried to follow Jeffrey's video but looks like dispatchfrom is removed for some reason. This is what i'm trying to do now:
This is my controller:
public function PostSignUp(Request $request)
{
dispatch(new RegisterUser($request->all()));
return 'done';
}
This is my job:
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class RegisterUser implements ShouldQueue
{
use InteractsWithQueue, Queueable, SerializesModels;
protected $request;
/**
* Create a new job instance.
* #param $request
* #return void
*/
public function __construct($request)
{
$this->request = $request;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
$email = $this->request->email;
var_dump('I should register user with email:' . $email);
}
}
I also tried to put
just $request instead of $request->all()
but then i get
Serialization of 'Closure' is not allowed
And now I'm getting Trying to get property of non-object error. Is this good way to pass whole request to job ? Should i do it some other way ?
try with input()
$request->input()
When you do $request->all(), that means you are passing an array to the job and not the whole $request. Therefore, you can simply do this in your Job Handler.
public function handle()
{
$email = $this->request['email'];
var_dump('I should register user with email:' . $email);
}
Let me know if something else is required :)
Related
Running into an issue when turning my Mailable into a Queue
When the construct is disabled and the variable is injected directly into the build method, the job loads to the job table without issue, yet the job fails when the worker arrives due to the construct being missing with the following error: Illuminate\Contracts\Container\BindingResolutionException: Unable to resolve dependency [Parameter #0...
That said, when I enable the construct and remove the variable from the build method, I get an Exception Serialization of 'Closure' is not allowed.
Goal is to convert this send() to a queue() so that the db update can be performed ahead of an email being triggered.
Controller
public function store(ContactsStoreRequest $request)
{
$request->validated();
$submission = Contact::create(request()->all());
$request->id = $submission->id;
$emails = explode(',', config('mail.mailto'));
$when = now()->addMinutes(1);
Mail::to($emails)
->bcc(['notifications#xxxx.com'])
->later($when, new ContactSubmission($request));
return redirect('/contact/#loc')->with('status', 'success');
}
Mail Class
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class ContactSubmission extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
public $topic;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($topic)
{
$this->topic = $topic;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('emails.contact-submission')
->subject('XXX - Contact Submission #' . $this->topic->id)
->replyTo($this->topic->email_address);
}
}
Any help would be appreciated here!
I'm trying to send email notifications to my app users, limiting the number of emails to only 2 per minute, so as not to breach my email provider's allowed sending rate. So in MailingController.php I have:
<?php
namespace App\Http\Controllers;
use App\Jobs\SendMessages;
use Illuminate\Http\Request;
class MailingController extends Controller
{
public function send(Request $request) {
SendMessages::dispatch();
return redirect()->back()->withSuccess('Successful operation.');
}
}
SendMessages.php content is:
<?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\Middleware\RateLimited;
use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Redis;
class SendMessages implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $timeout = 7200;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct()
{
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
$users = User::all();
foreach ($users as $user) {
Log::debug('SendMessages#handle() ' . $user->email);
$user->notify(new VerifyEmail);
}
}
public function middleware()
{
return [new RateLimited];
}
}
And finally, RateLimited.php content is:
<?php
namespace App\Jobs\Middleware;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
class RateLimited
{
/**
* Process the queued job.
*
* #param mixed $job
* #param callable $next
* #return mixed
*/
public function handle($job, $next)
{
Redis::throttle('key')
->block(0)->allow(1)->every(30)
->then(function () use ($job, $next) {
// Lock obtained...
Log::debug('RateLimited');
$next($job);
}, function () use ($job) {
// Could not obtain lock...
$job->release(16);
});
}
}
All these are copied and pasted from a Laravel 8 application that works perfectly fine, sending one email every 30 seconds as expected, but in my brand new Laravel 9 application the same code no longer works, and all email notifications are sent at once. I know I must be missing something, but have ran out of ideas. Any help would be greatly appreciated.
Thank you.
I'm working with one of my Laravel 8 API project's that I've built where a user is able to add a domain to their account. The domain needs to be crawled to obtain expiration dates etc and is available in the user's account.
This process takes some time and so I've extracted the logic that fetches the domain data into a job called DomainExpiryChecker.
When a new domain is added, a job is dispatched, but may not execute straight away, and in some cases the user may even delete the domain before the job runs.
For some reason, even after dispatching my job after a record has been made, I'm getting the following failed job error and I'm not sure what I'm missing:
Illuminate\Database\Eloquent\ModelNotFoundException: No query results for model [App\Models\Domains]
My controller where the job is dispatched resembles the following:
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use App\Models\User;
use App\Models\Domains;
use Carbon\Carbon;
use App\Jobs\DomainExpiryChecker;
class DomainsController extends Controller
{
/**
* Instantiate a new DomainsController instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Add a new domain
*
* #param Request $request
* #return Response
*/
public function add(Request $request)
{
$domain = new Domains();
$domain->domain = '';
$domain->crawled = 'pending';
$domain->has_valid_ssl = false;
$domain->user_id = Auth::id();
$domain->save();
// on-demand
if ($domain) {
DomainExpiryChecker::dispatch($domain)->onQueue('on-demand-runs-now');
}
// everything went okay!
return response()->json(['success' => true, 'message' => "Added $domain_name successfully, please allow between 24 and 48 hours for crawling"], 201);
}
}
Whilst my job looks like the following:
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Http;
use GuzzleHttp\Client;
use App\Models\Settings;
use App\Models\Domains;
use Carbon\Carbon;
class DomainExpiryChecker implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* The domain instance.
*/
protected $domain;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct($domain)
{
$this->domain = $domain;
}
/**
* Get single domain
*
* #return object
*/
public function getDomain($domain)
{
$domain = Domains::where('id', $domain['id'])
->first();
return $domain;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
$updatableDomain = $this->getDomain($this->domain);
if (!$updatableDomain) {
return;
}
// stuff happens here
}
}
What am I missing, I'm sure it's just one thing.
so i have this variables in NasabahEloquent.php for my notifications.
$shohibuls = ShohibulFinance::where('barang_id','=',$submission->id)->get();
the notifications:
foreach($shohibuls as $sohib){
User::find($sohib->shohibul_id)->notify(New NasabahAkadItemToInvestor($submission,$data));
}
the notifications runs fine. but when in put it in a jobs for sending email, it return an error :
Symfony\Component\Debug\Exception\FatalThrowableError: Call to a member function notify() on null in /opt/lampp/htdocs/_pain/app/Jobs/JobForNasabahAkadItemToInvestor.php:36
this is the job dispatch on NasabahEloquent.php
foreach($shohibuls as $sohib){
$userdata = User::where('id',$sohib->shohibul_id)->get();
$AkadEndJob = (new JobForNasabahAkadItemToInvestor($userdata,$submission))->delay(Carbon::now()->addSeconds(2));
dispatch($AkadEndJob);
}
this is the handle and line 36 where the error comes from in JobForNasabahAkadItemToInvestor.php
public function handle()
{
$this->userdata->notify(New NasabahAkadItemToInvestorMail($this->submission));
}
why does my job have null on the user variables?
EDIT : the JobForNasabahAkadItemToInvestor.php file
<?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\Notifications\NasabahAkadItemToInvestorMail;
class JobForNasabahAkadItemToInvestor implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
private $userdata;
private $submission;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct($userdata, $submission)
{
$this->$userdata = $userdata;
$this->$submission = $submission;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
//nda tau lagi dah
//FIXME:Symfony\Component\Debug\Exception\FatalThrowableError: Call to a member function notify() on null in /opt/lampp/htdocs/_pain/app/Jobs/JobForNasabahAkadItemToInvestor.php:36
$this->userdata->notify(New NasabahAkadItemToInvestorMail($this->submission));
}
}
In your __construct, you access the properties the wrong way.
$this->$userdata = $userdata;
$this->$submission = $submission;
Should be:
$this->userdata = $userdata;
$this->submission = $submission;
Notice the excess $ signs. I think that's what causes the problem.
Looking around I cant find much information on how to do this. Plenty of the same examples just explaining the basic implementation of the mailable class but thats it.
I am sending an email from a contact form and have a route set up for testing that my form posts to:
Route::post('/sendmail', function() {
Mail::to("my email.com")->send(new MyTestMail());
});
I then have my mailable class which I have passed a test variable as a test string to:
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class MyTestMail extends Mailable
{
use Queueable, SerializesModels;
public $test;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct()
{
$this->test = "test";
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('emails.myTestMail');
}
}
What I wish to do is have access to my post values from the contact from and use them in the email view.
You can try passing the data you need to the constructor of that mailable.
public $postdata;
public function __construct($data)
{
$this->postdata = $data;
}
Now 'postdata' will be available to your view.
Mail::to("my email.com")->send(new MyTestMail($request->all()))