mailing.php 4.52 KB
Newer Older
Scott committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
<?php
/*
	Question2Answer by Gideon Greenspan and contributors
	http://www.question2answer.org/

	Description: Functions for sending a mailing to all users


	This program is free software; you can redistribute it and/or
	modify it under the terms of the GNU General Public License
	as published by the Free Software Foundation; either version 2
	of the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	More about this license: http://www.question2answer.org/license.php
*/

Scott committed
22
if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
23
	header('Location: ../../');
Scott committed
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
	exit;
}


/**
 * Start a mailing to all users, unless one has already been started
 */
function qa_mailing_start()
{
	require_once QA_INCLUDE_DIR . 'db/admin.php';

	if (strlen(qa_opt('mailing_last_userid')) == 0) {
		qa_opt('mailing_last_timestamp', time());
		qa_opt('mailing_last_userid', '0');
		qa_opt('mailing_total_users', qa_db_count_users());
		qa_opt('mailing_done_users', 0);
Scott committed
40
	}
Scott committed
41
}
Scott committed
42 43


Scott committed
44 45 46 47 48 49 50 51 52 53
/**
 * Stop a mailing to all users
 */
function qa_mailing_stop()
{
	qa_opt('mailing_last_timestamp', '');
	qa_opt('mailing_last_userid', '');
	qa_opt('mailing_done_users', '');
	qa_opt('mailing_total_users', '');
}
Scott committed
54 55


Scott committed
56 57 58 59 60 61
/**
 * Allow the mailing to proceed forwards, for the appropriate amount of time and users, based on the options
 */
function qa_mailing_perform_step()
{
	require_once QA_INCLUDE_DIR . 'db/users.php';
Scott committed
62

Scott committed
63
	$lastuserid = qa_opt('mailing_last_userid');
Scott committed
64

Scott committed
65 66 67 68
	if (strlen($lastuserid)) {
		$thistime = time();
		$lasttime = qa_opt('mailing_last_timestamp');
		$perminute = qa_opt('mailing_per_minute');
Scott committed
69

Scott committed
70 71 72 73
		if (($lasttime - $thistime) > 60) // if it's been a while, we assume there hasn't been continuous mailing...
			$lasttime = $thistime - 1; // ... so only do 1 second's worth
		else // otherwise...
			$lasttime = max($lasttime, $thistime - 6); // ... don't do more than 6 seconds' worth
Scott committed
74

Scott committed
75
		$count = min(floor(($thistime - $lasttime) * $perminute / 60), 100); // don't do more than 100 messages at a time
Scott committed
76

Scott committed
77 78 79
		if ($count > 0) {
			qa_opt('mailing_last_timestamp', $thistime + 30);
			// prevents a parallel call to qa_mailing_perform_step() from sending messages, unless we're very unlucky with timing (poor man's mutex)
Scott committed
80

Scott committed
81 82
			$sentusers = 0;
			$users = qa_db_users_get_mailing_next($lastuserid, $count);
Scott committed
83

Scott committed
84 85 86 87
			if (count($users)) {
				foreach ($users as $user) {
					$lastuserid = max($lastuserid, $user['userid']);
				}
Scott committed
88

Scott committed
89 90
				qa_opt('mailing_last_userid', $lastuserid);
				qa_opt('mailing_done_users', qa_opt('mailing_done_users') + count($users));
Scott committed
91

Scott committed
92 93 94 95 96 97
				foreach ($users as $user) {
					if (!($user['flags'] & QA_USER_FLAGS_NO_MAILINGS)) {
						qa_mailing_send_one($user['userid'], $user['handle'], $user['email'], $user['emailcode']);
						$sentusers++;
					}
				}
Scott committed
98

Scott committed
99
				qa_opt('mailing_last_timestamp', $lasttime + $sentusers * 60 / $perminute); // can be floating point result, based on number of mails actually sent
Scott committed
100

Scott committed
101 102
			} else
				qa_mailing_stop();
Scott committed
103 104
		}
	}
Scott committed
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
}


/**
 * Send a single message from the mailing, to $userid with $handle and $email.
 * Pass the user's existing $emailcode if there is one, otherwise a new one will be set up
 * @param $userid
 * @param $handle
 * @param $email
 * @param $emailcode
 * @return bool
 */
function qa_mailing_send_one($userid, $handle, $email, $emailcode)
{
	require_once QA_INCLUDE_DIR . 'app/emails.php';
	require_once QA_INCLUDE_DIR . 'db/users.php';

	if (!strlen(trim($emailcode))) {
		$emailcode = qa_db_user_rand_emailcode();
		qa_db_user_set($userid, 'emailcode', $emailcode);
Scott committed
125 126
	}

Scott committed
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
	$unsubscribeurl = qa_path_absolute('unsubscribe', array('c' => $emailcode, 'u' => $handle));

	return qa_send_email(array(
		'fromemail' => qa_opt('mailing_from_email'),
		'fromname' => qa_opt('mailing_from_name'),
		'toemail' => $email,
		'toname' => $handle,
		'subject' => qa_opt('mailing_subject'),
		'body' => trim(qa_opt('mailing_body')) . "\n\n\n" . qa_lang('users/unsubscribe') . ' ' . $unsubscribeurl,
		'html' => false,
	));
}


/**
 * Return a message describing current progress in the mailing
 */
function qa_mailing_progress_message()
{
	require_once QA_INCLUDE_DIR . 'app/format.php';

	if (strlen(qa_opt('mailing_last_userid'))) {
		return strtr(qa_lang('admin/mailing_progress'), array(
			'^1' => qa_format_number(qa_opt('mailing_done_users')),
			'^2' => qa_format_number(qa_opt('mailing_total_users')),
		));
Scott committed
153 154
	}

Scott committed
155 156
	return null;
}