You are here

fullcalendar.module in FullCalendar 8.5

Provides a views style plugin for FullCalendar

File

fullcalendar.module
View source
<?php

/**
 * @file
 * Provides a views style plugin for FullCalendar
 */
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\views\Plugin\views\field\EntityField;

/**
 * The minimum supported version of the FullCalendar plugin.
 */
define('FULLCALENDAR_MIN_PLUGIN_VERSION', '4.0.0');

/**
 * Implements hook_help().
 */
function fullcalendar_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {
    case 'help.page.fullcalendar':
      $output = '';
      $output .= '<h3>' . t('Fullcalendar') . '</h3>';
      $output .= '<p>' . t('The Fullcalendar module is an integration of the <a href=":fullcalendar-uri">Adam Shaw\'s FullCalendar Javascript calendar</a> with Drupal.', [
        ':fullcalendar-uri' => Url::fromUri('https://fullcalendar.io')
          ->toString(),
      ]) . '</p>';
      return $output;
  }
}

/**
 * Implements hook_theme().
 */
function fullcalendar_theme($existing, $type, $theme, $path) {
  return [
    'views_view__fullcalendar' => [
      'template' => 'views-view--fullcalendar',
      'base hook' => 'view',
    ],
  ];
}

/**
 * Implements hook_permission().
 *
 * @return array
 *   An array of valid permissions for the FullCalendar module.
 */
function fullcalendar_permission() {
  return [
    'update any fullcalendar event' => [
      'title' => t('Update any FullCalendar event'),
      'description' => t('Allow user to edit events, ignoring other permissions.'),
    ],
  ];
}

/**
 * Implements hook_fullcalendar_classes().
 */
function fullcalendar_fullcalendar_classes(EntityInterface $entity) {
  $classes = [];
  if (\Drupal::moduleHandler()
    ->moduleExists('colors')) {
    $classes = array_merge($classes, \Drupal::service('module_handler')
      ->invokeAll('colors_classes', [
      $entity,
    ]));
  }
  $classes = array_merge($classes, [
    'fc-event-default',
    $entity
      ->bundle(),
  ]);
  return $classes;
}

/**
 * Implements hook_form_FORM_ID_alter() for views_ui_edit_display_form().
 *
 * Since we force the query to be distinct, reflect that in the UI.
 */
function fullcalendar_form_views_ui_edit_display_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $style = $form_state
    ->get('view')
    ->get('executable')->display_handler
    ->getOption('style');
  if ($style['type'] != 'fullcalendar' || empty($form['options']['query']['options']['distinct'])) {
    return;
  }
  $distinct =& $form['options']['query']['options']['distinct'];
  if (!isset($distinct['#description'])) {
    $distinct['#description'] = '';
  }
  else {
    $distinct['#description'] .= '<br>';
  }
  $distinct['#disabled'] = TRUE;
  $distinct['#description'] .= '<strong>' . t('FullCalendar requires that the query be distinct.') . '</strong>';
}

/**
 * Determines if a given field is a date field.
 *
 * @param \Drupal\views\Plugin\views\field\EntityField $field
 *   A Views field handler object.
 *
 * @return bool
 *   Boolean, TRUE if the field is a date field, FALSE otherwise.
 */
function fullcalendar_field_is_date(EntityField $field) {
  if (!$field instanceof EntityField) {
    return FALSE;
  }
  $entity_type = $field->definition['entity_type'];
  if (empty($entity_type)) {
    return FALSE;
  }

  /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $field_manager */
  $field_manager = \Drupal::getContainer()
    ->get('entity_field.manager');

  /** @var \Drupal\Core\Field\FieldStorageDefinitionInterface[] $field_storages */
  $field_storages = $field_manager
    ->getFieldStorageDefinitions($entity_type);
  if (isset($field_storages[$field->definition['field_name']])) {

    /** @var \Drupal\Core\Field\FieldStorageDefinitionInterface $field_storage */
    $field_storage = $field_storages[$field->definition['field_name']];
    return in_array($field_storage
      ->getType(), [
      'datetime',
      'daterange',
      'date_recur',
    ]);
  }
  return FALSE;
}

/**
 * Returns the version of FullCalendar plugin that is installed.
 *
 * This can be used by other modules' hook_requirements() to ensure that the
 * proper version of FullCalendar plugin is installed.
 *
 * @see version_compare()
 */
