View source
<?php
namespace Drupal\fullcalendar_view\Plugin\views\style;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\fullcalendar_view\TaxonomyColor;
use Drupal\core\form\FormStateInterface;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
use Drupal\views\Plugin\views\style\StylePluginBase;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Link;
use Drupal\Core\Url;
use Drupal\Core\Datetime\DrupalDateTime;
use Symfony\Component\DependencyInjection\ContainerInterface;
class FullCalendarDisplay extends StylePluginBase {
protected $usesFields = TRUE;
protected $taxonomyColorService;
public function __construct(array $configuration, $plugin_id, $plugin_definition, TaxonomyColor $taxonomyColorService) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->taxonomyColorService = $taxonomyColorService;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('fullcalendar_view.taxonomy_color'));
}
protected function defineOptions() {
$options = parent::defineOptions();
$options['default_date_source'] = [
'default' => 'now',
];
$options['defaultDate'] = [
'default' => '',
];
$options['start'] = [
'default' => '',
];
$options['end'] = [
'default' => '',
];
$options['des'] = [
'default' => '',
];
$options['title'] = [
'default' => '',
];
$options['use_entity_fields'] = [
'default' => TRUE,
];
$options['business_start'] = [
'default' => '',
];
$options['business_end'] = [
'default' => '',
];
$options['bundle_type'] = [
'default' => '',
];
$options['tax_field'] = [
'default' => '',
];
$options['color_bundle'] = [
'default' => [],
];
$options['color_taxonomies'] = [
'default' => [],
];
$options['vocabularies'] = [
'default' => '',
];
$options['right_buttons'] = [
'default' => [
'agendaWeek' => 'agendaWeek',
'agendaDay' => 'agendaDay',
'listYear' => 'listYear',
],
];
$options['default_view'] = [
'default' => 'month',
];
$options['nav_links'] = [
'default' => 1,
];
$options['timeFormat'] = [
'default' => 'H(:mm)',
];
$options['defaultLanguage'] = [
'default' => 'en',
];
$options['languageSelector'] = [
'default' => 0,
];
$options['alloweventOverlap'] = [
'default' => 1,
];
$options['updateAllowed'] = [
'default' => 1,
];
$options['updateConfirm'] = [
'default' => 1,
];
$options['dialogWindow'] = [
'default' => 0,
];
$options['createEventLink'] = [
'default' => 0,
];
$options['openEntityInNewTab'] = [
'default' => 1,
];
return $options;
}
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
if (isset($form['grouping'])) {
unset($form['grouping']);
}
$form['default_date_source'] = [
'#type' => 'radios',
'#options' => [
'now' => $this
->t('Current date'),
'first' => $this
->t('Date of first view result'),
'fixed' => $this
->t('Fixed value'),
],
'#title' => $this
->t('Default date source'),
'#default_value' => isset($this->options['default_date_source']) ? $this->options['default_date_source'] : '',
'#description' => $this
->t('Source of the initial date displayed when the calendar first loads.'),
];
$form['defaultDate'] = [
'#type' => 'date',
'#title' => $this
->t('Default date'),
'#default_value' => isset($this->options['defaultDate']) ? $this->options['defaultDate'] : '',
'#description' => $this
->t('Fixed initial date displayed when the calendar first loads.'),
'#states' => [
'visible' => [
[
':input[name="style_options[default_date_source]"]' => [
'value' => 'fixed',
],
],
],
],
];
$field_names = $this->displayHandler
->getFieldLabels();
$entity_type = $this->view
->getBaseEntityType()
->id();
$form['start'] = [
'#title' => $this
->t('Start Date Field'),
'#type' => 'select',
'#options' => $field_names,
'#default_value' => !empty($this->options['start']) ? $this->options['start'] : '',
];
$form['end'] = [
'#title' => $this
->t('End Date Field'),
'#type' => 'select',
'#options' => $field_names,
'#empty_value' => '',
'#default_value' => !empty($this->options['end']) ? $this->options['end'] : '',
];
$form['title'] = [
'#title' => $this
->t('Title Field'),
'#type' => 'select',
'#options' => $field_names,
'#default_value' => !empty($this->options['title']) ? $this->options['title'] : '',
];
$form['des'] = [
'#title' => $this
->t('Description Field'),
'#description' => $this
->t('Description for event tooltip. If select none, there will not be popup tooltip. For multiple content types, you can select multiple fields here.'),
'#type' => 'select',
'#options' => $field_names,
'#empty_value' => '',
'#default_value' => !empty($this->options['des']) ? $this->options['des'] : '',
'#multiple' => TRUE,
];
$form['display'] = [
'#type' => 'details',
'#title' => $this
->t('Display'),
'#description' => $this
->t('Calendar display settings.'),
];
$form['use_entity_fields'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Use entity fields'),
'#description' => $this
->t('Use entity fields for rendering rather than the raw view fields. This is checked by default to prevent legacy views from breaking. However, it will prevent using views rewriting and does not support non-standard date fields (fields other than timestamp, datetime and daterange).'),
'#fieldset' => 'display',
'#default_value' => $this->options['use_entity_fields'],
];
$form['right_buttons'] = [
'#type' => 'checkboxes',
'#fieldset' => 'display',
'#options' => [
'agendaWeek' => $this
->t('Week'),
'agendaDay' => $this
->t('Day'),
'listYear' => $this
->t('List'),
],
'#default_value' => empty($this->options['right_buttons']) ? [] : $this->options['right_buttons'],
'#title' => $this
->t('Right side buttons'),
];
$form['default_view'] = [
'#type' => 'radios',
'#fieldset' => 'display',
'#options' => [
'month' => $this
->t('Month'),
'agendaWeek' => $this
->t('Week'),
'agendaDay' => $this
->t('Day'),
'listYear' => $this
->t('List'),
],
'#default_value' => empty($this->options['default_view']) ? 'month' : $this->options['default_view'],
'#title' => $this
->t('Default view'),
];
$form['firstDay'] = [
'#type' => 'radios',
'#fieldset' => 'display',
'#options' => [
'0' => $this
->t('Sunday'),
'1' => $this
->t('Monday'),
'2' => $this
->t('Tuesday'),
'3' => $this
->t('Wednesday'),
'4' => $this
->t('Thursday'),
'5' => $this
->t('Friday'),
'6' => $this
->t('Saturday'),
],
'#default_value' => empty($this->options['firstDay']) ? '0' : $this->options['firstDay'],
'#title' => $this
->t('First Day'),
];
$form['nav_links'] = [
'#type' => 'checkbox',
'#fieldset' => 'display',
'#default_value' => !isset($this->options['nav_links']) ? 1 : $this->options['nav_links'],
'#title' => $this
->t('Day/Week are links'),
'#description' => $this
->t('If this option is selected, day/week names will be linked to navigation views.'),
];
$form['timeFormat'] = [
'#fieldset' => 'display',
'#type' => 'textfield',
'#title' => $this
->t('Time Format settings for month view'),
'#default_value' => isset($this->options['timeFormat']) ? $this->options['timeFormat'] : 'HH:mm',
'#description' => $this
->t('See the %fullcalendar_doc and %momentjs_doc for available formatting options. <br />Leave it blank to default format.', array(
'%fullcalendar_doc' => Link::fromTextAndUrl($this
->t('Fullcalendar documentation'), Url::fromUri('https://fullcalendar.io/docs/v3/timeFormat', array(
'attributes' => array(
'target' => '_blank',
),
)))
->toString(),
'%momentjs_doc' => Link::fromTextAndUrl($this
->t('MomentJS’s formatting characters'), Url::fromUri('http://momentjs.com/docs/#/displaying/format/', array(
'attributes' => array(
'target' => '_blank',
),
)))
->toString(),
)),
'#size' => 20,
];
$form['alloweventOverlap'] = [
'#type' => 'checkbox',
'#fieldset' => 'display',
'#default_value' => !isset($this->options['alloweventOverlap']) ? 1 : $this->options['alloweventOverlap'],
'#title' => $this
->t('Allow calendar events to overlap'),
'#description' => $this
->t('If this option is selected, calendar events are allowed to overlap (default).'),
];
$form['updateAllowed'] = [
'#type' => 'checkbox',
'#fieldset' => 'display',
'#default_value' => !isset($this->options['updateAllowed']) ? 1 : $this->options['updateAllowed'],
'#title' => $this
->t('Allow event editing.'),
'#description' => $this
->t('If this option is selected, editing by dragging and dropping an event will be enabled.'),
];
$form['updateConfirm'] = [
'#type' => 'checkbox',
'#fieldset' => 'display',
'#default_value' => !isset($this->options['updateConfirm']) ? 1 : $this->options['updateConfirm'],
'#title' => $this
->t('Event update confirmation pop-up dialog.'),
'#description' => $this
->t('If this option is selected, a confirmation dialog will pop-up after dragging and dropping an event.'),
];
$locale = [
'current_lang' => $this
->t('Current active language on the page'),
'en' => 'English',
'af' => 'Afrikaans',
'ar-dz' => 'Arabic - Algeria',
'ar-kw' => 'Arabic - Kuwait',
'ar-ly' => 'Arabic - Libya',
'ar-ma' => 'Arabic - Morocco',
'ar-sa' => 'Arabic - Saudi Arabia',
'ar-tn' => 'Arabic - Tunisia',
'ar' => 'Arabic',
'bg' => 'Bulgarian',
'ca' => 'Catalan',
'cs' => 'Czech',
'da' => 'Danish',
'de-at' => 'German - Austria',
'de-ch' => 'German - Switzerland',
'de' => 'German',
'el' => 'Greek',
'en-au' => 'English - Australia',
'en-ca' => 'English - Canada',
'en-gb' => 'English - United Kingdom',
'en-ie' => 'English - Ireland',
'en-nz' => 'English - New Zealand',
'es-do' => 'Spanish - Dominican Republic',
'es-us' => 'Spanish - United States',
'es' => 'Spanish',
'et' => 'Estonian',
'eu' => 'Basque',
'fa' => 'Farsi',
'fi' => 'Finnish',
'fr-ca' => 'French - Canada',
'fr-ch' => 'French - Switzerland',
'fr' => 'French',
'gl' => 'Galician',
'he' => 'Hebrew',
'hi' => 'Hindi',
'hr' => 'Croatian',
'hu' => 'Hungarian',
'id' => 'Indonesian',
'is' => 'Icelandic',
'it' => 'Italian',
'ja' => 'Japanese',
'kk' => 'Kannada',
'ko' => 'Korean',
'lb' => 'Lebanon',
'lt' => 'Lithuanian',
'lv' => 'Latvian',
'mk' => 'FYRO Macedonian',
'ms-my' => 'Malay - Malaysia',
'ms' => 'Malay',
'nb' => 'Norwegian (Bokmål) - Norway',
'nl-be' => 'Dutch - Belgium',
'nl' => 'Dutch',
'nn' => 'Norwegian',
'pl' => 'Polish',
'pt-br' => 'Portuguese - Brazil',
'pt' => 'Portuguese',
'ro' => 'Romanian',
'ru' => 'Russian',
'sk' => 'Slovak',
'sl' => 'Slovenian',
'sq' => 'Albanian',
'sr-cyrl' => 'Serbian - Cyrillic',
'sr' => 'Serbian',
'sv' => 'Swedish',
'th' => 'Thai',
'tr' => 'Turkish',
'uk' => 'Ukrainian',
'vi' => 'Vietnamese',
'zh-cn' => 'Chinese - China',
'zh-tw' => 'Chinese - Taiwan',
];
$form['defaultLanguage'] = [
'#title' => $this
->t('Default Language'),
'#fieldset' => 'display',
'#type' => 'select',
'#options' => $locale,
'#default_value' => !empty($this->options['defaultLanguage']) ? $this->options['defaultLanguage'] : 'en',
];
$form['languageSelector'] = [
'#type' => 'checkbox',
'#fieldset' => 'display',
'#default_value' => empty($this->options['languageSelector']) ? 0 : $this->options['languageSelector'],
'#title' => $this
->t('Allow client to select language.'),
];
$form['dialogWindow'] = [
'#type' => 'checkbox',
'#fieldset' => 'display',
'#default_value' => empty($this->options['dialogWindow']) ? 0 : $this->options['dialogWindow'],
'#title' => $this
->t('Open event links in dialog window.'),
'#description' => $this
->t('If this option is selected and the title field is linked to entity, event links in the calendar will open in a dialog window.'),
];
$form['createEventLink'] = [
'#type' => 'checkbox',
'#fieldset' => 'display',
'#default_value' => empty($this->options['createEventLink']) ? 0 : $this->options['createEventLink'],
'#title' => $this
->t('Create a new event via the Off-Canvas dialog.'),
'#description' => $this
->t('If this option is selected, there wiil be an Add Event link below the calendar that provides the ability to create an event In-Place.'),
];
$form['openEntityInNewTab'] = [
'#type' => 'checkbox',
'#fieldset' => 'display',
'#default_value' => !isset($this->options['openEntityInNewTab']) ? 1 : $this->options['openEntityInNewTab'],
'#title' => $this
->t('Open entities (calendar items) into new tabs'),
];
$form['colors'] = [
'#type' => 'details',
'#title' => $this
->t('Legend Colors'),
'#description' => $this
->t('Set color value of legends for each content type or each taxonomy.'),
];
$cabNames = taxonomy_vocabulary_get_names();
$tax_fields = [];
foreach ($field_names as $field_name => $lable) {
$field_conf = FieldStorageConfig::loadByName($entity_type, $field_name);
if (empty($field_conf)) {
continue;
}
if ($field_conf
->getType() == 'entity_reference') {
$tax_fields[$field_name] = $lable;
}
}
$moduleHandler = \Drupal::service('module_handler');
if ($moduleHandler
->moduleExists('taxonomy')) {
$form['tax_field'] = [
'#title' => $this
->t('Event Taxonomy Field'),
'#description' => $this
->t('In order to specify colors for event taxonomies, you must select a taxonomy reference field for the View.'),
'#type' => 'select',
'#options' => $tax_fields,
'#empty_value' => '',
'#disabled' => empty($tax_fields),
'#fieldset' => 'colors',
'#default_value' => !empty($this->options['tax_field']) ? $this->options['tax_field'] : '',
];
$form['vocabularies'] = [
'#title' => $this
->t('Vocabularies'),
'#type' => 'select',
'#options' => $cabNames,
'#empty_value' => '',
'#fieldset' => 'colors',
'#description' => $this
->t('Specify which vocabulary is using for calendar event color. If the vocabulary selected is not the one that the taxonomy field belonging to, the color setting would be ignored.'),
'#default_value' => !empty($this->options['vocabularies']) ? $this->options['vocabularies'] : '',
'#states' => [
'invisible' => [
[
':input[name="style_options[tax_field]"]' => [
'value' => '',
],
],
],
],
'#ajax' => [
'callback' => 'Drupal\\fullcalendar_view\\Plugin\\views\\style\\FullCalendarDisplay::taxonomyColorCallback',
'event' => 'change',
'wrapper' => 'color-taxonomies-div',
'progress' => [
'type' => 'throbber',
'message' => $this
->t('Verifying entry...'),
],
],
];
}
if (!isset($form_state
->getUserInput()['style_options'])) {
$form['color_taxonomies'] = $this->taxonomyColorService
->colorInputBoxs($this->options['vocabularies'], $this->options['color_taxonomies']);
}
$form['color_bundle'] = [
'#type' => 'details',
'#title' => $this
->t('Colors for Bundle Types'),
'#description' => $this
->t('Specify colors for each bundle type. If taxonomy color is specified, this settings would be ignored.'),
'#fieldset' => 'colors',
];
$bundles = \Drupal::service('entity_type.bundle.info')
->getBundleInfo($entity_type);
$bundlesList = [];
foreach ($bundles as $id => $bundle) {
$label = $bundle['label'];
$bundlesList[$id] = $label;
$form['color_bundle'][$id] = [
'#title' => $label,
'#default_value' => isset($this->options['color_bundle'][$id]) ? $this->options['color_bundle'][$id] : '#3a87ad',
'#type' => 'color',
];
}
if ($moduleHandler
->moduleExists('calendar_recurring_event')) {
$form['recurring'] = [
'#type' => 'details',
'#title' => $this
->t('Recurring event settings'),
];
$form['business_start'] = [
'#type' => 'datetime',
'#title' => $this
->t('Business start time'),
'#description' => $this
->t('The time of a day when a recurring all day event starts. The recurring events whose start date include hour and minute will use their respective start time instead.'),
'#fieldset' => 'recurring',
'#default_value' => empty($this->options['business_start']) ? new DrupalDateTime('2018-02-24T08:00:00') : new DrupalDateTime($this->options['business_start']),
'#date_date_element' => 'none',
'#date_time_element' => 'time',
'#date_time_format' => 'H:i',
];
$form['business_end'] = [
'#type' => 'datetime',
'#title' => $this
->t('Business end time'),
'#description' => $this
->t('The time of a day when a recurring event ends. The recurring events whose end date include hour and minute will use their respective end time instead.'),
'#fieldset' => 'recurring',
'#default_value' => empty($this->options['business_end']) ? new DrupalDateTime('2018-02-24T18:00:00') : new DrupalDateTime($this->options['business_end']),
'#date_date_element' => 'none',
'#date_time_element' => 'time',
'#date_time_format' => 'H:i',
];
$form['excluding_dates'] = [
'#title' => $this
->t('Excluding dates Field'),
'#description' => $this
->t('Choose field date with excluding dates.'),
'#type' => 'select',
'#fieldset' => 'recurring',
'#options' => $field_names,
'#default_value' => !empty($this->options['excluding_dates']) ? $this->options['excluding_dates'] : '',
];
}
$form['bundle_type'] = [
'#title' => $this
->t('Event bundle (Content) type'),
'#description' => $this
->t('The bundle (content) type of a new event. Once this is set, you can create a new event by double clicking a calendar entry.'),
'#type' => 'select',
'#options' => $bundlesList,
'#default_value' => !empty($this->options['bundle_type']) ? $this->options['bundle_type'] : '',
];
$form['classes'] = [
'#type' => 'textfield',
'#title' => $this
->t('CSS classes'),
'#default_value' => isset($this->options['classes']) ? $this->options['classes'] : '',
'#description' => $this
->t('CSS classes for further customization of this view.'),
];
}
public function submitOptionsForm(&$form, FormStateInterface $form_state) {
$options =& $form_state
->getValue('style_options');
$input_value = $form_state
->getUserInput();
$input_colors = isset($input_value['style_options']['color_taxonomies']) ? $input_value['style_options']['color_taxonomies'] : [];
foreach ($input_colors as $id => $color) {
if (!empty($color)) {
$options['color_taxonomies'][$id] = $color;
}
}
if (isset($options['business_start'])) {
$options['business_start'] = $options['business_start']
->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT);
}
if (isset($options['business_end'])) {
$options['business_end'] = $options['business_end']
->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT);
}
$options['timeFormat'] = Xss::filter($options['timeFormat']);
parent::submitOptionsForm($form, $form_state);
}
public static function taxonomyColorCallback(array &$form, FormStateInterface $form_state) {
$options = $form_state
->getValue('style_options');
$vid = $options['vocabularies'];
$taxonomy_color_service = \Drupal::service('fullcalendar_view.taxonomy_color');
if (isset($options['color_taxonomies'])) {
$defaultValues = $options['color_taxonomies'];
}
else {
$defaultValues = [];
}
$form['color_taxonomies'] = $taxonomy_color_service
->colorInputBoxs($vid, $defaultValues, TRUE);
return $form['color_taxonomies'];
}
}