I allow users to export a PDF file and save it to their PC and I also allow them to send the PDF through email. Since the PDF can take a while to be generated, if the users decide to send it through email, I created a job that handles the creation of the PDF file & sends by email.
My objective is to prevent the user from having to wait while the file is being generated and while the email is being sent.
Controller
class ReportsController extends Controller
{
public function sendByEmail(Request $request)
{
$report = (new ReportService)
->setStartAt($request->start_at)
->setEndAt($request->end_at)
->setProducts($request->product)
->sendByEmail();
return response()->json([], 200);
}
}
ReportService
class ReportService
{
.....
/**
* Dispatches the job that sends the report by email
*/
public function sendByEmail(): void
{
dispatch(new \App\Jobs\SendReportByEmail($this));
}
/**
* Downloads / exports the file
*/
public function download(): string|Exception
{
$url = (new ReportProductService)
->setReportService($this)
->download();
return $url;
}
}
Job SendReportByEmail
class SendReportByEmail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*/
public function __construct(public ReportService $reportService) { }
/**
* Execute the job.
*/
public function handle(): void
{
// Inside the job generates the PDF file
$url = $this->reportService->download();
\Mail::queue((new \App\Mails\Report($this->reportService, $url)));
}
}
On local server everything works great.
On production server I'm getting the error:
Symfony\Component\Mime\Exception\InvalidArgumentException: Unable to open path "https://my-website/public/reports/products-report-1693859875.pdf". in /home/my_website/public_html/vendor/symfony/mime/Part/TextPart.php:154
The file actually exists / is generated, which means the mail is sent faster than the file is being generated. How can I prevent this from happening?
I tried Job Batching and create a job also for generating the PDF but got nowhere.
Solved.
The code is perfectly fine, but for some reason in the production server the absolute url as an attachment it doesn't work properly. It must be a relative path.
/**
* Execute the job.
*/
public function handle(): void
{
// HERE: $url must be a relative path (at least in my case...)
$url = $this->reportService->download();
\Mail::queue((new \App\Mails\Report($this->reportService, $url)));
}