| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440 |
- <?php
- /**
- * @file
- * Provides a views style plugin for FullCalendar
- */
- /**
- * The default path to the FullCalendar plugin.
- */
- function fullcalendar_default_path() {
- return module_exists('libraries') ? libraries_get_path('fullcalendar') : 'sites/all/libraries/fullcalendar';
- }
- /**
- * The minimum supported version of the FullCalendar plugin.
- */
- define('FULLCALENDAR_MIN_PLUGIN_VERSION', '1.4.10');
- /**
- * The recommended version of the FullCalendar plugin.
- */
- define('FULLCALENDAR_RECOMMENDED_PLUGIN_VERSION', '1.5.1');
- /**
- * Implements hook_views_api().
- */
- function fullcalendar_views_api() {
- return array(
- 'api' => '3',
- 'path' => drupal_get_path('module', 'fullcalendar') . '/includes/views',
- );
- }
- /**
- * Implements hook_theme().
- */
- function fullcalendar_theme($existing, $type, $theme, $path) {
- return array(
- 'fullcalendar_event' => array(
- 'variables' => array(
- 'event' => NULL,
- 'entity' => NULL,
- ),
- 'file' => 'theme.inc',
- 'path' => $path . '/theme',
- ),
- );
- }
- /**
- * Implements hook_library().
- */
- function fullcalendar_library() {
- $path = variable_get('fullcalendar_path', fullcalendar_default_path());
- $css_files = array($path . '/fullcalendar.css' => array('media' => 'screen'));
- // Add fullcalendar.print.css if it is available.
- if (version_compare(fullcalendar_get_version(), '1.5.0', '>=')) {
- $css_files[$path . '/fullcalendar.print.css'] = array('media' => 'print');
- }
- $libraries['fullcalendar'] = array(
- 'title' => 'FullCalendar',
- 'website' => 'http://arshaw.com/fullcalendar',
- 'version' => FULLCALENDAR_MIN_PLUGIN_VERSION,
- 'js' => array(
- fullcalendar_get_js_path() => array(),
- $path . '/gcal.js' => array(),
- ),
- 'css' => $css_files,
- 'dependencies' => array(
- array('system', 'ui.draggable'),
- array('system', 'ui.droppable'),
- array('system', 'ui.resizable'),
- array('system', 'effects.highlight'),
- ),
- );
- return $libraries;
- }
- /**
- * Implements hook_permission().
- *
- * @return array
- * An array of valid permissions for the FullCalendar module.
- */
- function fullcalendar_permission() {
- return array(
- 'update any fullcalendar event' => array(
- 'title' => t('Update any FullCalendar event'),
- 'description' => t('Allow user to edit events, ignoring other permissions.'),
- ),
- );
- }
- /**
- * Implements hook_menu().
- *
- * @return array
- * An array of menu items.
- */
- function fullcalendar_menu() {
- $items = array();
- $items['admin/config/user-interface/fullcalendar'] = array(
- 'title' => 'FullCalendar',
- 'description' => 'Adjust FullCalendar settings.',
- 'file' => 'fullcalendar.admin.inc',
- 'file path' => drupal_get_path('module', 'fullcalendar') . '/includes',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('fullcalendar_admin_settings'),
- 'access arguments' => array('administer site configuration'),
- 'type' => MENU_NORMAL_ITEM,
- 'weight' => 0,
- );
- $items['admin/config/user-interface/fullcalendar/default'] = array(
- 'title' => 'FullCalendar',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- 'weight' => 0,
- );
- $items['fullcalendar/ajax/update/%/%'] = array(
- 'title' => 'Update event',
- 'description' => 'Save the updated event datetime.',
- 'page callback' => 'fullcalendar_update',
- 'page arguments' => array(3, 4),
- 'access callback' => '_fullcalendar_update_access',
- 'access arguments' => array(4),
- 'type' => MENU_CALLBACK,
- );
- $items['fullcalendar/ajax/results'] = array(
- 'title' => 'Events',
- 'description' => 'Get events from views with arguments',
- 'page callback' => 'fullcalendar_results',
- 'access arguments' => array('access content'),
- 'delivery callback' => 'ajax_deliver',
- 'theme callback' => 'ajax_base_page_theme',
- 'type' => MENU_CALLBACK,
- );
- return $items;
- }
- /**
- * Saves the updated FullCalendar event's datetime.
- *
- * @param string $action
- * Value can be 'drop' or 'resize'.
- * @param int $eid
- * The id of the entity that will be updated.
- */
- function fullcalendar_update($action, $eid) {
- if (empty($_POST['field']) || !isset($_POST['index'])) {
- return;
- }
- // Retrieve the post vars form the ajax call.
- $field = check_plain($_POST['field']);
- $index = check_plain($_POST['index']);
- $all_day = isset($_POST['all_day']) ? check_plain($_POST['all_day']) : '';
- $delta = ' ' . check_plain($_POST['day_delta']) . ' days ' . check_plain($_POST['minute_delta']) . ' minutes';
- $entity_type = check_plain($_POST['entity_type']);
- $entity = entity_load($entity_type, array($eid));
- $entity = reset($entity);
- $langcode = field_language($entity_type, $entity, $field);
- $item = &$entity->{$field}[$langcode][$index];
- $old_start = $item['value'];
- $old_end = $item['value2'];
- // Adjust for different date formats.
- $format = date_type_format($item['date_type']);
- // Datestamp can't combine with words for strtotime, convert to ISO for now.
- if ($format == DATE_FORMAT_UNIX) {
- $old_start = date(DATE_FORMAT_ISO, $old_start);
- $old_end = date(DATE_FORMAT_ISO, $old_end);
- }
- // No break after 'drop' so it will reuse the code of 'resize'.
- switch ($action) {
- case 'drop':
- $item['value'] = date($format, strtotime($old_start . $delta));
- case 'resize':
- $item['value2'] = date($format, strtotime($old_end . $delta));
- break;
- }
- // Save the new start/end values.
- if (module_exists('entity')) {
- entity_save($entity_type, $entity);
- }
- else {
- field_attach_presave($entity_type, $entity);
- field_attach_update($entity_type, $entity);
- }
- drupal_json_output(array('msg' => t('The new event time has been saved.') . ' [' . l(t('Close'), NULL, array('attributes' => array('class' => array('fullcalendar-status-close')))) . ']', 'dom_id' => $_POST['dom_id']));
- }
- /**
- * Implements hook_fullcalendar_classes().
- */
- function fullcalendar_fullcalendar_classes($entity) {
- $classes = array(
- 'fc-event-default',
- $entity->bundle,
- );
- // Add a class for the date field being used.
- if (isset($entity->fullcalendar_date_field)) {
- $classes[] = "fc-event-field-$entity->fullcalendar_date_field";
- }
- 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, &$form_state, $form_id) {
- if ($form_state['view']->display_handler->get_option('style_plugin') != '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>';
- }
- /**
- * Returns events for FullCalendar.
- */
- function fullcalendar_results($view_name = NULL, $view_display = NULL) {
- // Bail out if no view_name or view_display is passed.
- if (empty($view_name) || empty($view_display) || empty($_POST['dom_id'])) {
- return;
- }
- // Find Views arguments.
- $args = func_get_args();
- unset($args[0], $args[1]);
- $args = array_values($args);
- $dom_id = check_plain($_POST['dom_id']);
- $view_name = check_plain($view_name);
- $view_display = check_plain($view_display);
- // Add all $_POST data, because AJAX is always a post and many things,
- // such as tablesorts, exposed filters and paging assume $_GET.
- $_GET += $_POST;
- // Get the view and check access.
- $view = views_get_view($view_name);
- if (!$view || !$view->access($view_display)) {
- return;
- }
- if (!$view->set_display($view_display)) {
- return;
- }
- $view->dom_id = $dom_id;
- $view->fullcalendar_ajax = TRUE;
- $view->pre_execute($args);
- $view->init_style();
- $view->execute($view_display);
- $output = $view->style_plugin->render();
- $view->post_execute();
- return array(
- '#type' => 'ajax',
- '#commands' => array(
- array('command' => 'fullcalendar_results_response', 'data' => $output),
- ),
- );
- }
- /**
- * Checks if the user has access to update the given FullCalendar event.
- *
- * @param object $entity
- * The entity that will be updated.
- *
- * @return bool
- * TRUE if the user is allowed to update the entity;
- * FALSE if the user is not permitted to update the entity.
- */
- function _fullcalendar_update_access($entity) {
- global $user;
- if (!empty($entity) && ((user_access('administer content')
- || user_access('update any fullcalendar event')
- || user_access('edit any ' . $entity->bundle . ' content')
- || (user_access('edit own ' . $entity->bundle . ' content') && $entity->uid == $user->uid)))) {
- return TRUE;
- }
- return FALSE;
- }
- /**
- * Implements hook_fullcalendar_editable().
- *
- * Use our access callback as the editable setting.
- */
- function fullcalendar_fullcalendar_editable($entity, $view) {
- return _fullcalendar_update_access($entity);
- }
- /**
- * Determines if a given field is a date field.
- *
- * @param object $field
- * A Views field handler object.
- * @param bool $include_gcal
- * Boolean indicating whether or not to count gcal fields as a date field.
- *
- * @return bool
- * Boolean, TRUE if the field is a date field, FALSE otherwise.
- */
- function fullcalendar_field_is_date($field, $include_gcal = FALSE) {
- if ($include_gcal && $field->field == 'gcal') {
- return TRUE;
- }
- return !empty($field->definition['is date']) && isset($field->field_info);
- }
- /**
- * Checks FullCalendar dependencies.
- *
- * @return bool
- * Array with TRUE/FALSE for each dependency.
- *
- * @see fullcalendar_requirements()
- */
- function _fullcalendar_status() {
- $status = array();
- $status['fullcalendar_plugin'] = FALSE;
- $path = fullcalendar_get_js_path();
- if (!file_exists($path)) {
- return FALSE;
- }
- if (version_compare(fullcalendar_get_version($path), FULLCALENDAR_MIN_PLUGIN_VERSION, '>=')) {
- $status['fullcalendar_plugin'] = TRUE;
- }
- return $status;
- }
- /**
- * 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 v([0-9\.a-z]+)#';
- // No file is passed in so use the default location.
- if (is_null($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 = array('none' => 'fullcalendar.js', 'min' => 'fullcalendar.min.js');
- return variable_get('fullcalendar_path', fullcalendar_default_path()) . '/' . $fullcalendar_file[variable_get('fullcalendar_compression_type', 'min')];
- }
- /**
- * Includes all FullCalendar API plugins.
- */
- function fullcalendar_include_api() {
- ctools_include('plugins');
- return ctools_plugin_api_include('fullcalendar', 'fullcalendar', fullcalendar_api_version(), fullcalendar_api_minimum_version());
- }
- /**
- * Implements hook_ctools_plugin_api_hook_name().
- */
- function fullcalendar_ctools_plugin_api_hook_name() {
- return 'fullcalendar_api';
- }
- /**
- * Declares the current FullCalendar API version.
- */
- function fullcalendar_api_version() {
- return '1';
- }
- /**
- * Declares the minimum FullCalendar API version.
- */
- function fullcalendar_api_minimum_version() {
- return '1';
- }
- /**
- * Implements hook_fullcalendar_api().
- */
- function fullcalendar_fullcalendar_api() {
- return array(
- 'api' => fullcalendar_api_version(),
- 'path' => drupal_get_path('module', 'fullcalendar') . '/includes',
- );
- }
|