0
votes

My Application sends feeds to users as email. For that I have created one command name SendFeedEmails.php to send email.

Above command will get all feeds for today and stores user_id in array and execute private function named sendEmailToUser.

By that function all data will go FeedEmailDigest mailable class.

But I wanna set status as sent in table named feed_statuses after the email sent to users.

  1. SendFeedEmails.php(Command)
<?php

namespace App\Console\Commands;

use App\User;
use App\FeedStatus;
use App\Mail\FeedEmailDigest;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Mail;

class SendFeedEmails extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'feed:emails';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Send email notification to users about feeds.';

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

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        // Get all feeds for today
        $feeds = FeedStatus::query()
            ->with(['feeds'])
            ->where('msg_date', now()->format('Y-m-d'))
            ->where('status', 'pending')
            ->orderBy('user_id')
            ->get();

        // Group by user
        $data = [];
        foreach ($feeds as $feed) {
            $data[$feed->user_id][] = $feed->toArray();
        }

        //dd($data);

        foreach ($data as $userId => $feeds) {
            $this->sendEmailToUser($userId, $feeds);

        }
        
        // Send email
        return 0;
    }

    private function sendEmailToUser($userId, $feeds)
    {
        $user = User::find($userId);
        Mail::to($user)->send(new FeedEmailDigest($feeds));
    }
}
  1. FeedEmailDigest.php(Mail)
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class FeedEmailDigest extends Mailable implements ShouldQueue
{
    use Queueable, SerializesModels;

    private $feeds;
    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($feeds)
    {
        $this->feeds = $feeds;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->markdown('emails.feed-digest')
            ->with('feeds', $this->feeds);
    }
}
  1. feed_statuses(table)

enter image description here

1
There's an event fired when the email is actually sent (described in the manual) however I am unclear as to what arguments the event is fired with. it gets the Swit_Message instance as well as some data but you may need to log this somewhere first to see what data it has in order to determine how to infer the correct row to update from it (because mailing is queued)apokryfos

1 Answers

0
votes

Try the following

Edit the sendmail function to become..

    private function sendEmailToUser($userId, $feeds)
    {
        $user = User::find($userId);
        //Since you expect to have more than one entry for same user eg. feed 1 user 1, feed 2 user 1,   a loop will be in order
        foreach($feeds as $feed){
          $affected = DB::table('feed_statuses')->where(['user_id'=> $userId , 'feed_id' => $feed->id])->update(['status' => 'sent']);
        }
        Mail::to($user)->send(new FeedEmailDigest($feeds));

    }