Commit 310d7cae authored by Fabian de Rijk's avatar Fabian de Rijk
Browse files

Issue #3295360 by BramDriesen, fabianderijk: Outlook Calendar - Support any content entity

parent b30d5497
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line

o365_outlook_calendar:
  version: 1.x
  css:
+11 −6
Original line number Diff line number Diff line
@@ -7,7 +7,6 @@

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\node\Entity\Node;

/**
 * Implements hook_theme().
@@ -60,11 +59,17 @@ function o365_outlook_calendar_form_alter(&$form, FormStateInterface $form_state
  $moduleConfig = Drupal::config('o365_outlook_calendar.settings');
  if (!empty($moduleConfig->get('enabled'))) {
    $contentType = $moduleConfig->get('content_type');
    $checkFormId = 'node_' . $contentType . '_form';
    $contentTypeFormId = $moduleConfig->get('content_entity_form_id');

    $checkFormId = ['node_' . $contentType . '_form'];

    if (!empty($contentTypeFormId)) {
      $checkFormId = explode(',', $contentTypeFormId);
    }

    // Only show our field on new node form and for nodes of the selected
    // type.
    if ($form_id === $checkFormId) {
    if (in_array($form_id, $checkFormId, TRUE)) {
      // Add out own fields.
      $form['fs_o365_calendar'] = [
        '#type' => 'container',
@@ -100,11 +105,11 @@ function o365_outlook_calendar_form_alter(&$form, FormStateInterface $form_state
 */
