sitewide_alerts-1.0.0/src/Form/SiteAlertTweetForm.php

src/Form/SiteAlertTweetForm.php
<?php

namespace Drupal\sitewide_alerts\Form;

use Abraham\TwitterOAuth\TwitterOAuth;
use Abraham\TwitterOAuth\TwitterOAuthException;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageManager;
use Drupal\Core\Url;
use Drupal\key\KeyRepository;
use Drupal\sitewide_alerts\SiteAlertInterface;
use Drupal\sitewide_alerts\SiteAlertService;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Defines a form for tweeting site alert.
 */
class SiteAlertTweetForm extends FormBase {

  const TWEET_ALERT_DEFAULT_TEXT = 'New alert: @alert_link';

  /**
   * The site alert entity id.
   */
  protected int $siteAlertId;

  /**
   * The site alert entity.
   */
  protected SiteAlertInterface $siteAlert;

  /**
   * The site alert service.
   */
  protected SiteAlertService $siteAlertService;

  /**
   * The language manager.
   */
  protected LanguageManager $languageManager;

  /**
   * The current language code.
   */
  protected string $language;

  /**
   * The key repository.
   */
  protected KeyRepository $keyRepository;

  /**
   * The constructor.
   *
   * @param \Drupal\sitewide_alerts\SiteAlertService $site_alert_service
   *   The site alert service.
   * @param \Drupal\Core\Language\LanguageManager $language_manager
   *   The language manager.
   * @param \Drupal\key\KeyRepository $key_repository
   *   The key repository.
   */
  public function __construct(
    SiteAlertService $site_alert_service,
    LanguageManager $language_manager,
    KeyRepository $key_repository
  ) {
    $this->siteAlertService = $site_alert_service;
    $this->languageManager = $language_manager;
    $this->language = $language_manager->getCurrentLanguage()->getId();
    $this->keyRepository = $key_repository;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('sitewide_alerts.site_alert_service'),
      $container->get('language_manager'),
      $container->get('key.repository')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId(): string {
    return "site_alert_tweet_form";
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, $site_alert = NULL): array {
    $disabled = FALSE;

    // Check for site alert entity.
    if (empty($site_alert)) {
      $this->messenger()
        ->addError($this->t('Site alert is missing or not found. Unable to tweet alert.'));
      $disabled = TRUE;
    }

    $this->siteAlertId = (int) $site_alert;
    $this->siteAlert = $this->siteAlertService->getSiteAlert($this->siteAlertId);

    $state_keys = [
      'twitter_key_name.' . $this->language,
      'twitter_access_token.' . $this->language,
      'twitter_secret_token.' . $this->language,
    ];
    $config = $this->siteAlertService->getStateConfig($state_keys);

    // Twitter credentials key check.
    $twitter_key_name = $config['twitter_key_name.' . $this->language] ?? NULL;
    if (empty($twitter_key_name)) {
      $this->messenger()
        ->addWarning($this->t('Twitter app key is not configured. Please configure key on <a href="@link">settings page</a>.', [
          '@link' => Url::fromRoute('sitewide_alerts.twitter_config_form')
            ->toString(),
        ]));
      $disabled = TRUE;
    }

    // Twitter account authorization check.
    $twitter_access_token = $config['twitter_access_token.' . $this->language] ?? NULL;
    $twitter_secret_token = $config['twitter_secret_token.' . $this->language] ?? NULL;
    if (empty($twitter_access_token) || empty($twitter_secret_token)) {
      $this->messenger()
        ->addWarning($this->t('Twitter account authorization has not been completed. Please <a href="@link">authorize account</a> now.', [
          '@link' => Url::fromRoute('sitewide_alerts.twitter_authorize_form')
            ->toString(),
        ]));
      $disabled = TRUE;
    }

    $form['twitter'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Twitter configuration'),
      '#disabled' => $disabled,
    ];

    $form['twitter']['language'] = [
      '#markup' => '<p>' . $this->t('Language: %language', ['%language' => $this->languageManager->getCurrentLanguage()->getName()]) . '</p>',
    ];

    $tweet = $this::TWEET_ALERT_DEFAULT_TEXT;
    if (!empty($form_state->getValue('tweet'))) {
      $tweet = $form_state->getValue('tweet');
    }

    $form['twitter']['tweet'] = [
      '#type' => 'textarea',
      '#title' => $this->t('Tweet message'),
      '#description' => $this->t('Text that would be pushed for tweet.<br>The following placeholders are available: @alert_title, @alert_link, @alerts_link.'),
      '#maxlength' => 280,
      '#default_value' => $tweet,
      '#required' => TRUE,
      '#maxlength_js' => TRUE,
      '#attributes' => [
        'data-maxlength' => 280,
        'class' => [
          'maxlength',
          'maxlength_js_enforce',
        ],
      ],
      '#attached' => [
        'library' => [
          'maxlength/maxlength',
        ],
      ],
    ];

    $form['twitter']['update_preview'] = [
      '#type' => 'button',
      '#value' => $this->t('Update preview'),
      '#ajax' => [
        'event' => 'click',
        'callback' => '::updatePreviewCallback',
        'wrapper' => 'tweet-preview',
      ],
    ];

    $form['twitter']['preview'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Tweet preview'),
    ];

    // Replace placeholders.
    $tweet = $this->replacePlaceholders($tweet);

    $form['twitter']['preview']['tweet_preview'] = [
      '#markup' => sprintf('<div id="tweet-preview">%s</div>', $tweet),
    ];

    $form['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Push tweet'),
      '#disabled' => $disabled,
    ];

    return $form;
  }

