Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

EternalWay's avatar

How get Job id Laravel 9

Hello! I really want to understand how to get a job id in Laravel. So:

  1. My parent controller implements the illuminate\Foundation\Bus\DispatchesJobs trait

  2. I call $jobId = $this->dispatch(new MyJob())

  3. Logs show me that my $jobId = null :(

Now to the implementation: Controller(DispatchesJobs trait is used in the inherited Controller):

class Reports extends Controller
{
    public function build(Report $report, ReportQueue $reportQueue): Response
    {
        $jobId = null;

        if ($report->type_is_users) {
            $jobId = $this->dispatch(new BuildUsersReport($report, 1000000));
        }

        if ($report->type_is_message_recipients) {
            $jobId = $this->dispatch(
                new BuildMessageRecipientsReport(
                    $report,
                    $report->reportable,
                    1000000
                )
            );
        }

        if ($report->type_is_message_recipients_excluded) {
            $jobId = $this->dispatch(
                new BuildMessageRecipientsExcludedReport(
                    $report,
                    $report->reportable,
                    1000000
                )
            );
        }

        if ($report->type_is_sms_log) {
            $jobId = $this->dispatch(
                new BuildSmsLogReport(
                    $report,
                    1000000
                )
            );
        }

        if ($jobId) {
            $reportQueue->handle($report);
        } else {
            return Response::error("Тип отчета \"$report->type_label\" не найден.");
        }

        return Response::success(
            [
                'job_id' => $jobId,
            ]
        );
    }

Let me draw your attention to the fact that in my case “if” type_is_users is true

Job (traits Dispatchable, InteractsWithQueue, Queueable, SerializesModels are used in the parent job ExcelReport):

final class BuildUsersReport extends ExcelReport
{
    public const CHUNK_COUNT = 1000;
    public int $tries = 2;

    public function __construct(Report $report, int $sheetLineCount)
    {
        if (! $report->type_is_users) {
            throw new RuntimeException("Тип отчета должен быть {$report->type_label}.");
        }

        parent::__construct($report, $sheetLineCount);
    }

    public function handle(
        ReportWork $reportWork,
        ReportReady $reportReady,
        ReportError $reportError,
        ReportSend $reportSend,
        FilesystemManager $filesystemManager,
        UserFilter $userFilter
    ): void {
        $logger = DirectoryLogger::forReports()->getLogger();

        try {
            $reportWork->handle($this->report);

            $this->writer->openToFile(
                $filesystemManager->disk(Report::DISK)->path($this->report->filename)
            );

            $serviceId = Arr::get($this->report->filters, 'service_id');
            $serviceCategoryId = Arr::get($this->report->filters, 'service_category_id');

            $userFilter
                ->handle($this->report->filters)
                ->select([
                    'users.id',
                    'users.email',
                    'users.phone',
                    'users.family_name',
                    'users.given_name',
                    'users.patronymic',
                    'users.created_at',
                    'users.last_logged_in_at',
                    'users.latest_mobile_app_request_at',
                ])
                ->orderBy('id')
                ->chunk(self::CHUNK_COUNT, function (Collection $users) use ($serviceId, $serviceCategoryId) {
                    foreach ($users as $user) {
                        /**
                         * @var User $user
                         */

                        $favorites = $user->favorites
                            ->when($serviceCategoryId && ! $serviceId, function ($collection) use ($serviceCategoryId) {
                                return $collection->filter(function (UserService $item) use ($serviceCategoryId) {
                                    if ($item->service && $item->service->categories) {
                                        $categories = $item->service->categories;
                                        return $categories->contains('id', '=', $serviceCategoryId)
                                            || $categories->contains('parent_id', '=', $serviceCategoryId);
                                    }
                                    return false;
                                });
                            })
                            ->when($serviceId, function ($collection) use ($serviceId) {
                                return $collection->where('service_id', $serviceId);
                            });

                        $rowData = [
                            'id' => $user->id ?? '',
                            'email' => $user->email ?? '',
                            'phone' => $user->phone ?? '',
                            'full_name' => $user->full_name ?? '',
                            'favorites.*.service.main_category.name' => '',
                            'favorites.*.service.name' => '',
                            'favorites.*.service.code' => '',
                            'favorites.*.account' => '',
                            'region.name' => $user->region ? $user->region->name ?? '' : '',
                            'last_logged_in_at' => $user->last_logged_in_at ?? '',
                            'latest_mobile_app_request_at' => $user->latest_mobile_app_request_at ?? '',
                            'created_at' => $user->created_at ? $user->created_at->toDateTimeString() : '',
                        ];

                        if ($favorites->count() > 0) {
                            foreach ($favorites as $favorite) {
                                $this->addRow(
                                    array_merge(
                                        $rowData,
                                        [
                                            'favorites.*.service.main_category.name' => $favorite->service->main_category->name ?? '',
                                            'favorites.*.service.name' => $favorite->service->name ?? '',
                                            'favorites.*.service.code' => $favorite->service->code ?? '',
                                            'favorites.*.account' => $favorite->account ?? '',
                                        ]
                                    )
                                );
                            }
                        } elseif (! $serviceCategoryId && ! $serviceId) {
                            $this->addRow($rowData);
                        }
                    }

                    gc_collect_cycles();
                });

            $this->writer->close();

            $reportReady->handle($this->report);

            if ($this->report->recipients) {
                $reportSend->handle(
                    $this->report,
                    [
                        'text' => $this->fileIsEmpty(
                        ) ? 'Пользователи не найдены' : 'Файл со списком пользователей в приложении',
                        'subject' => 'Выгрузка пользователей',
                        'sender_email' => config('mail.from.address'),
                        'sender_name' => config('mail.from.name'),
                        'recipients' => $this->report->recipients,
                        'attach_file' => ! $this->fileIsEmpty(),
                    ]
                );
            }
        } catch (Throwable $throwable) {
            $this->writer->close();

            $this->logError($logger, $throwable);

            $reportError->handle(
                $this->report,
                $throwable instanceof ValidationException ? $throwable->errors() : [$throwable->getMessage()]
            );
        }
    }
}

Actually, that’s all, I’m not sure that it makes sense to overload with the rest of the information, because traits in parent controllers/jobs are used correctly. Hope someone sees my question

UPD: If you need additional information, write and I will send everything I can

0 likes
0 replies

Please or to participate in this conversation.