You are here

appointment_calendar.module in Appointment Calendar 7

Same filename and directory in other branches
  1. 8 appointment_calendar.module

Adds Appointment calendar filtering and displays Availability.

File

appointment_calendar.module
View source
<?php

/**
 * @file
 * Adds Appointment calendar filtering and displays Availability.
 */

/**
 * Implements hook_permission().
 */
function appointment_calendar_permission() {
  return array(
    'access appointment calendar settings page' => array(
      'title' => t('Access Appointment Calendar Settings'),
      'description' => t('Appointment Calendar for Timeslots booking using Node creation'),
    ),
    'access appointment calendar list page' => array(
      'title' => t('Access Appointment Calendar Settings'),
      'description' => t('Datewise List for Appointment Calendar'),
    ),
    'access appointment calendar view page' => array(
      'title' => t('Access Appointment Calendar View Page'),
      'description' => t('List for Appointment Calendar View'),
    ),
    'access appointment calendar edit page' => array(
      'title' => t('Access Appointment Calendar Edit Page'),
      'description' => t('List for Appointment Calendar Edit'),
    ),
    'access appointment calendar delete page' => array(
      'title' => t('Access Appointment Calendar Delete Page'),
      'description' => t('List for Appointment Calendar Edit'),
    ),
  );
}

/**
 * Implements hook_menu().
 */
function appointment_calendar_menu() {
  $items = array();
  $items['admin/config/appointment-calendar/settings'] = array(
    'title' => 'Appointment Calendar',
    'description' => 'Configuration Page for Appointment Calendar',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'appointment_calendar_settings_form',
    ),
    'file' => 'appointment_calendar_admin_settings.inc',
    'access arguments' => array(
      'access appointment calendar settings page',
    ),
    'type' => MENU_NORMAL_ITEM,
  );
  $items['admin/config/appointment-calendar/settings/list-date'] = array(
    'title' => 'Appointment Calendar Date List',
    'description' => 'List of Appointment Calendar Date(s) that have time slot(s)',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'appointment_calendar_date_list_form',
    ),
    'file' => 'appointment_calendar_list.inc',
    'access arguments' => array(
      'access appointment calendar list page',
    ),
  );
  $items['admin/appointment-calendar/view'] = array(
    'title' => 'Appointment Calendar Date View',
    'description' => 'View Appointment Calendar',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'appointment_calendar_view_date_form',
    ),
    'file' => 'appointment_calendar_view.inc',
    'access arguments' => array(
      'access appointment calendar view page',
    ),
    'type' => MENU_SUGGESTED_ITEM,
  );
  $items['admin/appointment-calendar/edit'] = array(
    'title' => 'Appointment Calendar Date Edit',
    'description' => 'Edit Appointment Calendar',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'appointment_calendar_list_date_form',
    ),
    'file' => 'appointment_calendar_edit.inc',
    'access arguments' => array(
      'access appointment calendar edit page',
    ),
    'type' => MENU_SUGGESTED_ITEM,
  );
  $items['admin/appointment-calendar/delete'] = array(
    'title' => 'Appointment Calendar Date Delete',
    'description' => 'Delete Appointment Calendar',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'appointment_calendar_list_delete_form',
    ),
    'file' => 'appointment_calendar_delete.inc',
    'access arguments' => array(
      'access appointment calendar delete page',
    ),
    'type' => MENU_SUGGESTED_ITEM,
  );
  $items['appointcal'] = array(
    'page callback' => 'appointment_calendar_appointment_show',
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
  return $items;
}

/**
 * Implements hook_node_info().
 */
function appointment_calendar_node_info() {
  return array(
    'appointment_calendar' => array(
      'name' => t('Appointment Calendar'),
      'base' => 'appointment',
      'description' => t('A appointment calendar content type'),
      'has_title' => TRUE,
      'locked' => FALSE,
    ),
  );
}

/**
 * Implements hook_form().
 */
