| 1 |
<?php |
<?php |
| 2 |
// $Id: bookingsapi.module,v 1.11 2008/08/18 09:03:30 carson Exp $ |
// $Id: bookingsapi.module,v 1.12 2008/08/18 19:58:05 carson Exp $ |
| 3 |
/** |
/** |
| 4 |
* @file |
* @file |
| 5 |
* Bookings API |
* Bookings API |
| 100 |
$record = bookingsapi_record_load($record['record_id']); |
$record = bookingsapi_record_load($record['record_id']); |
| 101 |
if($record) { |
if($record) { |
| 102 |
// call hook |
// call hook |
| 103 |
bookingsapi_extend('bookingsapi_record_status', 'change', &$record, null); |
$config = null; |
| 104 |
|
bookingsapi_extend('bookingsapi_record_status', 'change', $record, $config); |
| 105 |
|
|
| 106 |
// TODO: combine 2 queries into one. |
// TODO: combine 2 queries into one. |
| 107 |
$sql = 'UPDATE {bookings_records} SET status=%d WHERE record_id=%d'; |
$sql = 'UPDATE {bookings_records} SET status=%d WHERE record_id=%d'; |
| 226 |
* All recurrences formatted as DATETIMEs |
* All recurrences formatted as DATETIMEs |
| 227 |
*/ |
*/ |
| 228 |
function bookingsapi_parse_rrule(&$record, &$exceptions, &$intervals) { |
function bookingsapi_parse_rrule(&$record, &$exceptions, &$intervals) { |
| 229 |
if(empty($record['ical_rrule']) || strpos($record['ical_rrule'],'FREQ=NONE')) { |
if(empty($record['rrule']) || strpos($record['rrule'],'FREQ=NONE')) { |
| 230 |
$record['ical_rrule'] = ''; |
$record['rrule'] = ''; |
| 231 |
$intervals = array( array($record['start'], $record['end']) ); |
$intervals = array( array($record['start'], $record['end']) ); |
| 232 |
} else { |
} else { |
| 233 |
$exceptions = bookingsapi_rrule_exdates($record['ical_rrule']); |
$exceptions = bookingsapi_rrule_exdates($record['rrule']); |
| 234 |
$intervals = date_repeat_calc($record['ical_rrule'], $record['start'], $record['ical_rrule_until'], $exceptions); |
$intervals = date_repeat_calc($record['rrule'], $record['start'], $record['rrule_until'], $exceptions); |
| 235 |
$intervals = bookingsapi_interval_build($intervals, $record['start'], $record['end']); |
$intervals = bookingsapi_interval_build($intervals, $record['start'], $record['end']); |
| 236 |
} |
} |
| 237 |
} |
} |
| 337 |
*/ |
*/ |
| 338 |
function _bookingsapi_record_instances_save(&$record) { |
function _bookingsapi_record_instances_save(&$record) { |
| 339 |
if (empty($record['record_id'])) return; |
if (empty($record['record_id'])) return; |
| 340 |
if(!empty($record['ical_rrule'])) { |
if(!empty($record['rrule'])) { |
| 341 |
$exceptions = bookingsapi_rrule_exdates($record['ical_rrule']); |
$exceptions = bookingsapi_rrule_exdates($record['rrule']); |
| 342 |
$instance_dates = date_repeat_calc($record['ical_rrule'], $record['start'], $record['ical_rrule_until'], $exceptions); |
$instance_dates = date_repeat_calc($record['rrule'], $record['start'], $record['rrule_until'], $exceptions); |
| 343 |
} else { |
} else { |
| 344 |
$instance_dates = array($record['start']); |
$instance_dates = array($record['start']); |
| 345 |
} |
} |
| 358 |
$cur_instance = db_fetch_array(db_query($sql)); |
$cur_instance = db_fetch_array(db_query($sql)); |
| 359 |
$cur_count = $cur_instance ? $cur_instance['count'] : 0; |
$cur_count = $cur_instance ? $cur_instance['count'] : 0; |
| 360 |
|
|
| 361 |
if (empty($record['ical_rrule']) && $cur_count > 0) { |
if (empty($record['rrule']) && $cur_count > 0) { |
| 362 |
// if the RRULE is empty, delete all instances of it except the original |
// if the RRULE is empty, delete all instances of it except the original |
| 363 |
$sql = "DELETE FROM {bookings_schedules} WHERE record_id=%d AND start!='%s'"; |
$sql = "DELETE FROM {bookings_schedules} WHERE record_id=%d AND start!='%s'"; |
| 364 |
db_query($sql, $record['record_id'], $record['start']); |
db_query($sql, $record['record_id'], $record['start']); |
| 452 |
*/ |
*/ |
| 453 |
function bookingsapi_booking_save(&$booking, $return_object = false) { |
function bookingsapi_booking_save(&$booking, $return_object = false) { |
| 454 |
$op = empty($booking['record_id']) ? 'update' : 'insert'; |
$op = empty($booking['record_id']) ? 'update' : 'insert'; |
| 455 |
bookingsapi_extend('bookingsapi_booking', $op, &$booking); |
bookingsapi_extend('bookingsapi_booking', $op, $booking); |
| 456 |
$status = bookingsapi_record_save($booking); |
$status = bookingsapi_record_save($booking); |
| 457 |
if(!$return_object) $booking = (array) $booking; |
if(!$return_object) $booking = (array) $booking; |
| 458 |
return $status; |
return $status; |
| 468 |
* BOOKINGSAPI_TIME_CONFLICT if there is a time conflict |
* BOOKINGSAPI_TIME_CONFLICT if there is a time conflict |
| 469 |
*/ |
*/ |
| 470 |
function bookingsapi_record_save(&$record) { |
function bookingsapi_record_save(&$record) { |
| 471 |
$record['ical_rrule_until'] = bookingsapi_rrule_until_as_dt($record['ical_rrule']); |
$record['rrule_until'] = bookingsapi_rrule_until_as_dt($record['rrule']); |
| 472 |
|
|
| 473 |
// TODO: lock and unlock tables: this is a critical procedure |
// TODO: lock and unlock tables: this is a critical procedure |
| 474 |
|
|
| 486 |
if($using_sql_ts_triggers) $record['modified'] = date(DATE_FORMAT_DATETIME); |
if($using_sql_ts_triggers) $record['modified'] = date(DATE_FORMAT_DATETIME); |
| 487 |
} |
} |
| 488 |
|
|
| 489 |
$status = drupal_write_record('bookings_records', &$record, $update); |
$status = drupal_write_record('bookings_records', $record, $update); |
| 490 |
_bookingsapi_record_instances_save($record); |
_bookingsapi_record_instances_save($record); |
| 491 |
return $status; |
return $status; |
| 492 |
} |
} |
| 517 |
if(empty($instance['record_id'])) $instance = bookingsapi_instance_load($instance['instance_id']); |
if(empty($instance['record_id'])) $instance = bookingsapi_instance_load($instance['instance_id']); |
| 518 |
// get the record for the instance |
// get the record for the instance |
| 519 |
$parent = bookingsapi_record_load($instance['record_id']); |
$parent = bookingsapi_record_load($instance['record_id']); |
| 520 |
if(!empty($record['ical_rrule'])) { |
if(!empty($record['rrule'])) { |
| 521 |
// this is one instance of many; update the parent's EXDATE to reflect the deletion |
// this is one instance of many; update the parent's EXDATE to reflect the deletion |
| 522 |
$rrule = explode("\n", $parent['ical_rrule']); |
$rrule = explode("\n", $parent['rrule']); |
| 523 |
$exception = substr($instance['start'], 0, 11) . '00:00:00'; // reset time according to RFC spec |
$exception = substr($instance['start'], 0, 11) . '00:00:00'; // reset time according to RFC spec |
| 524 |
$exception = date_convert($exception, DATE_DATETIME, DATE_ICAL); |
$exception = date_convert($exception, DATE_DATETIME, DATE_ICAL); |
| 525 |
if (array_key_exists(1, $rrule)) { |
if (array_key_exists(1, $rrule)) { |
| 528 |
$rrule[1] = 'EXDATE:' . $exception; // create new |
$rrule[1] = 'EXDATE:' . $exception; // create new |
| 529 |
} |
} |
| 530 |
$rrule = implode("\n",$rrule); |
$rrule = implode("\n",$rrule); |
| 531 |
db_query("UPDATE {bookings_records} SET ical_rrule='%s' WHERE record_id=%d LIMIT 1", $rrule, $instance['record_id']); |
db_query("UPDATE {bookings_records} SET rrule='%s' WHERE record_id=%d LIMIT 1", $rrule, $instance['record_id']); |
| 532 |
} else { |
} else { |
| 533 |
// deleting the one and only instance of a record, so delete record also |
// deleting the one and only instance of a record, so delete record also |
| 534 |
db_query('DELETE FROM {bookings_records} WHERE record_id=%d LIMIT 1', $instance['record_id']); |
db_query('DELETE FROM {bookings_records} WHERE record_id=%d LIMIT 1', $instance['record_id']); |
| 588 |
*/ |
*/ |
| 589 |
function bookingsapi_availability_save(&$avail, $return_object = false) { |
function bookingsapi_availability_save(&$avail, $return_object = false) { |
| 590 |
$op = empty($avail['record_id']) ? 'update' : 'insert'; |
$op = empty($avail['record_id']) ? 'update' : 'insert'; |
| 591 |
bookingsapi_extend('bookingsapi_booking', $op, &$avail); |
bookingsapi_extend('bookingsapi_booking', $op, $avail); |
| 592 |
$status = bookingsapi_record_save($avail); |
$status = bookingsapi_record_save($avail); |
| 593 |
if(!$return_object) $booking = (array) $avail; |
if(!$return_object) $booking = (array) $avail; |
| 594 |
return $status; |
return $status; |
| 642 |
function bookingsapi_resource_save(&$resource, $return_object = false) { |
function bookingsapi_resource_save(&$resource, $return_object = false) { |
| 643 |
$op = empty($resource['resource_id']) ? 'insert' : 'update'; |
$op = empty($resource['resource_id']) ? 'insert' : 'update'; |
| 644 |
$update = empty($resource['resource_id']) ? array() : 'resource_id'; |
$update = empty($resource['resource_id']) ? array() : 'resource_id'; |
| 645 |
bookingsapi_extend('bookingsapi_resource', $op, &$resource); |
bookingsapi_extend('bookingsapi_resource', $op, $resource); |
| 646 |
$retval = drupal_write_record('bookings_resources', &$resource, $update); |
$retval = drupal_write_record('bookings_resources', $resource, $update); |
| 647 |
if(!$return_object) $resource = (array) $resource; |
if(!$return_object) $resource = (array) $resource; |
| 648 |
return $retval; |
return $retval; |
| 649 |
} |
} |
| 717 |
* @param $config is configuration data |
* @param $config is configuration data |
| 718 |
* @return an array of data |
* @return an array of data |
| 719 |
*/ |
*/ |
| 720 |
function bookingsapi_extend($hook_name, $op = null, $data = null, $config = null) { |
function bookingsapi_extend($hook_name, $op = null, &$data = null, &$config = null) { |
| 721 |
$items = array(); |
$items = array(); |
| 722 |
foreach (module_implements($hook_name) as $module) { |
foreach (module_implements($hook_name) as $module) { |
| 723 |
//echo $module . $hook_name; |
//echo $module . $hook_name; |
| 738 |
$tests = file_scan_directory($dir, '\.test$'); |
$tests = file_scan_directory($dir, '\.test$'); |
| 739 |
return array_keys($tests); |
return array_keys($tests); |
| 740 |
} |
} |
| 741 |
|
|
| 742 |
|
/** |
| 743 |
|
* Implementation of hook_views_api(). |
| 744 |
|
*/ |
| 745 |
|
function bookingsapi_views_api() { |
| 746 |
|
return array( |
| 747 |
|
'api' => '2.0', |
| 748 |
|
); |
| 749 |
|
} |
| 750 |
|
|
| 751 |
|
/** |
| 752 |
|
* Implementation of hook_views_handlers(). |
| 753 |
|
*/ |
| 754 |
|
function bookingsapi_views_handlers() { |
| 755 |
|
return array( |
| 756 |
|
'info' => array( |
| 757 |
|
'path' => drupal_get_path('module', 'bookingsapi') . '/handlers', |
| 758 |
|
), |
| 759 |
|
'handlers' => array( |
| 760 |
|
'views_handler_field_datetime' => array( |
| 761 |
|
'parent' => 'views_handler_field_date', |
| 762 |
|
'file' => 'views_handler_field_date.inc', |
| 763 |
|
), |
| 764 |
|
'views_handler_filter_datetime' => array( |
| 765 |
|
'parent' => 'views_handler_filter_date', |
| 766 |
|
'file' => 'views_handler_filter_date.inc', |
| 767 |
|
), |
| 768 |
|
'views_handler_filter_bookings_resource_disabled' => array( |
| 769 |
|
'parent' => 'views_handler_filter_boolean_operator', |
| 770 |
|
'file' => 'views_handler_filter_boolean_operator.inc', |
| 771 |
|
), |
| 772 |
|
'views_handler_filter_bookings_record_types' => array( |
| 773 |
|
'parent' => 'views_handler_filter_in_operator', |
| 774 |
|
'file' => 'views_handler_filter_in_operator.inc', |
| 775 |
|
), |
| 776 |
|
'views_handler_filter_bookings_record_statuses' => array( |
| 777 |
|
'parent' => 'views_handler_filter_in_operator', |
| 778 |
|
'file' => 'views_handler_filter_in_operator.inc', |
| 779 |
|
), |
| 780 |
|
'views_handler_filter_bookings_resource_id' => array( |
| 781 |
|
'parent' => 'views_handler_filter_in_operator', |
| 782 |
|
'file' => 'views_handler_filter_in_operator.inc', |
| 783 |
|
), |
| 784 |
|
'views_handler_filter_bookings_record_id' => array( |
| 785 |
|
'parent' => 'views_handler_filter_in_operator', |
| 786 |
|
'file' => 'views_handler_filter_in_operator.inc', |
| 787 |
|
), |
| 788 |
|
'views_handler_field_bookings_resource_disabled' => array( |
| 789 |
|
'parent' => 'views_handler_field', |
| 790 |
|
'file' => 'views_handler_field.inc', |
| 791 |
|
), |
| 792 |
|
'views_handler_field_bookings_record_types' => array( |
| 793 |
|
'parent' => 'views_handler_field', |
| 794 |
|
'file' => 'views_handler_field.inc', |
| 795 |
|
), |
| 796 |
|
'views_handler_field_bookings_default_availability' => array( |
| 797 |
|
'parent' => 'views_handler_field', |
| 798 |
|
'file' => 'views_handler_field.inc', |
| 799 |
|
), |
| 800 |
|
'views_handler_field_bookings_rrule' => array( |
| 801 |
|
'parent' => 'views_handler_field', |
| 802 |
|
'file' => 'views_handler_field.inc', |
| 803 |
|
), |
| 804 |
|
'views_handler_field_bookings_record_statuses' => array( |
| 805 |
|
'parent' => 'views_handler_field', |
| 806 |
|
'file' => 'views_handler_field.inc', |
| 807 |
|
), |
| 808 |
|
), |
| 809 |
|
); |
| 810 |
|
} |