function fullcalendar_get_version($fullcalendar_path = NULL) {
  $version =& drupal_static(__FUNCTION__);
  if (empty($version)) {
    $version = 0;
    $pattern = '#FullCalendar Core Package v([0-9\\.a-z]+)#';

    // No file is passed in so use the default location.
    if (!$fullcalendar_path) {
      $fullcalendar_path = fullcalendar_get_js_path();
    }

    // Return the version of FullCalendar plugin.
    $fullcalendar_plugin = file_get_contents($fullcalendar_path, NULL, NULL, 0, 40);
    if (preg_match($pattern, $fullcalendar_plugin, $matches)) {
      $version = $matches[1];
    }
  }
  return $version;
}

/**
 * Returns the path to the FullCalendar plugin.
 */
function fullcalendar_get_js_path() {
  $fullcalendar_file = [
    'none' => 'main.js',
    'min' => 'main.js',
  ];
  $config = \Drupal::config('fullcalendar.settings');
  return $config
    ->get('path') . '/' . $fullcalendar_file[$config
    ->get('compression')];
}

/**
 * Implements hook_theme_suggestions_alter().
 */
function fullcalendar_theme_suggestions_alter(array &$suggestions, array $variables, $hook) {
  if ($hook === 'views_view') {
    $suggestions[] = "views_view__" . $variables['view']->style_plugin
      ->getPluginId();
  }
}

/**
 * Implements hook_preprocess_fullcalendar().
 *
 * Process FullCalendar Colors after the structure is built.
 */
function fullcalendar_page_attachments(array &$attachments) {

  // TODO D8: Remove weight once http://drupal.org/node/1388546 is fixed.
  // TODO: This doesn't work because the style tag is positioned too high in
  // the head to have any effect.
  $css = colors_create_css('fullcalendar');
  $attachments['#attached']['html_head'][] = [
    [
      '#type' => 'html_tag',
      '#tag' => 'style',
      '#value' => $css,
      '#weight' => 1000,
    ],
    'fullcalendar-inline-css',
  ];
}

/**
 * Implements hook_colors_rebuild().
 */
function fullcalendar_colors_rebuild() {
  return TRUE;
}

/**
 * Implements hook_colors_build_selector().
 */
function fullcalendar_colors_build_selector($class) {
  $selector = [
    ".{$class}",
    ".{$class} .fc-event-default",
    ".{$class} .fc-event-default .fc-event-skin",
    ".{$class} .fc-event-default .fc-event-time",
    ".{$class} .fc-event-default a",
  ];
  return implode(', ', $selector);
}

/**
 * Implements hook_fullcalendar_palette().
 */
function fullcalendar_fullcalendar_palette($entity) {
  $palette = [];
  if (\Drupal::moduleHandler()
    ->moduleExists('colors')) {
    $palettes = \Drupal::service('module_handler')
      ->invokeAll('colors_palette', [
      $entity,
    ]);
    if (!empty($palettes)) {
      $palettes = reset($palettes);
      $palette['backgroundColor'] = $palettes['bg'];
      $palette['borderColor'] = $palettes['borders'];
      $palette['textColor'] = $palettes['text'];
    }
  }
  return $palette;
}

Functions

Namesort descending Description
fullcalendar_colors_build_selector Implements hook_colors_build_selector().
fullcalendar_colors_rebuild Implements hook_colors_rebuild().
fullcalendar_field_is_date Determines if a given field is a date field.
fullcalendar_form_views_ui_edit_display_form_alter Implements hook_form_FORM_ID_alter() for views_ui_edit_display_form().
fullcalendar_fullcalendar_classes Implements hook_fullcalendar_classes().
fullcalendar_fullcalendar_palette Implements hook_fullcalendar_palette().
fullcalendar_get_js_path Returns the path to the FullCalendar plugin.
fullcalendar_get_version Returns the version of FullCalendar plugin that is installed.
fullcalendar_help Implements hook_help().
fullcalendar_page_attachments Implements hook_preprocess_fullcalendar().
fullcalendar_permission Implements hook_permission().
fullcalendar_theme Implements hook_theme().
fullcalendar_theme_suggestions_alter Implements hook_theme_suggestions_alter().

Constants

Namesort descending Description
FULLCALENDAR_MIN_PLUGIN_VERSION The minimum supported version of the FullCalendar plugin.