function appointment_calendar_form($node, $form_state) {

  // Adds title in appointment calendar node.
  $type = node_type_get_type($node);
  $form['title'] = array(
    '#type' => 'textfield',
    '#title' => check_plain($type->title_label),
    '#default_value' => !empty($node->title) ? $node->title : '',
    '#required' => TRUE,
    '#weight' => -5,
  );
  return $form;
}

/**
 * Implements hook_form_alter().
 */
function appointment_calendar_form_alter(&$form, &$form_state, $form_id) {

  // In Appointment Calendar node.
  global $base_url;
  if ($form_id == 'appointment_calendar_node_form') {
    $form['appointment_date'][LANGUAGE_NONE][0]['#ajax'] = array(
      'callback' => 'appointment_calendar_appointment_calendar_timeslot_callback_form',
      'wrapper' => 'slot-check',
      'method' => 'replace',
      'effect' => 'fade',
    );
    $form['error_msg'] = array(
      '#markup' => '<div class="error-calendar"></div>',
    );
    $form['appointment_slot']['#prefix'] = '<div id="slot-check">';
    if (!empty($form_state['values'])) {

      // Fetch Timeslots.
      $selected_date = $form_state['values']['appointment_date'][LANGUAGE_NONE][0]['value'];
      $selected_date = explode('T', $form_state['values']['appointment_date'][LANGUAGE_NONE][0]['value']);
      $slot_query = db_select('appointment_date', 'ad');
      $slot_query
        ->fields('ad', array(
        'slot_values',
      ));
      $slot_query
        ->condition('date', strtotime($selected_date[0]));
      $slot_result = $slot_query
        ->execute()
        ->fetchField();
      if (!empty($slot_result)) {
        $form['appointment_slot'][LANGUAGE_NONE]['#options'] = (array) json_decode($slot_result);
      }
    }
    else {
      $selected_date = explode('T', $form['appointment_date'][LANGUAGE_NONE][0]['#default_value']['value']);
      $slot_query = db_select('appointment_date', 'ad');
      $slot_query
        ->fields('ad', array(
        'slot_values',
      ));
      $slot_query
        ->condition('date', strtotime($selected_date[0]));
      $slot_result = $slot_query
        ->execute()
        ->fetchField();
      if (!empty($slot_result)) {
        $form['appointment_slot'][LANGUAGE_NONE]['#options'] = (array) json_decode($slot_result);
      }
    }

    // Set values in edit page.
    if (arg(2) == 'edit') {
      $selected_date = $form['appointment_date'][LANGUAGE_NONE][0]['#default_value']['value'];
      $selected_date = explode('T', $selected_date);
      $slot_query = db_select('appointment_date', 'ad');
      $slot_query
        ->fields('ad', array(
        'slot_values',
      ));
      $slot_query
        ->condition('date', strtotime($selected_date[0]));
      $slot_result = $slot_query
        ->execute()
        ->fetchField();
      $slot_value = appointment_calendar_slot_value(arg(1));

      // Default time slot fetch and values filled for date.
      if (!empty($slot_result)) {
        $form['appointment_slot'][LANGUAGE_NONE]['#options'] = (array) json_decode($slot_result);
        $form['appointment_slot'][LANGUAGE_NONE]['#default_value'] = $slot_value;
      }
    }
    $form['appointment_slot']['#suffix'] = '</div>';
    $form['check'] = array(
      '#type' => 'button',
      '#value' => 'Check Availability',
      '#weight' => 34,
      '#ajax' => array(
        'callback' => 'appointment_calendar_check_availability_form',
        'wrapper' => 'check-availability',
      ),
    );
    $form['calendar'] = array(
      '#weight' => 39,
      '#suffix' => '<div id="check-availability" style="display:none"><iframe width="350px" src= "' . $base_url . '/appointcal"></iframe></div>',
    );

    // Validate function to check availability in submit.
    $form['#validate'][] = 'appointment_calendar_node_form_validate';
    $form['#attached']['js'] = array(
      drupal_get_path('module', 'appointment_calendar') . '/js/appointment_calendar.js',
    );
  }
}

