Пример #1
0
 /**
  * {@inheritdoc}
  */
 public function nextMail()
 {
     // Get the current mail spool row and update the internal pointer to the
     // next row.
     $return = each($this->mails);
     // If we're done, return false.
     if (!$return) {
         return FALSE;
     }
     $spool_data = $return['value'];
     // Store this spool row as processed.
     $this->processed[$spool_data->msid] = $spool_data;
     $entity = entity_load($spool_data->entity_type, $spool_data->entity_id);
     if (!$entity) {
         // If the entity load failed, set the processed status done and proceed with
         // the next mail.
         $this->processed[$spool_data->msid]->result = array('status' => SpoolStorageInterface::STATUS_DONE, 'error' => TRUE);
         return $this->nextMail();
     }
     if ($spool_data->data) {
         $subscriber = $spool_data->data;
     } else {
         $subscriber = simplenews_subscriber_load_by_mail($spool_data->mail);
     }
     if (!$subscriber) {
         // If loading the subscriber failed, set the processed status done and
         // proceed with the next mail.
         $this->processed[$spool_data->msid]->result = array('status' => SpoolStorageInterface::STATUS_DONE, 'error' => TRUE);
         return $this->nextMail();
     }
     $mail = new MailEntity($entity, $subscriber, \Drupal::service('simplenews.mail_cache'));
     // Set the langcode langcode.
     $this->processed[$spool_data->msid]->langcode = $mail->getEntity()->language()->getId();
     return $mail;
 }
 /**
  * {@inheritdoc}
  */
 public function submitForm(array &$form, FormStateInterface $form_state)
 {
     $added = array();
     $invalid = array();
     $unsubscribed = array();
     $checked_newsletters = array_keys(array_filter($form_state->getValue('newsletters')));
     $langcode = $form_state->getValue('language');
     $emails = preg_split("/[\\s,]+/", $form_state->getValue('emails'));
     foreach ($emails as $email) {
         $email = trim($email);
         if ($email == '') {
             continue;
         }
         if (valid_email_address($email)) {
             $subscriber = simplenews_subscriber_load_by_mail($email);
             /** @var \Drupal\simplenews\Subscription\SubscriptionManagerInterface $subscription_manager */
             $subscription_manager = \Drupal::service('simplenews.subscription_manager');
             foreach (simplenews_newsletter_load_multiple($checked_newsletters) as $newsletter) {
                 // If there is a valid subscriber, check if there is a subscription for
                 // the current newsletter and if this subscription has the status
                 // unsubscribed.
                 $is_unsubscribed = $subscriber ? $subscriber->isUnsubscribed($newsletter->id()) : FALSE;
                 if (!$is_unsubscribed || $form_state->getValue('resubscribe') == TRUE) {
                     $subscription_manager->subscribe($email, $newsletter->id(), FALSE, 'mass subscribe', $langcode);
                     $added[] = $email;
                 } else {
                     $unsubscribed[$newsletter->label()][] = $email;
                 }
             }
         } else {
             $invalid[] = $email;
         }
     }
     if ($added) {
         $added = implode(", ", $added);
         drupal_set_message(t('The following addresses were added or updated: %added.', array('%added' => $added)));
         $list_names = array();
         foreach (simplenews_newsletter_load_multiple($checked_newsletters) as $newsletter) {
             $list_names[] = $newsletter->label();
         }
         drupal_set_message(t('The addresses were subscribed to the following newsletters: %newsletters.', array('%newsletters' => implode(', ', $list_names))));
     } else {
         drupal_set_message(t('No addresses were added.'));
     }
     if ($invalid) {
         $invalid = implode(", ", $invalid);
         drupal_set_message(t('The following addresses were invalid: %invalid.', array('%invalid' => $invalid)), 'error');
     }
     foreach ($unsubscribed as $name => $subscribers) {
         $subscribers = implode(", ", $subscribers);
         drupal_set_message(t('The following addresses were skipped because they have previously unsubscribed from %name: %unsubscribed.', array('%name' => $name, '%unsubscribed' => $subscribers)), 'warning');
     }
     if (!empty($unsubscribed)) {
         drupal_set_message(t("If you would like to resubscribe them, use the 'Force resubscription' option."), 'warning');
     }
     // Return to the parent page.
     $form_state->setRedirect('view.simplenews_subscribers.page_1');
 }
 /**
  * {@inheritdoc}
  */
 public function getMails($limit = self::UNLIMITED, $conditions = array())
 {
     $messages = array();
     // Continue to support 'nid' as a condition.
     if (!empty($conditions['nid'])) {
         $conditions['entity_type'] = 'node';
         $conditions['entity_id'] = $conditions['nid'];
         unset($conditions['nid']);
     }
     // Add default status condition if not set.
     if (!isset($conditions['status'])) {
         $conditions['status'] = array(SpoolStorageInterface::STATUS_PENDING, SpoolStorageInterface::STATUS_IN_PROGRESS);
     }
     // Special case for the status condition, the in progress actually only
     // includes spool items whose locking time has expired. So this need to build
     // an OR condition for them.
     $status_or = new Condition('OR');
     $statuses = is_array($conditions['status']) ? $conditions['status'] : array($conditions['status']);
     foreach ($statuses as $status) {
         if ($status == SpoolStorageInterface::STATUS_IN_PROGRESS) {
             $status_or->condition((new Condition('AND'))->condition('status', $status)->condition('s.timestamp', $this->getExpirationTime(), '<'));
         } else {
             $status_or->condition('status', $status);
         }
     }
     unset($conditions['status']);
     $query = $this->connection->select('simplenews_mail_spool', 's')->fields('s')->condition($status_or)->orderBy('s.timestamp', 'ASC');
     // Add conditions.
     foreach ($conditions as $field => $value) {
         $query->condition($field, $value);
     }
     /* BEGIN CRITICAL SECTION */
     // The semaphore ensures that multiple processes get different message ID's,
     // so that duplicate messages are not sent.
     if ($this->lock->acquire('simplenews_acquire_mail')) {
         // Get message id's
         // Allocate messages
         if ($limit > 0) {
             $query->range(0, $limit);
         }
         foreach ($query->execute() as $message) {
             if (Unicode::strlen($message->data)) {
                 $message->data = unserialize($message->data);
             } else {
                 $message->data = simplenews_subscriber_load_by_mail($message->mail);
             }
             $messages[$message->msid] = $message;
         }
         if (count($messages) > 0) {
             // Set the state and the timestamp of the messages
             $this->updateMails(array_keys($messages), array('status' => SpoolStorageInterface::STATUS_IN_PROGRESS));
         }
         $this->lock->release('simplenews_acquire_mail');
     }
     /* END CRITICAL SECTION */
     return new SpoolList($messages);
 }
 /**
  * {@inheritdoc}
  */
 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);
         // Save the changes in the subscriber if there is a real subscriber object.
         if ($subscriber && $subscriber->id()) {
             $subscriber->save();
         }
     }
     $sent = !empty($this->confirmations);
     $this->confirmations = array();
     return $sent;
 }
 /**
  * testSubscribeAuthenticated
  *
  * Steps performed:
  *   0. Preparation
  *   1. Subscribe authenticated via block
  *   2. Unsubscribe authenticated via subscription page
  *   3. Subscribe authenticated via subscription page
  *   4. Unsubscribe authenticated via account page
  *   5. Subscribe authenticated via account page
  *   6. Subscribe authenticated via multi block
  */
 function testSubscribeAuthenticated()
 {
     // 0. Preparation
     // Login admin
     // Set permission for anonymous to subscribe
     // Enable newsletter block
     // Logout admin
     // Login Subscriber
     $admin_user = $this->drupalCreateUser(array('administer blocks', 'administer content types', 'administer nodes', 'access administration pages', 'administer permissions', 'administer newsletters'));
     $this->drupalLogin($admin_user);
     // Create some newsletters for multi-sign up block.
     $this->drupalGet('admin/config/services/simplenews');
     for ($i = 0; $i < 5; $i++) {
         $this->clickLink(t('Add newsletter'));
         $name = $this->randomMachineName();
         $edit = array('name' => $name, 'id' => strtolower($name), 'description' => $this->randomString(20), 'opt_inout' => 'double');
         $this->drupalPostForm(NULL, $edit, t('Save'));
     }
     $newsletter_id = $this->getRandomNewsletter();
     $this->drupalLogout();
     // Setup subscription block with subscription form.
     $block_settings = array('newsletters' => array($newsletter_id), 'message' => $this->randomMachineName(4));
     $single_block = $this->setupSubscriptionBlock($block_settings);
     $subscriber_user = $this->drupalCreateUser(array('subscribe to newsletters'));
     $this->drupalLogin($subscriber_user);
     // 1. Subscribe authenticated via block
     // Subscribe + submit
     // Assert confirmation message
     $this->drupalPostForm(NULL, [], t('Subscribe'));
     $this->assertText(t('You have been subscribed.'), t('Authenticated user subscribed using the subscription block.'));
     // 2. Unsubscribe authenticated via subscription page
     // Unsubscribe + submit
     // Assert confirmation message
     $edit = array("subscriptions[{$newsletter_id}]" => 0);
     $this->drupalPostForm('newsletter/subscriptions', $edit, t('Update'));
     $this->assertRaw(t('The newsletter subscriptions for %mail have been updated.', array('%mail' => $subscriber_user->getEmail())), t('Authenticated user unsubscribed on the subscriptions page.'));
     // 3. Subscribe authenticated via subscription page
     // Subscribe + submit
     // Assert confirmation message
     $edit = array("subscriptions[{$newsletter_id}]" => '1');
     $this->drupalPostForm('newsletter/subscriptions', $edit, t('Update'));
     $this->assertRaw(t('The newsletter subscriptions for %mail have been updated.', array('%mail' => $subscriber_user->getEmail())), t('Authenticated user subscribed on the subscriptions page.'));
     // 4. Unsubscribe authenticated via account page
     // Unsubscribe + submit
     // Assert confirmation message
     $edit = array("subscriptions[{$newsletter_id}]" => FALSE);
     $url = 'user/' . $subscriber_user->id() . '/simplenews';
     $this->drupalPostForm($url, $edit, t('Save'));
     $this->assertRaw(t('Your newsletter subscriptions have been updated.', array('%mail' => $subscriber_user->getEmail())), t('Authenticated user unsubscribed on the account page.'));
     $subscriber = simplenews_subscriber_load_by_mail($subscriber_user->getEmail());
     $subscription = $subscriber->getSubscription($newsletter_id);
     $this->assertEqual(SIMPLENEWS_SUBSCRIPTION_STATUS_UNSUBSCRIBED, $subscription->status, t('Subscription is unsubscribed'));
     // 5. Subscribe authenticated via account page
     // Subscribe + submit
     // Assert confirmation message
     $edit = array("subscriptions[{$newsletter_id}]" => '1');
     $url = 'user/' . $subscriber_user->id() . '/simplenews';
     $this->drupalPostForm($url, $edit, t('Save'));
     $this->assertRaw(t('Your newsletter subscriptions have been updated.', array('%mail' => $subscriber_user->getEmail())), t('Authenticated user unsubscribed on the account page.'));
     // Disable the newsletter block.
     $single_block->delete();
     // Setup subscription block with subscription form.
     $block_settings = array('newsletters' => array_keys(simplenews_newsletter_get_all()), 'message' => $this->randomMachineName(4));
     $multi_block = $this->setupSubscriptionBlock($block_settings);
     // Try to submit multi-signup form without selecting a newsletter.
     $subscriber_user2 = $this->drupalCreateUser(array('subscribe to newsletters'));
     $this->drupalLogin($subscriber_user2);
     // Check that the user has only access to his own subscriptions page.
     $this->drupalGet('user/' . $subscriber_user->id() . '/simplenews');
     $this->assertResponse(403);
     $this->drupalGet('user/' . $subscriber_user2->id() . '/simplenews');
     $this->assertResponse(200);
     $this->assertNoField('mail[0][value]');
     $this->drupalPostForm(NULL, array(), t('Update'));
     $this->assertText(t('The newsletter subscriptions for @mail have been updated.', array('@mail' => $subscriber_user2->getEmail())));
     // Nothing should have happened.
     $this->assertNoFieldChecked('edit-subscriptions-' . $newsletter_id);
     // Now fill out the form and try again.
     $edit = array('subscriptions[' . $newsletter_id . ']' => TRUE);
     $this->drupalPostForm(NULL, $edit, t('Update'));
     $this->assertText(t('The newsletter subscriptions for @mail have been updated.', array('@mail' => $subscriber_user2->getEmail())));
     $this->assertFieldChecked('edit-subscriptions-' . $newsletter_id);
     // Unsubscribe.
     $edit = array('subscriptions[' . $newsletter_id . ']' => FALSE);
     $this->drupalPostForm(NULL, $edit, t('Update'));
     $this->assertText(t('The newsletter subscriptions for @mail have been updated.', array('@mail' => $subscriber_user2->getEmail())));
     $this->assertNoFieldChecked('edit-subscriptions-' . $newsletter_id);
     // And now the same for the newsletter/subscriptions page.
     $subscriber_user3 = $this->drupalCreateUser(array('subscribe to newsletters'));
     $this->drupalLogin($subscriber_user3);
     $this->assertNoField('mail[0][value]');
     $this->drupalPostForm('newsletter/subscriptions', array(), t('Update'));
     $this->assertText(t('The newsletter subscriptions for @mail have been updated.', array('@mail' => $subscriber_user3->getEmail())));
     // Nothing should have happened.
     $this->assertNoFieldChecked('edit-subscriptions-' . $newsletter_id);
     // Now fill out the form and try again.
     $edit = array('subscriptions[' . $newsletter_id . ']' => TRUE);
     $this->drupalPostForm('newsletter/subscriptions', $edit, t('Update'));
     $this->assertText(t('The newsletter subscriptions for @mail have been updated.', array('@mail' => $subscriber_user3->getEmail())));
     $this->assertFieldChecked('edit-subscriptions-' . $newsletter_id);
     // Unsubscribe.
     $edit = array('subscriptions[' . $newsletter_id . ']' => FALSE);
     $this->drupalPostForm('newsletter/subscriptions', $edit, t('Update'));
     $this->assertText(t('The newsletter subscriptions for @mail have been updated.', array('@mail' => $subscriber_user3->getEmail())));
     $this->assertNoFieldChecked('edit-subscriptions-' . $newsletter_id);
 }
 /**
  * {@inheritdoc}
  */
 public function submitForm(array &$form, FormStateInterface $form_state)
 {
     // Subclasses try to load an existing subscriber in different ways in
     // buildForm. For anonymous user the email is unknown in buildForm, but here
     // we can try again to load an existing subscriber.
     $mail = $form_state->getValue(array('mail', 0, 'value'));
     if ($this->entity->isNew() && isset($mail) && ($subscriber = simplenews_subscriber_load_by_mail($mail))) {
         $this->setEntity($subscriber);
     }
     parent::submitForm($form, $form_state);
 }
 /**
  * Test with disabled caching.
  */
 function testSendMissingSubscriber()
 {
     $this->setUpSubscribers(1);
     $edit = array('title[0][value]' => $this->randomString(10), 'body[0][value]' => "Mail token: <strong>[simplenews-subscriber:mail]</strong>", 'simplenews_issue' => 'default');
     $this->drupalPostForm('node/add/simplenews_issue', $edit, 'Save and publish');
     $this->assertTrue(preg_match('|node/(\\d+)$|', $this->getUrl(), $matches), 'Node created');
     $node = Node::load($matches[1]);
     // Add node to spool.
     \Drupal::service('simplenews.spool_storage')->addFromEntity($node);
     // Delete the subscriber.
     $subscriber = simplenews_subscriber_load_by_mail(reset($this->subscribers));
     $subscriber->delete();
     \Drupal::service('simplenews.mailer')->sendSpool();
     // Make sure that no mails have been sent.
     $this->assertEqual(0, count($this->drupalGetMails()));
     $spool_row = db_query('SELECT * FROM {simplenews_mail_spool}')->fetchObject();
     $this->assertEqual(SpoolStorageInterface::STATUS_DONE, $spool_row->status);
 }
