o365-2.0.3/modules/o365_outlook_calendar/src/OutlookCalendarSaveEventService.php

modules/o365_outlook_calendar/src/OutlookCalendarSaveEventService.php
<?php

namespace Drupal\o365_outlook_calendar;

use Drupal\Component\Utility\EmailValidatorInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Link;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\o365\GraphService;

/**
 * Service that handles to saving of events in Outlook.
 */
class OutlookCalendarSaveEventService {

  /**
   * The o365 Graph service.
   *
   * @var \Drupal\o365\GraphService
   */
  protected GraphService $graphService;

  /**
   * The module config.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   */
  protected ImmutableConfig $config;

  /**
   * The email validator.
   *
   * @var \Drupal\Component\Utility\EmailValidatorInterface
   */
  protected EmailValidatorInterface $emailValidator;

  /**
   * The Drupal messenger.
   *
   * @var \Drupal\Core\Messenger\MessengerInterface
   */
  protected MessengerInterface $messenger;

  /**
   * The entity field manager.
   *
   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
   */
  protected EntityFieldManagerInterface $entityFieldManager;

  /**
   * Constructor for the OutlookCalendarSaveEventService service.
   *
   * @param \Drupal\o365\GraphService $graphService
   *   The graph service.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
   *   The config factory.
   * @param \Drupal\Component\Utility\EmailValidatorInterface $emailValidator
   *   The email validator.
   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
   *   The Drupal messenger service.
   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entityFieldManager
   *   The entity field manager.
   */
  public function __construct(GraphService $graphService, ConfigFactoryInterface $configFactory, EmailValidatorInterface $emailValidator, MessengerInterface $messenger, EntityFieldManagerInterface $entityFieldManager) {
    $this->graphService = $graphService;
    $this->config = $configFactory->get('o365_outlook_calendar.settings');
    $this->emailValidator = $emailValidator;
    $this->messenger = $messenger;
    $this->entityFieldManager = $entityFieldManager;
  }

  /**
   * Generate the calendar form fields.
   *
   * @return array
   *   The list of fields.
   */
  public function getCalendarFormFields(): array {
    return [
      'subject' => [
        '#title' => new TranslatableMarkup('Subject'),
        '#description' => new TranslatableMarkup('This is the name of the event in Outlook. You need to select a string field.'),
        '#required' => TRUE,
      ],
      'body' => [
        '#title' => new TranslatableMarkup('Body'),
        '#description' => new TranslatableMarkup('This will be used as the body of the event. You need to select a string or text field.'),
      ],
      'start' => [
        '#title' => new TranslatableMarkup('Start date'),
        '#description' => new TranslatableMarkup('The start date of the event. You need to select a date(time) field.'),
        '#required' => TRUE,
      ],
      'end' => [
        '#title' => new TranslatableMarkup('End date'),
        '#description' => new TranslatableMarkup('The end date of the event. You need to select a date(time) field.'),
        '#required' => TRUE,
      ],
      'location' => [
        '#title' => new TranslatableMarkup('Location'),
        '#description' => new TranslatableMarkup('The location of the event. You can select a string or text field.'),
      ],
    ];
  }

  /**
   * Get all fields in a certain content type.
   *
   * @param string $contentType
   *   The content type.
   *
   * @return array
   *   The list of fields.
   */
  public function getEntityTypeFields(string $contentType): array {
    $empty = new TranslatableMarkup('- Make your choice -');
    $fields = [
      '' => $empty,
    ];

    if (str_starts_with($contentType, 'node_')) {
      $contentType = str_replace('node_', '', $contentType);
      $entityFields = $this->entityFieldManager->getFieldDefinitions('node', $contentType);
    }
    else {
      $contentType = str_replace('content_entity_', '', $contentType);
      $entityFields = $this->entityFieldManager->getFieldDefinitions($contentType, $contentType);
    }

    if (!empty($entityFields)) {
      foreach ($entityFields as $fieldDefinition) {
        $fields[$fieldDefinition->getName()] = $fieldDefinition->getLabel() . ' (' . $fieldDefinition->getType() . ')';
      }
    }

    return $fields;
  }