  /**
   * Update preview AJAX callback.
   *
   * @param array $form
   *   The form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   *
   * @return array
   *   Returns the preview form element.
   */
  public function updatePreviewCallback(array $form, FormStateInterface $form_state): array {
    return $form['twitter']['preview']['tweet_preview'];
  }

  /**
   * Replace tweet message placeholders.
   *
   * @param string $tweet
   *   The tweet message.
   *
   * @return string
   *   Returns the tweet message with placeholders replaced.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\Core\Entity\EntityMalformedException
   */
  private function replacePlaceholders(string $tweet): string {
    // Get site alert link.
    $alert_link = $this->siteAlert->getAlertLink();

    // Get default site alerts page/link.
    $alerts_link = '';
    $config = $this->siteAlertService->getConfig();
    $alerts_page_nid = $config->get('default_alerts_page');
    if (!empty($alerts_page_nid)) {
      /** @var \Drupal\node\Entity\Node $node */
      $node = $this->siteAlertService->getEntityTypeManager()->getStorage('node')
        ->load($alerts_page_nid);
      // Get proper translation.
      if ($node->isTranslatable() && $node->hasTranslation($this->language)) {
        $node = $node->getTranslation($this->language);
      }
      if ($node) {
        $options = [
          'language' => $this->languageManager->getCurrentLanguage(),
          'absolute' => TRUE,
        ];
        $alerts_link = $node->toUrl()->setOptions($options)->toString();
      }
    }

    // Get site alert title.
    $alert_title = $this->siteAlert->label();

    // Replace placeholders.
    return str_replace(['@alert_link', '@alerts_link', '@alert_title'], [
      $alert_link,
      $alerts_link,
      $alert_title,
    ], $tweet);
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    $tweet = $form_state->getValue('tweet');
    if (empty($tweet)) {
      $form_state->setErrorByName('tweet', $this->t('Tweet message is blank.'));
    }
    if (strlen($tweet) > 280) {
      $form_state->setErrorByName('tweet', $this->t('Tweet message has exceeded 280 characters.'));
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    // Make sure we have site alert entity.
    if (!empty($this->siteAlert)) {

      // Get language and proper site alert translation to use.
      if ($this->siteAlert->hasTranslation($this->language)) {
        $this->siteAlert = $this->siteAlert->getTranslation($this->language);
      }

      // Get submitted tweet/text.
      $tweet = $form_state->getValue('tweet');

      // Replace placeholders.
      $tweet = $this->replacePlaceholders($tweet);

      // Make sure we have tweet/text and is valid.
      if (!empty($tweet)) {

        // Get current language and associated twitter configuration.
        $state_keys = [
          'twitter_key_name.' . $this->language,
          'twitter_access_token.' . $this->language,
          'twitter_secret_token.' . $this->language,
        ];
        $config = $this->siteAlertService->getStateConfig($state_keys);

        // Get twitter key name.
        $twitter_key_name = $config['twitter_key_name.' . $this->language] ?? NULL;
        if (!empty($twitter_key_name)) {

          // Get key and credentials.
          $twitter_credentials = parse_ini_string($this->keyRepository->getKey($twitter_key_name)->getKeyValue());

          // Set twitter configuration vars.
          $twitter_version = $twitter_credentials['version'] ?? NULL;
          $twitter_consumer_key = $twitter_credentials['key'] ?? NULL;
          $twitter_consumer_secret = $twitter_credentials['key_secret'] ?? NULL;

          // Set access token.
          $twitter_access_token = $twitter_credentials['access_token'] ?? NULL;
          if (!empty($config['twitter_access_token.' . $this->language])) {
            $twitter_access_token = $config['twitter_access_token.' . $this->language];
          }

          // Set secret token.
          $twitter_access_token_secret = $twitter_credentials['access_token_secret'] ?? NULL;
          if (!empty($config['twitter_secret_token.' . $this->language])) {
            $twitter_access_token_secret = $config['twitter_secret_token.' . $this->language];
          }

          try {
            // Attempt to tweet alert.
            $connection = new TwitterOAuth($twitter_consumer_key, $twitter_consumer_secret, $twitter_access_token, $twitter_access_token_secret);

            // Set version.
            if (!empty($twitter_version)) {
              $connection->setApiVersion($twitter_version);
            }

            // Adjust API call for specified version.
            if ($twitter_version == 2) {
              // Version 2 call.
              $result = $connection->post('tweets', ['text' => $tweet], TRUE);
            }
            else {
              // Version 1.1 call. Requires elevated access.
              $result = $connection->post("statuses/update", ["status" => $tweet]);
            }

            // Check http code and display proper message.
            if ($connection->getLastHttpCode() == 200 || $connection->getLastHttpCode() == 201) {
              $this->messenger()
                ->addMessage($this->t('Tweet alert was successfully sent! "@message"', ['@message' => $tweet]));
            }
            else {
              if (is_array($result)) {
                $this->messenger()->addError($result->errors[0]->message);
              }
              else {
                $this->messenger()
                  ->addError($this->t('Failed to tweet alert. Please try again.'));
              }
            }
          }
          catch (TwitterOAuthException $exception) {
            watchdog_exception('sitewide_alerts', $exception);
            $this->messenger()->addError($exception->getMessage());
          }
        }
      }
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc