public function index($ar_list_id) { $rows = []; if ($users = Lists::getInstance()->getTargetUsers($ar_list_id)) { foreach ($users as $user) { if ($attributes = $user->attributes()) { unset($attributes['password']); /** @var DateTime $r */ $attributes['created_at'] = $attributes['created_at'] instanceof DateTime ? $attributes['created_at']->format() : ''; $attributes['updated_at'] = $attributes['updated_at'] instanceof DateTime ? $attributes['updated_at']->format() : ''; if ($levels = $user->user_level) { $attributes['levels'] = implode(', ', array_map(function ($level) { return $level->level; }, $levels)); } if (empty($rows)) { $rows[] = array_keys($attributes); } $rows[] = array_values($attributes); } } HttpResponse::getInstance()->sendDownload(sprintf('ar_download_list_%d.csv', $ar_list_id), 'text/csv'); $out = fopen('php://output', 'w'); foreach ($rows as $row) { fputcsv($out, $row); } fclose($out); } else { throw new BasicError("No matching users: List does not contain any users"); } }
public function queueBroadcast() { if ($broadcasts = ArBroadcast::find('all', ['conditions' => 'status = "pending" and send_at <= NOW()'])) { foreach ($broadcasts as $broadcast) { try { $this->updateBroadcastStatus($broadcast, 'processing'); if ($user_ids = Lists::getInstance()->getTargetUserIds($broadcast->ar_list_id)) { if ($mail_id = $broadcast->mail_id) { if ($max_time = ($broadcast->mailing_time ?: 1) * 60 * 60) { $time_offset = 0; $mails_per_sec = min(1, $max_time / count($user_ids)); foreach ($user_ids as $user_id) { try { $send_at = date('Y-m-d H:i:s', time() + floor($time_offset)); if (ArQueue::create_direct(['user_id' => $user_id, 'mail_id' => $mail_id, 'send_at' => $send_at, 'status' => 'pending'])) { $time_offset += $mails_per_sec; } } catch (\Exception $e) { } } } } } } finally { $this->updateBroadcastStatus($broadcast, 'sent'); } } } }
public function getTargetUsers($ar_list_id) { if ($user_ids = Lists::getInstance()->getTargetUserIds($ar_list_id)) { if ($users = @User::find_all_by_user_id($user_ids)) { return is_array($users) ? $users : [$users]; } } return null; }
public function queueEmails() { ArCampaign::$has_many = [['messages', 'foreign_key' => 'ar_campaign_id', 'class_name' => 'ArMessage', 'order' => 'sequence asc']]; if ($autoresponders = ArCampaign::find_all_by_enabled('y')) { $lists = Lists::getInstance(); $ext_mail_id = function ($msg) { return $msg->mail_id ?: 0; }; foreach ($autoresponders as $autoresponder_id => $autoresponder) { if ($messages = $autoresponder->messages) { $mails = $mail_ids = []; foreach ($messages as $message) { if ($mail_id = $message->mail_id) { $mails[$mail_id] = $message; $mail_ids[] = $mail_id; } } if ($user_ids = $lists->getTargetUserIds($autoresponder->ar_list_id)) { $count = 0; printf("Found %d users in list: {$autoresponder->ar_list_id}\n", count($user_ids)); $sql = sprintf('SELECT user_id, MAX(sent_at) AS last_sent, COUNT(user_id) AS total_sent FROM ar_history WHERE user_id IN (%s) AND mail_id IN (%s) ' . 'GROUP BY user_id HAVING ((total_sent = %d) OR (last_sent > DATE_SUB(NOW(), INTERVAL 1 DAY)))', join(',', $user_ids), join(',', $mail_ids), count($messages)); if ($recent_or_full = User::find_by_sql($sql)) { # find all users that have been sent all messages |OR| last mail sent is within 1 day foreach ($recent_or_full as $i_user) { $ignored_user_ids[$i_user->user_id] = 1; } } if ($send_to = !empty($ignored_user_ids) ? array_diff($user_ids, array_keys($ignored_user_ids)) : $user_ids) { foreach ($send_to as $user_id) { $days_since_last_email = 1000; if ($messages_sent = ArHistory::find_all_by_user_id($user_id, ['select' => 'mail_id, sent_at', 'order' => 'sent_at ASC', 'limit' => count($messages)])) { $message_sent_ids = array_map($ext_mail_id, $messages_sent); if ($last_sent = end($messages_sent)) { $days_since_last_email = floor(max(0, time() - $last_sent->sent_at->getTimestamp()) / 86400); } } if ($messages_remaining = !empty($message_sent_ids) ? array_diff($mail_ids, $message_sent_ids) : $mail_ids) { if ($mail_id_to_send = array_shift($messages_remaining)) { try { $wait_days = !empty($message_sent_ids) && !empty($mails[$mail_id_to_send]) ? $mails[$mail_id_to_send]->wait : 0; if ($days_since_last_email >= $wait_days) { $send_at = new DateTime(); if ($schedule = $autoresponder->schedule) { if ($ranges = json_decode($schedule, true)) { $user = User::find_cached($user_id); $timezone = !empty($user->tz_offset) ? timezone_name_from_abbr("", $user->tz_offset * -60, 0) : date_default_timezone_get(); $send_at = $this->getQueueDate($ranges, $timezone) ?: $send_at; } } $sent_at = $send_at->format(Connection::$datetime_format); if (ArHistory::create_direct(['user_id' => $user_id, 'mail_id' => $mail_id_to_send, 'sent_at' => $sent_at])) { $now = new DateTime(); $count = $count + 1; if ($send_at > $now) { echo "Queued mail_id #{$mail_id_to_send} for user_id #{$user_id} at {$sent_at}\n"; ArQueue::create_direct(['send_at' => $sent_at, 'user_id' => $user_id, 'mail_id' => $mail_id_to_send, 'status' => 'pending']); } else { echo "Sending mail_id #{$mail_id_to_send} to user_id #{$user_id} right now\n"; SendMail::getInstance()->send($mail_id_to_send, $user_id); } } } } catch (Exception $e) { App::getInstance()->warn("Unable to send mail: " . $e->getMessage()); } } } } } print "{$count} mails sent\n"; } } } } }