Source for file viewer.php

Documentation is available at viewer.php

  1. <?php
  2.  
  3. class net_nemein_reservations_viewer {
  4. var $_debug_prefix;
  5. var $_prefix;
  6. var $_config;
  7. var $_topic;
  8. var $_root_event;
  9. var $_root_group;
  10. var $_l10n;
  11. var $_l10n_midcom;
  12. var $_config_dm;
  13. var $_resource;
  14. var $_reservation;
  15. var $_mode;
  16. var $_toolbar;
  17. var $_auth;
  18.  
  19. var $errcode;
  20. var $errstr;
  21. function net_nemein_reservations_viewer($topic, $config) {
  22. $this->_debug_prefix = "net.nemein.reservationsviewer::";
  23.  
  24. $this->_prefix = $GLOBALS["midcom"]->get_context_data(MIDCOM_CONTEXT_ANCHORPREFIX);
  25. $this->_config = $config;
  26. $this->_topic = $topic;
  27. $this->_root_event = null;
  28. $this->_root_group = null;
  29. $this->_config_dm = null;
  30. $this->_mode = "";
  31. $this->_toolbar = Array();
  32. $this->_auth = null;
  33. $i18n =& $GLOBALS["midcom"]->get_service("i18n");
  34. $this->_l10n = $i18n->get_l10n("net.nemein.reservations");
  35. $this->_l10n_midcom = $i18n->get_l10n("midcom");
  36. $this->errcode = MIDCOM_ERROK;
  37. $this->errstr = "";
  38. $this->_check_root_event();
  39. $this->_check_root_group();
  40. $this->_prepare_config_dm();
  41. }
  42. function get_metadata() {
  43. return FALSE;
  44. }
  45.  
  46. function can_handle($argc, $argv) {
  47. $GLOBALS["midcom"]->set_custom_context_data("configuration", $this->_config);
  48. $GLOBALS["midcom"]->set_custom_context_data("configuration_dm", $this->_config_dm);
  49. $GLOBALS["midcom"]->set_custom_context_data("root_group", $this->_root_group);
  50. $GLOBALS["midcom"]->set_custom_context_data("root_event", $this->_root_event);
  51. $GLOBALS["midcom"]->set_custom_context_data("l10n", $this->_l10n);
  52. $GLOBALS["midcom"]->set_custom_context_data("l10n_midcom", $this->_l10n_midcom);
  53. $GLOBALS["midcom"]->set_custom_context_data("errstr", $this->errstr);
  54. $GLOBALS["midcom"]->set_custom_context_data("auth", $this->_auth);
  55. $GLOBALS["midcom"]->set_custom_context_data("view_toolbar", $this->_view_toolbar);
  56. $GLOBALS["midcom"]->set_custom_context_data("resource", $this->_resource);
  57. $GLOBALS["midcom"]->set_custom_context_data("reservation", $this->_reservation);
  58. $this->_auth = new net_nemein_reservations_auth();
  59. if ($argc <= 1)
  60. return TRUE;
  61. if ($argc == 2) {
  62. switch ($argv[1]) {
  63. case "res_start":
  64. case "res_end":
  65. case "res_detail":
  66. case "res_complete":
  67. return true;
  68. }
  69. }
  70. return FALSE;
  71. }
  72.  
  73.  
  74. function handle($argc, $argv) {
  75. debug_push($this->_debug_prefix . "handle");
  76. debug_pop();
  77. if ($argc == 0) {
  78. $this->_mode = "welcome";
  79. return true;
  80. }
  81. if ($argc == 1) {
  82. return $this->_init_view($argv[0]);
  83. }
  84. if ($argc == 2) {
  85. switch($argv[1]){
  86. case "res_start":
  87. return $this->_init_res_start($argv[0]);
  88. case "res_end":
  89. return $this->_init_res_end($argv[0]);
  90. case "res_detail":
  91. return $this->_init_res_detail($argv[0]);
  92. case "res_complete":
  93. return $this->_init_res_complete($argv[0]);
  94. }
  95. }
  96. $this->errcode = MIDCOM_ERRCRIT;
  97. $this->errstr = "Method unknown";
  98. return TRUE;
  99. }
  100. function show() {
  101. eval("\$this->_show_" . $this->_mode . "();");
  102. return TRUE;
  103. }
  104. /************** PAGE: Welcome ***************************/
  105.  
  106. function _show_welcome() {
  107. debug_push($this->_debug_prefix . "_show_welcome");
  108. midcom_show_style("heading-resource-index");
  109. midcom_show_style("resource-index-begin");
  110. $resources = net_nemein_reservations_resource::list_resources();
  111. if (count($resources) == 0) {
  112. midcom_show_style("resource-index-none");
  113. } else {
  114. foreach ($resources as $id => $resource) {
  115. $this->_resource = $resource;
  116. $GLOBALS["view_guid"] = $resource->person->guid();
  117. midcom_show_style("resource-index-item");
  118. }
  119. }
  120. midcom_show_style("resource-index-end");
  121. debug_pop();
  122. }
  123. /************** PAGE: Reservation step 1: Start time ***************************/
  124.  
  125. function _init_res_start($guid) {
  126. debug_push($this->_debug_prefix . "_init_res_start");
  127. // Load JScalendar
  128. $this->_prepare_jscalendar('net_nemein_reservations_form_start');
  129. $session = new midcom_service_session();
  130. $this->_resource = new net_nemein_reservations_resource($guid);
  131. if (! $this->_resource) {
  132. $this->errstr = "Failed to open resource. See Debug Log for details.";
  133. $this->errcode = MIDCOM_ERRNOTFOUND;
  134. debug_pop();
  135. return false;
  136. }
  137. $GLOBALS["net_nemein_reservations_current_leaf"] = $this->_resource->person->id;
  138. /* Do we have a cancel button. */
  139. if (array_key_exists("form_cancel", $_REQUEST)) {
  140. $this->_relocate($this->_resource->dm->data["_storage_guid"] . ".html");
  141. /* This will exit() */
  142. }
  143. /* Check for submit, if it is there, check the date. */
  144. if (array_key_exists("form_submit", $_REQUEST)) {
  145. if (! array_key_exists("form_start", $_REQUEST)) {
  146. $this->errstr = "Request incomplete";
  147. $this->errcode = MIDCOM_ERRCRIT;
  148. debug_print_r("Request was:", $_REQUEST);
  149. debug_pop();
  150. return false;
  151. }
  152. if (trim($_REQUEST["form_start"]) == "") {
  153. /* Error in timestamp */
  154. $session->set("reservation_errmsg", $this->_l10n->get("start time is invalid."));
  155. $this->_mode = "res_start";
  156. debug_pop();
  157. return true;
  158. }
  159. $start = strtotime($_REQUEST["form_start"]);
  160. if ($start == -1) {
  161. /* Error in timestamp */
  162. $session->set("reservation_errmsg", $this->_l10n->get("start time is invalid."));
  163. $this->_mode = "res_start";
  164. debug_pop();
  165. return true;
  166. }
  167. if ($start < time()) {
  168. /* Error in timestamp */
  169. $session->set("reservation_errmsg", $this->_l10n->get("start time is in the past."));
  170. $this->_mode = "res_start";
  171. debug_pop();
  172. return true;
  173. }
  174. /* Check for other events */
  175. $res = $this->_resource->get_reservation_at($start);
  176. $newstart = -1;
  177. while( ! is_null($res)
  178. && $res->event->end >= $start)
  179. {
  180. debug_print_r("The following event conflicts. searching a new start date and checking again:", $res->event);
  181. $newstart = $res->event->end + 1;
  182. $res = $this->_resource->get_reservation_at($newstart);
  183. }
  184. // TODO: Check wether the gap found is at least as wide as the buffer time
  185. //$next = array_shift($this->_resource->list_reservations($newstart));
  186. if ($newstart != -1) {
  187. $session->set("reservation_errmsg",
  188. $this->_l10n->get("this resource is already booked at that time. advanced to next free time gap"));
  189. $_REQUEST["form_start"] = strftime("%Y-%m-%d %H:%M:%S", $newstart);
  190. $this->_mode = "res_start";
  191. debug_pop();
  192. return true;
  193. }
  194. $session->set("reservation_start", $start);
  195. $this->_relocate($this->_resource->dm->data["_storage_guid"] . "/res_end.html");
  196. /* This will exit() */
  197. }
  198. /* Nothing happened so far */
  199. $this->_mode = "res_start";
  200. debug_pop();
  201. return true;
  202. }
  203. function _show_res_start() {
  204. midcom_show_style("heading-reservation-start");
  205. midcom_show_style("show-resource-short");
  206. midcom_show_style("reservation-errmsg");
  207. midcom_show_style("form-reservation-starttime");
  208. }
  209. /************** PAGE: Reservation step 2: End time ***************************/
  210.  
  211. function _init_res_end($guid) {
  212. debug_push($this->_debug_prefix . "_init_res_end");
  213. // Load JScalendar
  214. $this->_prepare_jscalendar('net_nemein_reservations_form_end');
  215. $session = new midcom_service_session();
  216. $this->_resource = new net_nemein_reservations_resource($guid);
  217. if (! $this->_resource) {
  218. $this->errstr = "Failed to open resource. See Debug Log for details.";
  219. $this->errcode = MIDCOM_ERRNOTFOUND;
  220. debug_pop();
  221. return false;
  222. }
  223. $GLOBALS["net_nemein_reservations_current_leaf"] = $this->_resource->person->id;
  224. /* Do we have a cancel button. */
  225. if (array_key_exists("form_cancel", $_REQUEST)) {
  226. $session->remove("reservation_start");
  227. $this->_relocate($this->_resource->dm->data["_storage_guid"] . ".html");
  228. /* This will exit() */
  229. }
  230. /* Check for submit, if it is there, check the date. */
  231. if (array_key_exists("form_submit", $_REQUEST)) {
  232. if (! array_key_exists("form_end", $_REQUEST)) {
  233. $this->errstr = "Request incomplete";
  234. $this->errcode = MIDCOM_ERRCRIT;
  235. debug_print_r("Request was:", $_REQUEST);
  236. debug_pop();
  237. return false;
  238. }
  239. if (trim($_REQUEST["form_end"]) == "") {
  240. /* Error in timestamp */
  241. $session->set("reservation_errmsg", $this->_l10n->get("end time is invalid."));
  242. $this->_mode = "res_end";
  243. debug_pop();
  244. return true;
  245. }
  246. $end = strtotime($_REQUEST["form_end"]);
  247. if ($end == -1) {
  248. /* Error in timestamp */
  249. $session->set("reservation_errmsg", $this->_l10n->get("end time is invalid."));
  250. $this->_mode = "res_end";
  251. debug_pop();
  252. return true;
  253. }
  254. /* Add buffer time to registration */
  255. $buffer = ((int) $this->_config->get("event_buffer_time")) * 60;
  256. $end += $buffer;
  257. $start = $session->get("reservation_start");
  258. if ($end < $start) {
  259. /* Error in timestamp */
  260. $session->set("reservation_errmsg", $this->_l10n->get("end time before start time."));
  261. $this->_mode = "res_end";
  262. debug_pop();
  263. return true;
  264. }
  265. /* Check for other events */
  266. $reservations = $this->_resource->list_reservations($start, $end);
  267. if (count($reservations) > 0) {
  268. foreach ($reservations as $id => $reservation) {
  269. if ($reservation->event->start > $end || $reservation->event->end < $start) {
  270. debug_print_r("Skipping this event, it is in the future.", $reservation->event);
  271. continue;
  272. }
  273. debug_add("Another reservation does already exist here, can't create another one.", MIDCOM_LOG_INFO);
  274. debug_print_r("Event was:", $reservation->event);
  275. $session->set("reservation_errmsg",
  276. $this->_l10n->get("this resource is already booked at that time. end time adjusted"));
  277. $_REQUEST["form_end"] = strftime("%Y-%m-%d %H:%M:%S", $reservation->event->start - $buffer - 1);
  278. $this->_mode = "res_end";
  279. debug_pop();
  280. return true;
  281. }
  282. }
  283. /* Ok, we have a valid timespan, lets create an event and redirect to stage 3 */
  284. $this->_su();
  285. $event = net_nemein_reservations_reservation::create_empty_event($start, $end, $this->_resource);
  286. if (is_null($event))
  287. {
  288. // Format errors before mgd_unsetuid'ing, or mgd_errstr gets lost.
  289. $this->errstr = "Could not create an empty event, this is critical: " . mgd_errstr();
  290. $this->errcode = MIDCOM_ERRCRIT;
  291. $this->_su(false);
  292. debug_pop();
  293. return false;
  294. }
  295. $event->parameter("midcom.helper.datamanager", "layout", $this->_config->get("schema_reservation"));
  296. $this->_su(false);
  297. $session->remove("reservation_start");
  298. $session->remove("reservation_end");
  299. $session->set("reservation_guid", $event->guid());
  300. $this->_relocate($this->_resource->dm->data["_storage_guid"] . "/res_detail.html");
  301. /* This will exit() */
  302. }
  303. /* Nothing happened so far */
  304. $this->_mode = "res_end";
  305. debug_pop();
  306. return true;
  307. }
  308. function _show_res_end() {
  309. midcom_show_style("heading-reservation-end");
  310. midcom_show_style("show-resource-short");
  311. midcom_show_style("reservation-errmsg");
  312. midcom_show_style("form-reservation-endtime");
  313. }
  314. /************** PAGE: Reservation step 3: Reservation details ***************************/
  315.  
  316. function _init_res_detail($guid) {
  317. debug_push($this->_debug_prefix . "_init_res_detail");
  318. $session = new midcom_service_session();
  319. $this->_resource = new net_nemein_reservations_resource($guid);
  320. if (! $this->_resource) {
  321. $this->errstr = "Failed to open resource. See Debug Log for details.";
  322. $this->errcode = MIDCOM_ERRNOTFOUND;
  323. debug_pop();
  324. return false;
  325. }
  326. $GLOBALS["net_nemein_reservations_current_leaf"] = $this->_resource->person->id;
  327. $this->_reservation = new net_nemein_reservations_reservation($session->get("reservation_guid"));
  328. if (! $this->_reservation) {
  329. $this->errstr = "Failed to open reservation. See Debug Log for details.";
  330. $this->errcode = MIDCOM_ERRNOTFOUND;
  331. debug_pop();
  332. return false;
  333. }
  334. $this->_su();
  335. $result = $this->_reservation->dm->process_form();
  336. $this->_su(false);
  337. $errors = $this->_reservation->dm->errstr;
  338. if (strlen(trim($errors)) > 0)
  339. $session->set("reservation_errmsg", $errors);
  340. switch ($result) {
  341. case MIDCOM_DATAMGR_EDITING:
  342. debug_add("Still editing");
  343. break;
  344. case MIDCOM_DATAMGR_SAVED:
  345. debug_add("Saved");
  346. $this->_su();
  347. $result = $this->_reservation->finish();
  348. $this->_su(false);
  349. if ($result) {
  350. $this->_relocate($this->_resource->dm->data["_storage_guid"] . "/res_complete.html");
  351. } else {
  352. // errstr is set by finsih().
  353. $this->errcode = MIDCOM_ERRCRIT;
  354. debug_pop();
  355. return false;
  356. }
  357. // Relocate to success
  358. break;
  359. case MIDCOM_DATAMGR_CANCELLED:
  360. debug_add("Cancelled");
  361. $this->_reservation->delete();
  362. $this->_relocate($this->_resource->dm->data["_storage_guid"] . ".html");
  363. break;
  364. case MIDCOM_DATAMGR_FAILED:
  365. $this->errstr = "Datamanager failed to process the form. See the debug log.";
  366. $this->errcode = MIDCOM_ERRCRIT;
  367. debug_pop();
  368. return false;
  369. default:
  370. $this->errstr = "Unknown Datamanager return code. See the debug log.";
  371. $this->errcode = MIDCOM_ERRCRIT;
  372. debug_pop();
  373. return false;
  374. }
  375. /* Nothing happened so far */
  376. $this->_mode = "res_detail";
  377. debug_pop();
  378. return true;
  379. }
  380. function _show_res_detail() {
  381. midcom_show_style("heading-reservation-detail");
  382. midcom_show_style("show-resource-short");
  383. midcom_show_style("reservation-errmsg");
  384. midcom_show_style("dmform-reservation");
  385. }
  386. /************** PAGE: Reservation step 4: Reservation complete ***************************/
  387.  
  388. function _init_res_complete($guid) {
  389. debug_push($this->_debug_prefix . "_init_res_complete");
  390. $session = new midcom_service_session();
  391. $this->_resource = new net_nemein_reservations_resource($guid);
  392. if (! $this->_resource) {
  393. $this->errstr = "Failed to open resource. See Debug Log for details.";
  394. $this->errcode = MIDCOM_ERRNOTFOUND;
  395. debug_pop();
  396. return false;
  397. }
  398. $GLOBALS["net_nemein_reservations_current_leaf"] = $this->_resource->person->id;
  399. $this->_reservation = new net_nemein_reservations_reservation($session->get("reservation_guid"));
  400. if (! $this->_reservation) {
  401. $this->errstr = "Failed to open reservation. See Debug Log for details.";
  402. $this->errcode = MIDCOM_ERRNOTFOUND;
  403. debug_pop();
  404. return false;
  405. }
  406. $session->remove("reservation_guid");
  407. /* Nothing happened so far */
  408. $this->_mode = "res_complete";
  409. debug_pop();
  410. return true;
  411. }
  412. function _show_res_complete() {
  413. midcom_show_style("heading-reservation-complete");
  414. midcom_show_style("show-resource-short");
  415. midcom_show_style("reservation-errmsg");
  416. midcom_show_style("dmview-reservation");
  417. }
  418. /************** PAGE: Resource Detail ***************************/
  419.  
  420. function _init_view($guid) {
  421. debug_push($this->_debug_prefix . "_init_view");
  422. $this->_resource = new net_nemein_reservations_resource($guid);
  423. if (! $this->_resource) {
  424. $this->errstr = "Failed to open resource. See Debug Log for details.";
  425. $this->errcode = MIDCOM_ERRNOTFOUND;
  426. debug_pop();
  427. return false;
  428. }
  429. $GLOBALS["net_nemein_reservations_current_leaf"] = $this->_resource->person->id;
  430. $this->_mode = "view";
  431. debug_pop();
  432. return true;
  433. }
  434. function _show_view() {
  435. midcom_show_style("heading-resource-view");
  436. midcom_show_style("show-resource");
  437. $this->_show_reservations_for_resource();
  438. }
  439. /************** PRIVATE HELPER METHODS **********************/
  440.  
  441. function _show_reservations_for_resource() {
  442. midcom_show_style("heading-reservations-index");
  443. midcom_show_style("reservations-index-start");
  444. $reservations = $this->_resource->list_reservations(time());
  445. if (count($reservations) == 0) {
  446. midcom_show_style("reservations-index-none");
  447. } else {
  448. foreach ($reservations as $id => $reservation) {
  449. $this->_reservation = $reservation;
  450. midcom_show_style("reservations-index-item");
  451. }
  452. }
  453. midcom_show_style("reservations-index-end");
  454. }
  455. function _su ($on = true) {
  456. if ( $_MIDGARD['admin']
  457. || mgd_is_event_owner($this->_root_event->id))
  458. {
  459. // No need to sudo, we already have write permissions
  460. return true;
  461. }
  462. if ($on) {
  463. if (! mgd_auth_midgard ($this->_config->get("admin_user"), $this->_config->get("admin_password"), false)) {
  464. $this->errstr = "mgd_auth_midgard to admin level user failed.";
  465. $this->errcode = MIDCOM_ERRFORBIDDEN;
  466. return false;
  467. } else {
  468. /* Call mgd_get_midgard, seems to be required according to emile/piotras */
  469. $midgard = mgd_get_midgard();
  470. debug_print_r("New midgard object is: ", $midgard);
  471. return true;
  472. }
  473. } else {
  474. $result = mgd_unsetuid();
  475. /* Call mgd_get_midgard, seems to be required according to emile/piotras */
  476. $unused = mgd_get_midgard();
  477. return $result;
  478. }
  479. }
  480. function _relocate ($url) {
  481. $GLOBALS["midcom"]->relocate(
  482. $GLOBALS["midcom"]->get_context_data(MIDCOM_CONTEXT_ANCHORPREFIX)
  483. . $url);
  484. }
  485. function _check_root_event () {
  486. debug_push($this->_debug_prefix . "_check_root_event" );
  487. $guid = $this->_config->get("root_event_guid");
  488. if (! is_null ($guid)) {
  489. $object = mgd_get_object_by_guid($guid);
  490. if (