appointment_calendar.module in Appointment Calendar 7
Same filename and directory in other branches
Adds Appointment calendar filtering and displays Availability.
File
appointment_calendar.moduleView 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);
}