View source  
  <?php
namespace Drupal\sms\Provider;
use Drupal\sms\Event\SmsDeliveryReportEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Drupal\sms\Entity\SmsMessage;
use Drupal\sms\Entity\SmsGatewayInterface;
use Drupal\sms\Entity\SmsMessageInterface as SmsMessageEntityInterface;
use Drupal\sms\Event\SmsMessageEvent;
use Drupal\sms\Message\SmsMessageInterface;
use Drupal\sms\Plugin\SmsGateway\SmsIncomingEventProcessorInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Drupal\sms\Exception\SmsException;
use Drupal\sms\Exception\SmsDirectionException;
use Drupal\sms\Direction;
use Drupal\sms\Event\SmsEvents;
class DefaultSmsProvider implements SmsProviderInterface {
  
  protected $eventDispatcher;
  
  public function __construct(EventDispatcherInterface $event_dispatcher) {
    $this->eventDispatcher = $event_dispatcher;
  }
  
  public function queue(SmsMessageInterface $sms_message) {
    if (!$sms_message
      ->getDirection()) {
      throw new SmsDirectionException('Missing direction for message.');
    }
    $sms_messages = $this
      ->dispatchEvent(SmsEvents::MESSAGE_PRE_PROCESS, [
      $sms_message,
    ])
      ->getMessages();
    $sms_messages = $this
      ->dispatchEvent(SmsEvents::MESSAGE_QUEUE_PRE_PROCESS, $sms_messages)
      ->getMessages();
    foreach ($sms_messages as $gateway_id => &$sms_message) {
      
      $sms_message
        ->setOption('_skip_preprocess_event', TRUE);
      
      if ($sms_message instanceof SmsMessageEntityInterface) {
        $errors = [];
        $violations = $sms_message
          ->validate();
        foreach ($violations
          ->getFieldNames() as $field_name) {
          foreach ($violations
            ->getByField($field_name) as $violation) {
            $errors[] = "[{$field_name}]: " . strip_tags((string) $violation
              ->getMessage());
          }
        }
        if ($errors) {
          throw new SmsException(sprintf('Can not queue SMS message because there are %s validation error(s): %s', count($errors), implode(' ', $errors)));
        }
      }
      if ($sms_message
        ->getGateway()
        ->getSkipQueue()) {
        switch ($sms_message
          ->getDirection()) {
          case Direction::INCOMING:
            $this
              ->incoming($sms_message);
            break;
          case Direction::OUTGOING:
            $this
              ->send($sms_message);
            break;
        }
        continue;
      }
      $sms_message = SmsMessage::convertFromSmsMessage($sms_message);
      $sms_message
        ->save();
    }
    
    return $this
      ->dispatchEvent(SmsEvents::MESSAGE_QUEUE_POST_PROCESS, $sms_messages)
      ->getMessages();
  }
  
  public function send(SmsMessageInterface $sms) {
    $sms
      ->setDirection(Direction::OUTGOING);
    $dispatch = !$sms
      ->getOption('_skip_preprocess_event');
    $sms_messages = $dispatch ? $this
      ->dispatchEvent(SmsEvents::MESSAGE_PRE_PROCESS, [
      $sms,
    ])
      ->getMessages() : [
      $sms,
    ];
    $sms_messages = $this
      ->dispatchEvent(SmsEvents::MESSAGE_OUTGOING_PRE_PROCESS, $sms_messages)
      ->getMessages();
    
    foreach ($sms_messages as &$sms_message) {
      $plugin = $sms_message
        ->getGateway()
        ->getPlugin();
      $result = $plugin
        ->send($sms_message);
      $sms_message
        ->setResult($result);
      $this
        ->dispatchEvent(SmsEvents::MESSAGE_OUTGOING_POST_PROCESS, [
        $sms_message,
      ]);
      $this
        ->dispatchEvent(SmsEvents::MESSAGE_POST_PROCESS, [
        $sms_message,
      ]);
    }
    return $sms_messages;
  }
  
  public function incoming(SmsMessageInterface $sms_message) {
    $sms_message
      ->setDirection(Direction::INCOMING);
    
    $plugin = $sms_message
      ->getGateway()
      ->getPlugin();
    $dispatch = !$sms_message
      ->getOption('_skip_preprocess_event');
    $sms_messages = $dispatch ? $this
      ->dispatchEvent(SmsEvents::MESSAGE_PRE_PROCESS, [
      $sms_message,
    ])
      ->getMessages() : [
      $sms_message,
    ];
    $sms_messages = $this
      ->dispatchEvent(SmsEvents::MESSAGE_INCOMING_PRE_PROCESS, $sms_messages)
      ->getMessages();
    if ($plugin instanceof SmsIncomingEventProcessorInterface) {
      $event = new SmsMessageEvent($sms_messages);
      $plugin
        ->incomingEvent($event);
    }
    $this
      ->dispatchEvent(SmsEvents::MESSAGE_INCOMING_POST_PROCESS, $sms_messages);
    $this
      ->dispatchEvent(SmsEvents::MESSAGE_POST_PROCESS, $sms_messages);
    return $sms_messages;
  }
  
  public function processDeliveryReport(Request $request, SmsGatewayInterface $sms_gateway) {
    $response = new Response();
    $reports = $sms_gateway
      ->getPlugin()
      ->parseDeliveryReports($request, $response);
    $event = new SmsDeliveryReportEvent();
    $event
      ->setResponse($response)
      ->setReports($reports);
    $this->eventDispatcher
      ->dispatch(SmsEvents::DELIVERY_REPORT_POST_PROCESS, $event);
    return $event
      ->getResponse();
  }
  
  protected function dispatchEvent($event_name, array $sms_messages) {
    $event = new SmsMessageEvent($sms_messages);
    return $this->eventDispatcher
      ->dispatch($event_name, $event);
  }
}