Class 'Mpdf\Mpdf' not found (Laravel Job) - laravel

I have the following code for a laravel Job. It works just fine when in the Controller, but once I transferred it to a job, it fails with the error
Class 'Mpdf\Mpdf' not found
I have imported the class at the top of the job as I did with the controller so can't figure out why it can't find it.
<?php
namespace App\Jobs;
use Mpdf\Mpdf;
use App\DocumentRequest;
use Illuminate\Bus\Queueable;
use Intervention\Image\Facades\Image;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Storage;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class ProcessUploads implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $uuid;
public function __construct($uuid)
{
$this->uuid = $uuid;
}
public function handle()
{
$mpdf = new Mpdf();
$mpdf->WriteHTML($this->uuid);
$mpdf->Output('Output.pdf', 'F');
}
}

Steps to do for this type of errors:
Check composer that this package is already installed
Use the composer dump-autoload command to update autoload classes.
Check the documentation of this package for the valid class call
Restart the queue (because queue and tinker cache the code)

My supervisor job was running in the background and hadn’t been restarted to reflect the changes.

Related

Laravel 8 jobs not dispatching

I have this Job
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 App\Http\Traits\CreateTrait;
class CreateJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, CreateTrait;
protected $contactForm;
public function __construct($contactForm)
{
$this->contactForm = $contactForm;
}
public function handle()
{
//This connects to SSH and takes 5-10s
$this->CreateOnetime($this->contactForm->room_id, $this->contactForm->company_id, $this->contactForm->id);
}
}
Then I try in controller
use App\Jobs\CreateJob;
class ContactFormController extends Controller
{
public function save(StoreContactFormRequest $request, $cid, $rid){
$validated = $request->validated();
$validated['room_id'] = $rid;
$validated['company_id'] = $cid;
$contactForm = ContactForm::create($validated);
CreateJob::dispatch($contactForm);
return back();
}
}
Nothing written in the DB, though I have QUEUE_DRIVER=database in the .env file.
The function runs synchronously, so it does not create the Job somehow, just runs it.
Problem was I had QUEUE_CONNECTION=sync somewhere after QUEUE_DRIVER=database

Laravel 6 - dispatch event doesn't work (broadcast drive log)

I am trying to start the work on broadcasting and event, but so far the event won't fire at all, and I don't have a clue what is going on
In my .env file I have this:
BROADCAST_DRIVER=log
Event class:
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class OrdersStatusUpdate implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct()
{
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new Channel('orders');
// return new PrivateChannel('channel-name');
}
}
My controller:
<?php
namespace App\Http\Controllers\Frontend;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Events\OrdersStatusUpdate;
class SiteController extends Controller
{
public function index(){
OrdersStatusUpdate::dispatch();
}
}
Nothing is happening when I fire a request in the browser (log is not created).
I am running PHP 7.4.3 on localhost:9099
What am I doing wrong here?
Try to run php artisan queue:work to start your queue worker and processing queue jobs. You can also use supervisor to automate this.

How to push the Laravel job to the queue

I have a class XYJob which was created by artisan command and implements the ShouldQueue class.
The QUEUE_DRIVER=redis in the .env file.
The problem is that when i dispatch the job, it runs as a simple php function. The queue listener is not running, but the job runs as a simple function.
It is laravel 5.8 application with predis/predis: ^1.1.
I have tried to clear the cache and the config. I have tried to use composer dump-autoload.
namespace Modules\ModuleName\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class XYJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
\Log::info('Job is running');
}
}
Laravel documentation says:
The generated class will implement the ShouldQueue interface, indicating to Laravel that the job should be pushed onto the queue to run asynchronously.
BUT my job is definitely running.
Laravel 5.8 application should has QUEUE_CONNECTION in the .env file.
How are you dispatching the job? Have you followed the example on the Laravel doscs site at https://laravel.com/docs/5.8/queues#dispatching-jobs i.e.
\App\Jobs\ProcessPodcast::dispatch($podcast);
or dispatch(new \App\Jobs\ProcessPodcast($podcast);
dispatch(new \App\Jobs\ProcessPodcast($podcast);
If the job is not dispatched in this manner (i.e. you're simply newing up the job class), it will not be pushed to the queue.

How to queue Laravel 5.7 "email verification" email sending

Laravel 5.7 included "email verification" feature works well but not async email sending (during user register or resend link page) is not ideal.
Is there any way to send the email verification email through a queue without rewrite whole email verification in Laravel 5.7 ?
There is no built in way, but you can do it easily by extending and overriding.
First, create a new notification that extends the built-in notification, and also implements the ShouldQueue contract (to enable queuing). The following class assumes you create a notification at app/Notifications/VerifyEmailQueued.php:
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Auth\Notifications\VerifyEmail;
class VerifyEmailQueued extends VerifyEmail implements ShouldQueue
{
use Queueable;
// Nothing else needs to go here unless you want to customize
// the notification in any way.
}
Now you need to tell the framework to use your custom notification instead of the default one. You do this by overriding the sendEmailVerificationNotification() on your User model. This simply changes which notification gets sent out.
public function sendEmailVerificationNotification()
{
$this->notify(new \App\Notifications\VerifyEmailQueued);
}
Yes! It's possible. And to do that you will have to rewrite the sendEmailVerificationNotification in your App\User. This method is provided by the Illuminate\Auth\MustVerfiyEmail trait. The method sendEmailVerificationNotification notifies the created user by sending an Email as defined in the Illuminate\Auth\Notifications\VerifyEmail Notification class.
// This is the code defined in the sendEmailVerificationNotification
public function sendEmailVerificationNotification()
{
$this->notify(new Notifications\VerifyEmail);
}
You can change this method to not notify directly the user. You will have to define a Job which you will dispath in the sendEmailVerificationNotification method instead of notifying the created user.
In the Job class you will create a handle method where you can send the email to the user, but you must provide the $user to the Job which can be performed by passing it as a parameter to the dispatch method like this:
public function sendEmailVerificationNotification()
{
VerifyEmail::dispatch($this);
}
$this represents the created user and the App\Jobs\VerififyEmail job (which you will create) will receive all the parameters passed to the dispatch in its __construct
The code of the VerifyEmail will look like this:
namespace App\Jobs;
use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Auth\Notifications\VerifyEmail;
class VerifyEmail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $user;
public function __construct(User $user)
{
$this->user = $user;
}
public function handle()
{
// Here the email verification will be sent to the user
$this->user->notify(new VerifyEmail);
}
}
My solution is for if you gonna register a user manually in the controller.
Laravel already created the Registered event and its listener SendEmailVerificationNotification.
-first configure queue in application
in .env file update QUEUE_CONNECTION=database.
for more queue documentation read https://laravel.com/docs/6.x/queues
publish queue table by php artisan queue:table
php artisan migrate
php artisan make:job EmailVerificationJob
in EmailVerificationJob.php add public variable
public $user;
in EmailVerificationJob.php constructor
public function __construct(User $user)
{
$this->user = $user;
}
in EmailVerificationJob.php handle function write event(new Registered($this->user)).
in your controller if user created successfully add this code for job to work.
EmailVerificationJob::dispatch($user)
->delay(now()->addSeconds(5));
here job delay for 5 seconds.
at the end you must start queue worker php artisan queue:work --tries=3 . here tries means how many times queue should try the job.
Update#1
this solution I used in Laravel 8.
first create SendEmailVerificationNotification notification class
php artisan make:notification SendEmailVerificationNotification
app/Notifications/SendEmailVerificationNotification.php file content will be this one. here we are going to extend Laravel default SendEmailVerificationNotification class and implement should queue
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class SendEmailVerificationNotification extends \Illuminate\Auth\Listeners\SendEmailVerificationNotification implements ShouldQueue
{
use Queueable;
}
the last step is editing EventServiceProvider class $listen array. Comment out default notification of Registered event and add custom notification which we have created.
use App\Notifications\SendEmailVerificationNotification as QueuedSendEmailVerificationNotification;
use Illuminate\Auth\Events\Registered;
//use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
protected $listen = [
Registered::class => [
// SendEmailVerificationNotification::class,
QueuedSendEmailVerificationNotification::class
],
];
The solution is pretty simple:
Steps:
Configure Queue Driver
Go To --> Illuminate\Auth\Notifications\VerifyEmail
Implement 'ShouldQueue' interface and add a trait 'Queueable' on above mentioned class i.e. 'VerifyEmail' like this:
class VerifyEmail extends Notification implements ShouldQueue{
use Queueable;
....
....
...
}
3.That's it
Path of interface & trait:
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Bus\Queueable;
Please check the docs too:
https://laravel.com/docs/5.7/notifications#queueing-notifications

Recursive queue job, 100% CPU usage

I'm trying to create a queue job that runs continuously, i.e. runs a new job after the previous job has finished.
I've created a skeleton job just to test out the performance of doing this:
<?php
namespace App\Jobs;
use App\Jobs\Job;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Models\Page;
class PageParser extends Job implements ShouldQueue
{
use InteractsWithQueue, SerializesModels;
protected $page;
public function __construct(Page $page)
{
$this->page = $page;
}
public function handle()
{
$this->delete();
dispatch(new PageParser($this->page));
}
}
I ran the queue listenener, and immediately my CPU usage jumped to 100% and stayed at that level indefinitely.
Why is it using 100% of my CPU? Is there any way to fix this? Does ShouldQueue have anything to do with this?

Resources