/**
 * Implements hook_form_validate().
 */
function appointment_calendar_node_form_validate($form, &$form_state) {

  // In Appointment calendar node.
  if (arg(1) == 'add') {
    if ($form_state['values']['op'] == t('Save')) {
      $form['#attached']['js'] = array(
        drupal_get_path('module', 'appointment_calendar') . '/js/appointment_calendar.js',
      );
      $time_slot = $form_state['values']['appointment_slot'][LANGUAGE_NONE][0]['value'];

      // Check for empty timeslot.
      if (strlen($time_slot) == 0) {
        form_set_error('appointment_slot', t('Time slot not available for Selected Date'));
        return FALSE;
      }

      // Checking for completed slots before submit.
      $selected_date = $form_state['values']['appointment_date'][LANGUAGE_NONE][0]['value'];
      $date_query = db_select('field_data_appointment_date', 'ap');
      $date_query
        ->join('field_data_appointment_slot', 'aps', 'aps.entity_id = ap.entity_id');
      $date_query
        ->fields('aps', array(
        'appointment_slot_value ',
      ));
      $date_query
        ->condition('ap.appointment_date_value', $selected_date, '=');
      $date_queryresult = $date_query
        ->execute()
        ->fetchAll(PDO::FETCH_ASSOC);
      $date = explode('T', $selected_date);
      $slot_capacity = appointment_calendar_slot_capacity(strtotime($date[0]));

      // Booked slots is greater than or equal to allowed capacity.
      if (!empty($slot_capacity)) {
        $capacity = json_decode($slot_capacity);
        if (count($date_queryresult) >= $capacity->{$time_slot}) {
          $form_state['values']['appointment_date'][LANGUAGE_NONE][0]['value'] = '';
          form_set_error('appointment_date', t('Time slot not available/booked for Selected Date'));
          form_set_error('appointment_slot', t('Time slot not available/booked for Selected Date'));
        }
      }
    }
  }
  if (arg(2) == 'edit') {
    if ($form_state['values']['op'] == t('Save')) {
      $node_load = node_load(arg(1));
      $previous_slot = $node_load->appointment_slot[LANGUAGE_NONE][0]['value'];
      drupal_add_js(drupal_get_path('module', 'appointment_calendar') . '/js/appointment_calendar.js');
      $time_slot = $form_state['values']['appointment_slot'][LANGUAGE_NONE][0]['value'];
      $selected_date = $form_state['values']['appointment_date'][LANGUAGE_NONE][0]['value'];

      // Check for empty timeslot.
      if (strlen($time_slot) == 0) {
        form_set_error('appointment_slot', t('Time slot not available for Selected Date'));
        return FALSE;
      }
      $date_query = db_select('field_data_appointment_date', 'ap');
      $date_query
        ->join('field_data_appointment_slot', 'aps', 'aps.entity_id = ap.entity_id');
      $date_query
        ->fields('aps', array(
        'appointment_slot_value ',
      ));
      $date_query
        ->condition('ap.appointment_date_value', $selected_date, '=');
      $date_queryresult = $date_query
        ->execute()
        ->fetchAll(PDO::FETCH_ASSOC);
      $date = explode('T', $selected_date);
      $slot_capacity = appointment_calendar_slot_capacity(strtotime($date[0]));

      // Booked slots is greater than or equal to allowed capacity.
      // If pervious saved slot is not equal to new selected slot anda date.
      if ($previous_slot != $time_slot) {
        if (!empty($slot_capacity)) {
          $capacity = json_decode($slot_capacity);
          if (count($date_queryresult) >= $capacity->{$time_slot}) {
            $form_state['values']['appointment_date'][LANGUAGE_NONE][0]['value'] = '';
            form_set_error('appointment_date', t('Time slot not available/booked for Selected Date'));
            form_set_error('appointment_slot', t('Time slot not available/booked for Selected Date'));
          }
        }
      }
    }
  }
}

