echo "<label for='newsletter-recipients-csv'>" . elgg_echo("newsletter:recipients:csv") . "</label>"; echo elgg_view("input/file", array("name" => "csv", "id" => "newsletter-recipients-csv")); echo "<div class='elgg-subtext'>" . elgg_echo("newsletter:recipients:csv:description") . "</div>"; echo "</div>"; echo "<div>"; echo "<label for='newsletter-recipients-autocomplete'>" . elgg_echo("newsletter:recipients:recipient") . "</label>"; echo elgg_view("input/text", array("name" => "q", "id" => "newsletter-recipients-autocomplete", "class" => "elgg-input-autocomplete")); echo "<div class='elgg-subtext'>" . elgg_echo("newsletter:recipients:recipient:description") . "</div>"; echo "</div>"; // recipient wrapper // add subscribers $checked = array(); if (!empty($subscribers)) { $checked = array("checked" => "checked"); } $subscriber_count = newsletter_get_subscribers($container, true); $checkboxes = "<div>"; $checkboxes .= elgg_view("input/checkbox", array("name" => "subscribers", "value" => "1", "id" => "newsletter-recipients-subscribers") + $checked); $checkboxes .= "<label for='newsletter-recipients-subscribers'>" . elgg_echo("newsletter:recipients:subscribers") . "<span class='mls'>(" . $subscriber_count . ")</span></label>"; $checkboxes .= "</div>"; // add members $checked = array(); if (!empty($members)) { $checked = array("checked" => "checked"); } $member_count = 0; if (elgg_instanceof($container, "site")) { $options = array("site_guids" => false, "count" => true); $member_count = $container->getMembers($options); $member_count .= " " . elgg_echo("newsletter:recipients:members:site"); } elseif (elgg_instanceof($container, "group")) {
/** * Process the newsletter for a given guid * * @param int $entity_guid guid of the newsletter * * @return void */ function newsletter_process($entity_guid) { $entity_guid = sanitise_int($entity_guid, false); if (!empty($entity_guid)) { // ignore access $ia = elgg_set_ignore_access(true); $entity = get_entity($entity_guid); // is this a Newsletter if (!empty($entity) && elgg_instanceof($entity, "object", Newsletter::SUBTYPE)) { $logging = array("start_time" => time()); $site = elgg_get_site_entity(); $container = $entity->getContainerEntity(); $dbprefix = elgg_get_config("dbprefix"); // ================================ // set newsletter status to sending // ================================ $entity->status = "sending"; $entity->start_time = $logging["start_time"]; // ================== // get the recipients // ================== // basic set of user selection options $basic_user_options = array("type" => "user", "limit" => false, "selects" => array("ue.email"), "joins" => array("JOIN " . $dbprefix . "users_entity ue ON e.guid = ue.guid"), "callback" => "newsletter_user_row_to_subscriber_info"); // include users without settings if (newsletter_include_existing_users()) { // yes, so exclude blocked $basic_user_options["wheres"] = array("(e.guid NOT IN (SELECT guid_one\n\t\t\t\t\t\tFROM " . $dbprefix . "entity_relationships\n\t\t\t\t\t\tWHERE relationship = '" . NewsletterSubscription::GENERAL_BLACKLIST . "'\n\t\t\t\t\t\tAND guid_two = " . $site->getGUID() . ")\n\t\t\t\t\t)", "(e.guid NOT IN (SELECT guid_one\n\t\t\t\t\t\tFROM " . $dbprefix . "entity_relationships\n\t\t\t\t\t\tWHERE relationship = '" . NewsletterSubscription::BLACKLIST . "'\n\t\t\t\t\t\tAND guid_two = " . $container->getGUID() . ")\n\t\t\t\t\t)"); } else { // no, so subscription is required $basic_user_options["wheres"] = array("(e.guid IN (SELECT guid_one\n\t\t\t\t\t\tFROM " . $dbprefix . "entity_relationships\n\t\t\t\t\t\tWHERE relationship = '" . NewsletterSubscription::SUBSCRIPTION . "'\n\t\t\t\t\t\tAND guid_two = " . $container->getGUID() . ")\n\t\t\t\t\t)"); } $filtered_recipients = array("users" => array(), "emails" => array()); $recipients = $entity->getRecipients(); if (empty($recipients)) { // no recipients so report error $entity->status = "sent"; return false; } // recipients is an array consisting of: // - user_guids: individual users // - group_guids: groups to send the content to // - emails: individual email addresses // - subscribers: (int) whether or not to add the subscribers of the container // - members: (int) whether or not to aad the member of the container $user_guids = elgg_extract("user_guids", $recipients); if (!empty($user_guids)) { if (!is_array($user_guids)) { $user_guids = array($user_guids); } // convert to a format we can use $options = $basic_user_options; $options["wheres"][] = "(e.guid IN (" . implode(",", $user_guids) . "))"; $users = elgg_get_entities($options); if (!empty($users)) { $new_users = array(); foreach ($users as $user) { $new_users[$user["guid"]] = $user["email"]; } $filtered_recipients["users"] += $new_users; } } $group_guids = elgg_extract("group_guids", $recipients); if (!empty($group_guids)) { if (!is_array($group_guids)) { $group_guids = array($group_guids); } $options = $basic_user_options; $options["joins"][] = "JOIN " . $dbprefix . "entity_relationships r ON e.guid = r.guid_one"; $options["wheres"][] = "(r.guid_two IN (" . implode(",", $group_guids) . ") AND r.relationship = 'member')"; $users = elgg_get_entities($options); if (!empty($users)) { $new_users = array(); foreach ($users as $user) { $new_users[$user["guid"]] = $user["email"]; } $filtered_recipients["users"] += $new_users; } } $subscribers = elgg_extract("subscribers", $recipients); if (!empty($subscribers)) { $subscribers = newsletter_get_subscribers($container); $filtered_recipients["users"] += $subscribers["users"]; $filtered_recipients["emails"] = array_merge($filtered_recipients["emails"], $subscribers["emails"]); } $members = elgg_extract("members", $recipients); if (!empty($members)) { $relationship = "member"; if (elgg_instanceof($container, "site")) { $relationship = "member_of_site"; } $options = $basic_user_options; $options["relationship"] = $relationship; $options["relationship_guid"] = $container->getGUID(); $options["inverse_relationship"] = true; $users = elgg_get_entities_from_relationship($options); if (!empty($users)) { $new_users = array(); foreach ($users as $user) { $new_users[$user["guid"]] = $user["email"]; } $filtered_recipients["users"] += $new_users; } } $emails = elgg_extract("emails", $recipients); if (!empty($emails)) { if (!is_array($emails)) { $emails = array($emails); } // get blocked users $options = array("type" => "user", "limit" => false, "selects" => array("ue.email"), "joins" => array("JOIN " . $dbprefix . "users_entity ue ON e.guid = ue.guid"), "wheres" => array("(ue.email IN ('" . implode("','", $emails) . "'))", "(e.guid IN (SELECT guid_one\n\t\t\t\t\t\t\tFROM " . $dbprefix . "entity_relationships\n\t\t\t\t\t\t\tWHERE relationship = '" . NewsletterSubscription::GENERAL_BLACKLIST . "'\n\t\t\t\t\t\t\tAND guid_two = " . $site->getGUID() . ")\n\t\t\t\t\t\tOR\n\t\t\t\t\t\te.guid IN (SELECT guid_one\n\t\t\t\t\t\t\tFROM " . $dbprefix . "entity_relationships\n\t\t\t\t\t\t\tWHERE relationship = '" . NewsletterSubscription::BLACKLIST . "'\n\t\t\t\t\t\t\tAND guid_two = " . $container->getGUID() . ")\n\t\t\t\t\t\t)"), "callback" => "newsletter_user_row_to_subscriber_info"); $users = elgg_get_entities($options); if (!empty($users)) { $blocked_emails = array(); foreach ($users as $user) { $blocked_emails[] = $user["email"]; } $emails = array_diff($emails, $blocked_emails); } if (!empty($emails)) { // get blocked emails $options = array("type" => "object", "subtype" => NewsletterSubscription::SUBTYPE, "limit" => false, "selects" => array("oe.title AS email"), "joins" => array("JOIN " . $dbprefix . "objects_entity oe ON e.guid = oe.guid"), "wheres" => array("(oe.title IN ('" . implode("','", $emails) . "'))", "(e.guid IN (SELECT guid_one\n\t\t\t\t\t\t\t\tFROM " . $dbprefix . "entity_relationships\n\t\t\t\t\t\t\t\tWHERE relationship = '" . NewsletterSubscription::GENERAL_BLACKLIST . "'\n\t\t\t\t\t\t\t\tAND guid_two = " . $site->getGUID() . ")\n\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\te.guid IN (SELECT guid_one\n\t\t\t\t\t\t\t\tFROM " . $dbprefix . "entity_relationships\n\t\t\t\t\t\t\t\tWHERE relationship = '" . NewsletterSubscription::BLACKLIST . "'\n\t\t\t\t\t\t\t\tAND guid_two = " . $container->getGUID() . ")\n\t\t\t\t\t\t\t)"), "callback" => "newsletter_user_row_to_subscriber_info"); $subscriptions = elgg_get_entities($options); if (!empty($subscriptions)) { $blocked_emails = array(); foreach ($subscriptions as $subscription) { $blocked_emails[] = $subscription["email"]; } $emails = array_diff($emails, $blocked_emails); } if (!empty($emails)) { $filtered_recipients["emails"] = array_merge($filtered_recipients["emails"], $emails); } } } // ====================== // get newsletter content // ====================== if ($entity->subject) { $message_subject = $entity->subject; } else { $message_subject = elgg_echo("newsletter:subject", array($container->name, $entity->title)); } $message_plaintext_content = elgg_echo("newsletter:plain_message", array(elgg_normalize_url($entity->getURL()))); $message_html_content = elgg_view_layout("newsletter", array("entity" => $entity)); // convert to inline CSS for email clients $message_html_content = html_email_handler_css_inliner($message_html_content); // ======================= // proccess all recipients // ======================= $send_options = array("from" => html_email_handler_make_rfc822_address($container), "subject" => $message_subject, "plaintext_message" => $message_plaintext_content); foreach ($filtered_recipients as $type => $recipients) { if (!empty($recipients)) { foreach ($recipients as $id => $recipient) { $recipient_log = array("type" => $type, "email" => $recipient, "time" => date(DATE_RFC1123), "timestamp" => time(), "status" => false); // ============================================= // create individual footer for unsubscribe link // ============================================= if ($type == "users") { $recipient_log["guid"] = $id; $unsubscribe_link = newsletter_generate_unsubscribe_link($container, $id); } else { $unsubscribe_link = newsletter_generate_unsubscribe_link($container, $recipient); } // place the unsubscribe link in the message $unsubscribe_link = elgg_normalize_url($unsubscribe_link); $message_html_content_user = str_ireplace(urlencode("{unsublink}"), $unsubscribe_link, $message_html_content); // replace the online link for logged out users to add an emailadres if ($type !== "users") { $online_link = $entity->getURL(); $new_online_link = $online_link . "?e=" . $recipient; $message_html_content_user = str_ireplace($online_link, $new_online_link, $message_html_content_user); } // add URL postfix to all internal links $message_html_content_user = newsletter_apply_url_postfix($message_html_content_user); // ========= // send mail // ========= $send_options["to"] = $recipient; $send_options["html_message"] = $message_html_content_user; $recipient_log["status"] = html_email_handler_send_email($send_options); if ($recipient_log["status"] && !empty($recipient_log["guid"])) { $entity->addRelationship($recipient_log["guid"], Newsletter::SEND_TO); } // ============== // add to logging // ============== $logging["recipients"][] = $recipient_log; $entity->saveLogging($logging); } } } $logging["end_time"] = time(); $entity->saveLogging($logging); // ============================= // set newsletter status to done // ============================= $entity->status = "sent"; // ======================== // send status notification // ======================== if (!empty($entity->status_notification) && newsletter_is_email_address($entity->status_notification)) { $from = html_email_handler_make_rfc822_address($site); $subject = elgg_echo("newsletter:status_notification:subject"); $message = elgg_echo("newsletter:status_notification:message", array($entity->title, $entity->getURL())); elgg_send_email($from, $entity->status_notification, $subject, $message); } } // restore access elgg_set_ignore_access($ia); } }
/** * Process the newsletter for a given guid * * @param int $entity_guid guid of the newsletter * * @return void */ function newsletter_process($entity_guid) { $entity_guid = sanitise_int($entity_guid, false); if (empty($entity_guid)) { return; } // ignore access $ia = elgg_set_ignore_access(true); $entity = get_entity($entity_guid); // is this a Newsletter if (!elgg_instanceof($entity, 'object', Newsletter::SUBTYPE)) { elgg_set_ignore_access($ia); return; } $logging = ['start_time' => time()]; $site = elgg_get_site_entity(); $container = $entity->getContainerEntity(); $dbprefix = elgg_get_config('dbprefix'); // set newsletter status to sending $entity->status = 'sending'; $entity->start_time = $logging['start_time']; // get the recipients // basic set of user selection options $basic_user_options = ['type' => 'user', 'limit' => false, 'selects' => ['ue.email'], 'joins' => ['JOIN ' . $dbprefix . 'users_entity ue ON e.guid = ue.guid'], 'callback' => 'newsletter_user_row_to_subscriber_info']; // include users without settings if (newsletter_include_existing_users()) { // yes, so exclude blocked $basic_user_options['wheres'] = ["(e.guid NOT IN (SELECT guid_one\n\t\t\t\tFROM " . $dbprefix . "entity_relationships\n\t\t\t\tWHERE relationship = '" . NewsletterSubscription::GENERAL_BLACKLIST . "'\n\t\t\t\tAND guid_two = " . $site->getGUID() . ")\n\t\t\t)", "(e.guid NOT IN (SELECT guid_one\n\t\t\t\tFROM " . $dbprefix . "entity_relationships\n\t\t\t\tWHERE relationship = '" . NewsletterSubscription::BLACKLIST . "'\n\t\t\t\tAND guid_two = " . $container->getGUID() . ")\n\t\t\t)"]; } else { // no, so subscription is required $basic_user_options['wheres'] = ["(e.guid IN (SELECT guid_one\n\t\t\t\tFROM " . $dbprefix . "entity_relationships\n\t\t\t\tWHERE relationship = '" . NewsletterSubscription::SUBSCRIPTION . "'\n\t\t\t\tAND guid_two = " . $container->getGUID() . ")\n\t\t\t)"]; } $filtered_recipients = ['users' => [], 'emails' => []]; $recipients = $entity->getRecipients(); if (empty($recipients)) { // no recipients so report error $entity->status = 'sent'; return false; } // recipients is an array consisting of: // - user_guids: individual users // - group_guids: groups to send the content to // - emails: individual email addresses // - subscribers: (int) whether or not to add the subscribers of the container // - members: (int) whether or not to aad the member of the container $user_guids = elgg_extract('user_guids', $recipients); if (!empty($user_guids)) { if (!is_array($user_guids)) { $user_guids = [$user_guids]; } // convert to a format we can use $options = $basic_user_options; $options['wheres'][] = '(e.guid IN (' . implode(',', $user_guids) . '))'; $users = elgg_get_entities($options); if (!empty($users)) { $new_users = []; foreach ($users as $user) { $new_users[$user['guid']] = $user['email']; } $filtered_recipients['users'] += $new_users; } } $group_guids = elgg_extract('group_guids', $recipients); if (!empty($group_guids)) { if (!is_array($group_guids)) { $group_guids = [$group_guids]; } $options = $basic_user_options; $options['joins'][] = 'JOIN ' . $dbprefix . 'entity_relationships r ON e.guid = r.guid_one'; $options['wheres'][] = '(r.guid_two IN (' . implode(',', $group_guids) . ') AND r.relationship = "member")'; $users = elgg_get_entities($options); if (!empty($users)) { $new_users = []; foreach ($users as $user) { $new_users[$user['guid']] = $user['email']; } $filtered_recipients['users'] += $new_users; } } $subscribers = elgg_extract('subscribers', $recipients); if (!empty($subscribers)) { $subscribers = newsletter_get_subscribers($container); $filtered_recipients['users'] += $subscribers['users']; $filtered_recipients['emails'] = array_merge($filtered_recipients['emails'], $subscribers['emails']); } $members = elgg_extract('members', $recipients); if (!empty($members)) { $relationship = 'member'; if (elgg_instanceof($container, 'site')) { $relationship = 'member_of_site'; } $options = $basic_user_options; $options['relationship'] = $relationship; $options['relationship_guid'] = $container->getGUID(); $options['inverse_relationship'] = true; $users = elgg_get_entities_from_relationship($options); if (!empty($users)) { $new_users = []; foreach ($users as $user) { $new_users[$user['guid']] = $user['email']; } $filtered_recipients['users'] += $new_users; } } $emails = elgg_extract('emails', $recipients); if (!empty($emails)) { if (!is_array($emails)) { $emails = [$emails]; } // get blocked users $options = ['type' => 'user', 'limit' => false, 'selects' => ['ue.email'], 'joins' => ['JOIN ' . $dbprefix . 'users_entity ue ON e.guid = ue.guid'], 'wheres' => ["(ue.email IN ('" . implode("','", $emails) . "'))", "(e.guid IN (SELECT guid_one\n\t\t\t\t\tFROM " . $dbprefix . "entity_relationships\n\t\t\t\t\tWHERE relationship = '" . NewsletterSubscription::GENERAL_BLACKLIST . "'\n\t\t\t\t\tAND guid_two = " . $site->getGUID() . ")\n\t\t\t\tOR\n\t\t\t\te.guid IN (SELECT guid_one\n\t\t\t\t\tFROM " . $dbprefix . "entity_relationships\n\t\t\t\t\tWHERE relationship = '" . NewsletterSubscription::BLACKLIST . "'\n\t\t\t\t\tAND guid_two = " . $container->getGUID() . ")\n\t\t\t\t)"], 'callback' => 'newsletter_user_row_to_subscriber_info']; $users = elgg_get_entities($options); if (!empty($users)) { $blocked_emails = []; foreach ($users as $user) { $blocked_emails[] = $user['email']; } $emails = array_diff($emails, $blocked_emails); } if (!empty($emails)) { // get blocked emails $options = ['type' => 'object', 'subtype' => NewsletterSubscription::SUBTYPE, 'limit' => false, 'selects' => ['oe.title AS email'], 'joins' => ['JOIN ' . $dbprefix . 'objects_entity oe ON e.guid = oe.guid'], 'wheres' => ["(oe.title IN ('" . implode("','", $emails) . "'))", "(e.guid IN (SELECT guid_one\n\t\t\t\t\t\tFROM " . $dbprefix . "entity_relationships\n\t\t\t\t\t\tWHERE relationship = '" . NewsletterSubscription::GENERAL_BLACKLIST . "'\n\t\t\t\t\t\tAND guid_two = " . $site->getGUID() . ")\n\t\t\t\t\tOR\n\t\t\t\t\te.guid IN (SELECT guid_one\n\t\t\t\t\t\tFROM " . $dbprefix . "entity_relationships\n\t\t\t\t\t\tWHERE relationship = '" . NewsletterSubscription::BLACKLIST . "'\n\t\t\t\t\t\tAND guid_two = " . $container->getGUID() . ")\n\t\t\t\t\t)"], 'callback' => 'newsletter_user_row_to_subscriber_info']; $subscriptions = elgg_get_entities($options); if (!empty($subscriptions)) { $blocked_emails = []; foreach ($subscriptions as $subscription) { $blocked_emails[] = $subscription['email']; } $emails = array_diff($emails, $blocked_emails); } if (!empty($emails)) { $filtered_recipients['emails'] = array_merge($filtered_recipients['emails'], $emails); } } } // get newsletter content if ($entity->subject) { $message_subject = $entity->subject; } else { $message_subject = elgg_echo('newsletter:subject', [$container->name, $entity->title]); } $message_plaintext_content = elgg_echo('newsletter:plain_message', [elgg_normalize_url($entity->getURL())]); $message_html_content = elgg_view_layout('newsletter', ['entity' => $entity]); // convert to inline CSS for email clients $message_html_content = html_email_handler_css_inliner($message_html_content); // proccess all recipients if (newsletter_custom_from_enabled() && !empty($entity->from)) { // from is validated to a valid email address in the newsletter save action $from = $entity->from; } else { // default to the container email address $from = html_email_handler_make_rfc822_address($container); } // set default send options $send_options = ['from' => $from, 'subject' => $message_subject, 'plaintext_message' => $message_plaintext_content]; foreach ($filtered_recipients as $type => $recipients) { if (empty($recipients)) { continue; } foreach ($recipients as $id => $recipient) { $recipient_log = ['type' => $type, 'email' => $recipient, 'time' => date(DATE_RFC1123), 'timestamp' => time(), 'status' => false]; // create individual footer for unsubscribe link if ($type == 'users') { $recipient_log['guid'] = $id; $unsubscribe_link = newsletter_generate_unsubscribe_link($container, $id); } else { $unsubscribe_link = newsletter_generate_unsubscribe_link($container, $recipient); } // place the unsubscribe link in the message $unsubscribe_link = elgg_normalize_url($unsubscribe_link); $message_html_content_user = str_ireplace(urlencode("{unsublink}"), $unsubscribe_link, $message_html_content); // replace the online link for logged out users to add an emailadres if ($type !== 'users') { $online_link = $entity->getURL(); $new_online_link = $online_link . '?e=' . $recipient; $message_html_content_user = str_ireplace($online_link, $new_online_link, $message_html_content_user); } // add URL postfix to all internal links $message_html_content_user = newsletter_apply_url_postfix($message_html_content_user, $entity); // send mail $send_options['to'] = $recipient; $send_options['html_message'] = $message_html_content_user; $recipient_log['status'] = html_email_handler_send_email($send_options); if ($recipient_log['status'] && !empty($recipient_log['guid'])) { $entity->addRelationship($recipient_log['guid'], Newsletter::SEND_TO); } // add to logging $logging['recipients'][] = $recipient_log; $entity->saveLogging($logging); } } $logging['end_time'] = time(); $entity->saveLogging($logging); // set newsletter status to done $entity->status = 'sent'; // send status notification if (newsletter_is_email_address($entity->status_notification)) { $from = html_email_handler_make_rfc822_address($site); $subject = elgg_echo('newsletter:status_notification:subject'); $message = elgg_echo('newsletter:status_notification:message', [$entity->title, $entity->getURL()]); elgg_send_email($from, $entity->status_notification, $subject, $message); } // restore access elgg_set_ignore_access($ia); }