  /**
   * Add the event to Outlook.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity that contains the event values.
   * @param string $attendees
   *   The comma seperated string of attendees.
   * @param bool $returnLink
   *   If we want to return the weblink. If true, no messages are logged.
   *
   * @return bool|string
   *   The web link or TRUE/FALSE.
   *
   * @throws \Drupal\Core\TempStore\TempStoreException
   * @throws \GuzzleHttp\Exception\GuzzleException
   * @throws \League\OAuth2\Client\Provider\Exception\IdentityProviderException
   */
  public function addEvent(EntityInterface $entity, string $attendees = '', bool $returnLink = FALSE): bool|string {
    // Get the field names from config.
    $subjectField = $this->config->get('subject');
    $bodyField = $this->config->get('body');
    $startField = $this->config->get('start');
    $endField = $this->config->get('end');
    $locationField = $this->config->get('location');

    // Load values from the node.
    // @phpstan-ignore-next-line
    $subject = $entity->get($subjectField)->value;
    // @phpstan-ignore-next-line
    $start = $entity->get($startField)->value;

    // @phpstan-ignore-next-line
    $end = $entity->get($endField)->value;
    if ($startField === $endField) {
      // @phpstan-ignore-next-line
      $end = $entity->get($endField)->end_value;
    }

    // Body and location are not required, so we need to check.
    $body = $location = FALSE;
    // @phpstan-ignore-next-line
    if ($entity->hasField($bodyField)) {
      // @phpstan-ignore-next-line
      $body = $entity->get($bodyField)->value;
    }

    // @phpstan-ignore-next-line
    if ($entity->hasField($locationField)) {
      // @phpstan-ignore-next-line
      $location = $entity->get($locationField)->value;
    }

    // Create the data array we want to send.
    $data = [
      'subject' => $subject,
      'start' => [
        'dateTime' => $start,
        'timeZone' => 'UTC',
      ],
      'end' => [
        'dateTime' => $end,
        'timeZone' => 'UTC',
      ],
      'allowNewTimeProposals' => TRUE,
      'isOnlineMeeting' => TRUE,
    ];

    // Check if this is an all day event (start & end date are the same)
    if ($start === $end) {
      // Set all day data.
      $data['isAllDay'] = TRUE;
      $timestamp = strtotime($start);
      $startDate = date('Y-m-d', $timestamp) . 'T00:00:00';
      $startTs = strtotime($startDate);
      $endTs = strtotime('+ 1 day', $startTs);

      // Change the start & end dates according to the API documentation.
      $data['start']['dateTime'] = $startDate;
      $data['end']['dateTime'] = date('Y-m-d', $endTs) . 'T00:00:00';
    }

    // Append the link to the entity to the body and add the body.
    $url = $entity->toUrl('canonical', ['absolute' => TRUE]);
    $linkText = new TranslatableMarkup('View this event here');
    $link = Link::fromTextAndUrl($linkText, $url);
    $body .= $link->toString();
    $data['body'] = [
      'contentType' => 'HTML',
      'content' => $body,
    ];

    // Add the location, if any.
    if (!empty($location)) {
      $data['location'] = [
        'displayName' => $location,
      ];
    }

    // Set up attendees if there are any.
    if (!empty($attendees)) {
      $attendeesArray = explode(',', $attendees);

      if (!empty($attendeesArray)) {
        $invalidEmails = [];
        $data['attendees'] = [];
        foreach ($attendeesArray as $attendee) {
          $attendee = trim($attendee);
          if ($this->emailValidator->isValid($attendee)) {
            $data['attendees'][] = [
              'emailAddress' => [
                'address' => $attendee,
              ],
              'type' => 'optional',
            ];
          }
          else {
            $invalidEmails[] = $attendee;
          }
        }

        // Show a warning if there are any invalid email addresses.
        if (!empty($invalidEmails)) {
          $warning = new TranslatableMarkup('The following mail addresses where not valid and not automatically added as attendee: @addresses', ['@addresses' => implode(', ', $invalidEmails)]);
          $this->messenger->addWarning($warning);
        }
      }
    }

    // Do a call to the webservice and a according message.
    $return = $this->graphService->sendGraphData('/me/events', $data);
    if ($return) {
      if ($returnLink) {
        return $return['webLink'];
      }

      $url = Url::fromUri($return['webLink'], ['attributes' => ['target' => '_blank']]);
      $link = Link::fromTextAndUrl('Outlook Calendar', $url);
      $message = new TranslatableMarkup('This event has been created in your @link', ['@link' => $link->toString()]);
      $this->messenger->addMessage($message);
      return TRUE;
    }

    if (!$returnLink) {
      $warning = new TranslatableMarkup('Something went wrong creating this event in Outlook. Please add it manually.');
      $this->messenger->addError($warning);
    }

    return FALSE;
  }

}

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

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