View source
<?php
namespace Drupal\simplenews\Subscription;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\DestructableInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Psr\Log\LoggerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Utility\Token;
use Drupal\simplenews\Entity\Subscriber;
use Drupal\simplenews\Mail\MailerInterface;
use Drupal\simplenews\NewsletterInterface;
use Drupal\simplenews\SubscriberInterface;
class SubscriptionManager implements SubscriptionManagerInterface, DestructableInterface {
protected $combineConfirmations = FALSE;
protected $confirmations = [];
protected $subscribedCache = [];
protected $mailer;
protected $languageManager;
protected $config;
protected $token;
protected $logger;
protected $currentUser;
public function __construct(LanguageManagerInterface $language_manager, ConfigFactoryInterface $config_factory, MailerInterface $mailer, Token $token, LoggerInterface $logger, AccountInterface $current_user) {
$this->languageManager = $language_manager;
$this->config = $config_factory
->get('simplenews.settings');
$this->mailer = $mailer;
$this->token = $token;
$this->logger = $logger;
$this->currentUser = $current_user;
}
public function subscribe($mail, $newsletter_id, $confirm = NULL, $source = 'unknown', $preferred_langcode = NULL) {
$subscriber = simplenews_subscriber_load_by_mail($mail);
if (!$subscriber) {
$account = user_load_by_mail($mail);
if ($this->languageManager
->isMultilingual()) {
if ($account) {
$preferred_langcode = $account
->getPreferredLangcode();
}
else {
$preferred_langcode = isset($preferred_langcode) ? $preferred_langcode : $this->languageManager
->getCurrentLanguage();
}
}
else {
$preferred_langcode = '';
}
$subscriber = Subscriber::create(array());
$subscriber
->setMail($mail);
if ($account) {
$subscriber
->setUserId($account
->id());
}
$subscriber
->setLangcode($preferred_langcode);
$subscriber
->setStatus(SubscriberInterface::ACTIVE);
$subscriber
->save();
}
$newsletter = simplenews_newsletter_load($newsletter_id);
if ($confirm === NULL) {
$confirm = $this
->requiresConfirmation($newsletter, $subscriber
->getUserId());
}
if ($confirm) {
if (!$subscriber
->isSubscribed($newsletter_id)) {
$subscriber
->subscribe($newsletter_id, SIMPLENEWS_SUBSCRIPTION_STATUS_UNCONFIRMED, $source);
$subscriber
->save();
}
$this
->addConfirmation('subscribe', $subscriber, $newsletter);
}
elseif (!$subscriber
->isSubscribed($newsletter_id)) {
$subscriber
->subscribe($newsletter_id, SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED, $source);
$subscriber
->save();
}
return $this;
}
public function unsubscribe($mail, $newsletter_id, $confirm = NULL, $source = 'unknown') {
$subscriber = simplenews_subscriber_load_by_mail($mail);
if (!$subscriber) {
throw new \Exception('The subscriber does not exist.');
}
if (!($newsletter = simplenews_newsletter_load($newsletter_id))) {
$this->logger
->error('Attempt to unsubscribe from non existing mailing list ID %id', array(
'%id' => $newsletter_id,
));
return $this;
}
if ($confirm === NULL) {
$confirm = $this
->requiresConfirmation($newsletter, $subscriber
->getUserId());
}
if ($confirm) {
if (empty($subscriber)) {
$subscriber = Subscriber::create(array());
$subscriber
->setMail($mail);
$subscriber
->save();
}
$this
->addConfirmation('unsubscribe', $subscriber, $newsletter);
}
elseif ($subscriber && $subscriber
->isSubscribed($newsletter_id)) {
$subscriber
->unsubscribe($newsletter_id, $source);
$subscriber
->save();
}
return $this;
}
public function isSubscribed($mail, $newsletter_id) {
if (!isset($this->subscribedCache[$mail][$newsletter_id])) {
$subscriber = simplenews_subscriber_load_by_mail($mail);
$this->subscribedCache[$mail][$newsletter_id] = $subscriber && $subscriber
->getStatus() && $subscriber
->isSubscribed($newsletter_id);
}
return $this->subscribedCache[$mail][$newsletter_id];
}
public function getChangesList(SubscriberInterface $subscriber, $changes = NULL, $langcode = NULL) {
if (empty($langcode)) {
$language = $this->languageManager
->getCurrentLanguage();
$langcode = $language
->getId();
}
if (empty($changes)) {
$changes = $subscriber
->getChanges();
}
$changes_list = array();
foreach ($changes as $newsletter_id => $action) {
$subscribed = $subscriber
->isSubscribed($newsletter_id);
if ($action == 'subscribe' && !$subscribed) {
$line = $this->config
->get('subscription.confirm_combined_line_subscribe_unsubscribed');
}
elseif ($action == 'subscribe' && $subscribed) {
$line = $this->config
->get('subscription.confirm_combined_line_subscribe_subscribed');
}
elseif ($action == 'unsubscribe' && !$subscribed) {
$line = $this->config
->get('subscription.confirm_combined_line_unsubscribe_unsubscribed');
}
elseif ($action == 'unsubscribe' && $subscribed) {
$line = $this->config
->get('subscription.confirm_combined_line_unsubscribe_subscribed');
}
$newsletter_context = array(
'simplenews_subscriber' => $subscriber,
'newsletter' => simplenews_newsletter_load($newsletter_id),
);
$changes_list[$newsletter_id] = $this->token
->replace($line, $newsletter_context, array(
'sanitize' => FALSE,
));
}
return $changes_list;
}
public function sendConfirmations() {
foreach ($this->confirmations as $mail => $changes) {
$subscriber = simplenews_subscriber_load_by_mail($mail);
if (!$subscriber) {
$subscriber = Subscriber::create(array());
$subscriber
->setMail($mail);
$subscriber
->setLangcode($this->languageManager
->getCurrentLanguage());
$subscriber
->save();
}
$subscriber
->setChanges($changes);
$this->mailer
->sendCombinedConfirmation($subscriber);
if ($subscriber && $subscriber
->id()) {
$subscriber
->save();
}
}
$sent = !empty($this->confirmations);
$this->confirmations = array();
return $sent;
}
public function reset() {
$this->subscribedCache = [];
}
public function destruct() {
$this
->sendConfirmations();
}
protected function addConfirmation($action, SubscriberInterface $subscriber, NewsletterInterface $newsletter) {
$this->confirmations[$subscriber
->getMail()][$newsletter
->id()] = $action;
}
protected function requiresConfirmation(NewsletterInterface $newsletter, $uid) {
if ($this->currentUser
->id() && $uid && $this->currentUser
->id() == $uid) {
return FALSE;
}
else {
return $newsletter->opt_inout == 'double';
}
}
}