o365-2.0.3/modules/o365_outlook_calendar/src/Form/OutlookCalendarSettingsForm.php
modules/o365_outlook_calendar/src/Form/OutlookCalendarSettingsForm.php
<?php
namespace Drupal\o365_outlook_calendar\Form;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\node\Entity\NodeType;
use Drupal\o365_outlook_calendar\OutlookCalendarSaveEventService;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Configure Microsoft 365 - Outlook Calendar settings for this site.
*/
final class OutlookCalendarSettingsForm extends ConfigFormBase {
/**
* The event service.
*
* @var \Drupal\o365_outlook_calendar\OutlookCalendarSaveEventService
*/
protected OutlookCalendarSaveEventService $eventService;
/**
* A list of calendar fields.
*
* @var string[]
*/
protected array $calendarFields = [];
public function __construct(ConfigFactoryInterface $config_factory, TypedConfigManagerInterface $typed_config_manager, OutlookCalendarSaveEventService $eventService) {
$this->eventService = $eventService;
$this->calendarFields = $this->eventService->getCalendarFormFields();
parent::__construct($config_factory, $typed_config_manager);
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('config.factory'),
$container->get('config.typed'),
$container->get('o365_outlook_calendar.save_event',
));
}
/**
* {@inheritdoc}
*/
public function getFormId(): string {
return 'o365_outlook_calendar_outlook_calendar_settings';
}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames(): array {
return ['o365_outlook_calendar.settings'];
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state): array {
$config = $this->config('o365_outlook_calendar.settings');
$form['enabled'] = [
'#type' => 'checkbox',
'#title' => $this->t('Automatically save events as Outlook Event.'),
'#description' => $this->t('When enabled user will be presented with a checkbox to save events in their Outlook Calendar.'),
'#default_value' => $config->get('enabled'),
];
$form['content_type'] = [
'#type' => 'select',
'#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',
'callback' => '::promptCallback',
],
'#states' => [
'required' => [
':input[name="enabled"]' => ['checked' => TRUE],
],
],
];
$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'),
'#open' => TRUE,
'#attributes' => ['id' => 'content-type-fieldset-wrapper'],
];
$form['fields_fieldset']['description'] = [
'#markup' => $this->t('When you have selected a content type you can make a mapping on fields from the content type to the fields in the event created in Outlook Calendar.'),
];
$contentType = $form_state->getValue('content_type');
if (!$contentType && !empty($config->get('content_type'))) {
$contentType = $config->get('content_type');
}
if (!empty($contentType)) {
$this->getEntityTypeFormFieldsCheckboxes($form['fields_fieldset'], $contentType);
}
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state): void {
// We want to reset the config before saving the new values.
$this->config('o365_outlook_calendar.settings')->delete();
// Update our config based on form values.
$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));
}
$config->save();
parent::submitForm($form, $form_state);
}
/**
* Helper function to populate the content type dropdown.
*
* @return array
* Dropdown options.
*/
public static function getEntityTypeOptions(): array {
$types = NodeType::loadMultiple();
$options = ['node' => [], 'other' => []];
foreach ($types as $type) {
$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 entity type fields.
*
* @param array $form
* The form array. Passed by reference.
* @param string $contentType
* The content type.
*/
public function getEntityTypeFormFieldsCheckboxes(array &$form, $contentType): void {
$config = $this->config('o365_outlook_calendar.settings');
$fields = $this->eventService->getEntityTypeFields($contentType);
/**
* @var string $key
* @var array $calendarField
*/
foreach ($this->calendarFields as $key => $calendarField) {
$form[$key] = $calendarField;
$form[$key]['#type'] = 'select';
$form[$key]['#options'] = $fields;
$form[$key]['#default_value'] = $config->get($key);
}
}
/**
* Callback for the select element.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*
* @return array
* The form structure.
*/
public function promptCallback(array $form, FormStateInterface $form_state): array {
return $form['fields_fieldset'];
}
}
