/[drupal]/contributions/modules/openresort/accommodation/accommodation.module
ViewVC logotype

Contents of /contributions/modules/openresort/accommodation/accommodation.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.23 - (show annotations) (download) (as text)
Sun Jan 27 21:24:55 2008 UTC (21 months, 4 weeks ago) by marcingy
Branch: MAIN
CVS Tags: DRUPAL-5--1-16-6, DRUPAL-5--1-16-5, HEAD
Changes since 1.22: +1 -0 lines
File MIME type: text/x-php
*** empty log message ***
1 <?php
2 // $Id: $
3 define('ECMAIL_TYPE_CONFIRMATION', 'Confirmation email');
4
5 define('MAILVAR_CUSTOMER_CONFIMATION', 'ec_mail_customer_confirmation');
6
7 function accommodation_exit($destination = NULL) {
8 //we need to clear the cache to ensure that calanders are updated
9 //if calendars aren't enable
10 global $base_root;
11
12 $unit = variable_get('unit_calender_unit',true);
13 $hotel =variable_get('unit_calender_hotel',true);
14
15 if($unit||$hotel){
16 $this_page = request_uri();
17 $result = db_result(db_query("SELECT SUBSTRING(src FROM 6) as src FROM {url_alias} WHERE dst = '%s' AND src LIKE 'node/%'",substr($this_page,1)));
18 if(strlen($result) > 0){
19 $type = db_result(db_query("SELECT type FROM {node} WHERE nid = %d AND (type ='business' OR type='unit')",$result));
20 if($type == 'business' && $hotel){
21 $ecommerce = db_result(db_query('SELECT ecommerce FROM {business} WHERE nid = %d',$result));
22 }
23 if(($type == 'unit'&& $unit)||($type == 'business' && $hotel && $ecommerce == '1')){
24 cache_clear_all($base_root . $this_page, 'cache_page');
25 }
26 }
27 }
28 return;
29 }
30
31 function accommodation_access($op, $node) {
32 global $user;
33
34 if ($op == 'create' || $op == 'update' || $op == 'delete') {
35 if (user_access('edit own businesses') && ($user->uid == $node->uid)) {
36 return TRUE;
37 }
38 else {
39 return user_access('administer businesses');
40 }
41 }
42 }
43
44 /**
45 * Implementation of hook_perm().
46 */
47 function accommodation_perm() {
48 return array('manage all availability', 'manage own availability','change ecommerce setting','administer accommodation');
49 }
50
51 function accommodation_payment(){
52 if(is_numeric(arg(2))){
53 $txn = store_transaction_load(arg(2));
54 }else{
55 drupal_goto('');
56 }
57 $goto = module_invoke($txn->payment_method, 'paymentapi', $txn, 'payment page');
58 if (is_array($goto)) {
59 call_user_func_array('drupal_goto', $goto);
60 }
61 elseif (isset($goto)) {
62 drupal_goto($goto);
63 }
64 drupal_goto('');
65 }
66
67 function accommodation_availability_search(){
68
69 $edit = $_POST ? $_POST : $_GET;
70 $node = node_load(variable_get('accommodation_search_id',0));
71 $node->available = unit_availability_search($node, $edit,true);
72 return theme('accommodation_availability',$node,$edit);
73 }
74
75 /**
76 * Implmentation of menu_hook()
77 */
78 function accommodation_menu($may_cache) {
79
80 $items = array();
81
82 if ($may_cache) {
83 $access = user_access('access content');
84 $items[] = array('path' => 'booking/cart',
85 'title' => t('My Itinerary'),
86 'callback' => 'cart_view',
87 'access' => $access,
88 'weight' => 10,
89 'type' => MENU_IS_LOCAL_TASK);
90 $items[] = array('path' => 'booknow/accommodation',
91 'title' => t('Accommodation'),
92 'callback' => 'accommodation_booknow',
93 'access' => $access,
94 'type' => MENU_CALLBACK);
95 $items[] = array('path' => 'availability/search',
96 'title' => t('Accommodation availability'),
97 'callback' => 'accommodation_availability_search',
98 'access' => $access,
99 'type' => MENU_CALLBACK);
100 $items[] = array('path' => 'accommodation/list',
101 'callback' => 'accommodation_list',
102 'access' => $access,
103 'type' => MENU_CALLBACK);
104 }else{
105 $items[] = array('path' => 'accommodation/payment',
106 'access' => true,
107 'type' => MENU_CALLBACK,
108 'callback' => 'accommodation_payment');
109 $access = user_access('administer accommodation');
110 $items[] = array('path' => 'admin/business/bedtypes',
111 'title' => t('Bed types'),
112 'callback' => 'accommodation_bedtypes_admin',
113 'access' => $access);
114 $items[] = array('path' => 'admin/business/bedtypes/list',
115 'title' => t('list'),
116 'type' => MENU_DEFAULT_LOCAL_TASK,
117 'weight' => -10,
118 'access' => $access);
119 $items[] = array('path' => 'admin/business/bedtypes/add',
120 'title' => t('add bed type'),
121 'callback' => 'accommodation_bedtypes_admin_edit',
122 'access' => $access,
123 'type' => MENU_LOCAL_TASK);
124 $items[] = array('path' => 'admin/business/bedtypes/'.arg(3).'/edit',
125 'callback' => 'accommodation_bedtypes_admin_edit',
126 'callback arguments' => array(arg(3)),
127 'access' => $access,
128 'type' => MENU_CALLBACK);
129 $items[] = array('path' => 'admin/business/cart/timers',
130 'title' => t('Reservation times'),
131 'callback' => 'accommodation_cart_admin',
132 'access' => $access);
133 $items[] = array('path' => 'admin/business/cart/email',
134 'title' => t('From email address'),
135 'callback' => 'accommodation_cart_email',
136 'access' => $access);
137 }
138 return $items;
139 }
140
141 function accommodation_cart_admin(){
142 return drupal_get_form('accommodation_cart_admin_form');
143 }
144
145 function accommodation_cart_email(){
146 return drupal_get_form('accommodation_cart_email_form');
147 }
148
149 function accommodation_cart_admin_form_submit($form_id, $form_values){
150 variable_set('accommodation_cart_clear_down',$form_values['availability_cron']);
151 variable_set('accommodation_hold_cust_time',$form_values['availability_reserve']);
152 variable_set('accommodation_cart_accom_hold',$form_values['availability_response']);
153 variable_set('accommodation_hold_instant_time',$form_values['availability_instant']);
154 drupal_set_message(t('Times updated.'));
155 }
156
157 function accommodation_cart_email_form_submit($form_id, $form_values){
158 variable_set('reservation_email',$form_values['reservation_email']);
159 drupal_set_message(t('Email address updated.'));
160 }
161
162 function accommodation_cart_admin_form(){
163
164 $options = array('604800'=>'1 week','1209600'=>'2 weeks','1814400'=>'3 weeks','2419200'=>'4 weeks','3024000'=>'5 weeks','3628800'=>'6 weeks','4233600'=>'7 weeks','4838400'=>'8 weeks');
165
166 $form['availability_cron']=array(
167 '#type' => 'select',
168 '#title' => t('Availability clear down'),
169 '#default_value' => variable_get('accommodation_cart_clear_down',2419200),
170 '#options' => $options,
171 '#description' => t('How long data is retained in the availability table for after the date of the booking has passed.'),
172 '#multiple' => NULL,
173 '#required' => TRUE,
174 );
175
176 $options = array('300'=>'5 Minutes','600'=>'10 Minutes','900'=>'15 Minutes','1200'=>'20 Minutes','1500'=>'25 Minutes','1800'=>'30 Minutes');
177
178 $form['availability_reserve']=array(
179 '#type' => 'select',
180 '#title' => t('Availability reservation'),
181 '#default_value' => variable_get('accommodation_hold_cust_time',900),
182 '#options' => $options,
183 '#description' => t('How long an item is reserved for by the customer after they have added it to their cart.'),
184 '#multiple' => NULL,
185 '#required' => TRUE,
186 );
187
188 $options = array(
189 '0'=>'0 Minutes',
190 '900'=>'15 Minutes',
191 '1800'=>'30 Minutes',
192 '2700'=>'45 Minutes',
193 '3600'=>'60 Minutes',
194 '4500' =>'75 Minutes',
195 '5400' =>'90 Minutes',
196 '6300' =>'105 Minutes',
197 '7200' => '120 Minutes',
198 );
199
200 $form['availability_instant']=array(
201 '#type' => 'select',
202 '#title' => t('Availability instant hold time'),
203 '#default_value' => variable_get('accommodation_hold_instant_time',3600),
204 '#options' => $options,
205 '#description' => t('How long before an item mark as instant is processed.'),
206 '#multiple' => NULL,
207 '#required' => TRUE,
208 );
209
210 $options = array('21600'=>'6 hours','43200'=>'12 hours','64800'=>'18 hours','86400'=>'24 hours','108000'=>'30 hours','129600'=>'36 hours','151200'=>'42 hours','172800'=>'48 hours');
211
212 $form['availability_response']=array(
213 '#type' => 'select',
214 '#title' => t('Availability response'),
215 '#default_value' => variable_get('accommodation_cart_accom_hold',86400),
216 '#options' => $options,
217 '#description' => t('How long an item is held as reserved after a transaction has been created and a response from an accommodator is required.'),
218 '#multiple' => NULL,
219 '#required' => TRUE,
220 );
221
222 $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
223
224 return $form;
225 }
226
227 function accommodation_cart_email_form(){
228
229 $form['reservation_email']=array(
230 '#type' => 'textfield',
231 '#title' => t('Reservations email address'),
232 '#default_value' => variable_get('reservation_email',variable_get('site_mail','')),
233 '#description' => t('The address which will appear in from field for any openresort emails you generate.'),
234 '#required' => TRUE,
235 );
236
237 $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
238
239 return $form;
240 }
241
242 function accommodation_bedtypes_admin_edit($bed_id=null) {
243 if ($bed_id) {
244 $edit = db_fetch_array(db_query("SELECT * FROM {accommodation_bed_types} WHERE bed_id = '%s'", $bed_id));
245 return drupal_get_form('accommodation_bedtype_form', $edit);
246 }
247 else {
248 return drupal_get_form('accommodation_bedtype_form');
249 }
250 }
251
252 function accommodation_bedtype_form($edit = array()) {
253
254 $form['name'] = array(
255 '#type' => 'textfield',
256 '#title' => t('Name'),
257 '#default_value' => $edit['name'],
258 '#maxlength' => 20,
259 '#description' =>t('The name displayed for a given bed type'),
260 '#required' => TRUE,
261 '#weight' => -1
262 );
263 $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
264 if ($edit['name']) {
265 $form['delete'] = array('#type' => 'submit', '#value' => t('Delete'));
266 $form['savedid'] = array('#type' => 'value', '#value' => $edit['bed_id']);
267 }
268 return $form;
269 }
270
271
272 function accommodation_bedtype_form_submit($form_id, $form_values) {
273 switch (accommodation_bedtype_form_save($form_values)) {
274 case SAVED_NEW:
275 drupal_set_message(t('Bed type added'));
276 break;
277 case SAVED_UPDATED:
278 drupal_set_message(t('Bed type updated'));
279 break;
280 case SAVED_DELETED:
281 drupal_set_message(t('Bed type deleted'));
282 break;
283 }
284 return 'admin/business/bedtypes';
285 }
286
287 function accommodation_bedtype_form_save($edit) {
288 $edit['op'] = $_POST['op'];
289
290 if ($edit['op'] == "Delete" && $edit['savedid']) {
291 db_query("DELETE FROM {accommodation_bed_types} WHERE bed_id = '%s'", $edit['savedid']);
292 $status = SAVED_DELETED;
293 }
294 else if ($edit['savedid']) {
295 db_query("UPDATE {accommodation_bed_types} SET name = '%s' WHERE bed_id = '%s'", $edit['name'],$edit['savedid']);
296 $status = SAVED_UPDATED;
297 } else {
298 db_query("INSERT INTO {accommodation_bed_types} (name) VALUES ('%s')", $edit['name']);
299 $status = SAVED_NEW;
300 }
301 return $status;
302 }
303
304 function accommodation_bedtypes_admin() {
305
306 drupal_set_title(t("Bed Types"));
307
308 $header = array(t('ID'), t('Name'), t('Operations'));
309
310
311 $result = db_query('SELECT * FROM {accommodation_bed_types}');
312 $rows = array();
313 while ($bedtype = db_fetch_object($result)) {
314 $rows[] = array($bedtype->bed_id,
315 $bedtype->name,
316 l(t('edit'), "admin/business/bedtypes/$bedtype->bed_id/edit"));
317 }
318 if (!$rows) {
319 $rows[] = array(array('data' => t('No Bed Types available.'), 'colspan' => '3'));
320 }
321
322 return theme('table', $header, $rows, array('id' => 'bedtypes'));
323 }
324
325 /**
326 * The controller for viewing the accommodation listings. Callback happens via menu().
327 *
328 * @return string Completely themed HTML page.
329 */
330
331 function accommodation_availability_update($edit) {
332
333 // transform days/months in American format
334 $start = explode ("/", $edit['startdate']);
335 $end = explode ("/", $edit['enddate']);
336 $startstamp = strtotime(implode ("/", array($start[1], $start[0], $start[2])));
337 $endstamp = strtotime(implode ("/", array($end[1], $end[0], $end[2])));
338 $endstamp = $endstamp + (60 * 60 * 24); // include the last day in the update
339 $days = intval(($endstamp - $startstamp)/(24*60*60));
340 $edit['status'] ? $status = $edit['status'] : $status = 0;
341 $errors =false;
342 if($edit['price']){
343 if(!is_numeric($edit['price'])){
344 drupal_set_message(t('The price number is not numeric. Please enter a numeric value.'));
345 $errors = true;
346 }
347 }
348 if($edit['min_nights']){
349 if(!is_numeric($edit['min_nights'])){
350 drupal_set_message(t('The minimum number of nights is not numeric. Please enter a numeric value.'));
351 $errors = true;
352 }
353 }
354 if (!$errors){
355 for ($day = $startstamp; $day < $endstamp; $day = $day + (24*60*60)) {
356 $sqldate = date('Y-m-d', $day);
357
358 $result = db_query("SELECT iid, bid, price, min_nights,status FROM {accommodation_availability} " .
359 "WHERE bid = %d AND iid = %d AND date = '%s'", $edit['nid'], $edit['iid'], $sqldate);
360 if ($results = db_fetch_object($result)) {
361 if ($edit['price']){
362 $price = $edit['price'];
363 }else{
364 $price = $results->price;
365 }
366 if ($edit['min_nights']){
367 $min_nights = $edit['min_nights'];
368 }else{
369 $min_nights = $results->min_nights;
370 }
371 //remove status if it isn't changing and if new item it won't have status
372 if($status == -2){
373 $status = $results->status;
374 }
375 db_query("UPDATE {accommodation_availability} SET price = '%s', min_nights = %d, status = %d " .
376 "WHERE bid = %d AND iid = %d AND date = '%s'",
377 $price, $min_nights, $status, $edit['nid'], $edit['iid'], $sqldate);
378 } else {
379 //no status is set so make it unvailable
380 if($status == -2){
381 $status = 0;
382 }
383 db_query("INSERT INTO {accommodation_availability} (iid, bid, date, price, min_nights, status) " .
384 "VALUES (%d, %d, '%s', '%s',%d, %d)",
385 $edit['iid'], $edit['nid'], $sqldate, $edit['price'],$edit['min_nights'], $status);
386 }
387 }
388 }
389 }
390
391 //hook cron clears down dates more than a 4 weeks old
392 function accommodation_cron(){
393 _accommodation_cleardown_availability();
394 _accommodation_process_instant();
395 }
396
397
398 function accommodation_confirmation_email($t){
399 $variables = token_get_values('global',$t);
400 $mid = variable_get(MAILVAR_CUSTOMER_CONFIMATION, 0);
401 if ($t->mail && valid_email_address($t->mail)) {
402 $to = $t->mail;
403 } elseif ($t->uid != 0) {
404 $to = db_result(db_query("SELECT mail FROM {users} WHERE uid = '%d'", $t->uid));
405 }
406 return ec_mail_send_mid($mid,$to,$t,variable_get('reservation_email',variable_get('site_mail','')));
407 }
408
409 function _accommodation_process_instant(){
410 $time = time();
411 $result = db_query('SELECT txnid FROM {ec_transaction} WHERE (payment_status =7 OR payment_status =2) AND workflow =1 AND created < %d',$time - variable_get('accommodation_hold_instant_time',3600));
412 while($txnid = db_fetch_object($result)){
413 $t = store_transaction_load($txnid->txnid);
414 $t->workflow = 3;
415
416 if(! module_exists('openresort')){
417 $items = db_query("SELECT item_status FROM {ec_transaction_product} WHERE txnid = %d",$t->txnid);
418 while($transaction = db_fetch_object($items)){
419 if($t->workflow != 2){
420 if($transaction->item_status != 1){
421 $t->workflow = 2;
422 break;
423 }
424 }
425 }
426 }
427
428 $from = variable_get('reservation_email', ini_get('sendmail_from'));
429 $mail = variable_get('reservation_email', ini_get('sendmail_from'));
430 $subject = t('Transaction %tran automatically process (status change)', array('%tran' => $t->txnid));
431 if($t->workflow == 3){
432 accommodation_confirmation_email($t);
433 $body = t('Transaction %tran has had it status changed to booking confirmed', array('%tran' => $t->txnid));
434 watchdog('openresort', t('Transaction txnid %tran automatically processed (confirmed)', array('%tran' => $t->txnid)),WATCHDOG_NOTICE);
435 }else{
436 //if openresort is enabled this will never run as cron in that module will deal with it
437 if($t->workflow == 2){
438 $body = t('Transaction %tran has had it status changed to awaiting accommodator response', array('%tran' => $t->txnid));
439 watchdog('openresort', t('Transaction txnid %tran automatically processed (awaiting response)', array('%tran' => $t->txnid)),WATCHDOG_NOTICE);
440 }
441 }
442 accommodation_mail($mail, $subject, $body, "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");
443 store_transaction_save($t);
444 }
445 }
446
447 /**
448 * Send an e-mail message.
449 */
450 function accommodation_mail($mail, $subject, $message, $header) {
451 if (variable_get('smtp_library', '') && file_exists(variable_get('smtp_library', ''))) {
452 include_once './' . variable_get('smtp_library', '');
453 return drupal_mail_wrapper($mail, $subject, $message, $header);
454 }
455 else {
456 return mail(
457 $mail,
458 mime_header_encode($subject),
459 str_replace("\r", '', $message),
460 "MIME-Version: 1.0\nContent-Type: text/plain; charset=UTF-8; format=flowed\nContent-transfer-encoding: 8Bit\n" . $header
461 );
462 }
463 }
464
465
466 function _accommodation_cleardown_availability(){
467 $cleardowntime = variable_get('accommodation_cart_clear_down',2419200);
468 $adjusteddate = date('Y-m-d',time() - $cleardowntime);
469 db_query("DELETE FROM {accommodation_availability} where date < '%s'",$adjusteddate);
470 }
471
472 function accommodation_list($string) {
473 $matches = array();
474 $result = db_query_range("SELECT title FROM {node} n JOIN {business} b ON n.nid = b.nid WHERE type = 'business' AND ecommerce = 1 AND LOWER(title) LIKE LOWER('%s%%')", $string, 0, 10);
475 while ($business = db_fetch_object($result)) {
476 $matches[$business->title] = check_plain($business->title);
477 }
478 print drupal_to_js($matches);
479 exit();
480 }
481
482 /**
483 * Implementation of hook_block().
484 */
485 function accommodation_block($op = 'list', $delta = 0, $edit = array()) {
486 global $user;
487
488 switch($op){
489 case 'list':
490 $blocks[0]['info'] = t('Accommodation availability');
491 $blocks[1]['info'] = t('Outstanding payments');
492 $blocks[2]['info'] = t('Accommodation availability - any page');
493 return $blocks;
494
495 case 'view':
496 $block = array();
497 switch ($delta) {
498 case 0:
499 if (user_access('access content')&& accommodation_availability_block_access()) {
500 $block['subject'] = t('Availability search');
501 $block['content'] = accommodation_availability_block_form();
502 }
503 return $block;
504 case 1:
505 if($user->uid > 0){
506 $txnid = db_result(db_query("SELECT txnid FROM {ec_transaction} WHERE workflow = 1 AND payment_status = 1 AND uid = %d",$user->uid));
507 if (user_access('access content')&& $txnid) {
508 $block['subject'] = t('Outstanding payments');
509 $block['content'] = accommodation_outstanding_block($txnid);
510 }
511 }
512 return $block;
513 case 2:
514 if (user_access('access content') && (! function_exists('unit_availability_block_access')||(function_exists('unit_availability_block_access')&& !unit_availability_block_access())) && !accommodation_availability_block_access() && variable_get('accommodation_search_id',0) > 0) {
515 $block['subject'] = t('Availability search');
516 $block['content'] = accommodation_availability_block_form(false);
517 }
518 return $block;
519 }
520 case 'configure':
521 switch($delta){
522 case 1:
523 $form['accommodation_payment_link_text']= array(
524 '#type' => 'textfield',
525 '#title' => t('Link text'),
526 '#default_value' => variable_get('accommodation_payment_link_text','You have outstanding payments')
527 );
528 $form['accommodation_payment_html_ind']= array(
529 '#type' => 'checkbox',
530 '#title' => t('Link is html'),
531 '#return_value' => true,
532 '#default_value' => variable_get('accommodation_payment_html_ind',false),
533 '#description' => t('Use this if an image is required'),
534 );
535 return $form;
536 case 2:
537 $node = node_load(variable_get('accommodation_search_id',0));
538 $form['accommodation_search_id']= array(
539 '#type' => 'textfield',
540 '#title' => t('Name of property'),
541 '#default_value' => $node->title?$node->title:'',
542 '#description' => 'Please enter the name of the business that you want to make the search availabile for.',
543 '#autocomplete_path' => 'accommodation/list',
544 );
545 return $form;
546 }
547 case 'save':
548 switch($delta){
549 case 1:
550 variable_set('accommodation_payment_link_text',$edit['accommodation_payment_link_text']);
551 variable_set('accommodation_payment_html_ind',$edit['accommodation_payment_html_ind']);
552 break;
553 case 2:
554 if ($node = node_load(array('title' => $edit['accommodation_search_id']))) {
555 $node_id = $node->nid;
556 }
557 else {
558 $node_id = 0;
559 }
560 variable_set('accommodation_search_id',$node_id);
561 }
562 }
563 }
564
565 function accommodation_outstanding_block($txnid){
566 //load the image and the create the link
567 return l(variable_get('accommodation_payment_link_text','You have outstanding payments'),'accommodation/payment/'.$txnid,array(),null,null,null,variable_get('accommodation_payment_html_ind',false));
568 }
569
570 /**
571 * called by the block configuration
572 */
573 function accommodation_availability_block_access() {
574 if (arg(0) == 'node' && is_numeric(arg(1)) && ! arg(2)) {
575 $node = node_load(array('nid' => arg(1)));
576
577 // If it can be booked, only show on the view page
578 if ($node && $node->type == 'business'&& $node->ecommerce && ! arg(3)) {
579 return TRUE;
580 }
581 }
582 return FALSE;
583 }
584
585
586 function accommodation_availability_block_form($ajax = true) {
587 $form = null;
588 if($ajax){
589 drupal_add_js('misc/progress.js');
590 $path = drupal_get_path('module', 'accommodation');
591 module_invoke('jstools', 'add_js',$path . '/js/accommodation.js');
592 }
593 $output = drupal_get_form('accommodation_unit_block', $form,$ajax);
594
595 return $output;
596 }
597
598 function accommodation_unit_block_submit($form_id, $form_values){
599 $edit = $_POST;
600 if($edit['ajax'] == 'true'){
601 $node = node_load($_COOKIE['bid']);
602 $node->available = unit_availability_search($node, $edit,true);
603 print drupal_to_js(array('status' => TRUE, 'data' => theme('accommodation_availability',$node,$edit)));
604 exit();
605 }
606 }
607
608 function accommodation_unit_block($form,$ajax = true){
609
610 // Load values from cookies or set some defaults
611 $_COOKIE['arrive'] ? $edit['arrive'] = $_COOKIE['arrive'] : $edit['arrive'] = date("d/m/Y", strtotime('next Friday + 1 week'));
612 $_COOKIE['depart'] ? $edit['depart'] = $_COOKIE['depart'] : $edit['depart'] = date("d/m/Y", strtotime('next Friday + 1 week') + (60 * 60 * 24 * 3));
613 $_COOKIE['num_people'] ? $edit['num_people'] = $_COOKIE['num_people'] : $edit['num_people'] = 2;
614
615 $form['ajax'] = array(
616 '#type' => 'hidden',
617 '#value' => $ajax?'true':'false',
618 );
619
620 if(!$ajax){
621 $form['#action'] = url('availability/search');
622 $form['#redirect'] = FALSE;
623 }
624
625 $form['arrive'] = array(
626 '#type' => 'textfield',
627 '#title' => t('Arrival'),
628 '#size' => 10,
629 '#maxlength' => 10,
630 '#default_value' => $edit['arrive'],
631 '#description' => 'dd/mm/yyyy',
632 '#required' => TRUE,
633 '#attributes' => array('class' => 'jscalendar'),
634 '#jscalendar_ifFormat' => '%d/%m/%Y',
635 // Don't show time.
636 '#jscalendar_showsTime' => 'false',
637 // Show 24-hour clock.
638 '#jscalendar_timeFormat' => '24',
639 );
640 $form['depart'] = array(
641 '#type' => 'textfield',
642 '#title' => t('Departure'),
643 '#description' => 'dd/mm/yyyy',
644 '#size' => 10,
645 '#maxlength' => 10,
646 '#default_value' => $edit['depart'],
647 '#required' => TRUE,
648 '#attributes' => array('class' => 'jscalendar'),
649 '#jscalendar_ifFormat' => '%d/%m/%Y',
650 // Don't show time.
651 '#jscalendar_showsTime' => 'false',
652 // Show 24-hour clock.
653 '#jscalendar_timeFormat' => '24',
654 );
655 $form['num_people'] = array(
656 '#type' => 'select',
657 '#title' => t('Number of people'),
658 '#default_value' => $edit['num_people'],
659 '#options' => array(1 => 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15),
660 '#description' => '',
661 '#extra' => 0,
662 '#multiple' => 0,
663 '#required' => 0,
664 '#prefix' => '<div class="other-selection">',
665 '#suffix' => '</div>',
666 );
667 $form['op'] = array(
668 '#type' => 'submit',
669 '#value' => t('Check Availability'),
670 '#attributes' => array('class' => 'check'),
671 );
672
673 if (isset($_POST['accommodation'])) {
674 $form['op']['accommodation'] = array();
675 }
676 return $form;
677 }
678
679 /**
680 * Validates a search request and sets timestamp and MySQL conversions of the dates
681 */
682 function accommodation_search_validate(&$edit,$clear = false) {
683 static $datachecked;
684
685 if($datachecked !== true && $datachecked !== false || $clear == true){
686 if ($edit['arrive'] && $edit['depart']) {
687 $date = explode("/", $edit['arrive']); // Convert to US format for strtotime
688 $edit['arrive_ts'] = strtotime(implode ("/", array($date[1], $date[0], $date[2])));
689 if (! $edit['arrive_db'] = date("Y-m-d", $edit['arrive_ts'])) {
690 drupal_set_message("Your arrival date seems invalid. Please use the format 'dd/mm/yy'.", "error");
691 return 0;
692 }
693 $date = explode("/", $edit['depart']); // Convert to US format for strtotime
694 $edit['depart_ts'] = strtotime(implode ("/", array($date[1], $date[0], $date[2])));
695 if (! $edit['depart_db'] = date("Y-m-d", $edit['depart_ts'])) {
696 drupal_set_message("Your arrival date seems invalid. Please use the format 'dd/mm/yy'.", "error");
697 return 0;
698 }
699 $adjustedtime = $edit['arrive_ts'];
700 $localtime = time() + (60*60*24);
701 if ( $adjustedtime < $localtime) {
702 drupal_set_message(t("The arrival date cannot be within 24 hours."), "error");
703 return 0;
704 }
705 // Calculate length of stay
706 $edit['num_nights'] = floor(($edit['depart_ts'] - $edit['arrive_ts']) / (60 * 60 * 24));
707
708 // Set cookies to remember last search
709 setcookie("arrive", $edit['arrive']);
710 setcookie("depart", $edit['depart']);
711 setcookie("num_people", $edit['num_people']);
712 setcookie("room_type", $edit['room_type']);
713 setcookie("property_location", $edit['property_location']);
714 setcookie("property_price", $edit['property_price']);
715 } else {
716 $datachecked = false;
717 return 0;
718 }
719 $datachecked = true;
720 return 1;
721 }else{
722 if($datachecked == true){
723 return 1;
724 }else{
725 return 0;
726 }
727 }
728 }
729
730 function accommodation_availability_block_validate(&$edit) {
731 if ($edit['arrive'] && $edit['depart']) {
732 $date = explode("/", $edit['arrive']); // Convert to US format for strtotime
733 $edit['arrive_ts'] = strtotime(implode ("/", array($date[1], $date[0], $date[2])));
734 if (! $edit['arrive_db'] = date("Y-m-d", $edit['arrive_ts'])) {
735 drupal_set_message(t("Your dates seems invalid. Please use the format 'dd/mm/yy'."), "error");
736 return 0;
737 }
738 $date = explode("/", $edit['depart']); // Convert to US format for strtotime
739 $edit['depart_ts'] = strtotime(implode ("/", array($date[1], $date[0], $date[2])));
740 if (! $edit['depart_db'] = date("Y-m-d", $edit['depart_ts'])) {
741 drupal_set_message(t("Your dates seems invalid. Please use the format 'dd/mm/yy'."), "error");
742 return 0;
743 }
744 // Calculate length of stay
745 $edit['num_nights'] = floor(($edit['depart_ts'] - $edit['arrive_ts']) / (60 * 60 * 24));
746
747 // Set cookies to remember last search
748 setcookie("arrive", $edit['arrive']);
749 setcookie("depart", $edit['depart']);
750 setcookie("num_people", $edit['num_people']);
751 setcookie("room_type", $edit['room_type']);
752 setcookie("room_type", $edit['property_type']);
753 setcookie("room_type", $edit['property_price']);
754 } else {
755 return 0;
756 }
757 return 1;
758 }
759
760 function accommodation_validate_dates($edit) {
761 // Make sure valid dates have been submitted
762 if (! $edit['dbrangestart'] or ! $edit['dbrangeend']) {
763 if ($edit['startdate'] and $edit['enddate']) {
764 $date = array();
765 $date = explode("/", $edit['startdate']);
766 $edit['dbrangestart'] = date('Y-m-d', mktime(0, 0, 0, $date[1], $date[0], $date[2]));
767 $date = explode("/", $edit['enddate']);
768 $edit['dbrangeend'] = date('Y-m-d', mktime(0, 0, 0, $date[1], $date[0], $date[2]));
769 }
770 }
771 if (! $edit['dbrangestart'] or ! $edit['dbrangeend']) {
772 drupal_set_message(t("You must first select arrival and departure dates."), "error");
773 return 0;
774 }
775
776 if (strtotime($edit['dbrangestart']) < time()) {
777 drupal_set_message(t("The arrival date must be in the future."), "error");
778 return 0;
779 }
780 $adjustedtime = strtotime($edit['dbrangestart']);
781 $localtime = time() + (60*60*24);
782 if ( $adjustedtime < $localtime) {
783 drupal_set_message(t("The arrival date cannot be within 24 hours."), "error");
784 return 0;
785 }
786 return 1;
787 }
788
789 /**
790 * Validates a booknow request, takng params from the url
791 */
792 function accommodation_booknow_validate(&$edit) {
793 // we need to convert the vars from the url to pass back
794 if (is_numeric(arg(2)) && arg(3) && arg(4)) {
795 $edit['nid'] = arg(2);
796 $edit['dbrangestart'] = arg(3);
797 $edit['dbrangeend'] = arg(4);
798 $edit['iid'] = arg(5);
799 $edit['occupants'] = arg(6);
800 }
801 else {
802 return 0;
803 }
804 return 1;
805 }
806
807 /**
808 * Add an accommodation to the cart
809 */
810 function accommodation_booknow() {
811 $edit = null;
812 $subitem = array();
813
814 if (! accommodation_booknow_validate($edit)) {
815 drupal_set_message(t("Validation error"), "error");
816 return;
817 }
818 $unit_id = db_result(db_query("SELECT unit_id FROM {accommodation_inventory} WHERE iid = %d",$edit['iid']));
819 $iid_list = db_query("SELECT iid FROM {accommodation_inventory} WHERE unit_id = %d",$unit_id);
820 while ($iid_item = db_fetch_object($iid_list)) {
821 //do we get enough nights returned
822 $rows_returned = db_result(db_query(
823 "SELECT count(*) " .
824 "FROM {accommodation_availability} a " .
825 "INNER JOIN {node} n ON a.bid = n.nid " .
826 "INNER JOIN {business} b ON n.nid = b.nid " .
827 "WHERE a.bid = %d " .
828 "AND a.iid = %d " .
829 "AND a.date >= '%s' " .
830 "AND a.date < '%s' " .
831 //virtual units are set to -1 so it only nodes with zero that we ignore
832 "AND a.status <> 0 AND a.status <> 3 " .
833 "AND n.status = 1 " .
834 "AND b.ecommerce = 1 " .
835 "AND a.reserved_date <= '". date('Y-m-d H:i:s',time()) ."' ".
836 "ORDER BY a.date asc",
837 $edit['nid'], $iid_item->iid, $edit['dbrangestart'], $edit['dbrangeend']
838 ));
839 //convert arrive and depart into a number of days then test against min_nights
840 $arriveexplode = explode('-',$edit['dbrangestart']);
841 $departexplode = explode('-',$edit['dbrangeend']);
842 $daysstay = (gmmktime (0, 0, 0,$departexplode['1'],$departexplode['2'],$departexplode['0']) - gmmktime (0, 0, 0,$arriveexplode['1'],$arriveexplode['2'],$arriveexplode['0']))/60/60/24;
843 //if we do we use the current iid and book the rooms
844 if($daysstay == $rows_returned){
845 $result = db_query(
846 "SELECT n.title as title, a.aid as aid, a.date as date, a.price as price, a.iid as iid " .
847 "FROM {accommodation_availability} a " .
848 "INNER JOIN {node} n ON a.bid = n.nid " .
849 "INNER JOIN {business} b ON n.nid = b.nid " .
850 "WHERE a.bid = %d " .
851 "AND a.iid = %d " .
852 "AND a.date >= '%s' " .
853 "AND a.date < '%s' " .
854 //virtual units are set to -1 so it only nodes with zero that we ignore
855 "AND a.status <> 0 AND a.status <> 3 " .
856 "AND n.status = 1 " .
857 "AND b.ecommerce = 1 " .
858 "AND a.reserved_date <= '". date('Y-m-d H:i:s',time()) ."' ".
859 "ORDER BY a.date asc",
860 $edit['nid'], $iid_item->iid, $edit['dbrangestart'], $edit['dbrangeend']);
861 $holdtime = variable_get('accommodation_hold_cust_time',900);
862 while ($item = db_fetch_object($result)) {
863 $subitem[$item->aid]->title = $item->title;
864 $subitem[$item->aid]->date = $item->date;
865 $subitem[$item->aid]->price = $item->price;
866 $subitem[$item->aid]->status = $item->status;
867
868 $price += $item->price;
869 $days += 1;
870 $dates[$days] = $item->date;
871 $title = $item->title;
872 if(module_exists('virtual_unit')){
873 virtual_unit_update_availability($item,$holdtime);
874 }
875 db_query("UPDATE {accommodation_availability} SET reserved_date = '%s' WHERE aid = %d", date('Y-m-d H:i:s',time() + ($holdtime)),$item->aid);
876 }
877
878 $data->type = 'business';
879 $data->title = $days . ($days > 1 ? t(" nights ") : t(" night ")) . t("stay at ") . $title;
880 $data->subitem = $subitem;
881 $data->price = $price;
882 $data->days = $days;
883 $data->occupants = $edit['occupants'];
884
885 // Insert or update, depending if this node is already in the cart or not
886 //Do we allow the item to added to the cart as many times as they want this will be
887 //different for activities as it will have a quantity field.
888 $item_count = db_result(db_query("SELECT qty FROM {ec_cart} WHERE cookie_id = '%s' AND nid = %d", cart_get_id(), $edit['nid']));
889 if ($item_count == 0) {
890 db_query("INSERT INTO {ec_cart} (cookie_id, nid, qty, changed, data) VALUES ('%s', %d, %d, %d, '%s')", cart_get_id(), $edit['nid'], 1, time(), serialize($data));
891 drupal_set_message(t('<strong>%product-title</strong> added to <a href="%cart_view">your itinerary</a>', array('%cart_view' => url('cart/view'), '%product-title' => $data->title)));
892 }else{
893 db_query("INSERT INTO {ec_cart} (cookie_id, nid, qty, changed, data) VALUES ('%s', %d, %d, %d, '%s')", cart_get_id(), $edit['nid'], $item_count, time(), serialize($data));
894 drupal_set_message(t('<strong>%product-title</strong> added to <a href="%cart_view">your itinerary</a>', array('%cart_view' => url('cart/view'), '%product-title' => $data->title)));
895 }
896
897 cache_clear_all();
898 drupal_goto('cart');
899 }
900 }
901 //if get here no room was found
902 drupal_set_message(t('The property you have selected is no longer available. Another customer currently has it reserved. Please try again in 15 minutes as the property may become available.'));
903 drupal_goto('booking/accommodation');
904 }
905
906
907 /**
908 * Misc helper functions
909 */
910
911 /**
912 * Gets all the availability info for a accommodation unit for the current month
913 */
914 function accommodation_get_available(&$edit) {
915
916 accommodation_get_display_month($edit);
917 $displaystart = date('Y-m-d', mktime(0, 0, 0, substr($edit['displaymonth'], 0, 2), 1, substr($edit['displaymonth'], 2, 4)));
918 $displayend = date('Y-m-d', mktime(0, 0, 0, substr($edit['displaymonth'], 0, 2), 31, substr($edit['displaymonth'], 2, 4)));
919
920 $query = "SELECT a.*, UNIX_TIMESTAMP(a.date) as timestamp FROM {accommodation_availability} a " .
921 "WHERE a.bid = %d AND " .
922 " a.iid = %d AND " .
923 "a.date >= '%s' AND a.date <= '%s' ORDER BY date ASC";
924
925 $result = db_query($query,$edit[nid],$edit['iid'],$displaystart,$displayend);
926 while ($eventobj = db_fetch_object($result)) {
927 $eventdate = getdate($eventobj->timestamp);
928 $event[$eventdate['year']][$eventdate['mon']][$eventdate['mday']] = $eventobj;
929 }
930 return $event;
931 }
932
933 /**
934 * Works out which month to display
935 */
936 function accommodation_get_display_month(&$edit) {
937 if (! is_numeric($edit['displaymonth'])) {
938 if (arg(3) && strlen(arg(5)) == 6) {
939 $edit['displaymonth'] = arg(5);
940 }else {
941 if(is_numeric($edit['availdate']) && strlen($edit['availdate']) ==6){
942 $edit['displaymonth'] = $edit['availdate'];
943 }else{
944 $today = getdate();
945 $edit['displaymonth'] = _accommodation_pad($today['mon']) . $today['year'];
946 }
947 }
948 }
949 }
950
951 /**
952 * Overwrites current date range with the values from the url and converts them to db format
953 */
954 function accommodation_dates_from_get(&$edit) {
955
956 accommodation_get_display_month($edit);
957
958 if (! is_numeric($edit['rangestart']) && arg(6) && (strlen(arg(6)) == 8)) {
959 $edit['start_day'] = substr(arg(6), 0, 2);
960 $edit['start_month'] = substr(arg(6), 2, 2);
961 $edit['start_year'] = substr(arg(6), 4, 4);
962 if ($edit['dbrangestart'] = date('Y-m-d', mktime(0, 0, 0, substr(arg(6), 2, 2), substr(arg(6), 0, 2), substr(arg(6), 4, 4)))) {
963 $edit['rangestart'] = arg(6);
964 }
965 }
966 if (! is_numeric($edit['rangeend']) && arg(7) && (strlen(arg(7)) == 8)) {
967 $edit['end_day'] = substr(arg(7), 0, 2);
968 $edit['end_month'] = substr(arg(7), 2, 2);
969 $edit['end_year'] = substr(arg(7), 4, 4);
970 if ($edit['dbrangeend'] = date('Y-m-d', mktime(0, 0, 0, substr(arg(7), 2, 2), substr(arg(7), 0, 2), substr(arg(7), 4, 4)))) {
971 $edit['rangeend'] = arg(7);
972 }
973 }
974 return $edit;
975 }
976
977 /**
978 * Overwrites current date range with the values from post vars and converts them to db format
979 */
980 function accommodation_postdates_to_db(&$edit) {
981
982 accommodation_get_display_month($edit);
983
984 if (! is_numeric($edit['displaymonth'])) {
985 if (arg(3) && strlen(arg(3)) == 6) {
986 $edit['displaymonth'] = arg(3);
987 }
988 else {
989 $today = getdate();
990 $edit['displaymonth'] = _accommodation_pad($today['mon']) . $today['year'];
991 }
992 }
993
994 $start = explode("/", $edit['startdate']);
995 $edit['rangestart'] = $start[0] . $start[1] . $start[2];
996 $edit['dbrangestart'] = date('Y-m-d', strtotime(implode ("/", array($start[1], $start[0], $start[2]))));
997
998 $end = explode("/", $edit['enddate']);
999 $edit['rangeend'] = $end[0] . $end[1] . $end[2];
1000 $edit['dbrangeend'] = date('Y-m-d', strtotime(implode ("/", array($end[1], $end[0], $end[2]))));
1001
1002 return $edit;
1003 }
1004
1005 function _accommodation_days_in_month($month, $year) {
1006 if(checkdate($month, 31, $year)) return 31<