Checkbox+Automail

Hello again folks!

I have an app with 2 models: Users and Events

My client wants to be able to send emails containing the info about a certain event to several selected users from his list.

So far the users are being shown in the gridview with a checkbox column , and I even added an "all delete" button using ajax.

now I need somehow to add another button which sends all the info from a selected Event (probably in text format ) to all the users who were checked.

I have found some topics about different auto mails, but they look too simple and straight forward .

Thus I wounder if anyone had done such a thing before or can suggest some right code/extensions for this job? ;)

Cheers,

Mark.

I mean . . . do extensions like swiftmailer any good for such a job , or a totally custom code should be written?

First of all, this should be done using cronjob + console application.

Swiftmailer is ok, but custom code is also not so hard to write. The choice is yours.

Thanks again for your reply Orey.

The mail sent should not be automated.

Now re-reading my post I see the misunderstanding.

What I meant is that my client does it by hand (check the users , choose the event , and pressing send) because he chooses different users for different event types.

Cheers,

Mark.

Yes, but sending messages right from the controller is totally unreliable (what if the connection is suddenly lost, or some other error happens, and you have no idea how many messages has already been sent). Nobody wants email duplicates, you know.

If you still don’t want to use message queue, consider ajax request. So you check some users, select an event and submit this data via ajax to some action, that processes it and returns the result (was it successful, how many messages has been sent and so on).

The messaging code is pretty simple, basically it’s just


$to = $user->email;

$name = '=?UTF-8?B?' . base64_encode('...') . '?=';

$fromEmail = \Yii::$app->params['adminEmail'];

$subject = '=?UTF-8?B?' . base64_encode('...') . '?=';


$body = $this->renderPartial('//emails/mailing', [

    'var1' => $var1,

    'var2' => $var2,

]);


$headers = "From: $name <{$fromEmail}>\r\n" .

    "MIME-Version: 1.0\r\n" .

    "Content-type: text/html; charset=UTF-8";


$success = mail($to, $subject, $body, $headers);



so I dont think that using extra stuff like swiftmailer is a must.

Agree , but does cronjob solves it?

That was my plan: send ajax through clientscript from the view to a controller function that sends the mail.

The easiest solution is the best for me (under client I mean the person for whom I write the app as part of my degree final project - I’m a student and quite new to yii)

Thats all ? If I send ajax to user, subject, name and var’s it’ll work?

You have my thanks!

Cheers,

Mark.

Well, yes. You just create a queue task and forget about it. You can even turn off your internet connection, cron will do the job for you.

No no no, you’ll need to do some real coding of course. I just gave you an example of sending one mail to one user.

(and btw I left some php 5.4 and yii2 syntax, so don’t take it seriously).

I see , it really looked too simple.

I had no idea cron can be used for such thing , I’ll try to find some reading on the subject. (though if anyone have any info about cron mailing I’ll be happy to get some tips)

Thanks Orey

Cheers ,

Mark.

Well, cron itself can do only one thing: run some job periodically.

So you can create console application that checks some queue (db table, for example) for tasks, and, if any, process these tasks.

Let’s consider a simple table tbl_mailing that has these fields:

  1. id (unique identifier for job)

  2. name (internal name for job)

  3. message (text field containing mail body)

  4. user_ids (comma-separated list of user ids that should get this mail).

So you check some checkboxes in clients list, fill the message text (probably some placeholders should be used also, like "Hello, %username%!") and submit the form. This form is processed by action and new Mailing record is created. Ok, the job is in queue.

Let’s suppose that the cron runs every N minutes. So every N minutes your console app is started. It checks for new unfinished jobs (for example, $job = Mailing::model()->find(‘user_ids IS NOT NULL’));

If there’s an active job, console app explodes user_ids, finds the users from this list and starts mailing.

Every time email is successfully sent, corresponding item is removed from the array.

When the mailing is done (for example, you want to send only three emails in a row), the rest of the array is imploded and stored back to tbl_message. When the list is empty, NULL is stored instead.

This is the very basic example, so it can’t be taken as a working code. But I think you got the idea.

Now I see what you meant under your first post.

Indeed I haven’t thought about storing mails in a table.

Thank you Orey for providing both a solution and a new way to look at email system!

Cheers,

Mark.

Oh , one more question because it is new to me:

I’m guessing that user_ids should be int? and since checkbox is creating an array I guess that under “explode” you mean a counter that reads the id’s separately ?

Cheers,

Mark.

I meant comma-separated array of ints, so it’s a string, like ‘1,2,4,7’.

$user_ids = explode(’,’, $mailing->user_ids);

Or you can use built-in DB array types, but this is kinda tricky.

Actually, it’s probably better to use another table (mailing_id, user_id) to flag users that have already been mailed.

I see,

Thank you Orey !

Cheers,

Mark.