Пример #8
0
 /**
  * {@inheritdoc}
  */
 public function sendTest(NodeInterface $node, array $test_addresses)
 {
     // Force the current user to anonymous to ensure consistent permissions.
     $this->accountSwitcher->switchTo(new AnonymousUserSession());
     // Send the test newsletter to the test address(es) specified in the node.
     // Build array of test email addresses.
     // Send newsletter to test addresses.
     // Emails are send direct, not using the spool.
     $recipients = array('anonymous' => array(), 'user' => array());
     foreach ($test_addresses as $mail) {
         $mail = trim($mail);
         if (!empty($mail)) {
             $subscriber = simplenews_subscriber_load_by_mail($mail);
             if (!$subscriber) {
                 // @todo: Find a cleaner way to do this.
                 $subscriber = Subscriber::create(array());
                 $subscriber->setUserId(0);
                 $subscriber->setMail($mail);
                 $subscriber->setLangcode(\Drupal::languageManager()->getCurrentLanguage());
             }
             if ($subscriber->getUserId()) {
                 $account = $subscriber->uid->entity;
                 $recipients['user'][] = $account->getUserName() . ' <' . $mail . '>';
             } else {
                 $recipients['anonymous'][] = $mail;
             }
             $mail = new MailEntity($node, $subscriber, \Drupal::service('simplenews.mail_cache'));
             $mail->setKey('test');
             $this->sendMail($mail);
         }
     }
     if (count($recipients['user'])) {
         $recipients_txt = implode(', ', $recipients['user']);
         drupal_set_message(t('Test newsletter sent to user %recipient.', array('%recipient' => $recipients_txt)));
     }
     if (count($recipients['anonymous'])) {
         $recipients_txt = implode(', ', $recipients['anonymous']);
         drupal_set_message(t('Test newsletter sent to anonymous %recipient.', array('%recipient' => $recipients_txt)));
     }
     $this->accountSwitcher->switchBack();
 }
 /**
  * Test newsletter subscription management.
  *
  * Steps performed:
  */
 function testSubscriptionManagement()
 {
     $admin_user = $this->drupalCreateUser(array('administer newsletters', 'administer simplenews settings', 'administer simplenews subscriptions', 'administer users'));
     $this->drupalLogin($admin_user);
     // Create a newsletter.
     $newsletter_name = Unicode::strtolower($this->randomMachineName());
     $edit = array('name' => $newsletter_name, 'id' => $newsletter_name);
     $this->drupalPostForm('admin/config/services/simplenews/add', $edit, t('Save'));
     // Add a number of users to each newsletter separately and then add another
     // bunch to both.
     $subscribers = array();
     $groups = array();
     $newsletters = simplenews_newsletter_get_all();
     foreach ($newsletters as $newsletter) {
         $groups[$newsletter->id()] = array($newsletter->id());
     }
     $groups['all'] = array_keys($groups);
     $subscribers_flat = array();
     foreach ($groups as $key => $group) {
         for ($i = 0; $i < 5; $i++) {
             $mail = $this->randomEmail();
             $subscribers[$key][$mail] = $mail;
             $subscribers_flat[$mail] = $mail;
         }
     }
     // Create a user and assign him one of the mail addresses of the all group.
     $user = $this->drupalCreateUser(array('subscribe to newsletters'));
     // Make sure that user_save() does not update the user object, as it will
     // override the pass_raw property which we'll need to log this user in
     // later on.
     $user_mail = current($subscribers['all']);
     $user->setEmail($user_mail);
     $user->save();
     $delimiters = array(',', ' ', "\n");
     // Visit subscribers by clicking menu tab in people.
     $this->drupalGet('admin/people');
     $this->clickLink('Subscribers');
     $i = 0;
     foreach ($groups as $key => $group) {
         $this->clickLink(t('Mass subscribe'));
         $edit = array('emails' => implode($delimiters[$i++], $subscribers[$key]));
         foreach ($group as $newsletter_id) {
             $edit['newsletters[' . $newsletter_id . ']'] = TRUE;
         }
         $this->drupalPostForm(NULL, $edit, t('Subscribe'));
     }
     // The user to which the mail was assigned should be listed too.
     $this->assertText($user->label());
     // Verify that all addresses are displayed in the table.
     $rows = $this->xpath('//tbody/tr');
     $mail_addresses = array();
     for ($i = 0; $i < count($subscribers_flat); $i++) {
         $mail_addresses[] = trim((string) $rows[$i]->td[0]);
     }
     $this->assertEqual(15, count($mail_addresses));
     foreach ($mail_addresses as $mail_address) {
         $mail_address = (string) $mail_address;
         $this->assertTrue(isset($subscribers_flat[$mail_address]));
         unset($subscribers_flat[$mail_address]);
     }
     // All entries of the array should be removed by now.
     $this->assertTrue(empty($subscribers_flat));
     reset($groups);
     $first = 'default';
     $first_mail = array_rand($subscribers[$first]);
     $all_mail = array_rand($subscribers['all']);
     // Limit list to subscribers of the first newsletter only.
     // Build a flat list of the subscribers of this list.
     $subscribers_flat = array_merge($subscribers[$first], $subscribers['all']);
     $this->drupalGet('admin/people/simplenews', array('query' => array('subscriptions_target_id' => $first)));
     // Verify that all addresses are displayed in the table.
     $rows = $this->xpath('//tbody/tr');
     $mail_addresses = array();
     for ($i = 0; $i < count($subscribers_flat); $i++) {
         $mail_addresses[] = trim((string) $rows[$i]->td[0]);
     }
     $this->assertEqual(10, count($mail_addresses));
     foreach ($mail_addresses as $mail_address) {
         $mail_address = (string) $mail_address;
         $this->assertTrue(isset($subscribers_flat[$mail_address]));
         unset($subscribers_flat[$mail_address]);
     }
     // All entries of the array should be removed by now.
     $this->assertTrue(empty($subscribers_flat));
     // Filter a single mail address, the one assigned to a user.
     $edit = array('mail' => Unicode::substr(current($subscribers['all']), 0, 4));
     $this->drupalGet('admin/people/simplenews', array('query' => array('mail' => $edit['mail'])));
     $rows = $this->xpath('//tbody/tr');
     $this->assertEqual(1, count($rows));
     $this->assertEqual(current($subscribers['all']), trim((string) $rows[0]->td[0]));
     $this->assertEqual($user->label(), trim((string) $rows[0]->td[1]->span));
     // Reset the filter.
     $this->drupalGet('admin/people/simplenews');
     // Test mass-unsubscribe, unsubscribe one from the first group and one from
     // the all group, but only from the first newsletter.
     unset($subscribers[$first][$first_mail]);
     $edit = array('emails' => $first_mail . ', ' . $all_mail, 'newsletters[' . $first . ']' => TRUE);
     $this->clickLink(t('Mass unsubscribe'));
     $this->drupalPostForm(NULL, $edit, t('Unsubscribe'));
     // The all mail is still displayed because it's still subscribed to the
     // second newsletter. Reload the page to get rid of the confirmation
     // message.
     $this->drupalGet('admin/people/simplenews');
     $this->assertNoText($first_mail);
     $this->assertText($all_mail);
     // Limit to first newsletter, the all mail shouldn't be shown anymore.
     $this->drupalGet('admin/people/simplenews', array('query' => array('subscriptions_target_id' => $first)));
     $this->assertNoText($first_mail);
     $this->assertNoText($all_mail);
     // Check exporting.
     $this->clickLink(t('Export'));
     $this->drupalPostForm(NULL, array('newsletters[' . $first . ']' => TRUE), t('Export'));
     $export_field = $this->xpath($this->constructFieldXpath('name', 'emails'));
     $exported_mails = (string) $export_field[0];
     foreach ($subscribers[$first] as $mail) {
         $this->assertTrue(strpos($exported_mails, $mail) !== FALSE, t('Mail address exported correctly.'));
     }
     foreach ($subscribers['all'] as $mail) {
         if ($mail != $all_mail) {
             $this->assertTrue(strpos($exported_mails, $mail) !== FALSE, t('Mail address exported correctly.'));
         } else {
             $this->assertFALSE(strpos($exported_mails, $mail) !== FALSE, t('Unsubscribed mail address not exported.'));
         }
     }
     // Only export unsubscribed mail addresses.
     $edit = array('subscribed[subscribed]' => FALSE, 'subscribed[unsubscribed]' => TRUE, 'newsletters[' . $first . ']' => TRUE);
     $this->drupalPostForm(NULL, $edit, t('Export'));
     $export_field = $this->xpath($this->constructFieldXpath('name', 'emails'));
     $exported_mails = (string) $export_field[0];
     $exported_mails = explode(', ', $exported_mails);
     $this->assertEqual(2, count($exported_mails));
     $this->assertTrue(in_array($all_mail, $exported_mails));
     $this->assertTrue(in_array($first_mail, $exported_mails));
     /** @var \Drupal\simplenews\Subscription\SubscriptionManagerInterface $subscription_manager */
     $subscription_manager = \Drupal::service('simplenews.subscription_manager');
     // Make sure there are unconfirmed subscriptions.
     $unconfirmed = array();
     $unconfirmed[] = $this->randomEmail();
     $unconfirmed[] = $this->randomEmail();
     foreach ($unconfirmed as $mail) {
         $subscription_manager->subscribe($mail, $first, TRUE);
     }
     // Only export unconfirmed mail addresses.
     $edit = array('subscribed[subscribed]' => FALSE, 'subscribed[unconfirmed]' => TRUE, 'subscribed[unsubscribed]' => FALSE, 'newsletters[' . $first . ']' => TRUE);
     $this->drupalPostForm(NULL, $edit, t('Export'));
     $export_field = $this->xpath($this->constructFieldXpath('name', 'emails'));
     $exported_mails = (string) $export_field[0];
     $exported_mails = explode(', ', $exported_mails);
     $this->assertEqual(2, count($exported_mails));
     $this->assertTrue(in_array($unconfirmed[0], $exported_mails));
     $this->assertTrue(in_array($unconfirmed[1], $exported_mails));
     // Make sure the user is subscribed to the first newsletter_id.
     $subscription_manager->subscribe($user_mail, $first, FALSE);
     $before_count = simplenews_count_subscriptions($first);
     // Block the user.
     $user->block();
     $user->save();
     $this->drupalGet('admin/people/simplenews');
     // Verify updated subscriptions count.
     drupal_static_reset('simplenews_count_subscriptions');
     $after_count = simplenews_count_subscriptions($first);
     $this->assertEqual($before_count - 1, $after_count, t('Blocked users are not counted in subscription count.'));
     // Test mass subscribe with previously unsubscribed users.
     for ($i = 0; $i < 3; $i++) {
         $tested_subscribers[] = $this->randomEmail();
     }
     $subscription_manager->subscribe($tested_subscribers[0], $first, FALSE);
     $subscription_manager->subscribe($tested_subscribers[1], $first, FALSE);
     $subscription_manager->unsubscribe($tested_subscribers[0], $first, FALSE);
     $subscription_manager->unsubscribe($tested_subscribers[1], $first, FALSE);
     $unsubscribed = implode(', ', array_slice($tested_subscribers, 0, 2));
     $edit = array('emails' => implode(', ', $tested_subscribers), 'newsletters[' . $first . ']' => TRUE);
     $this->drupalPostForm('admin/people/simplenews/import', $edit, t('Subscribe'));
     \Drupal::entityManager()->getStorage('simplenews_subscriber')->resetCache();
     $subscription_manager->reset();
     $this->assertFalse($subscription_manager->isSubscribed($tested_subscribers[0], $first), t('Subscriber not resubscribed through mass subscription.'));
     $this->assertFalse($subscription_manager->isSubscribed($tested_subscribers[1], $first), t('Subscriber not resubscribed through mass subscription.'));
     $this->assertTrue($subscription_manager->isSubscribed($tested_subscribers[2], $first), t('Subscriber subscribed through mass subscription.'));
     $substitutes = array('@name' => SafeMarkup::checkPlain(simplenews_newsletter_load($first)->label()), '@mail' => $unsubscribed);
     $this->assertText(t('The following addresses were skipped because they have previously unsubscribed from @name: @mail.', $substitutes));
     $this->assertText(t("If you would like to resubscribe them, use the 'Force resubscription' option."));
     // Try to mass subscribe without specifying newsletters.
     $tested_subscribers[2] = $this->randomEmail();
     $edit = array('emails' => implode(', ', $tested_subscribers), 'resubscribe' => TRUE);
     $this->drupalPostForm('admin/people/simplenews/import', $edit, t('Subscribe'));
     $this->assertText('Subscribe to field is required.');
     // Test mass subscribe with previously unsubscribed users and force
     // resubscription.
     $tested_subscribers[2] = $this->randomEmail();
     $edit = array('emails' => implode(', ', $tested_subscribers), 'newsletters[' . $first . ']' => TRUE, 'resubscribe' => TRUE);
     $this->drupalPostForm('admin/people/simplenews/import', $edit, t('Subscribe'));
     $subscription_manager->reset();
     \Drupal::entityManager()->getStorage('simplenews_subscriber')->resetCache();
     $this->assertTrue($subscription_manager->isSubscribed($tested_subscribers[0], $first, t('Subscriber resubscribed trough mass subscription.')));
     $this->assertTrue($subscription_manager->isSubscribed($tested_subscribers[1], $first, t('Subscriber resubscribed trough mass subscription.')));
     $this->assertTrue($subscription_manager->isSubscribed($tested_subscribers[2], $first, t('Subscriber subscribed trough mass subscription.')));
     // Try to mass unsubscribe without specifying newsletters.
     $tested_subscribers[2] = $this->randomEmail();
     $edit = array('emails' => implode(', ', $tested_subscribers));
     $this->drupalPostForm('admin/people/simplenews/unsubscribe', $edit, t('Unsubscribe'));
     $this->assertText('Unsubscribe from field is required.');
     // Create two blocks, to ensure that they are updated/deleted when a
     // newsletter is deleted.
     $only_first_block = $this->setupSubscriptionBlock(['newsletters' => [$first]]);
     $all_block = $this->setupSubscriptionBlock(['newsletters' => array_keys($groups)]);
     $enabled_newsletters = $all_block->get('settings')['newsletters'];
     $this->assertTrue(in_array($first, $enabled_newsletters));
     // Delete newsletter.
     \Drupal::entityManager()->getStorage('simplenews_newsletter')->resetCache();
     $this->drupalGet('admin/config/services/simplenews/manage/' . $first);
     $this->clickLink(t('Delete'));
     $this->drupalPostForm(NULL, array(), t('Delete'));
     $this->assertText(t('All subscriptions to newsletter @newsletter have been deleted.', array('@newsletter' => $newsletters[$first]->name)));
     // Verify that all related data has been deleted/updated.
     $this->assertNull(Newsletter::load($first));
     $this->assertNull(Block::load($only_first_block->id()));
     $all_block = Block::load($all_block->id());
     $enabled_newsletters = $all_block->get('settings')['newsletters'];
     $this->assertFalse(in_array($first, $enabled_newsletters));
     // Verify that all subscriptions of that newsletter have been removed.
     $this->drupalGet('admin/people/simplenews');
     foreach ($subscribers[$first] as $mail) {
         $this->assertNoText($mail);
     }
     $this->clickLink(t('Edit'), 1);
     // Get the subscriber id from the path.
     $this->assertTrue(preg_match('|admin/people/simplenews/edit/(\\d+)\\?destination|', $this->getUrl(), $matches), 'Subscriber found');
     $subscriber = Subscriber::load($matches[1]);
     $this->assertTitle(t('Edit subscriber @mail', array('@mail' => $subscriber->getMail())) . ' | Drupal');
     $this->assertFieldChecked('edit-status');
     // Disable account.
     $edit = array('status' => FALSE);
     $this->drupalPostForm(NULL, $edit, t('Save'));
     \Drupal::entityManager()->getStorage('simplenews_subscriber')->resetCache();
     $subscription_manager->reset();
     $this->assertFalse($subscription_manager->isSubscribed($subscriber->getMail(), $this->getRandomNewsletter()), t('Subscriber is not active'));
     // Re-enable account.
     $this->drupalGet('admin/people/simplenews/edit/' . $subscriber->id());
     $this->assertTitle(t('Edit subscriber @mail', array('@mail' => $subscriber->getMail())) . ' | Drupal');
     $this->assertNoFieldChecked('edit-status');
     $edit = array('status' => TRUE);
     $this->drupalPostForm(NULL, $edit, t('Save'));
     \Drupal::entityManager()->getStorage('simplenews_subscriber')->resetCache();
     $subscription_manager->reset();
     $this->assertTrue($subscription_manager->isSubscribed($subscriber->getMail(), $this->getRandomNewsletter()), t('Subscriber is active again.'));
     // Remove the newsletter.
     $this->drupalGet('admin/people/simplenews/edit/' . $subscriber->id());
     $this->assertTitle(t('Edit subscriber @mail', array('@mail' => $subscriber->getMail())) . ' | Drupal');
     \Drupal::entityManager()->getStorage('simplenews_subscriber')->resetCache();
     $subscriber = Subscriber::load($subscriber->id());
     $nlids = $subscriber->getSubscribedNewsletterIds();
     // If the subscriber still has subscribed to newsletter, try to unsubscribe.
     $newsletter_id = reset($nlids);
     $edit['subscriptions[' . $newsletter_id . ']'] = FALSE;
     $this->drupalPostForm(NULL, $edit, t('Save'));
     \Drupal::entityManager()->getStorage('simplenews_subscriber')->resetCache();
     $subscription_manager->reset();
     $nlids = $subscriber->getSubscribedNewsletterIds();
     $this->assertFalse($subscription_manager->isSubscribed($subscriber->getMail(), reset($nlids)), t('Subscriber not subscribed anymore.'));
     // @todo Test Admin subscriber edit preferred language $subscription->language
     // Register a subscriber with an insecure e-mail address through the API
     // and make sure the address is correctly encoded.
     $xss_mail = "<script>alert('XSS');</script>";
     $subscription_manager->subscribe($xss_mail, $this->getRandomNewsletter(), FALSE);
     $this->drupalGet('admin/people/simplenews');
     $this->assertNoRaw($xss_mail);
     $this->assertRaw(SafeMarkup::checkPlain($xss_mail));
     $xss_subscriber = simplenews_subscriber_load_by_mail($xss_mail);
     $this->drupalGet('admin/people/simplenews/edit/' . $xss_subscriber->id());
     $this->assertNoRaw($xss_mail);
     $this->assertRaw(SafeMarkup::checkPlain($xss_mail));
     // Create a new user for the next test.
     $new_user = $this->drupalCreateUser(array('subscribe to newsletters'));
     // Test for saving the subscription for no newsletter.
     $this->drupalPostForm('user/' . $new_user->id() . '/simplenews', null, t('Save'));
     $this->assertText('The newsletter subscriptions for user ' . $new_user->getUsername() . ' have been updated.');
     // Editing a subscriber with subscription.
     $edit = array('subscriptions[' . $newsletter_name . ']' => TRUE, 'status' => TRUE, 'mail[0][value]' => '*****@*****.**');
     $this->drupalPostForm('admin/people/simplenews/edit/' . $xss_subscriber->id(), $edit, t('Save'));
     $this->assertText('Subscriber edit@example.com has been updated.');
     // Create a second newsletter.
     $second_newsletter_name = Unicode::strtolower($this->randomMachineName());
     $edit2 = array('name' => $second_newsletter_name, 'id' => $second_newsletter_name);
     $this->drupalPostForm('admin/config/services/simplenews/add', $edit2, t('Save'));
     // Test for adding a subscriber.
     $subscribe = array('newsletters[' . $newsletter_name . ']' => TRUE, 'emails' => '*****@*****.**');
     $this->drupalPostForm('admin/people/simplenews/import', $subscribe, t('Subscribe'));
     // The subscriber should appear once in the list.
     $rows = $this->xpath('//tbody/tr');
     $counter = 0;
     foreach ($rows as $value) {
         if (trim((string) $value->td[0]) == '*****@*****.**') {
             $counter++;
         }
     }
     $this->assertEqual(1, $counter);
     $this->assertText(t('The following addresses were added or updated: @email.', ['@email' => '*****@*****.**']));
     $this->assertText(t('The addresses were subscribed to the following newsletters: @newsletter.', ['@newsletter' => $newsletter_name]));
     // Check exact subscription statuses.
     $subscriber = simplenews_subscriber_load_by_mail('*****@*****.**');
     $this->assertEqual($subscriber->getSubscription($newsletter_name)->get('status')->getValue(), SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED);
     // The second newsletter was not subscribed, so there should be no
     // subscription record at all.
     $this->assertFalse($subscriber->getSubscription($second_newsletter_name));
 }