You are here

class NodeTabForm in Simplenews 8

Same name and namespace in other branches
  1. 8.2 src/Form/NodeTabForm.php \Drupal\simplenews\Form\NodeTabForm
  2. 3.x src/Form/NodeTabForm.php \Drupal\simplenews\Form\NodeTabForm

Configure simplenews subscriptions of a user.

Hierarchy

Expanded class hierarchy of NodeTabForm

1 string reference to 'NodeTabForm'
simplenews.routing.yml in ./simplenews.routing.yml
simplenews.routing.yml

File

src/Form/NodeTabForm.php, line 18

Namespace

Drupal\simplenews\Form
View source
class NodeTabForm extends FormBase {

  /**
   * The spool storage.
   *
   * @var \Drupal\simplenews\Spool\SpoolStorageInterface
   */
  protected $spoolStorage;

  /**
   * The recipient handler plugin manager.
   *
   * @var \Drupal\simplenews\RecipientHandler\RecipientHandlerManager
   */
  protected $recipientHandlerManager;

  /**
   * The currently authenticated user.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected $currentUser;

  /**
   * The simplenews mailer.
   *
   * @var \Drupal\simplenews\Mail\MailerInterface
   */
  protected $mailer;

  /**
   * Constructs a new NodeTabForm.
   *
   * @param \Drupal\simplenews\Spool\SpoolStorageInterface $spool_storage
   *   The spool storage.
   * @param \Drupal\simplenews\RecipientHandler\RecipientHandlerManager $recipient_handler_manager
   *   The recipient handler plugin manager.
   * @param \Drupal\Core\Session\AccountInterface $current_user
   *   The currently authenticated user.
   * @param \Drupal\simplenews\Mail\MailerInterface $simplenews_mailer
   *   The simplenews mailer service.
   */
  public function __construct(SpoolStorageInterface $spool_storage, RecipientHandlerManager $recipient_handler_manager, AccountInterface $current_user, MailerInterface $simplenews_mailer) {
    $this->spoolStorage = $spool_storage;
    $this->recipientHandlerManager = $recipient_handler_manager;
    $this->currentUser = $current_user;
    $this->mailer = $simplenews_mailer;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container
      ->get('simplenews.spool_storage'), $container
      ->get('plugin.manager.simplenews_recipient_handler'), $container
      ->get('current_user'), $container
      ->get('simplenews.mailer'));
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'simplenews_node_tab';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, NodeInterface $node = NULL) {
    $config = $this
      ->config('simplenews.settings');
    $status = $node->simplenews_issue->status;
    $summary = $this->spoolStorage
      ->issueSummary($node);
    $form['#title'] = $this
      ->t('<em>Newsletter issue</em> @title', array(
      '@title' => $node
        ->getTitle(),
    ));

    // We will need the node.
    $form_state
      ->set('node', $node);

    // Show newsletter sending options if newsletter has not been send yet.
    // If send a notification is shown.
    if ($status == SIMPLENEWS_STATUS_SEND_NOT) {
      $form['test'] = array(
        '#type' => 'details',
        '#open' => TRUE,
        '#title' => t('Test'),
      );
      $form['test']['test_address'] = array(
        '#type' => 'textfield',
        '#title' => t('Test email addresses'),
        '#description' => t('A comma-separated list of email addresses to be used as test addresses.'),
        '#default_value' => $this->currentUser
          ->getEmail(),
        '#size' => 60,
        '#maxlength' => 128,
      );
      $form['test']['submit'] = array(
        '#type' => 'submit',
        '#value' => t('Send test newsletter issue'),
        '#name' => 'send_test',
        '#submit' => array(
          '::submitTestMail',
        ),
        '#validate' => array(
          '::validateTestAddress',
        ),
      );
      $form['send'] = array(
        '#type' => 'details',
        '#open' => TRUE,
        '#title' => t('Send'),
      );
      $default_handler = isset($form_state
        ->getValue('simplenews')['recipient_handler']) ? $form_state
        ->getValue('simplenews')['recipient_handler'] : $node->simplenews_issue->handler;
      $recipient_handler_manager = $this->recipientHandlerManager;
      $options = $recipient_handler_manager
        ->getOptions();
      $form['send']['recipient_handler'] = array(
        '#type' => 'select',
        '#title' => t('Recipients'),
        '#description' => t('Please select to configure who to send the email to.'),
        '#options' => $options,
        '#default_value' => $default_handler,
        '#access' => count($options) > 1,
        '#ajax' => array(
          'callback' => '::ajaxUpdateRecipientHandlerSettings',
          'wrapper' => 'recipient-handler-settings',
          'method' => 'replace',
          'effect' => 'fade',
        ),
      );

      // Get the handler class.
      $handler_definitions = $recipient_handler_manager
        ->getDefinitions();
      $handler = $handler_definitions[$default_handler];
      $class = $handler['class'];
      $settings = $node->simplenews_issue->handler_settings;
      if (method_exists($class, 'settingsForm')) {
        $element = array(
          '#parents' => array(
            'simplenews',
            'recipient_handler_settings',
          ),
          '#prefix' => '<div id="recipient-handler-settings">',
          '#suffix' => '</div>',
        );
        $form['send']['recipient_handler_settings'] = $class::settingsForm($element, $settings);
      }
      else {
        $form['send']['recipient_handler']['#suffix'] = '<div id="recipient-handler-settings"></div>';
      }

      // Add some text to describe the send situation.
      $form['send']['count'] = array(
        '#type' => 'item',
        '#markup' => t('Send newsletter issue to @count subscribers.', array(
          '@count' => $summary['count'],
        )),
      );
      if (!$config
        ->get('mail.use_cron')) {
        $send_text = t('Mails will be sent immediately.');
      }
      else {
        $send_text = t('Mails will be sent when cron runs.');
      }
      $form['send']['method'] = array(
        '#type' => 'item',
        '#markup' => $send_text,
      );
      if ($node
        ->isPublished()) {
        $form['send']['send_now'] = array(
          '#type' => 'submit',
          '#button_type' => 'primary',
          '#value' => t('Send now'),
          '#submit' => array(
            '::submitForm',
            '::submitSendNow',
          ),
        );
      }
      else {
        $form['send']['send_on_publish'] = array(
          '#type' => 'submit',
          '#button_type' => 'primary',
          '#value' => t('Send on publish'),
          '#submit' => array(
            '::submitForm',
            '::submitSendLater',
          ),
        );
      }
    }
    else {
      $form['status'] = array(
        '#type' => 'item',
        '#title' => $summary['description'],
      );
      if ($status != SIMPLENEWS_STATUS_SEND_READY) {
        $form['actions'] = array(
          '#type' => 'actions',
        );
        $form['actions']['stop'] = array(
          '#type' => 'submit',
          '#submit' => array(
            '::submitStop',
          ),
          '#value' => t('Stop sending'),
        );
      }
    }
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    $values = $form_state
      ->getValues();

    // Validate recipient handler settings.
    if (!empty($form['recipient_handler_settings'])) {
      $handler = $values['recipient_handler'];
      $handler_definitions = $this->recipientHandlerManager
        ->getDefinitions();

      // Get the handler class.
      $handler = $handler_definitions[$handler];
      $class = $handler['class'];
      if (method_exists($class, 'settingsFormValidate')) {
        $class::settingsFormValidate($form['recipient_handler_settings'], $form_state);
      }
    }
    parent::validateForm($form, $form_state);
  }

  /**
   * Validates the test address.
   */
  public function validateTestAddress(array $form, FormStateInterface $form_state) {
    $test_address = $form_state
      ->getValue('test_address');
    $test_address = trim($test_address);
    if (!empty($test_address)) {
      $mails = explode(',', $test_address);
      foreach ($mails as $mail) {
        $mail = trim($mail);
        if (!valid_email_address($mail)) {
          $form_state
            ->setErrorByName('test_address', t('Invalid email address "%mail".', array(
            '%mail' => $mail,
          )));
        }
      }
      $form_state
        ->set('test_addresses', $mails);
    }
    else {
      $form_state
        ->setErrorByName('test_address', t('Missing test email address.'));
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $values = $form_state
      ->getValues();
    $node = $form_state
      ->get('node');

    // Save the recipient handler and it's settings.
    $node->simplenews_issue->handler = $values['recipient_handler'];
    if (!empty($form['recipient_handler_settings'])) {
      $handler = $values['recipient_handler'];
      $handler_definitions = $this->recipientHandlerManager
        ->getDefinitions();
      $handler = $handler_definitions[$handler];
      $class = $handler['class'];
      if (method_exists($class, 'settingsFormSubmit')) {
        $settings = $class::settingsFormSubmit($form['recipient_handler_settings'], $form_state);
        $node->simplenews_issue->handler_settings = (array) $settings;
      }
    }
    $node
      ->save();
  }

  /**
   * Submit handler for sending test mails.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   */
  public function submitTestMail(array &$form, FormStateInterface $form_state) {
    $this->mailer
      ->sendTest($form_state
      ->get('node'), $form_state
      ->get('test_addresses'));
  }

  /**
   * Submit handler for sending published newsletter issue.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   */
  public function submitSendNow(array &$form, FormStateInterface $form_state) {
    $node = $form_state
      ->get('node');
    $this->spoolStorage
      ->addFromEntity($node);

    // Attempt to send immediatly, if configured to do so.
    if ($this->mailer
      ->attemptImmediateSend(array(
      'entity_id' => $node
        ->id(),
      'entity_type' => 'node',
    ))) {
      $this
        ->messenger()
        ->addMessage(t('Newsletter %title sent.', array(
        '%title' => $node
          ->getTitle(),
      )));
    }
    else {
      $this
        ->messenger()
        ->addMessage(t('Newsletter issue %title pending.', array(
        '%title' => $node
          ->getTitle(),
      )));
    }
    $node
      ->save();
  }

  /**
   * Submit handler for sending unpublished newsletter issue.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   */
  public function submitSendLater(array &$form, FormStateInterface $form_state) {
    $node = $form_state
      ->get('node');

    // Set the node to pending status.
    $node->simplenews_issue->status = SIMPLENEWS_STATUS_SEND_PUBLISH;
    $this
      ->messenger()
      ->addMessage(t('Newsletter issue %title will be sent when published.', array(
      '%title' => $node
        ->getTitle(),
    )));
    $node
      ->save();
  }

  /**
   * {@inheritdoc}
   */
  public function submitStop(array &$form, FormStateInterface $form_state) {
    $node = $form_state
      ->get('node');

    // Delete the mail spool entries of this newsletter issue.
    $count = $this->spoolStorage
      ->deleteMails(array(
      'nid' => $node
        ->id(),
    ));

    // Set newsletter issue to not sent yet.
    $node->simplenews_issue->status = SIMPLENEWS_STATUS_SEND_NOT;
    $node
      ->save();
    $this
      ->messenger()
      ->addMessage(t('Sending of %title was stopped. @count pending email(s) were deleted.', array(
      '%title' => $node
        ->getTitle(),
      '@count' => $count,
    )));
  }

  /**
   * Checks access for the simplenews node tab.
   *
   * @param \Drupal\node\NodeInterface $node
   *   The node where the tab should be added.
   *
   * @return \Drupal\Core\Access\AccessResult
   *   An access result object.
   */
  public function checkAccess(NodeInterface $node) {
    $account = $this
      ->currentUser();
    if ($node
      ->hasField('simplenews_issue') && $node->simplenews_issue->target_id != NULL) {
      return AccessResult::allowedIfHasPermission($account, 'administer newsletters')
        ->orIf(AccessResult::allowedIfHasPermission($account, 'send newsletter'));
    }
    return AccessResult::neutral();
  }

  /**
   * Return the updated recipient handler settings form.
   */
  public function ajaxUpdateRecipientHandlerSettings($form, FormStateInterface $form_state) {
    return empty($form['simplenews']['recipient_handler_settings']) ? array(
      '#markup' => '<div id="recipient-handler-settings"></div>',
    ) : $form['simplenews']['recipient_handler_settings'];
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
FormBase::$configFactory protected property The config factory. 1
FormBase::$requestStack protected property The request stack. 1
FormBase::$routeMatch protected property The route match.
FormBase::config protected function Retrieves a configuration object.
FormBase::configFactory protected function Gets the config factory for this form. 1
FormBase::container private function Returns the service container.
FormBase::currentUser protected function Gets the current user.
FormBase::getRequest protected function Gets the request object.
FormBase::getRouteMatch protected function Gets the route match.
FormBase::logger protected function Gets the logger for a specific channel.
FormBase::redirect protected function Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait::redirect
FormBase::resetConfigFactory public function Resets the configuration factory.
FormBase::setConfigFactory public function Sets the config factory for this form.
FormBase::setRequestStack public function Sets the request stack object to use.
LinkGeneratorTrait::$linkGenerator protected property The link generator. 1
LinkGeneratorTrait::getLinkGenerator Deprecated protected function Returns the link generator.
LinkGeneratorTrait::l Deprecated protected function Renders a link to a route given a route name and its parameters.
LinkGeneratorTrait::setLinkGenerator Deprecated public function Sets the link generator service.
LoggerChannelTrait::$loggerFactory protected property The logger channel factory service.
LoggerChannelTrait::getLogger protected function Gets the logger for a specific channel.
LoggerChannelTrait::setLoggerFactory public function Injects the logger channel factory.
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
NodeTabForm::$currentUser protected property The currently authenticated user.
NodeTabForm::$mailer protected property The simplenews mailer.
NodeTabForm::$recipientHandlerManager protected property The recipient handler plugin manager.
NodeTabForm::$spoolStorage protected property The spool storage.
NodeTabForm::ajaxUpdateRecipientHandlerSettings public function Return the updated recipient handler settings form.
NodeTabForm::buildForm public function Form constructor. Overrides FormInterface::buildForm
NodeTabForm::checkAccess public function Checks access for the simplenews node tab.
NodeTabForm::create public static function Instantiates a new instance of this class. Overrides FormBase::create
NodeTabForm::getFormId public function Returns a unique string identifying the form. Overrides FormInterface::getFormId
NodeTabForm::submitForm public function Form submission handler. Overrides FormInterface::submitForm
NodeTabForm::submitSendLater public function Submit handler for sending unpublished newsletter issue.
NodeTabForm::submitSendNow public function Submit handler for sending published newsletter issue.
NodeTabForm::submitStop public function
NodeTabForm::submitTestMail public function Submit handler for sending test mails.
NodeTabForm::validateForm public function Form validation handler. Overrides FormBase::validateForm
NodeTabForm::validateTestAddress public function Validates the test address.
NodeTabForm::__construct public function Constructs a new NodeTabForm.
RedirectDestinationTrait::$redirectDestination protected property The redirect destination service. 1
RedirectDestinationTrait::getDestinationArray protected function Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url.
RedirectDestinationTrait::getRedirectDestination protected function Returns the redirect destination service.
RedirectDestinationTrait::setRedirectDestination public function Sets the redirect destination service.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.
UrlGeneratorTrait::$urlGenerator protected property The url generator.
UrlGeneratorTrait::getUrlGenerator Deprecated protected function Returns the URL generator service.
UrlGeneratorTrait::setUrlGenerator Deprecated public function Sets the URL generator service.
UrlGeneratorTrait::url Deprecated protected function Generates a URL or path for a specific route based on the given parameters.