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

cracker182's avatar

Best Practice Dynamic "Exporter"

Hi,

I've a question about a best practise guide for a dynamic exporter/mail sender.

I receive messges, store them to the DB. At the moment I have two types:

  • OrderFeedbackMessages
  • GoodsReceiptMessages

I store them into two seperate tables/models.

Now I have created a messageSender command, which should look, which of those messages aren't sent (transferred = false)

The Export-Process (i want to export the data to excel and send it via mail) of those two models differs a bit.

Here is my current and working attempt:

Message Sender Command:

<?php

namespace App\Console\Commands;

use App\Exports\GoodsReceiptExport;
use App\Exports\OrderFeedbackExport;
use App\GoodsReceiptFeedbackMessage;
use App\Mail\GoodsReceiptFeedbackMail;
use App\Mail\OrderResponseMail;
use App\OrderFeedbackMessage;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;

class MessageSender extends Command
{
    public $handlers = [
        'order_feedback'         => OrderFeedbackExport::class,
        'goods_receipt_feedback' => GoodsReceiptExport::class,
    ];

    public $models = [
        'order_feedback'         => OrderFeedbackMessage::class,
        'goods_receipt_feedback' => GoodsReceiptFeedbackMessage::class,
    ];

    public $mailables = [
        'order_feedback'         => OrderResponseMail::class,
        'goods_receipt_feedback' => GoodsReceiptFeedbackMail::class,
    ];

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'messages:send';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Sends all open messages (order_response / goods_receipt_response)';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        foreach ($this->handlers as $name => $exportHandler) {
            $filePath = $this->exportOpenMessages($exportHandler);
            Log::info($filePath);
            if (! $filePath) {
                return;
            }
            $this->markAsTransfered($this->models[$name])
                ->send($this->mailables[$name], $filePath);
        }
    }

    protected function exportOpenMessages($exportHandler)
    {
        return (new $exportHandler)->generate();
    }

    protected function send($mailable, $filePath)
    {

        Mail::to(config('cat.notifications.wa_response_indu.to'))
            ->cc(config('cat.notifications.wa_response_indu.cc'))
            ->queue(new $mailable($filePath, false));
    }

    protected function markAsTransfered($model)
    {
        $model::where('transferred', '=', false)
            ->update(['transferred' => true]);

        return $this;
    }
}

I have an ExportInterface:

<?php

namespace App\Exports;

interface ExportInterface
{
    public function generate();
}

and the implementation for each case:

<?php

namespace App\Exports;

use App\OrderFeedbackMessage;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
use Maatwebsite\Excel\Facades\Excel;

class OrderFeedbackExport implements ExportInterface
{
    protected $filePath;

    protected $fileName;

    protected $relativePath;

    public function __construct()
    {
        $this->filePath = storage_path('app/exports/wa_response/');
        $this->fileName = Carbon::now()->format('YmdHis') . '_wa_response';
        $this->relativePath = 'app/exports/wa_response/';
    }



    public function generate()
    {
        $data = OrderFeedbackMessage::forExport()->get();

        if (count($data) == 0) {
            return false;
        }

        Excel::create($this->fileName, function ($excel) use ($data) {
            $excel->sheet('Warenausgang', function ($sheet) use ($data) {

                $sheet->setColumnFormat([
                    'E' => '@'
                ]);
                $sheet->fromModel($data, null, 'A1', 'true');
            });
        })->store('xlsx', $this->filePath);

        return $this->relativePath . $this->fileName;
    }
}

is this approach ok? What could I do better? Thank you so much for your help and have a nice day.

Dennis

0 likes
0 replies

Please or to participate in this conversation.