PageRenderTime 59ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/application/controllers/Bookings.php

https://github.com/craigrodway/classroombookings
PHP | 542 lines | 359 code | 147 blank | 36 comment | 64 complexity | 8bbe2c759b03ec5c9099dd6bf3596c05 MD5 | raw file
  1. <?php
  2. defined('BASEPATH') OR exit('No direct script access allowed');
  3. class Bookings extends MY_Controller
  4. {
  5. public function __construct()
  6. {
  7. parent::__construct();
  8. $this->require_logged_in();
  9. $this->lang->load('bookings');
  10. $this->load->model(array(
  11. 'crud_model',
  12. 'rooms_model',
  13. 'periods_model',
  14. 'weeks_model',
  15. 'users_model',
  16. 'holidays_model',
  17. 'bookings_model',
  18. 'access_control_model',
  19. ));
  20. $this->school = array(
  21. 'users' => $this->users_model->Get(NULL, NULL, NULL),
  22. 'days_list' => $this->periods_model->days,
  23. );
  24. if ($this->userauth->is_level(TEACHER) && setting('maintenance_mode')) {
  25. $this->data['title'] = 'Bookings';
  26. $this->data['showtitle'] = '';
  27. $this->data['body'] = '';
  28. $this->render();
  29. $this->output->_display();
  30. exit();
  31. }
  32. }
  33. private function _store_query($data = array())
  34. {
  35. $_SESSION['query'] = $data;
  36. }
  37. private function _get_query()
  38. {
  39. if (array_key_exists('query', $_SESSION))
  40. {
  41. return $_SESSION['query'];
  42. }
  43. return array();
  44. }
  45. function index()
  46. {
  47. $query = $this->input->get();
  48. $user_id = $this->userauth->user->user_id;
  49. // $this->session->set_userdata('uri', $this->uri->uri_string());
  50. if ( ! isset($query['date']) ) {
  51. $query['date'] = date("Y-m-d");
  52. /*if( $this->session->userdata('chosen_date') ){
  53. #echo "session: {$this->session->userdata('chosen_date')}<br />";
  54. $this->school['chosen_date'] = $this->session->userdata('chosen_date');
  55. }*/
  56. // Day number of the chosen date
  57. $day_num = date('N', strtotime($query['date']));
  58. #$this->school['chosen_date'] = $chosen_date;
  59. #$this->session->set_userdata('chosen_date', $this->school['chosen_date']);
  60. }
  61. $room_of_user = $this->rooms_model->GetByUser($user_id);
  62. if ( ! isset($query['room'])) {
  63. if ( ! empty($room_of_user)) {
  64. $query['room'] = $room_of_user->room_id;
  65. } else {
  66. $query['room'] = NULL;
  67. }
  68. }
  69. if ( ! isset($query['direction'])) {
  70. $query['direction'] = 'forward';
  71. }
  72. $this->_store_query($query);
  73. #$this->school['room'] = $uri['room'];
  74. $body['html'] = $this->bookings_model->html(array(
  75. 'school' => $this->school,
  76. 'query' => $query,
  77. ));
  78. /*$body['html'] = $this->M_bookings->htmltable(
  79. $this->school_id,
  80. 'day',
  81. 'periods',
  82. $chosen_date,
  83. $this->school
  84. );*/
  85. $this->data['title'] = 'Bookings';
  86. $this->data['showtitle'] = '';
  87. $this->data['body'] = $this->session->flashdata('saved');
  88. $this->data['body'] .= $body['html'];
  89. return $this->render();
  90. }
  91. /**
  92. * This function takes the date that was POSTed and loads the view()
  93. */
  94. function load()
  95. {
  96. $style = $this->bookings_model->BookingStyle();
  97. #$chosen_date = $this->input->post('chosen_date');
  98. $this->load->library('form_validation');
  99. $this->form_validation->set_rules('chosen_date', 'Date', 'max_length[10]|callback_valid_date');
  100. $this->form_validation->set_rules('room_id', 'Room', 'integer');
  101. $this->form_validation->set_rules('direction', 'Diretion', '');
  102. if ($this->form_validation->run() == FALSE) {
  103. show_error("Sorry, the requested details cannot be loaded.");
  104. }
  105. // $query = $this->_get_query();
  106. $query = array(
  107. 'direction' => $this->input->post('direction'),
  108. 'date' => $this->input->post('chosen_date'),
  109. );
  110. switch ($style['display']) {
  111. case 'day':
  112. // Display type is one day at a time - all rooms/periods
  113. if ($this->input->post('chosen_date')) {
  114. $datearr = explode('/', $this->input->post('chosen_date'));
  115. if (count($datearr) != 3) {
  116. show_error('Invalid date chosen');
  117. }
  118. $query['date'] = date("Y-m-d", mktime(0, 0, 0, $datearr[1], $datearr[0], $datearr[2]));
  119. } else {
  120. show_error('No date chosen');
  121. }
  122. break;
  123. case 'room':
  124. if ($this->input->post('room_id')) {
  125. $query['room'] = $this->input->post('room_id');
  126. } else {
  127. show_error('No day selected');
  128. }
  129. break;
  130. }
  131. $uri = 'bookings/index?' . http_build_query($query);
  132. redirect($uri);
  133. }
  134. function book()
  135. {
  136. $query = $this->input->get();
  137. $this->data['title'] = 'Book a room';
  138. $this->data['showtitle'] = $this->data['title'];
  139. // Either no URI, or all URI info specified
  140. $this->data['hidden'] = new StdClass();
  141. if (isset($query['period']) && isset($query['room']) && isset($query['date'])) {
  142. // Create booking data
  143. $booking = new StdClass();
  144. $booking->booking_id = NULL;
  145. $booking->period_id = $query['period'];
  146. $booking->room_id = $query['room'];
  147. $booking->date = $query['date'];
  148. $booking->notes = '';
  149. $booking->user_id = $this->userauth->user->user_id;
  150. if ($this->userauth->is_level(ADMINISTRATOR)) {
  151. $booking->day_num = isset($query['day']) ? $query['day'] : NULL;
  152. $booking->week_id = isset($query['week']) ? $query['week'] : NULL;
  153. if (empty($booking->day_num)) {
  154. $booking->day_num = date('N', strtotime($query['date']));
  155. }
  156. }
  157. $this->data['booking'] = $booking;
  158. $this->data['hidden'] = (array) $booking;
  159. }
  160. // Lookups we need if an admin user
  161. if ($this->userauth->is_level(ADMINISTRATOR)) {
  162. $this->data['days'] = $this->periods_model->days;
  163. $this->data['rooms'] = $this->rooms_model->Get();
  164. $this->data['periods'] = $this->periods_model->Get();
  165. $this->data['weeks'] = $this->weeks_model->Get();
  166. $this->data['users'] = $this->school['users'];
  167. }
  168. $prev_query = $this->_get_query();
  169. $this->data['query_string'] = http_build_query($prev_query);
  170. $this->data['cancel_uri'] = 'bookings?' . http_build_query($prev_query);
  171. $this->data['body'] = $this->load->view('bookings/bookings_book', $this->data, TRUE);
  172. // If we have a date and the user is a teacher, do some extra checks
  173. //
  174. if (isset($query['date']) && $this->userauth->is_level(TEACHER)) {
  175. $booking_status = $this->userauth->can_create_booking($query['date']);
  176. if ($booking_status->result === FALSE) {
  177. $messages = [];
  178. if ( ! $booking_status->in_quota) {
  179. $msg = "You have reached the maximum number of active bookings (%d).";
  180. $msg = sprintf($msg, setting('num_max_bookings'));
  181. $messages[] = msgbox('error', $msg);
  182. }
  183. if ( ! $booking_status->is_future_date) {
  184. $msg = "The chosen date is in the past.";
  185. $messages[] = msgbox('error', $msg);
  186. }
  187. if ( ! $booking_status->date_in_range) {
  188. $msg = "The chosen date must be less than %d days in the future.";
  189. $msg = sprintf($msg, setting('bia'));
  190. $messages[] = msgbox('error', $msg);
  191. }
  192. $this->data['body'] = implode("\n", $messages);
  193. }
  194. }
  195. return $this->render();
  196. }
  197. /**
  198. * Process a form action from the bookings table
  199. *
  200. */
  201. public function action()
  202. {
  203. if ($this->input->post('cancel')) {
  204. return $this->process_cancel();
  205. }
  206. if ($this->input->post('recurring')) {
  207. return $this->process_recurring();
  208. }
  209. }
  210. private function process_recurring()
  211. {
  212. $bookings = array();
  213. foreach ($this->input->post('recurring') as $booking) {
  214. list($uri, $params) = explode('?', $booking);
  215. parse_str($params, $data);
  216. $bookings[] = $data;
  217. }
  218. $errcount = 0;
  219. foreach ($bookings as $booking) {
  220. $booking_data = array(
  221. 'user_id' => $this->input->post('user_id'),
  222. 'period_id' => $booking['period'],
  223. 'room_id' => $booking['room'],
  224. 'notes' => $this->input->post('notes'),
  225. 'week_id' => $booking['week'],
  226. 'day_num' => $booking['day_num'],
  227. );
  228. if ( ! $this->bookings_model->Add($booking_data)) {
  229. $errcount++;
  230. }
  231. }
  232. if ($errcount > 0) {
  233. $flashmsg = msgbox('error', 'One or more bookings could not be made.');
  234. } else {
  235. $flashmsg = msgbox('info', 'The bookings were created successfully.');
  236. }
  237. $this->session->set_userdata('notes', $booking_data['notes']);
  238. // Go back to index
  239. $this->session->set_flashdata('saved', $flashmsg);
  240. $query = $this->_get_query();
  241. $uri = 'bookings/index?' . http_build_query($query);
  242. redirect($uri);
  243. }
  244. private function process_cancel()
  245. {
  246. $id = $this->input->post('cancel');
  247. $booking = $this->bookings_model->Get($id);
  248. $user_id = $this->userauth->user->user_id;
  249. $room = $this->rooms_model->Get($booking->room_id);
  250. $query = $this->_get_query();
  251. $uri = 'bookings/index?' . http_build_query($query);
  252. $can_delete = ( ($this->userauth->is_level(ADMINISTRATOR))
  253. OR ($user_id == $booking->user_id)
  254. OR ( ($user_id == $room->user_id) && ($booking->date != NULL) )
  255. );
  256. if ( ! $can_delete) {
  257. $this->session->set_flashdata('saved', msgbox('error', "You do not have the correct privileges to cancel this booking."));
  258. return redirect($uri);
  259. }
  260. if ($this->bookings_model->Cancel($id)){
  261. $msg = msgbox('info', 'The booking has been cancelled.');
  262. } else {
  263. $msg = msgbox('error', 'An error occured cancelling the booking.');
  264. }
  265. $this->session->set_flashdata('saved', $msg);
  266. redirect($uri);
  267. }
  268. function edit($booking_id)
  269. {
  270. $booking = $this->bookings_model->Get($booking_id);
  271. $query = $this->_get_query();
  272. $uri = 'bookings?' . http_build_query($query);
  273. $can_edit = ( $this->userauth->is_level(ADMINISTRATOR) OR ($this->userauth->user->user_id == $booking->user_id));
  274. if ( ! $can_edit) {
  275. $this->session->set_flashdata('saved', msgbox('error', "You do not have the correct privileges to cancel this booking."));
  276. return redirect($uri);
  277. }
  278. $this->data['title'] = 'Edit booking';
  279. $this->data['showtitle'] = $this->data['title'];
  280. $this->data['cancel_uri'] = 'bookings?' . http_build_query($query);
  281. // Lookups we need if an admin user
  282. if ($this->userauth->is_level(ADMINISTRATOR)) {
  283. $this->data['days'] = $this->periods_model->days;
  284. $this->data['rooms'] = $this->rooms_model->Get();
  285. $this->data['periods'] = $this->periods_model->Get();
  286. $this->data['weeks'] = $this->weeks_model->Get();
  287. $this->data['users'] = $this->school['users'];
  288. }
  289. $this->data['booking'] = $booking;
  290. $this->data['hidden'] = (array) $booking;
  291. $this->data['body'] = $this->load->view('bookings/bookings_book', $this->data, TRUE);
  292. return $this->render();
  293. }
  294. function save()
  295. {
  296. // Get ID from form
  297. $booking_id = $this->input->post('booking_id');
  298. $this->load->library('form_validation');
  299. $this->form_validation->set_rules('booking_id', 'Booking ID', 'integer');
  300. $this->form_validation->set_rules('date', 'Date', 'max_length[10]');
  301. $this->form_validation->set_rules('use', 'Notes', 'max_length[100]');
  302. $this->form_validation->set_rules('period_id', 'Period', 'integer');
  303. $this->form_validation->set_rules('user_id', 'User', 'integer');
  304. $this->form_validation->set_rules('room_id', 'Room', 'integer');
  305. $this->form_validation->set_rules('week_id', 'Week', 'integer');
  306. $this->form_validation->set_rules('day_num', 'Day of week', 'integer');
  307. if ( ! $this->input->post('day_num')) {
  308. $this->form_validation->set_rules('date', 'Date', 'max_length[10]|callback_valid_date');
  309. }
  310. if ($this->form_validation->run() == FALSE) {
  311. return (empty($booking_id) ? $this->book() : $this->edit($booking_id));
  312. }
  313. $booking_data = array(
  314. 'user_id' => $this->input->post('user_id'),
  315. 'period_id' => $this->input->post('period_id'),
  316. 'room_id' => $this->input->post('room_id'),
  317. 'notes' => $this->input->post('notes'),
  318. 'booking_id' => $this->input->post('booking_id'),
  319. );
  320. // Determine if this booking is recurring or static.
  321. if ($this->input->post('date')) {
  322. $date_arr = explode('/', $this->input->post('date'));
  323. $booking_data['date'] = date("Y-m-d", mktime(0, 0, 0, $date_arr[1], $date_arr[0], $date_arr[2]));
  324. $booking_data['day_num'] = NULL;
  325. $booking_data['week_id'] = NULL;
  326. }
  327. if ($this->input->post('recurring') && $this->input->post('week_id') && $this->input->post('day_num')) {
  328. $booking_data['date'] = NULL;
  329. $booking_data['day_num'] = $this->input->post('day_num');
  330. $booking_data['week_id'] = $this->input->post('week_id');
  331. }
  332. if ($this->_check_unique_booking($booking_data)) {
  333. $this->_persist_booking($booking_id, $booking_data);
  334. } else {
  335. $flashmsg = msgbox('exclamation', "There is already a booking for that date, period and room.");
  336. $this->data['notice'] = $flashmsg;
  337. // $this->session->set_flashdata('saved', $flashmsg);
  338. return (empty($booking_id) ? $this->book() : $this->edit($booking_id));
  339. }
  340. $query = $this->_get_query();
  341. $uri = 'bookings/index?' . http_build_query($query);
  342. redirect($uri);
  343. }
  344. public function valid_date($date)
  345. {
  346. if (strpos($date, '/') !== FALSE) {
  347. $datearr = explode('/', $date);
  348. $valid = checkdate($datearr[1], $datearr[0], $datearr[2]);
  349. } elseif (strpos($date, '-') !== FALSE) {
  350. $datearr = explode('-', $date);
  351. $valid = checkdate($datearr[1], $datearr[2], $datearr[0]);
  352. } else {
  353. $this->form_validation->set_message('valid_date', 'Invalid date');
  354. return FALSE;
  355. }
  356. if ($valid) {
  357. return TRUE;
  358. }
  359. $this->form_validation->set_message('valid_date', 'Invalid date');
  360. return FALSE;
  361. }
  362. private function _check_unique_booking($data)
  363. {
  364. $bookings = $this->bookings_model->GetUnique(array(
  365. 'date' => $data['date'],
  366. 'period_id' => $data['period_id'],
  367. 'room_id' => $data['room_id'],
  368. 'booking_id' => $data['booking_id'],
  369. 'week_id' => $data['week_id'],
  370. 'day_num' => $data['day_num'],
  371. ));
  372. return count($bookings) == 0;
  373. }
  374. private function _persist_booking($booking_id = NULL, $booking_data = array())
  375. {
  376. if (empty($booking_id)) {
  377. unset($booking_data['booking_id']);
  378. $booking_id = $this->bookings_model->Add($booking_data);
  379. if ($booking_id) {
  380. $flashmsg = msgbox('info', "The booking has been made.");
  381. } else {
  382. $line = sprintf($this->lang->line('crbs_action_dberror'), 'adding');
  383. $flashmsg = msgbox('error', $line);
  384. }
  385. } else {
  386. if ($this->bookings_model->Edit($booking_id, $booking_data)) {
  387. $flashmsg = msgbox('info', "The booking has been updated.");
  388. } else {
  389. $line = sprintf($this->lang->line('crbs_action_dberror'), 'editing');
  390. $flashmsg = msgbox('error', $line);
  391. }
  392. }
  393. $this->session->set_flashdata('saved', $flashmsg);
  394. }
  395. }