o365-2.0.3/modules/o365_outlook_calendar/src/Plugin/Block/CalendarBlock.php

modules/o365_outlook_calendar/src/Plugin/Block/CalendarBlock.php
<?php

namespace Drupal\o365_outlook_calendar\Plugin\Block;

use Drupal\Core\Datetime\DateFormatter;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Drupal\o365\Block\O365UncachedBlockBase;
use Drupal\o365\GraphService;
use Drupal\o365\HelperService;
use Drupal\o365\PersonaRenderService;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides a 'Upcoming Appointments' block.
 *
 * @Block(
 *   id = "o365_outlook_calendar",
 *   admin_label = @Translation("Upcoming Appointments"),
 *   category = @Translation("Microsoft 365")
 * )
 */
final class CalendarBlock extends O365UncachedBlockBase implements ContainerFactoryPluginInterface {

  use StringTranslationTrait;

  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    GraphService $graphService,
    protected HelperService $helperService,
    protected DateFormatter $dateFormatter,
    protected PersonaRenderService $personaRenderService,
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $graphService);
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('o365.graph'),
      $container->get('o365.helpers'),
      $container->get('date.formatter'),
      $container->get('o365.profile_render')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function blockForm($form, FormStateInterface $form_state): array {
    $form = parent::blockForm($form, $form_state);
    $config = $this->getConfiguration();

    $form['amount'] = [
      '#type' => 'number',
      '#title' => $this->t('Amount of events to show.'),
      '#default_value' => $config['amount'] ?? 5,
      '#min' => 1,
      '#max' => 999,
    ];

    $form['show_calendar_block'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Show the calendar block when there is no data'),
      '#default_value' => $config['show_calendar_block'] ?? 0,
    ];

    $form['calendar_block_text'] = [
      '#type' => 'textarea',
      '#title' => $this->t('Mail block text'),
      '#description' => $this->t('Enter the text you would like to show'),
      '#placeholder' => $this->t('Enter the text you would like to show'),
      '#default_value' => $config['calendar_block_text'] ?? $this->t('No calendar items found.'),
      '#states' => [
        'visible' => [
          ':input[name="settings[show_calendar_block]"]' => [
            'checked' => TRUE,
          ],
        ],
      ],
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function blockSubmit($form, FormStateInterface $form_state): void {
    $values = $form_state->getValues();
    $this->configuration['amount'] = $values['amount'];
    $this->configuration['show_calendar_block'] = $values['show_calendar_block'];
    $this->configuration['calendar_block_text'] = $values['calendar_block_text'];
  }

  /**
   * {@inheritdoc}
   *
   * @throws \Drupal\Core\TempStore\TempStoreException
   * @throws \League\OAuth2\Client\Provider\Exception\IdentityProviderException
   * @throws \Exception
   */
  public function build(): array {
    $config = $this->getConfiguration();
    $amount = $config['amount'] ?? 5;
    $build = [];
    $fromDateTimestamp = date('U');
    $toDateTimestamp = strtotime('now + 30 days');
    $selectFromDate = $this->helperService->createIsoDate((int) $fromDateTimestamp);
    $selectEndDate = $this->helperService->createIsoDate((int) $toDateTimestamp);
    $eventData = $this->graphService->getGraphData('/me/calendarview?$top=' . $amount . '&$orderby=start/dateTime&$select=subject,start,end,attendees,isOnlineMeeting,onlineMeeting,webLink&startdatetime=' . $selectFromDate . '&enddatetime=' . $selectEndDate);

    $items = [];
    if (isset($eventData['value']) && !empty($eventData['value'])) {
      $webLinkText = $this->t('This link opens in a new window');
      $urlOptions = [
        'attributes' => [
          'target' => '_blank',
          'title' => $webLinkText,
        ],
      ];

      foreach ($eventData['value'] as $event) {
        $eventUrl = Url::fromUri($event['webLink'], $urlOptions);
        $onlineMeeting = FALSE;
        if ($event['isOnlineMeeting']) {
          $onlineMeeting = $event['onlineMeeting']['joinUrl'];
        }

        $webLink = Link::fromTextAndUrl($webLinkText, $eventUrl);
        $fromTs = $this->helperService->getTsFromDate($event['start']['dateTime'], $event['start']['timeZone']);
        $endTs = $this->helperService->getTsFromDate($event['end']['dateTime'], $event['end']['timeZone']);

        // Get the attendees for this event.
        $attendees = [];
        $this->getAttendees($event['attendees'], $attendees);

        $items[] = [
          '#theme' => 'o365_calendar',
          '#subject' => $event['subject'],
          '#fromTime' => $this->dateFormatter->format((int) $fromTs, 'o365_outlook_calendar_time'),
          '#endTime' => $this->dateFormatter->format((int) $endTs, 'o365_outlook_calendar_time'),
          '#fromDate' => $this->dateFormatter->format((int) $fromTs, 'o365_outlook_calendar_day'),
          '#endDate' => $this->dateFormatter->format((int) $endTs, 'o365_outlook_calendar_day'),
          '#fromTs' => $fromTs,
          '#endTs' => $endTs,
          '#attendees' => $attendees['attendees'] ?? FALSE,
          '#remainingAttendees' => $attendees['remaining'] ?? FALSE,
          '#webLink' => $webLink,
          '#onlineMeeting' => $onlineMeeting,
          '#onlineMeeting_class' => 'button--primary button',
        ];
      }
    }

    $build['content'] = [
      '#theme' => 'o365_calendar_list',
      '#no_items_text' => NULL,
      '#list' => [
        '#theme' => 'item_list',
        '#items' => NULL,
        '#attributes' => [
          'class' => ['o365-outlook-calendar-items'],
        ],
        '#wrapper_attributes' => [
          'class' => [
            'card__body',
          ],
        ],
      ],
      '#cache' => [
        'contexts' => [
          'user',
        ],
      ],
      '#attached' => [
        'library' => [
          'o365/persona',
          'o365_outlook_calendar/o365_outlook_calendar',
        ],
      ],
    ];

    if (empty($items) && (isset($config['show_calendar_block']) && !$config['show_calendar_block'])) {
      return [];
    }

    $build['content']['#no_items_text'] = ($config['calendar_block_text']) ?? '';
    $build['content']['#list']['#items'] = $items;

    return $build;
  }

  /**
   * Get the attendees for an event.
   *
   * @param array $attendees
   *   The attendees list.
   * @param array|bool $result
   *   The result.
   */
  private function getAttendees(array $attendees, &$result): void {
    if (!empty($attendees)) {
      $result['attendees'] = [];
      $result['remaining'] = FALSE;
      // Determine remaining, we only show 3.
      $count = count($attendees);
      if ($count > 3) {
        $result['remaining'] = $count - 3;
      }

      // Generate the initials and color per user.
      for ($count = 0; $count < 3; $count++) {
        if (isset($attendees[$count])) {
          $attendee = $attendees[$count];

          $value = [
            'bg' => $this->personaRenderService->getRandomPersonaColor(),
          ];

          $initials = explode(' ', $attendee['emailAddress']['name']);
          if (count($initials) > 1) {
            $first = reset($initials);
            $last = end($initials);

            $value['initials'] = strtoupper($first[0] . $last[0]);
          }
          else {
            $value['initials'] = strtoupper($initials[0][0]);
          }

          $result['attendees'][] = $value;
        }
      }
    }
    else {
      $result = FALSE;
    }
  }

}

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

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