/**
 * Implements callback to check availability.
 */
function appointment_calendar_check_availability_form($form, &$form_state) {

  // Callback to check Availability.
  global $base_url;
  $selected_date = explode('T', $form_state['values']['appointment_date'][LANGUAGE_NONE][0]['value2']);
  $url = $base_url . '/appointcal?date=' . $selected_date[0];
  $var = '<div id="check-availability"><iframe id="iid" style="overflow: hidden;" width=300 src= "' . $url . '" ></iframe></div>';
  return $var;
}

/**
 * TimeSlots callback to render derived slots.
 */
function appointment_calendar_appointment_calendar_timeslot_callback_form($form, &$form_state) {
  return $form['appointment_slot'];
}

/**
 * Implements hook_views_api().
 */
function appointment_calendar_views_api() {
  return array(
    'api' => 3.0,
    'path' => drupal_get_path('module', 'appointment_calendar') . '/views',
  );
}

/**
 * Implements hook_views_pre_render().
 */
function appointment_calendar_views_pre_render(&$view) {

  // If view is appointment calendar block.
  if ($view->name == 'appointment_calendar') {

    // Get Selected Date.
    $query = drupal_get_query_parameters();
    if (!empty($query['date'])) {
      $view->date_info->date_arg = $query['date'];
    }
    $selected_date = $view->date_info->date_arg;

    // Fetch timeslots based on date.
    $slot_query = db_select('appointment_date', 'ad');
    $slot_query
      ->fields('ad', array(
      'slot_values',
    ));
    $slot_query
      ->condition('date', strtotime($selected_date));
    $slot_result = $slot_query
      ->execute()
      ->fetchField();
    $date_values = '';
    $slot_values = '';
    $key = array_keys((array) json_decode($slot_result));
    if (!empty($slot_result)) {
      foreach ($key as $value) {
        $explode = explode('-', $value);
        $date_values .= $explode[0] . ':00,';
        $slot_values .= $value . ',';
      }
    }
    $view->header['area']->options['content'] = rtrim($slot_values, ',');

    // Setting time slot values.
    $view->style_plugin->options['groupby_times_custom'] = rtrim($date_values, ',');

    // Get filled appointment time slots.
    $date_query = db_select('field_data_appointment_date', 'ap');
    $date_query
      ->join('field_data_appointment_slot', 'aps', 'aps.entity_id = ap.entity_id');
    $date_query
      ->fields('aps', array(
      'appointment_slot_value ',
    ));
    $date_query
      ->condition('ap.appointment_date_value', '%' . db_like($selected_date) . '%', 'LIKE');
    $date_queryresult = $date_query
      ->execute()
      ->fetchAll(PDO::FETCH_ASSOC);
    $count_values = '';
    foreach ($date_queryresult as $slot_values) {
      @$count_values[$slot_values['appointment_slot_value']]++;
    }
    if (!empty($count_values)) {
      ksort($count_values);
    }
    $unset_values = '';
    $slot_capacity = appointment_calendar_slot_capacity(strtotime($selected_date));
    $slot_capacity_array = (array) json_decode($slot_capacity);
    if (!empty($count_values)) {
      $keys = array_keys($count_values);
      $booked = 0;
      for ($count = 0; $count < count($view->result); $count++) {
        $unset_values[] = $count;
      }

      // Checking Booked node count with filled slot capacity.
      for ($a = 0; $a < count($keys); $a++) {

        // Unset View Result if not booked.
        $booked += $count_values[$keys[$a]];
        if ($count_values[$keys[$a]] >= $slot_capacity_array[$keys[$a]]) {
          $view->result[$booked - 1]->field_appointment_date[0]['rendered']['#markup'] = '<span style="color:red">Booked</span>';
          unset($unset_values[$booked - 1]);
        }
      }

      // Unset Remaining View results.
      foreach ($unset_values as $reset) {
        unset($view->result[$reset]);
      }
    }
    drupal_add_js(drupal_get_path('module', 'appointment_calendar') . '/js/calendar.js');
  }
}