function _o365_outlook_calendar_save_submit(array $form, FormStateInterface $form_state) {
  if (!empty($form_state->getValue('o365_calendar_save'))) {
    $node = Node::load($form_state->getValue('nid'));
    if ($node) {
    $entity = $form_state->getFormObject()->getEntity();
    if ($entity) {
      /** @var \Drupal\o365_outlook_calendar\OutlookCalendarSaveEventService $eventService */
      $eventService = Drupal::service('o365_outlook_calendar.save_event');
      $eventService->addEvent($node, $form_state->getValue('o365_calendar_attendees'));
      $eventService->addEvent($entity, $form_state->getValue('o365_calendar_attendees'));
    }
  }
}
+23 −10
Original line number Diff line number Diff line
@@ -78,9 +78,9 @@ class OutlookCalendarSettingsForm extends ConfigFormBase {

    $form['content_type'] = [
      '#type' => 'select',
      '#title' => $this->t('Content type'),
      '#description' => $this->t('Pick the content type you want to enable this functionality on. When you place the "Add node to calendar" block this setting will prevent that block from being shown on other content types then the one selected.'),
      '#options' => static::getNodeTypeOptions(),
      '#title' => $this->t('Entity type and bundle'),
      '#description' => $this->t('Pick the entity type and bundle you want to enable this functionality on. When you place the "Add node to calendar" block this setting will prevent that block from being shown on other content types then the one selected.'),
      '#options' => static::getEntityTypeOptions(),
      '#default_value' => $config->get('content_type'),
      '#ajax' => [
        'wrapper' => 'content-type-fieldset-wrapper',
@@ -93,6 +93,13 @@ class OutlookCalendarSettingsForm extends ConfigFormBase {
      ],
    ];

    $form['content_entity_form_id'] = [
      '#type' => 'textfield',
      '#title' => $this->t('The form id of the custom entity'),
      '#description' => $this->t('Only needs to be filled in when selecting a custom content entity. For regular nodes leave this field empty. If you need multiple form ids (e.g add and edit) you can separate them with a comma (",").'),
      '#default_value' => $config->get('content_entity_form_id'),
    ];

    $form['fields_fieldset'] = [
      '#type' => 'details',
      '#title' => $this->t('Fields for the selected content type'),
@@ -109,7 +116,7 @@ class OutlookCalendarSettingsForm extends ConfigFormBase {
    }

    if (!empty($contentType)) {
      $this->getNodeTypeFormFieldsCheckboxes($form['fields_fieldset'], $contentType);
      $this->getEntityTypeFormFieldsCheckboxes($form['fields_fieldset'], $contentType);
    }

    return parent::buildForm($form, $form_state);
@@ -127,6 +134,7 @@ class OutlookCalendarSettingsForm extends ConfigFormBase {
      $config = $this->config('o365_outlook_calendar.settings');
      $config->set('enabled', $form_state->getValue('enabled'));
      $config->set('content_type', $form_state->getValue('content_type'));
      $config->set('content_entity_form_id', $form_state->getValue('content_entity_form_id'));

      foreach ($this->calendarFields as $key => $calendarField) {
        $config->set($key, $form_state->getValue($key));
@@ -148,27 +156,32 @@ class OutlookCalendarSettingsForm extends ConfigFormBase {
   * @return array
   *   Dropdown options.
   */
  public static function getNodeTypeOptions() {
  public static function getEntityTypeOptions() {
    $types = NodeType::loadMultiple();
    $options = [];
    $options = ['node' => [], 'other' => []];
    foreach ($types as $type) {
      $options[$type->id()] = $type->label();
      $options['node']['node_' . $type->id()] = $type->label() . ' (' . $type->id() . ')';
    }

    $custom_content_entities = \Drupal::service('entity_type.repository')->getEntityTypeLabels(TRUE);
    foreach ($custom_content_entities['Content'] as $custom_content_entity_id => $entity) {
      $options['other']['content_entity_' . $custom_content_entity_id] = $entity->getUntranslatedString() . ' (' . $custom_content_entity_id . ')';
    }

    return $options;
  }

  /**
   * Generate the node type fields.
   * Generate the entity type fields.
   *
   * @param array $form
   *   The form array. Passed by reference.
   * @param string $contentType
   *   The content type.
   */
  public function getNodeTypeFormFieldsCheckboxes(array &$form, $contentType) {
  public function getEntityTypeFormFieldsCheckboxes(array &$form, $contentType) {
    $config = $this->config('o365_outlook_calendar.settings');
    $fields = $this->eventService->getNodeTypeFields($contentType);
    $fields = $this->eventService->getEntityTypeFields($contentType);

    foreach ($this->calendarFields as $key => $calendarField) {
      $form[$key] = $calendarField;
+25 −17
Original line number Diff line number Diff line
@@ -5,11 +5,11 @@ namespace Drupal\o365_outlook_calendar;
use Drupal\Component\Utility\EmailValidatorInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
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\node\Entity\Node;
use Drupal\o365\GraphService;

/**
@@ -25,7 +25,7 @@ class OutlookCalendarSaveEventService {
  protected $graphService;

  /**
   * The modules config.
   * The module config.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   */
@@ -117,13 +117,21 @@ class OutlookCalendarSaveEventService {
   * @return array
   *   The list of fields.
   */
  public function getNodeTypeFields($contentType) {
  public function getEntityTypeFields($contentType) {
    $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() . ')';
@@ -136,8 +144,8 @@ class OutlookCalendarSaveEventService {
  /**
   * Add the event to Outlook.
   *
   * @param \Drupal\node\Entity\Node $node
   *   The node that contains the event values.
   * @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
@@ -150,7 +158,7 @@ class OutlookCalendarSaveEventService {
   * @throws \GuzzleHttp\Exception\GuzzleException
   * @throws \League\OAuth2\Client\Provider\Exception\IdentityProviderException
   */
  public function addEvent(Node $node, $attendees = '', $returnLink = FALSE) {
  public function addEvent(EntityInterface $entity, $attendees = '', $returnLink = FALSE) {
    // Get the field names from config.
    $subjectField = $this->config->get('subject');
    $bodyField = $this->config->get('body');
@@ -159,22 +167,22 @@ class OutlookCalendarSaveEventService {
    $locationField = $this->config->get('location');

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

    $end = $node->get($endField)->value;
    $end = $entity->get($endField)->value;
    if ($startField === $endField) {
      $end = $node->get($endField)->end_value;
      $end = $entity->get($endField)->end_value;
    }

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

    if ($node->hasField($locationField)) {
      $location = $node->get($locationField)->value;
    if ($entity->hasField($locationField)) {
      $location = $entity->get($locationField)->value;
    }

    // Create the data array we want to send.
@@ -206,8 +214,8 @@ class OutlookCalendarSaveEventService {
      $data['end']['dateTime'] = date('Y-m-d', $endTs) . 'T00:00:00';
    }

    // Append the link to the node to the body and add the body.
    $url = $node->toUrl('canonical', ['absolute' => TRUE]);
    // 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();