/**
 * Implements hook_block_info_alter().
 */
function appointment_calendar_block_info_alter(&$blocks, $theme, $code_blocks) {

  // To set block in region and display in page.
  if (isset($blocks['views']['appointment_calendar-block'])) {
    $blocks['views']['appointment_calendar-block']['status'] = 1;
    $blocks['views']['appointment_calendar-block']['region'] = 'content';
    $blocks['views']['appointment_calendar-block']['weight'] = 2;
    $blocks['views']['appointment_calendar-block']['visibility'] = BLOCK_VISIBILITY_LISTED;
    $blocks['views']['appointment_calendar-block']['pages'] = 'appointcal';
  }
}

/**
 * Callback function for appointcal page.
 */
function appointment_calendar_appointment_show() {
  if (module_exists('admin_menu')) {
    admin_menu_suppress();
  }
  return '';
}

/**
 * Implements function to get days in between from and to dates.
 */
function appointment_calendar_daysbetween($start, $end) {

  // Get days in between from and to dates.
  $dates = array();
  while ($start <= $end) {
    array_push($dates, strtotime(date('Y-m-d', $start)));
    $start += 86400;
  }
  return $dates;
}

/**
 * Implements function to fetch Slot Capacity using selected date.
 */
function appointment_calendar_slot_capacity($selected_date) {

  // Fetch Slot capacity.
  $slot_query = db_select('appointment_date', 'ad');
  $slot_query
    ->fields('ad', array(
    'slot_capacity',
  ));
  $slot_query
    ->condition('date', $selected_date);
  $slot_capacity = $slot_query
    ->execute()
    ->fetchField();
  return $slot_capacity;
}

/**
 * Implements function to get slot using NID.
 */
function appointment_calendar_slot_value($nid) {

  // Get slot value using nid.
  $slot_query = db_select('field_data_appointment_slot', 'ad');
  $slot_query
    ->fields('ad', array(
    'appointment_slot_value',
  ));
  $slot_query
    ->condition('ad.bundle', 'appointment_calendar', '=');
  $slot_query
    ->condition('ad.entity_id', $nid, '=');
  $slot_result = $slot_query
    ->execute()
    ->fetchField();
  return $slot_result;
}

/**
 * Implements function to get slot using NID.
 */
function appointment_calendar_slot_capacity_value($time_slot) {

  // Get slot value using nid.
  $slot_query = db_select('field_data_appointment_slot', 'ad');
  $slot_query
    ->fields('ad', array(
    'appointment_slot_value',
  ));
  $slot_query
    ->condition('ad.bundle', 'appointment_calendar', '=');
  $slot_query
    ->condition('ad.appointment_slot_value', $time_slot, '=');
  $slot_result = $slot_query
    ->execute()
    ->fetchAll();
  return count($slot_result);
}

Functions

Namesort descending Description
appointment_calendar_appointment_calendar_timeslot_callback_form TimeSlots callback to render derived slots.
appointment_calendar_appointment_show Callback function for appointcal page.
appointment_calendar_block_info_alter Implements hook_block_info_alter().
appointment_calendar_check_availability_form Implements callback to check availability.
appointment_calendar_daysbetween Implements function to get days in between from and to dates.
appointment_calendar_form Implements hook_form().
appointment_calendar_form_alter Implements hook_form_alter().
appointment_calendar_menu Implements hook_menu().
appointment_calendar_node_form_validate Implements hook_form_validate().
appointment_calendar_node_info Implements hook_node_info().
appointment_calendar_permission Implements hook_permission().
appointment_calendar_slot_capacity Implements function to fetch Slot Capacity using selected date.
appointment_calendar_slot_capacity_value Implements function to get slot using NID.
appointment_calendar_slot_value Implements function to get slot using NID.
appointment_calendar_views_api Implements hook_views_api().
appointment_calendar_views_pre_render Implements hook_views_pre_render().